diff --git a/test/fuzztest/audiodecoderape_fuzzer/BUILD.gn b/test/fuzztest/audiodecoderape_fuzzer/BUILD.gn index 716cf7d00bc0baafdd6ff2ab4047160a6f73dbe8..69b58de5b5b785ff507dd3dc242f19637c5c66bb 100644 --- a/test/fuzztest/audiodecoderape_fuzzer/BUILD.gn +++ b/test/fuzztest/audiodecoderape_fuzzer/BUILD.gn @@ -49,6 +49,7 @@ ohos_fuzztest("AudioDecoderApeFuzzTest") { ] sources = [ "audio_decoder_ape_demo.cpp", + "audio_decoder_ape_new_demo.cpp", "audiodecoderape_fuzzer.cpp", ] diff --git a/test/fuzztest/audiodecoderape_fuzzer/audio_decoder_ape_new_demo_new.cpp b/test/fuzztest/audiodecoderape_fuzzer/audio_decoder_ape_new_demo_new.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4554d6a43b1e2eb193808413026ef9d85e31dd03 --- /dev/null +++ b/test/fuzztest/audiodecoderape_fuzzer/audio_decoder_ape_new_demo_new.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2023 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_ape_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 supportedSampleRateSet[] = { + 44100, 48000, 88200, 96000, 176400, 192000, +}; +static int32_t supportedChannels[] = {1, 2}; +static OH_BitsPerSample supportedSampleFormats[] = { + OH_BitsPerSample::SAMPLE_S16LE, + OH_BitsPerSample::SAMPLE_S32LE, + OH_BitsPerSample::SAMPLE_U8, +}; +uint16_t supportedSampleRateSet_size = sizeof(supportedSampleRateSet) / sizeof(uint32_t); +uint16_t supportedChannels_size = sizeof(supportedChannels) / sizeof(int32_t); +uint16_t supportedSampleFormats_size = sizeof(supportedSampleFormats) / sizeof(OH_BitsPerSample); + + +void ApeFuzzDemo::RandomSetMeta(const uint8_t *data) +{ + int32_t channel = supportedChannels[(uint8_t)((*data) % supportedChannels_size)]; + data++; + uint32_t sampleRate = supportedSampleRateSet[(uint8_t)((*data) % supportedSampleRateSet_size)]; + data++; + OH_BitsPerSample sampleFormat = supportedSampleFormats[(uint8_t)((*data) % supportedSampleFormats_size)]; + OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), channel); + OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), sampleRate); + OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(), sampleFormat); + + return; +} + +bool ApeFuzzDemo::DoApeParserWithParserAPI(const uint8_t *data, size_t size) +{ + if (size < 4) { // 4 for ramdom set format data + return false; + } + signal_ = new ADecBufferSignal(); + + audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_APE_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 ApeFuzzDemo::Start() +{ + isRunning_.store(true); + OH_AudioCodec_Start(audioDec_); + inputLoop_ = make_unique(&ApeFuzzDemo::InputFunc, this); + DEMO_CHECK_AND_RETURN_RET_LOG(inputLoop_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory"); + + outputLoop_ = make_unique(&ApeFuzzDemo::OutputFunc, this); + DEMO_CHECK_AND_RETURN_RET_LOG(outputLoop_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory"); + + return AV_ERR_OK; +} + + +OH_AVErrCode ApeFuzzDemo::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 ApeFuzzDemo::Release() +{ + return OH_AudioCodec_Destroy(audioDec_); +} + +void ApeFuzzDemo::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 ApeFuzzDemo::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 diff --git a/test/fuzztest/audiodecoderape_fuzzer/audio_decoder_ape_new_demo_new.h b/test/fuzztest/audiodecoderape_fuzzer/audio_decoder_ape_new_demo_new.h new file mode 100644 index 0000000000000000000000000000000000000000..96c92af8e68d6bf62a04b8d01aeb8549ca1a6dd4 --- /dev/null +++ b/test/fuzztest/audiodecoderape_fuzzer/audio_decoder_ape_new_demo_new.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2023 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 stdl +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 ApeFuzzDemo : public NoCopyable { +public: + bool DoApeParserWithParserAPI(const uint8_t *data) +private: + void RandomSetMeta(const uint8_t *data); + 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_; + ADecBufferSignalv*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/audiodecoderape_fuzzer/audiodecoderape_fuzzer.cpp b/test/fuzztest/audiodecoderape_fuzzer/audiodecoderape_fuzzer.cpp index 717568b83675529d29ff987494d9260dfea9ee57..11e2cfe22e3c3e3ff926f9d9e01a51a75f0a0df0 100644 --- a/test/fuzztest/audiodecoderape_fuzzer/audiodecoderape_fuzzer.cpp +++ b/test/fuzztest/audiodecoderape_fuzzer/audiodecoderape_fuzzer.cpp @@ -19,12 +19,14 @@ #include #include #include "audio_decoder_ape_demo.h" +#include "audio_decoder_ape_new_demo.h" #define FUZZ_PROJECT_NAME "audiodecoderape_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,8 @@ bool AudioDecoderAPEFuzzTest(const uint8_t *data, size_t size) if (size < sizeof(int64_t)) { return false; } + // FUZZ ape new + ApeFuzzDemo* apeFuzzDemo = new ApeFuzzDemo(); // FUZZ ape ADecBufferDemo* aDecBufferDemo = new ADecBufferDemo(); aDecBufferDemo->InitFile("ape");