diff --git a/test/fuzztest/audiodecoderaac_fuzzer/BUILD.gn b/test/fuzztest/audiodecoderaac_fuzzer/BUILD.gn index 6a0a0b5ddfc83caa9cf2416e0b1ed15fb7900166..f80319a1d1713040da4f2d8e55caff69569d7b4d 100644 --- a/test/fuzztest/audiodecoderaac_fuzzer/BUILD.gn +++ b/test/fuzztest/audiodecoderaac_fuzzer/BUILD.gn @@ -49,6 +49,7 @@ ohos_fuzztest("AudioDecoderAacFuzzTest") { ] sources = [ "audio_decoder_aac_demo.cpp", + "audio_decoder_aac_new_demo.cpp", "audiodecoderaac_fuzzer.cpp", ] diff --git a/test/fuzztest/audiodecoderaac_fuzzer/audio_decoder_aac_new_demo.cpp b/test/fuzztest/audiodecoderaac_fuzzer/audio_decoder_aac_new_demo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a9162489870ff241b4ce1db169012bb859f6986e --- /dev/null +++ b/test/fuzztest/audiodecoderaac_fuzzer/audio_decoder_aac_new_demo.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "avcodec_codec_name.h" +#include "avcodec_errors.h" +#include "demo_log.h" +#include "media_description.h" +#include "native_avcodec_base.h" +#include "native_avformat.h" +#include "native_avbuffer.h" +#include "audio_decoder_aac_new_demo.h" + +using namespace std; +using namespace OHOS; +using namespace OHOS::Media; +using namespace OHOS::MediaAVCodec; +using namespace OHOS::MediaAVCodec::AudioBufferNewDemo; + +namespace OHOS { +static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData) +{ + return; +} + +static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData) +{ + cout << "OnOutputFormatChanged received" << endl; + return; +} + +static void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) +{ + ADecBufferSignal *signal = static_cast(userData); + unique_lock lock(signal->inMutex_); + signal->inQueue_.push(index); + signal->inBufferQueue_.push(data); + signal->inCond_.notify_all(); +} + +static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) +{ + ADecBufferSignal *signal = static_cast(userData); + unique_lock lock(signal->outMutex_); + signal->outQueue_.push(index); + signal->outBufferQueue_.push(data); + signal->outCond_.notify_all(); +} + +static uint32_t g_supportedSampleRateSet[] = { + 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000}; +static int32_t g_supportedChannels[] = {1, 2, 3, 4, 5, 6, 7, 8}; // 2 for max channel + +uint16_t g_supportedSampleRateSetSize = sizeof(g_supportedSampleRateSet) / sizeof(g_supportedSampleRateSet[0]); +uint16_t g_supportedChannelsSize = sizeof(g_supportedChannels) / sizeof(g_supportedChannels[0]); + + +void AacFuzzDemo::RandomSetMeta(const uint8_t *data) +{ + int32_t channel = g_supportedChannels[static_cast((*data) % g_supportedChannelsSize)]; + data++; + uint32_t sampleRate = g_supportedSampleRateSet[static_cast((*data) % g_supportedSampleRateSetSize)]; + data++; + OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), channel); + OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), sampleRate); + + return; +} + +bool AacFuzzDemo::DoAacParserWithParserAPI(const uint8_t *data, size_t size) +{ + if (size < 2) { // 2 for ramdom set format data + return false; + } + signal_ = new ADecBufferSignal(); + + audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AAC_NAME).data()); + cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable}; + DEMO_CHECK_AND_RETURN_RET_LOG(OH_AudioCodec_RegisterCallback(audioDec_, cb_, signal_) == AV_ERR_OK, + false, "Fatal: OH_AudioCodec_RegisterCallback fail"); + format = OH_AVFormat_Create(); + RandomSetMeta(data); + data_ = data; + size_ = size; + Start(); + Stop(); + Release(); + return true; +} + +OH_AVErrCode AacFuzzDemo::Start() +{ + isRunning_.store(true); + OH_AudioCodec_Start(audioDec_); + inputLoop_ = make_unique(&AacFuzzDemo::InputFunc, this); + DEMO_CHECK_AND_RETURN_RET_LOG(inputLoop_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory"); + + outputLoop_ = make_unique(&AacFuzzDemo::OutputFunc, this); + DEMO_CHECK_AND_RETURN_RET_LOG(outputLoop_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory"); + + return AV_ERR_OK; +} + + +OH_AVErrCode AacFuzzDemo::Stop() +{ + isRunning_.store(false); + if (inputLoop_ != nullptr && inputLoop_->joinable()) { + { + unique_lock lock(signal_->inMutex_); + signal_->inCond_.notify_all(); + } + inputLoop_->join(); + inputLoop_ = nullptr; + + while (!signal_->inQueue_.empty()) { + signal_->inQueue_.pop(); + } + + while (!signal_->inBufferQueue_.empty()) { + signal_->inBufferQueue_.pop(); + } + } + if (outputLoop_ != nullptr && outputLoop_->joinable()) { + { + unique_lock lock(signal_->outMutex_); + signal_->outCond_.notify_all(); + } + outputLoop_->join(); + outputLoop_ = nullptr; + while (!signal_->outQueue_.empty()) { + signal_->outQueue_.pop(); + } + while (!signal_->outBufferQueue_.empty()) { + signal_->outBufferQueue_.pop(); + } + } + return OH_AudioCodec_Stop(audioDec_); +} + +int32_t AacFuzzDemo::Release() +{ + return OH_AudioCodec_Destroy(audioDec_); +} + +void AacFuzzDemo::InputFunc() +{ + while (isRunning_.load()) { + unique_lock lock(signal_->inMutex_); + signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); }); + if (!isRunning_.load()) { + break; + } + uint32_t index = signal_->inQueue_.front(); + auto buffer = signal_->inBufferQueue_.front(); + DEMO_CHECK_AND_BREAK_LOG(buffer != nullptr, "Fatal: GetInputBuffer fail"); + DEMO_CHECK_AND_BREAK_LOG(size_ < sizeof(buffer->buffer_->flag_), "Fatal: GetInputBuffer fail"); + memcpy_s(reinterpret_cast(&buffer->buffer_->pts_), + sizeof(buffer->buffer_->pts_), data_, sizeof(buffer->buffer_->pts_)); + memcpy_s(reinterpret_cast(&buffer->buffer_->flag_), + sizeof(buffer->buffer_->flag_), data_, sizeof(buffer->buffer_->flag_)); + memcpy_s(reinterpret_cast(OH_AVBuffer_GetAddr(buffer)), size_, + data_, size_); + buffer->buffer_->memory_->SetSize(size_); + OH_AudioCodec_PushInputBuffer(audioDec_, index); + signal_->inQueue_.pop(); + signal_->inBufferQueue_.pop(); + } +} + +void AacFuzzDemo::OutputFunc() +{ + while (isRunning_.load()) { + unique_lock lock(signal_->outMutex_); + signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); }); + if (!isRunning_.load()) { + cout << "wait to stop, exit" << endl; + break; + } + + uint32_t index = signal_->outQueue_.front(); + signal_->outBufferQueue_.front(); + signal_->outBufferQueue_.pop(); + signal_->outQueue_.pop(); + OH_AudioCodec_FreeOutputBuffer(audioDec_, index); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/fuzztest/audiodecoderaac_fuzzer/audio_decoder_aac_new_demo.h b/test/fuzztest/audiodecoderaac_fuzzer/audio_decoder_aac_new_demo.h new file mode 100644 index 0000000000000000000000000000000000000000..c61f9bec45a95458213981e396b57a17f691d2f9 --- /dev/null +++ b/test/fuzztest/audiodecoderaac_fuzzer/audio_decoder_aac_new_demo.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AVCODEC_AUDIO_AVBUFFER_DECODER_NEW_DEMO_H +#define AVCODEC_AUDIO_AVBUFFER_DECODER_NEW_DEMO_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "native_avcodec_audiocodec.h" +#include "nocopyable.h" +#include "common/native_mfmagic.h" +#include "avcodec_audio_common.h" + +namespace OHOS { +namespace MediaAVCodec { +namespace AudioBufferNewDemo { + +using namespace std; +using namespace OHOS::Media; + +class ADecBufferSignal { +public: + std::mutex inMutex_; + std::mutex outMutex_; + std::mutex startMutex_; + std::condition_variable inCond_; + std::condition_variable outCond_; + std::condition_variable startCond_; + std::queue inQueue_; + std::queue outQueue_; + std::queue inBufferQueue_; + std::queue outBufferQueue_; +}; + +class AacFuzzDemo : public NoCopyable { +public: + void RandomSetMeta(const uint8_t *data); + bool DoAacParserWithParserAPI(const uint8_t *data, size_t size); +private: + void WriteData(); + + OH_AVErrCode Start(); + OH_AVErrCode Stop(); + OH_AVErrCode Flush(); + OH_AVErrCode Reset(); + int32_t Release(); + void InputFunc(); + void OutputFunc(); + + int32_t decodeMaxInput; + int32_t decodeMaxOutput; + shared_ptr inputBuffer; + shared_ptr outputBuffer; + OH_AVCodec *audioDec_; + struct OH_AVCodecCallback cb_; + ADecBufferSignal *signal_; + OH_AVFormat *format; + std::atomic isRunning_ = false; + std::unique_ptr inputLoop_; + std::unique_ptr outputLoop_; + const uint8_t *data_; + size_t size_; +}; +} // namespace AudioBufferNewDemo +} // namespace MediaAVCodec +} // namespace OHOS +#endif // AVCODEC_AUDIO_AVBUFFER_DECODER_NEW_DEMO_H \ No newline at end of file diff --git a/test/fuzztest/audiodecoderaac_fuzzer/audiodecoderaac_fuzzer.cpp b/test/fuzztest/audiodecoderaac_fuzzer/audiodecoderaac_fuzzer.cpp index 8345a357024c751c7ca6498c5d6539e6ec4499a8..e28ba8acf093ab1af75f53f751eb51b1c565bbed 100644 --- a/test/fuzztest/audiodecoderaac_fuzzer/audiodecoderaac_fuzzer.cpp +++ b/test/fuzztest/audiodecoderaac_fuzzer/audiodecoderaac_fuzzer.cpp @@ -19,12 +19,14 @@ #include #include #include "audio_decoder_aac_demo.h" +#include "audio_decoder_aac_new_demo.h" #define FUZZ_PROJECT_NAME "audiodecoderaac_fuzzer" using namespace std; using namespace OHOS::MediaAVCodec; using namespace OHOS; using namespace OHOS::MediaAVCodec::AudioBufferDemo; +using namespace OHOS::MediaAVCodec::AudioBufferNewDemo; namespace OHOS { @@ -33,6 +35,9 @@ bool AudioDecoderAACFuzzTest(const uint8_t *data, size_t size) if (size < sizeof(int64_t)) { return false; } + // FUZZ aac new + AacFuzzDemo* aacFuzzDemo = new AacFuzzDemo(); + aacFuzzDemo->DoAacParserWithParserAPI(data, size); // FUZZ aac ADecBufferDemo* aDecBufferDemo = new ADecBufferDemo(); aDecBufferDemo->InitFile("aac");