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