1da853ecaSopenharmony_ci/* 2da853ecaSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 3da853ecaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4da853ecaSopenharmony_ci * you may not use this file except in compliance with the License. 5da853ecaSopenharmony_ci * You may obtain a copy of the License at 6da853ecaSopenharmony_ci * 7da853ecaSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8da853ecaSopenharmony_ci * 9da853ecaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10da853ecaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11da853ecaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12da853ecaSopenharmony_ci * See the License for the specific language governing permissions and 13da853ecaSopenharmony_ci * limitations under the License. 14da853ecaSopenharmony_ci */ 15da853ecaSopenharmony_ci#include <arpa/inet.h> 16da853ecaSopenharmony_ci#include <sys/time.h> 17da853ecaSopenharmony_ci#include <utility> 18da853ecaSopenharmony_ci#include "videodec_sample.h" 19da853ecaSopenharmony_ci#include "native_avcapability.h" 20da853ecaSopenharmony_ciusing namespace OHOS; 21da853ecaSopenharmony_ciusing namespace OHOS::Media; 22da853ecaSopenharmony_ciusing namespace std; 23da853ecaSopenharmony_cinamespace { 24da853ecaSopenharmony_ciconstexpr int64_t NANOS_IN_SECOND = 1000000000L; 25da853ecaSopenharmony_ciconstexpr int64_t NANOS_IN_MICRO = 1000L; 26da853ecaSopenharmony_ciconstexpr int32_t EIGHT = 8; 27da853ecaSopenharmony_ciconstexpr int32_t SIXTEEN = 16; 28da853ecaSopenharmony_ciconstexpr int32_t TWENTY_FOUR = 24; 29da853ecaSopenharmony_ciconstexpr uint8_t H264_NALU_TYPE = 0x1f; 30da853ecaSopenharmony_ciconstexpr uint32_t START_CODE_SIZE = 4; 31da853ecaSopenharmony_ciconstexpr uint8_t START_CODE[START_CODE_SIZE] = {0, 0, 0, 1}; 32da853ecaSopenharmony_ciconstexpr uint8_t SEI = 6; 33da853ecaSopenharmony_ciconstexpr uint8_t SPS = 7; 34da853ecaSopenharmony_ciconstexpr uint8_t PPS = 8; 35da853ecaSopenharmony_ci 36da853ecaSopenharmony_ciVDecFuzzSample *g_decSample = nullptr; 37da853ecaSopenharmony_cibool g_fuzzError = false; 38da853ecaSopenharmony_civoid clearIntqueue(std::queue<uint32_t> &q) 39da853ecaSopenharmony_ci{ 40da853ecaSopenharmony_ci std::queue<uint32_t> empty; 41da853ecaSopenharmony_ci swap(empty, q); 42da853ecaSopenharmony_ci} 43da853ecaSopenharmony_ci 44da853ecaSopenharmony_civoid clearBufferqueue(std::queue<OH_AVCodecBufferAttr> &q) 45da853ecaSopenharmony_ci{ 46da853ecaSopenharmony_ci std::queue<OH_AVCodecBufferAttr> empty; 47da853ecaSopenharmony_ci swap(empty, q); 48da853ecaSopenharmony_ci} 49da853ecaSopenharmony_ci 50da853ecaSopenharmony_civoid clearAvBufferQueue(std::queue<OH_AVMemory *> &q) 51da853ecaSopenharmony_ci{ 52da853ecaSopenharmony_ci std::queue<OH_AVMemory *> empty; 53da853ecaSopenharmony_ci swap(empty, q); 54da853ecaSopenharmony_ci} 55da853ecaSopenharmony_ci} // namespace 56da853ecaSopenharmony_ci 57da853ecaSopenharmony_ciclass TestConsumerListener : public IBufferConsumerListener { 58da853ecaSopenharmony_cipublic: 59da853ecaSopenharmony_ci TestConsumerListener(sptr<Surface> cs) : cs(cs) {}; 60da853ecaSopenharmony_ci ~TestConsumerListener() {} 61da853ecaSopenharmony_ci void OnBufferAvailable() override 62da853ecaSopenharmony_ci { 63da853ecaSopenharmony_ci sptr<SurfaceBuffer> buffer; 64da853ecaSopenharmony_ci int32_t flushFence; 65da853ecaSopenharmony_ci cs->AcquireBuffer(buffer, flushFence, timestamp, damage); 66da853ecaSopenharmony_ci 67da853ecaSopenharmony_ci cs->ReleaseBuffer(buffer, -1); 68da853ecaSopenharmony_ci } 69da853ecaSopenharmony_ci 70da853ecaSopenharmony_ciprivate: 71da853ecaSopenharmony_ci int64_t timestamp = 0; 72da853ecaSopenharmony_ci Rect damage = {}; 73da853ecaSopenharmony_ci sptr<Surface> cs {nullptr}; 74da853ecaSopenharmony_ci}; 75da853ecaSopenharmony_ci 76da853ecaSopenharmony_ciVDecFuzzSample::~VDecFuzzSample() 77da853ecaSopenharmony_ci{ 78da853ecaSopenharmony_ci if (nativeWindow) { 79da853ecaSopenharmony_ci OH_NativeWindow_DestroyNativeWindow(nativeWindow); 80da853ecaSopenharmony_ci nativeWindow = nullptr; 81da853ecaSopenharmony_ci } 82da853ecaSopenharmony_ci Stop(); 83da853ecaSopenharmony_ci Release(); 84da853ecaSopenharmony_ci} 85da853ecaSopenharmony_ci 86da853ecaSopenharmony_civoid VdecError(OH_AVCodec *codec, int32_t errorCode, void *userData) 87da853ecaSopenharmony_ci{ 88da853ecaSopenharmony_ci cout << "Error errorCode=" << errorCode << endl; 89da853ecaSopenharmony_ci} 90da853ecaSopenharmony_ci 91da853ecaSopenharmony_civoid VdecFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData) 92da853ecaSopenharmony_ci{ 93da853ecaSopenharmony_ci int32_t currentWidth = 0; 94da853ecaSopenharmony_ci int32_t currentHeight = 0; 95da853ecaSopenharmony_ci OH_AVFormat_GetIntValue(format, OH_MD_KEY_WIDTH, ¤tWidth); 96da853ecaSopenharmony_ci OH_AVFormat_GetIntValue(format, OH_MD_KEY_HEIGHT, ¤tHeight); 97da853ecaSopenharmony_ci g_decSample->defaultWidth = currentWidth; 98da853ecaSopenharmony_ci g_decSample->defaultHeight = currentHeight; 99da853ecaSopenharmony_ci} 100da853ecaSopenharmony_ci 101da853ecaSopenharmony_civoid VdecInputDataReady(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, void *userData) 102da853ecaSopenharmony_ci{ 103da853ecaSopenharmony_ci VDecSignal *signal = static_cast<VDecSignal *>(userData); 104da853ecaSopenharmony_ci unique_lock<mutex> lock(signal->inMutex_); 105da853ecaSopenharmony_ci signal->inIdxQueue_.push(index); 106da853ecaSopenharmony_ci signal->inBufferQueue_.push(data); 107da853ecaSopenharmony_ci signal->inCond_.notify_all(); 108da853ecaSopenharmony_ci} 109da853ecaSopenharmony_ci 110da853ecaSopenharmony_civoid VdecOutputDataReady(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, OH_AVCodecBufferAttr *attr, 111da853ecaSopenharmony_ci void *userData) 112da853ecaSopenharmony_ci{ 113da853ecaSopenharmony_ci if (g_decSample->isSurfMode) { 114da853ecaSopenharmony_ci OH_VideoDecoder_RenderOutputData(codec, index); 115da853ecaSopenharmony_ci } else { 116da853ecaSopenharmony_ci OH_VideoDecoder_FreeOutputData(codec, index); 117da853ecaSopenharmony_ci } 118da853ecaSopenharmony_ci} 119da853ecaSopenharmony_ci 120da853ecaSopenharmony_ciint64_t VDecFuzzSample::GetSystemTimeUs() 121da853ecaSopenharmony_ci{ 122da853ecaSopenharmony_ci struct timespec now; 123da853ecaSopenharmony_ci (void)clock_gettime(CLOCK_BOOTTIME, &now); 124da853ecaSopenharmony_ci int64_t nanoTime = static_cast<int64_t>(now.tv_sec) * NANOS_IN_SECOND + now.tv_nsec; 125da853ecaSopenharmony_ci return nanoTime / NANOS_IN_MICRO; 126da853ecaSopenharmony_ci} 127da853ecaSopenharmony_ci 128da853ecaSopenharmony_ciint32_t VDecFuzzSample::ConfigureVideoDecoder() 129da853ecaSopenharmony_ci{ 130da853ecaSopenharmony_ci OH_AVFormat *format = OH_AVFormat_Create(); 131da853ecaSopenharmony_ci if (format == nullptr) { 132da853ecaSopenharmony_ci cout << "Fatal: Failed to create format" << endl; 133da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 134da853ecaSopenharmony_ci } 135da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, defaultWidth); 136da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, defaultHeight); 137da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_ROTATION, defaultRotation); 138da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, defaultPixelFormat); 139da853ecaSopenharmony_ci int ret = OH_VideoDecoder_Configure(vdec_, format); 140da853ecaSopenharmony_ci OH_AVFormat_Destroy(format); 141da853ecaSopenharmony_ci if (isSurfMode) { 142da853ecaSopenharmony_ci cs = Surface::CreateSurfaceAsConsumer(); 143da853ecaSopenharmony_ci sptr<IBufferConsumerListener> listener = new TestConsumerListener(cs); 144da853ecaSopenharmony_ci cs->RegisterConsumerListener(listener); 145da853ecaSopenharmony_ci auto p = cs->GetProducer(); 146da853ecaSopenharmony_ci ps = Surface::CreateSurfaceAsProducer(p); 147da853ecaSopenharmony_ci nativeWindow = CreateNativeWindowFromSurface(&ps); 148da853ecaSopenharmony_ci OH_VideoDecoder_SetSurface(vdec_, nativeWindow); 149da853ecaSopenharmony_ci } 150da853ecaSopenharmony_ci return ret; 151da853ecaSopenharmony_ci} 152da853ecaSopenharmony_ci 153da853ecaSopenharmony_ciint32_t VDecFuzzSample::RunVideoDec() 154da853ecaSopenharmony_ci{ 155da853ecaSopenharmony_ci int err = CreateVideoDecoder(); 156da853ecaSopenharmony_ci if (err != AV_ERR_OK) { 157da853ecaSopenharmony_ci cout << "Failed to create video decoder" << endl; 158da853ecaSopenharmony_ci return err; 159da853ecaSopenharmony_ci } 160da853ecaSopenharmony_ci 161da853ecaSopenharmony_ci err = ConfigureVideoDecoder(); 162da853ecaSopenharmony_ci if (err != AV_ERR_OK) { 163da853ecaSopenharmony_ci cout << "Failed to configure video decoder" << endl; 164da853ecaSopenharmony_ci Release(); 165da853ecaSopenharmony_ci return err; 166da853ecaSopenharmony_ci } 167da853ecaSopenharmony_ci 168da853ecaSopenharmony_ci err = SetVideoDecoderCallback(); 169da853ecaSopenharmony_ci if (err != AV_ERR_OK) { 170da853ecaSopenharmony_ci cout << "Failed to setCallback" << endl; 171da853ecaSopenharmony_ci Release(); 172da853ecaSopenharmony_ci return err; 173da853ecaSopenharmony_ci } 174da853ecaSopenharmony_ci 175da853ecaSopenharmony_ci err = StartVideoDecoder(); 176da853ecaSopenharmony_ci if (err != AV_ERR_OK) { 177da853ecaSopenharmony_ci cout << "Failed to start video decoder" << endl; 178da853ecaSopenharmony_ci Release(); 179da853ecaSopenharmony_ci return err; 180da853ecaSopenharmony_ci } 181da853ecaSopenharmony_ci return err; 182da853ecaSopenharmony_ci} 183da853ecaSopenharmony_ci 184da853ecaSopenharmony_ciint32_t VDecFuzzSample::SetVideoDecoderCallback() 185da853ecaSopenharmony_ci{ 186da853ecaSopenharmony_ci signal_ = new VDecSignal(); 187da853ecaSopenharmony_ci if (signal_ == nullptr) { 188da853ecaSopenharmony_ci cout << "Failed to new VDecSignal" << endl; 189da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 190da853ecaSopenharmony_ci } 191da853ecaSopenharmony_ci 192da853ecaSopenharmony_ci cb_.onError = VdecError; 193da853ecaSopenharmony_ci cb_.onStreamChanged = VdecFormatChanged; 194da853ecaSopenharmony_ci cb_.onNeedInputData = VdecInputDataReady; 195da853ecaSopenharmony_ci cb_.onNeedOutputData = VdecOutputDataReady; 196da853ecaSopenharmony_ci return OH_VideoDecoder_SetCallback(vdec_, cb_, static_cast<void *>(signal_)); 197da853ecaSopenharmony_ci} 198da853ecaSopenharmony_ci 199da853ecaSopenharmony_civoid VDecFuzzSample::ReleaseInFile() 200da853ecaSopenharmony_ci{ 201da853ecaSopenharmony_ci if (inFile_ != nullptr) { 202da853ecaSopenharmony_ci if (inFile_->is_open()) { 203da853ecaSopenharmony_ci inFile_->close(); 204da853ecaSopenharmony_ci } 205da853ecaSopenharmony_ci inFile_.reset(); 206da853ecaSopenharmony_ci inFile_ = nullptr; 207da853ecaSopenharmony_ci } 208da853ecaSopenharmony_ci} 209da853ecaSopenharmony_ci 210da853ecaSopenharmony_civoid VDecFuzzSample::StopInLoop() 211da853ecaSopenharmony_ci{ 212da853ecaSopenharmony_ci if (inputLoop_ != nullptr && inputLoop_->joinable()) { 213da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 214da853ecaSopenharmony_ci clearIntqueue(signal_->inIdxQueue_); 215da853ecaSopenharmony_ci signal_->inCond_.notify_all(); 216da853ecaSopenharmony_ci lock.unlock(); 217da853ecaSopenharmony_ci 218da853ecaSopenharmony_ci inputLoop_->join(); 219da853ecaSopenharmony_ci inputLoop_.reset(); 220da853ecaSopenharmony_ci } 221da853ecaSopenharmony_ci} 222da853ecaSopenharmony_ci 223da853ecaSopenharmony_ciint32_t VDecFuzzSample::StartVideoDecoder() 224da853ecaSopenharmony_ci{ 225da853ecaSopenharmony_ci int ret = OH_VideoDecoder_Start(vdec_); 226da853ecaSopenharmony_ci if (ret != AV_ERR_OK) { 227da853ecaSopenharmony_ci cout << "Failed to start codec" << endl; 228da853ecaSopenharmony_ci return ret; 229da853ecaSopenharmony_ci } 230da853ecaSopenharmony_ci isRunning_.store(true); 231da853ecaSopenharmony_ci inFile_ = make_unique<ifstream>(); 232da853ecaSopenharmony_ci if (inFile_ == nullptr) { 233da853ecaSopenharmony_ci isRunning_.store(false); 234da853ecaSopenharmony_ci (void)OH_VideoDecoder_Stop(vdec_); 235da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 236da853ecaSopenharmony_ci } 237da853ecaSopenharmony_ci inFile_->open(inpDir, ios::in | ios::binary); 238da853ecaSopenharmony_ci if (!inFile_->is_open()) { 239da853ecaSopenharmony_ci cout << "failed open file " << endl; 240da853ecaSopenharmony_ci isRunning_.store(false); 241da853ecaSopenharmony_ci (void)OH_VideoDecoder_Stop(vdec_); 242da853ecaSopenharmony_ci inFile_->close(); 243da853ecaSopenharmony_ci inFile_.reset(); 244da853ecaSopenharmony_ci inFile_ = nullptr; 245da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 246da853ecaSopenharmony_ci } 247da853ecaSopenharmony_ci 248da853ecaSopenharmony_ci inputLoop_ = make_unique<thread>(&VDecFuzzSample::InputFuncAVCC, this); 249da853ecaSopenharmony_ci if (inputLoop_ == nullptr) { 250da853ecaSopenharmony_ci cout << "Failed to create input loop" << endl; 251da853ecaSopenharmony_ci isRunning_.store(false); 252da853ecaSopenharmony_ci (void)OH_VideoDecoder_Stop(vdec_); 253da853ecaSopenharmony_ci ReleaseInFile(); 254da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 255da853ecaSopenharmony_ci } 256da853ecaSopenharmony_ci return AV_ERR_OK; 257da853ecaSopenharmony_ci} 258da853ecaSopenharmony_ci 259da853ecaSopenharmony_ciint32_t VDecFuzzSample::CreateVideoDecoder() 260da853ecaSopenharmony_ci{ 261da853ecaSopenharmony_ci OH_AVCapability *cap = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, HARDWARE); 262da853ecaSopenharmony_ci string codecName = OH_AVCapability_GetName(cap); 263da853ecaSopenharmony_ci vdec_ = OH_VideoDecoder_CreateByName("aabbcc"); 264da853ecaSopenharmony_ci if (vdec_) { 265da853ecaSopenharmony_ci OH_VideoDecoder_Destroy(vdec_); 266da853ecaSopenharmony_ci vdec_ = nullptr; 267da853ecaSopenharmony_ci } 268da853ecaSopenharmony_ci OH_AVCodec *tmpDec = OH_VideoDecoder_CreateByMime("aabbcc"); 269da853ecaSopenharmony_ci if (tmpDec) { 270da853ecaSopenharmony_ci OH_VideoDecoder_Destroy(tmpDec); 271da853ecaSopenharmony_ci tmpDec = nullptr; 272da853ecaSopenharmony_ci } 273da853ecaSopenharmony_ci tmpDec = OH_VideoDecoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 274da853ecaSopenharmony_ci if (tmpDec) { 275da853ecaSopenharmony_ci OH_VideoDecoder_Destroy(tmpDec); 276da853ecaSopenharmony_ci tmpDec = nullptr; 277da853ecaSopenharmony_ci } 278da853ecaSopenharmony_ci vdec_ = OH_VideoDecoder_CreateByName(codecName.c_str()); 279da853ecaSopenharmony_ci g_decSample = this; 280da853ecaSopenharmony_ci return vdec_ == nullptr ? AV_ERR_UNKNOWN : AV_ERR_OK; 281da853ecaSopenharmony_ci} 282da853ecaSopenharmony_ci 283da853ecaSopenharmony_civoid VDecFuzzSample::WaitForEOS() 284da853ecaSopenharmony_ci{ 285da853ecaSopenharmony_ci if (inputLoop_ && inputLoop_->joinable()) { 286da853ecaSopenharmony_ci inputLoop_->join(); 287da853ecaSopenharmony_ci } 288da853ecaSopenharmony_ci} 289da853ecaSopenharmony_ci 290da853ecaSopenharmony_civoid VDecFuzzSample::CopyStartCode(uint8_t *frameBuffer, uint32_t bufferSize, OH_AVCodecBufferAttr &attr) 291da853ecaSopenharmony_ci{ 292da853ecaSopenharmony_ci switch (frameBuffer[START_CODE_SIZE] & H264_NALU_TYPE) { 293da853ecaSopenharmony_ci case SPS: 294da853ecaSopenharmony_ci case PPS: 295da853ecaSopenharmony_ci case SEI: 296da853ecaSopenharmony_ci if (memcpy_s(frameBuffer, bufferSize + START_CODE_SIZE, START_CODE, START_CODE_SIZE) != EOK) { 297da853ecaSopenharmony_ci cout << "Fatal: memory copy failed" << endl; 298da853ecaSopenharmony_ci } 299da853ecaSopenharmony_ci attr.pts = GetSystemTimeUs(); 300da853ecaSopenharmony_ci attr.size = bufferSize + START_CODE_SIZE; 301da853ecaSopenharmony_ci attr.offset = 0; 302da853ecaSopenharmony_ci attr.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA; 303da853ecaSopenharmony_ci break; 304da853ecaSopenharmony_ci default: { 305da853ecaSopenharmony_ci if (memcpy_s(frameBuffer, bufferSize + START_CODE_SIZE, START_CODE, START_CODE_SIZE) != EOK) { 306da853ecaSopenharmony_ci cout << "Fatal: memory copy failed" << endl; 307da853ecaSopenharmony_ci } 308da853ecaSopenharmony_ci attr.pts = GetSystemTimeUs(); 309da853ecaSopenharmony_ci attr.size = bufferSize + START_CODE_SIZE; 310da853ecaSopenharmony_ci attr.offset = 0; 311da853ecaSopenharmony_ci attr.flags = AVCODEC_BUFFER_FLAGS_NONE; 312da853ecaSopenharmony_ci } 313da853ecaSopenharmony_ci } 314da853ecaSopenharmony_ci} 315da853ecaSopenharmony_ci 316da853ecaSopenharmony_ciint32_t VDecFuzzSample::ReadData(uint32_t index, OH_AVMemory *buffer) 317da853ecaSopenharmony_ci{ 318da853ecaSopenharmony_ci uint8_t ch[4] = {}; 319da853ecaSopenharmony_ci (void)inFile_->read(reinterpret_cast<char *>(ch), START_CODE_SIZE); 320da853ecaSopenharmony_ci if (inFile_->eof()) { 321da853ecaSopenharmony_ci SetEOS(index); 322da853ecaSopenharmony_ci return 1; 323da853ecaSopenharmony_ci } 324da853ecaSopenharmony_ci uint32_t bufferSize = static_cast<uint32_t>(((ch[3] & 0xFF)) | ((ch[2] & 0xFF) << EIGHT) | 325da853ecaSopenharmony_ci ((ch[1] & 0xFF) << SIXTEEN) | ((ch[0] & 0xFF) << TWENTY_FOUR)); 326da853ecaSopenharmony_ci 327da853ecaSopenharmony_ci return SendData(bufferSize, index, buffer); 328da853ecaSopenharmony_ci} 329da853ecaSopenharmony_ci 330da853ecaSopenharmony_ciuint32_t VDecFuzzSample::SendData(uint32_t bufferSize, uint32_t index, OH_AVMemory *buffer) 331da853ecaSopenharmony_ci{ 332da853ecaSopenharmony_ci OH_AVCodecBufferAttr attr; 333da853ecaSopenharmony_ci uint8_t *frameBuffer = new uint8_t[bufferSize + START_CODE_SIZE]; 334da853ecaSopenharmony_ci (void)inFile_->read(reinterpret_cast<char *>(frameBuffer + START_CODE_SIZE), bufferSize); 335da853ecaSopenharmony_ci CopyStartCode(frameBuffer, bufferSize, attr); 336da853ecaSopenharmony_ci int32_t size = OH_AVMemory_GetSize(buffer); 337da853ecaSopenharmony_ci if (size < attr.size) { 338da853ecaSopenharmony_ci delete[] frameBuffer; 339da853ecaSopenharmony_ci isRunning_.store(false); 340da853ecaSopenharmony_ci return 1; 341da853ecaSopenharmony_ci } 342da853ecaSopenharmony_ci uint8_t *bufferAddr = OH_AVMemory_GetAddr(buffer); 343da853ecaSopenharmony_ci if (memcpy_s(bufferAddr, size, frameBuffer, attr.size) != EOK) { 344da853ecaSopenharmony_ci delete[] frameBuffer; 345da853ecaSopenharmony_ci isRunning_.store(false); 346da853ecaSopenharmony_ci return 1; 347da853ecaSopenharmony_ci } 348da853ecaSopenharmony_ci delete[] frameBuffer; 349da853ecaSopenharmony_ci int32_t ret = OH_VideoDecoder_PushInputData(vdec_, index, attr); 350da853ecaSopenharmony_ci if (ret != AV_ERR_OK) { 351da853ecaSopenharmony_ci errCount++; 352da853ecaSopenharmony_ci } 353da853ecaSopenharmony_ci frameCount_++; 354da853ecaSopenharmony_ci if (inFile_->eof()) { 355da853ecaSopenharmony_ci isRunning_.store(false); 356da853ecaSopenharmony_ci } 357da853ecaSopenharmony_ci return 0; 358da853ecaSopenharmony_ci} 359da853ecaSopenharmony_ci 360da853ecaSopenharmony_civoid VDecFuzzSample::InputFuncAVCC() 361da853ecaSopenharmony_ci{ 362da853ecaSopenharmony_ci frameCount_ = 1; 363da853ecaSopenharmony_ci errCount = 0; 364da853ecaSopenharmony_ci while (true) { 365da853ecaSopenharmony_ci if (!isRunning_.load()) { 366da853ecaSopenharmony_ci break; 367da853ecaSopenharmony_ci } 368da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 369da853ecaSopenharmony_ci signal_->inCond_.wait(lock, [this]() { 370da853ecaSopenharmony_ci if (!isRunning_.load()) { 371da853ecaSopenharmony_ci cout << "quit signal" << endl; 372da853ecaSopenharmony_ci return true; 373da853ecaSopenharmony_ci } 374da853ecaSopenharmony_ci return signal_->inIdxQueue_.size() > 0; 375da853ecaSopenharmony_ci }); 376da853ecaSopenharmony_ci if (!isRunning_.load()) { 377da853ecaSopenharmony_ci break; 378da853ecaSopenharmony_ci } 379da853ecaSopenharmony_ci uint32_t index = signal_->inIdxQueue_.front(); 380da853ecaSopenharmony_ci auto buffer = signal_->inBufferQueue_.front(); 381da853ecaSopenharmony_ci signal_->inIdxQueue_.pop(); 382da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 383da853ecaSopenharmony_ci lock.unlock(); 384da853ecaSopenharmony_ci if (!inFile_->eof()) { 385da853ecaSopenharmony_ci int ret = ReadData(index, buffer); 386da853ecaSopenharmony_ci if (ret == 1) { 387da853ecaSopenharmony_ci break; 388da853ecaSopenharmony_ci } 389da853ecaSopenharmony_ci } 390da853ecaSopenharmony_ci } 391da853ecaSopenharmony_ci} 392da853ecaSopenharmony_ci 393da853ecaSopenharmony_ciOH_AVErrCode VDecFuzzSample::InputFuncFUZZ(const uint8_t *data, size_t size) 394da853ecaSopenharmony_ci{ 395da853ecaSopenharmony_ci uint32_t index; 396da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 397da853ecaSopenharmony_ci signal_->inCond_.wait(lock, [this]() { 398da853ecaSopenharmony_ci if (!isRunning_.load() && g_fuzzError) { 399da853ecaSopenharmony_ci return true; 400da853ecaSopenharmony_ci } 401da853ecaSopenharmony_ci return signal_->inIdxQueue_.size() > 0; 402da853ecaSopenharmony_ci }); 403da853ecaSopenharmony_ci if (g_fuzzError) 404da853ecaSopenharmony_ci return AV_ERR_TIMEOUT; 405da853ecaSopenharmony_ci index = signal_->inIdxQueue_.front(); 406da853ecaSopenharmony_ci auto buffer = signal_->inBufferQueue_.front(); 407da853ecaSopenharmony_ci lock.unlock(); 408da853ecaSopenharmony_ci int32_t bufferSize = OH_AVMemory_GetSize(buffer); 409da853ecaSopenharmony_ci uint8_t *bufferAddr = OH_AVMemory_GetAddr(buffer); 410da853ecaSopenharmony_ci 411da853ecaSopenharmony_ci if (memcpy_s(bufferAddr, bufferSize, data, size) != EOK) { 412da853ecaSopenharmony_ci cout << "Fatal: memcpy fail" << endl; 413da853ecaSopenharmony_ci return AV_ERR_NO_MEMORY; 414da853ecaSopenharmony_ci } 415da853ecaSopenharmony_ci OH_AVCodecBufferAttr attr; 416da853ecaSopenharmony_ci attr.pts = GetSystemTimeUs(); 417da853ecaSopenharmony_ci attr.size = bufferSize; 418da853ecaSopenharmony_ci attr.offset = 0; 419da853ecaSopenharmony_ci attr.flags = AVCODEC_BUFFER_FLAGS_NONE; 420da853ecaSopenharmony_ci OH_AVErrCode ret = OH_VideoDecoder_PushInputData(vdec_, index, attr); 421da853ecaSopenharmony_ci signal_->inIdxQueue_.pop(); 422da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 423da853ecaSopenharmony_ci return ret; 424da853ecaSopenharmony_ci} 425da853ecaSopenharmony_ci 426da853ecaSopenharmony_civoid VDecFuzzSample::SetEOS(uint32_t index) 427da853ecaSopenharmony_ci{ 428da853ecaSopenharmony_ci OH_AVCodecBufferAttr attr; 429da853ecaSopenharmony_ci attr.pts = 0; 430da853ecaSopenharmony_ci attr.size = 0; 431da853ecaSopenharmony_ci attr.offset = 0; 432da853ecaSopenharmony_ci attr.flags = AVCODEC_BUFFER_FLAGS_EOS; 433da853ecaSopenharmony_ci int32_t res = OH_VideoDecoder_PushInputData(vdec_, index, attr); 434da853ecaSopenharmony_ci cout << "OH_VideoDecoder_PushInputData EOS res: " << res << endl; 435da853ecaSopenharmony_ci} 436da853ecaSopenharmony_ci 437da853ecaSopenharmony_ciint32_t VDecFuzzSample::Flush() 438da853ecaSopenharmony_ci{ 439da853ecaSopenharmony_ci unique_lock<mutex> inLock(signal_->inMutex_); 440da853ecaSopenharmony_ci clearIntqueue(signal_->inIdxQueue_); 441da853ecaSopenharmony_ci signal_->inCond_.notify_all(); 442da853ecaSopenharmony_ci inLock.unlock(); 443da853ecaSopenharmony_ci unique_lock<mutex> outLock(signal_->outMutex_); 444da853ecaSopenharmony_ci clearIntqueue(signal_->outIdxQueue_); 445da853ecaSopenharmony_ci clearBufferqueue(signal_->attrQueue_); 446da853ecaSopenharmony_ci signal_->outCond_.notify_all(); 447da853ecaSopenharmony_ci outLock.unlock(); 448da853ecaSopenharmony_ci isRunning_.store(false); 449da853ecaSopenharmony_ci return OH_VideoDecoder_Flush(vdec_); 450da853ecaSopenharmony_ci} 451da853ecaSopenharmony_ci 452da853ecaSopenharmony_ciint32_t VDecFuzzSample::Reset() 453da853ecaSopenharmony_ci{ 454da853ecaSopenharmony_ci isRunning_.store(false); 455da853ecaSopenharmony_ci StopInLoop(); 456da853ecaSopenharmony_ci ReleaseInFile(); 457da853ecaSopenharmony_ci return OH_VideoDecoder_Reset(vdec_); 458da853ecaSopenharmony_ci} 459da853ecaSopenharmony_ci 460da853ecaSopenharmony_ciint32_t VDecFuzzSample::Release() 461da853ecaSopenharmony_ci{ 462da853ecaSopenharmony_ci int ret = 0; 463da853ecaSopenharmony_ci if (vdec_ != nullptr) { 464da853ecaSopenharmony_ci ret = OH_VideoDecoder_Destroy(vdec_); 465da853ecaSopenharmony_ci vdec_ = nullptr; 466da853ecaSopenharmony_ci } 467da853ecaSopenharmony_ci 468da853ecaSopenharmony_ci if (signal_ != nullptr) { 469da853ecaSopenharmony_ci clearAvBufferQueue(signal_->inBufferQueue_); 470da853ecaSopenharmony_ci delete signal_; 471da853ecaSopenharmony_ci signal_ = nullptr; 472da853ecaSopenharmony_ci } 473da853ecaSopenharmony_ci return ret; 474da853ecaSopenharmony_ci} 475da853ecaSopenharmony_ci 476da853ecaSopenharmony_ciint32_t VDecFuzzSample::Stop() 477da853ecaSopenharmony_ci{ 478da853ecaSopenharmony_ci StopInLoop(); 479da853ecaSopenharmony_ci clearIntqueue(signal_->outIdxQueue_); 480da853ecaSopenharmony_ci clearBufferqueue(signal_->attrQueue_); 481da853ecaSopenharmony_ci ReleaseInFile(); 482da853ecaSopenharmony_ci return OH_VideoDecoder_Stop(vdec_); 483da853ecaSopenharmony_ci} 484da853ecaSopenharmony_ci 485da853ecaSopenharmony_ciint32_t VDecFuzzSample::Start() 486da853ecaSopenharmony_ci{ 487da853ecaSopenharmony_ci int32_t ret = OH_VideoDecoder_Start(vdec_); 488da853ecaSopenharmony_ci if (ret == AV_ERR_OK) { 489da853ecaSopenharmony_ci isRunning_.store(true); 490da853ecaSopenharmony_ci } 491da853ecaSopenharmony_ci return ret; 492da853ecaSopenharmony_ci} 493da853ecaSopenharmony_ci 494da853ecaSopenharmony_civoid VDecFuzzSample::SetParameter(int32_t data) 495da853ecaSopenharmony_ci{ 496da853ecaSopenharmony_ci OH_AVFormat *format = OH_AVFormat_Create(); 497da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, data); 498da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, data); 499da853ecaSopenharmony_ci OH_VideoDecoder_SetParameter(vdec_, format); 500da853ecaSopenharmony_ci OH_AVFormat_Destroy(format); 501da853ecaSopenharmony_ci}