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 "openssl/crypto.h" 19da853ecaSopenharmony_ci#include "openssl/sha.h" 20da853ecaSopenharmony_ci#include "videoenc_sample.h" 21da853ecaSopenharmony_ciusing namespace OHOS; 22da853ecaSopenharmony_ciusing namespace OHOS::Media; 23da853ecaSopenharmony_ciusing namespace std; 24da853ecaSopenharmony_cinamespace { 25da853ecaSopenharmony_ciconstexpr int64_t NANOS_IN_SECOND = 1000000000L; 26da853ecaSopenharmony_ciconstexpr int64_t NANOS_IN_MICRO = 1000L; 27da853ecaSopenharmony_ciconstexpr uint32_t FRAME_INTERVAL = 16666; 28da853ecaSopenharmony_ciconstexpr uint32_t MAX_PIXEL_FMT = 5; 29da853ecaSopenharmony_ciconstexpr uint8_t RGBA_SIZE = 4; 30da853ecaSopenharmony_ciconstexpr uint32_t IDR_FRAME_INTERVAL = 10; 31da853ecaSopenharmony_ciconstexpr uint32_t DOUBLE = 2; 32da853ecaSopenharmony_ciVEncFuzzSample *g_encSample = nullptr; 33da853ecaSopenharmony_ci 34da853ecaSopenharmony_civoid clearIntqueue(std::queue<uint32_t> &q) 35da853ecaSopenharmony_ci{ 36da853ecaSopenharmony_ci std::queue<uint32_t> empty; 37da853ecaSopenharmony_ci swap(empty, q); 38da853ecaSopenharmony_ci} 39da853ecaSopenharmony_ci 40da853ecaSopenharmony_civoid clearBufferqueue(std::queue<OH_AVCodecBufferAttr> &q) 41da853ecaSopenharmony_ci{ 42da853ecaSopenharmony_ci std::queue<OH_AVCodecBufferAttr> empty; 43da853ecaSopenharmony_ci swap(empty, q); 44da853ecaSopenharmony_ci} 45da853ecaSopenharmony_ci} // namespace 46da853ecaSopenharmony_ci 47da853ecaSopenharmony_ciVEncFuzzSample::~VEncFuzzSample() 48da853ecaSopenharmony_ci{ 49da853ecaSopenharmony_ci Release(); 50da853ecaSopenharmony_ci} 51da853ecaSopenharmony_ci 52da853ecaSopenharmony_cistatic void VencError(OH_AVCodec *codec, int32_t errorCode, void *userData) 53da853ecaSopenharmony_ci{ 54da853ecaSopenharmony_ci cout << "Error errorCode=" << errorCode << endl; 55da853ecaSopenharmony_ci} 56da853ecaSopenharmony_ci 57da853ecaSopenharmony_cistatic void VencFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData) 58da853ecaSopenharmony_ci{ 59da853ecaSopenharmony_ci cout << "Format Changed" << endl; 60da853ecaSopenharmony_ci} 61da853ecaSopenharmony_ci 62da853ecaSopenharmony_cistatic void VencInputDataReady(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, void *userData) 63da853ecaSopenharmony_ci{ 64da853ecaSopenharmony_ci VEncSignal *signal = static_cast<VEncSignal *>(userData); 65da853ecaSopenharmony_ci unique_lock<mutex> lock(signal->inMutex_); 66da853ecaSopenharmony_ci signal->inIdxQueue_.push(index); 67da853ecaSopenharmony_ci signal->inBufferQueue_.push(data); 68da853ecaSopenharmony_ci signal->inCond_.notify_all(); 69da853ecaSopenharmony_ci} 70da853ecaSopenharmony_ci 71da853ecaSopenharmony_cistatic void VencOutputDataReady(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, OH_AVCodecBufferAttr *attr, 72da853ecaSopenharmony_ci void *userData) 73da853ecaSopenharmony_ci{ 74da853ecaSopenharmony_ci VEncSignal *signal = static_cast<VEncSignal *>(userData); 75da853ecaSopenharmony_ci unique_lock<mutex> lock(signal->outMutex_); 76da853ecaSopenharmony_ci signal->outIdxQueue_.push(index); 77da853ecaSopenharmony_ci signal->attrQueue_.push(*attr); 78da853ecaSopenharmony_ci signal->outBufferQueue_.push(data); 79da853ecaSopenharmony_ci signal->outCond_.notify_all(); 80da853ecaSopenharmony_ci} 81da853ecaSopenharmony_ciint64_t VEncFuzzSample::GetSystemTimeUs() 82da853ecaSopenharmony_ci{ 83da853ecaSopenharmony_ci struct timespec now; 84da853ecaSopenharmony_ci (void)clock_gettime(CLOCK_BOOTTIME, &now); 85da853ecaSopenharmony_ci int64_t nanoTime = static_cast<int64_t>(now.tv_sec) * NANOS_IN_SECOND + now.tv_nsec; 86da853ecaSopenharmony_ci return nanoTime / NANOS_IN_MICRO; 87da853ecaSopenharmony_ci} 88da853ecaSopenharmony_ci 89da853ecaSopenharmony_ciint32_t VEncFuzzSample::ConfigureVideoEncoder() 90da853ecaSopenharmony_ci{ 91da853ecaSopenharmony_ci OH_AVFormat *format = OH_AVFormat_Create(); 92da853ecaSopenharmony_ci if (format == nullptr) { 93da853ecaSopenharmony_ci cout << "Fatal: Failed to create format" << endl; 94da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 95da853ecaSopenharmony_ci } 96da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, defaultWidth); 97da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, defaultHeight); 98da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, defaultPixFmt); 99da853ecaSopenharmony_ci (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, defaultFrameRate); 100da853ecaSopenharmony_ci (void)OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, defaultBitrate); 101da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_I_FRAME_INTERVAL, defaultKeyFrameInterval); 102da853ecaSopenharmony_ci if (defaultBitrateMode == CQ) { 103da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_QUALITY, defaultQuality); 104da853ecaSopenharmony_ci } 105da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, defaultBitrateMode); 106da853ecaSopenharmony_ci int ret = OH_VideoEncoder_Configure(venc_, format); 107da853ecaSopenharmony_ci OH_AVFormat_Destroy(format); 108da853ecaSopenharmony_ci return ret; 109da853ecaSopenharmony_ci} 110da853ecaSopenharmony_ci 111da853ecaSopenharmony_ciint32_t VEncFuzzSample::ConfigureVideoEncoderFuzz(int32_t data) 112da853ecaSopenharmony_ci{ 113da853ecaSopenharmony_ci OH_VideoEncoder_Reset(venc_); 114da853ecaSopenharmony_ci OH_AVFormat *format = OH_AVFormat_Create(); 115da853ecaSopenharmony_ci if (format == nullptr) { 116da853ecaSopenharmony_ci cout << "Fatal: Failed to create format" << endl; 117da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 118da853ecaSopenharmony_ci } 119da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, data); 120da853ecaSopenharmony_ci defaultWidth = data; 121da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, data); 122da853ecaSopenharmony_ci defaultHeight = data; 123da853ecaSopenharmony_ci (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, data % MAX_PIXEL_FMT); 124da853ecaSopenharmony_ci double frameRate = data; 125da853ecaSopenharmony_ci (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, frameRate); 126da853ecaSopenharmony_ci 127da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_RANGE_FLAG, data); 128da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_COLOR_PRIMARIES, data); 129da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_TRANSFER_CHARACTERISTICS, data); 130da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_MATRIX_COEFFICIENTS, data); 131da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_I_FRAME_INTERVAL, data); 132da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, data); 133da853ecaSopenharmony_ci OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, data); 134da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_QUALITY, data); 135da853ecaSopenharmony_ci 136da853ecaSopenharmony_ci int ret = OH_VideoEncoder_Configure(venc_, format); 137da853ecaSopenharmony_ci OH_AVFormat_Destroy(format); 138da853ecaSopenharmony_ci return ret; 139da853ecaSopenharmony_ci} 140da853ecaSopenharmony_ci 141da853ecaSopenharmony_ciint32_t VEncFuzzSample::SetVideoEncoderCallback() 142da853ecaSopenharmony_ci{ 143da853ecaSopenharmony_ci signal_ = new VEncSignal(); 144da853ecaSopenharmony_ci if (signal_ == nullptr) { 145da853ecaSopenharmony_ci cout << "Failed to new VEncSignal" << endl; 146da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 147da853ecaSopenharmony_ci } 148da853ecaSopenharmony_ci 149da853ecaSopenharmony_ci cb_.onError = VencError; 150da853ecaSopenharmony_ci cb_.onStreamChanged = VencFormatChanged; 151da853ecaSopenharmony_ci cb_.onNeedInputData = VencInputDataReady; 152da853ecaSopenharmony_ci cb_.onNeedOutputData = VencOutputDataReady; 153da853ecaSopenharmony_ci return OH_VideoEncoder_SetCallback(venc_, cb_, static_cast<void *>(signal_)); 154da853ecaSopenharmony_ci} 155da853ecaSopenharmony_ci 156da853ecaSopenharmony_civoid VEncFuzzSample::ReleaseInFile() 157da853ecaSopenharmony_ci{ 158da853ecaSopenharmony_ci if (inFile_ != nullptr) { 159da853ecaSopenharmony_ci if (inFile_->is_open()) { 160da853ecaSopenharmony_ci inFile_->close(); 161da853ecaSopenharmony_ci } 162da853ecaSopenharmony_ci inFile_.reset(); 163da853ecaSopenharmony_ci inFile_ = nullptr; 164da853ecaSopenharmony_ci } 165da853ecaSopenharmony_ci} 166da853ecaSopenharmony_ci 167da853ecaSopenharmony_civoid VEncFuzzSample::StopInloop() 168da853ecaSopenharmony_ci{ 169da853ecaSopenharmony_ci if (inputLoop_ != nullptr && inputLoop_->joinable()) { 170da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 171da853ecaSopenharmony_ci clearIntqueue(signal_->inIdxQueue_); 172da853ecaSopenharmony_ci isRunning_.store(false); 173da853ecaSopenharmony_ci signal_->inCond_.notify_all(); 174da853ecaSopenharmony_ci lock.unlock(); 175da853ecaSopenharmony_ci 176da853ecaSopenharmony_ci inputLoop_->join(); 177da853ecaSopenharmony_ci inputLoop_ = nullptr; 178da853ecaSopenharmony_ci } 179da853ecaSopenharmony_ci} 180da853ecaSopenharmony_ci 181da853ecaSopenharmony_civoid VEncFuzzSample::GetStride() 182da853ecaSopenharmony_ci{ 183da853ecaSopenharmony_ci OH_AVFormat *format = OH_VideoEncoder_GetInputDescription(venc_); 184da853ecaSopenharmony_ci int32_t inputStride = 0; 185da853ecaSopenharmony_ci OH_AVFormat_GetIntValue(format, "stride", &inputStride); 186da853ecaSopenharmony_ci stride_ = inputStride; 187da853ecaSopenharmony_ci OH_AVFormat_Destroy(format); 188da853ecaSopenharmony_ci} 189da853ecaSopenharmony_ci 190da853ecaSopenharmony_ciint32_t VEncFuzzSample::OpenFile() 191da853ecaSopenharmony_ci{ 192da853ecaSopenharmony_ci if (fuzzMode) { 193da853ecaSopenharmony_ci return AV_ERR_OK; 194da853ecaSopenharmony_ci } 195da853ecaSopenharmony_ci int32_t ret = AV_ERR_OK; 196da853ecaSopenharmony_ci inFile_ = make_unique<ifstream>(); 197da853ecaSopenharmony_ci if (inFile_ == nullptr) { 198da853ecaSopenharmony_ci isRunning_.store(false); 199da853ecaSopenharmony_ci (void)OH_VideoEncoder_Stop(venc_); 200da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 201da853ecaSopenharmony_ci } 202da853ecaSopenharmony_ci inFile_->open(inpDir, ios::in | ios::binary); 203da853ecaSopenharmony_ci if (!inFile_->is_open()) { 204da853ecaSopenharmony_ci cout << "file open fail" << endl; 205da853ecaSopenharmony_ci isRunning_.store(false); 206da853ecaSopenharmony_ci (void)OH_VideoEncoder_Stop(venc_); 207da853ecaSopenharmony_ci inFile_->close(); 208da853ecaSopenharmony_ci inFile_.reset(); 209da853ecaSopenharmony_ci inFile_ = nullptr; 210da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 211da853ecaSopenharmony_ci } 212da853ecaSopenharmony_ci return ret; 213da853ecaSopenharmony_ci} 214da853ecaSopenharmony_ci 215da853ecaSopenharmony_ciint32_t VEncFuzzSample::StartVideoEncoder() 216da853ecaSopenharmony_ci{ 217da853ecaSopenharmony_ci isRunning_.store(true); 218da853ecaSopenharmony_ci int32_t ret = 0; 219da853ecaSopenharmony_ci OH_VideoEncoder_Start(venc_); 220da853ecaSopenharmony_ci OH_VideoEncoder_Stop(venc_); 221da853ecaSopenharmony_ci Flush(); 222da853ecaSopenharmony_ci ret = OH_VideoEncoder_Start(venc_); 223da853ecaSopenharmony_ci GetStride(); 224da853ecaSopenharmony_ci if (ret != AV_ERR_OK) { 225da853ecaSopenharmony_ci cout << "Failed to start codec" << endl; 226da853ecaSopenharmony_ci isRunning_.store(false); 227da853ecaSopenharmony_ci signal_->inCond_.notify_all(); 228da853ecaSopenharmony_ci signal_->outCond_.notify_all(); 229da853ecaSopenharmony_ci return ret; 230da853ecaSopenharmony_ci } 231da853ecaSopenharmony_ci if (OpenFile() != AV_ERR_OK) { 232da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 233da853ecaSopenharmony_ci } 234da853ecaSopenharmony_ci 235da853ecaSopenharmony_ci inputLoop_ = make_unique<thread>(&VEncFuzzSample::InputFunc, this); 236da853ecaSopenharmony_ci 237da853ecaSopenharmony_ci if (inputLoop_ == nullptr) { 238da853ecaSopenharmony_ci isRunning_.store(false); 239da853ecaSopenharmony_ci (void)OH_VideoEncoder_Stop(venc_); 240da853ecaSopenharmony_ci ReleaseInFile(); 241da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 242da853ecaSopenharmony_ci } 243da853ecaSopenharmony_ci outputLoop_ = make_unique<thread>(&VEncFuzzSample::OutputFunc, this); 244da853ecaSopenharmony_ci if (outputLoop_ == nullptr) { 245da853ecaSopenharmony_ci isRunning_.store(false); 246da853ecaSopenharmony_ci (void)OH_VideoEncoder_Stop(venc_); 247da853ecaSopenharmony_ci ReleaseInFile(); 248da853ecaSopenharmony_ci StopInloop(); 249da853ecaSopenharmony_ci Release(); 250da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 251da853ecaSopenharmony_ci } 252da853ecaSopenharmony_ci return AV_ERR_OK; 253da853ecaSopenharmony_ci} 254da853ecaSopenharmony_ci 255da853ecaSopenharmony_ciint32_t VEncFuzzSample::CreateVideoEncoder(const char *codecName) 256da853ecaSopenharmony_ci{ 257da853ecaSopenharmony_ci venc_ = OH_VideoEncoder_CreateByMime("aabbcc"); 258da853ecaSopenharmony_ci if (venc_) { 259da853ecaSopenharmony_ci OH_VideoEncoder_Destroy(venc_); 260da853ecaSopenharmony_ci venc_ = nullptr; 261da853ecaSopenharmony_ci } 262da853ecaSopenharmony_ci venc_ = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 263da853ecaSopenharmony_ci if (venc_) { 264da853ecaSopenharmony_ci OH_VideoEncoder_Destroy(venc_); 265da853ecaSopenharmony_ci venc_ = nullptr; 266da853ecaSopenharmony_ci } 267da853ecaSopenharmony_ci venc_ = OH_VideoEncoder_CreateByName("aabbcc"); 268da853ecaSopenharmony_ci if (venc_) { 269da853ecaSopenharmony_ci OH_VideoEncoder_Destroy(venc_); 270da853ecaSopenharmony_ci venc_ = nullptr; 271da853ecaSopenharmony_ci } 272da853ecaSopenharmony_ci venc_ = OH_VideoEncoder_CreateByName(codecName); 273da853ecaSopenharmony_ci g_encSample = this; 274da853ecaSopenharmony_ci return venc_ == nullptr ? AV_ERR_UNKNOWN : AV_ERR_OK; 275da853ecaSopenharmony_ci} 276da853ecaSopenharmony_ci 277da853ecaSopenharmony_civoid VEncFuzzSample::WaitForEOS() 278da853ecaSopenharmony_ci{ 279da853ecaSopenharmony_ci if (inputLoop_) 280da853ecaSopenharmony_ci inputLoop_->join(); 281da853ecaSopenharmony_ci if (outputLoop_) 282da853ecaSopenharmony_ci outputLoop_->join(); 283da853ecaSopenharmony_ci inputLoop_ = nullptr; 284da853ecaSopenharmony_ci outputLoop_ = nullptr; 285da853ecaSopenharmony_ci} 286da853ecaSopenharmony_ci 287da853ecaSopenharmony_ciuint32_t VEncFuzzSample::ReturnZeroIfEOS(uint32_t expectedSize) 288da853ecaSopenharmony_ci{ 289da853ecaSopenharmony_ci if (inFile_->gcount() != (expectedSize)) { 290da853ecaSopenharmony_ci cout << "no more data" << endl; 291da853ecaSopenharmony_ci return 0; 292da853ecaSopenharmony_ci } 293da853ecaSopenharmony_ci return 1; 294da853ecaSopenharmony_ci} 295da853ecaSopenharmony_ci 296da853ecaSopenharmony_ciuint32_t VEncFuzzSample::ReadOneFrameYUV420SP(uint8_t *dst) 297da853ecaSopenharmony_ci{ 298da853ecaSopenharmony_ci uint8_t *start = dst; 299da853ecaSopenharmony_ci // copy Y 300da853ecaSopenharmony_ci for (uint32_t i = 0; i < defaultHeight; i++) { 301da853ecaSopenharmony_ci inFile_->read(reinterpret_cast<char *>(dst), defaultWidth); 302da853ecaSopenharmony_ci if (!ReturnZeroIfEOS(defaultWidth)) { 303da853ecaSopenharmony_ci return 0; 304da853ecaSopenharmony_ci } 305da853ecaSopenharmony_ci dst += stride_; 306da853ecaSopenharmony_ci } 307da853ecaSopenharmony_ci // copy UV 308da853ecaSopenharmony_ci for (uint32_t i = 0; i < defaultHeight / sampleRatio; i++) { 309da853ecaSopenharmony_ci inFile_->read(reinterpret_cast<char *>(dst), defaultWidth); 310da853ecaSopenharmony_ci if (!ReturnZeroIfEOS(defaultWidth)) { 311da853ecaSopenharmony_ci return 0; 312da853ecaSopenharmony_ci } 313da853ecaSopenharmony_ci dst += stride_; 314da853ecaSopenharmony_ci } 315da853ecaSopenharmony_ci return dst - start; 316da853ecaSopenharmony_ci} 317da853ecaSopenharmony_ci 318da853ecaSopenharmony_civoid VEncFuzzSample::ReadOneFrameRGBA8888(uint8_t *dst) 319da853ecaSopenharmony_ci{ 320da853ecaSopenharmony_ci for (uint32_t i = 0; i < defaultHeight; i++) { 321da853ecaSopenharmony_ci inFile_->read(reinterpret_cast<char *>(dst), defaultWidth * RGBA_SIZE); 322da853ecaSopenharmony_ci dst += stride_; 323da853ecaSopenharmony_ci } 324da853ecaSopenharmony_ci} 325da853ecaSopenharmony_ci 326da853ecaSopenharmony_civoid VEncFuzzSample::SetEOS(uint32_t index) 327da853ecaSopenharmony_ci{ 328da853ecaSopenharmony_ci OH_AVCodecBufferAttr attr; 329da853ecaSopenharmony_ci attr.pts = 0; 330da853ecaSopenharmony_ci attr.size = 0; 331da853ecaSopenharmony_ci attr.offset = 0; 332da853ecaSopenharmony_ci attr.flags = AVCODEC_BUFFER_FLAGS_EOS; 333da853ecaSopenharmony_ci int32_t res = OH_VideoEncoder_PushInputData(venc_, index, attr); 334da853ecaSopenharmony_ci cout << "OH_VideoEncoder_PushInputData EOS res: " << res << endl; 335da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 336da853ecaSopenharmony_ci signal_->inIdxQueue_.pop(); 337da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 338da853ecaSopenharmony_ci} 339da853ecaSopenharmony_ci 340da853ecaSopenharmony_civoid VEncFuzzSample::SetForceIDR() 341da853ecaSopenharmony_ci{ 342da853ecaSopenharmony_ci OH_AVFormat *format = OH_AVFormat_Create(); 343da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_REQUEST_I_FRAME, 1); 344da853ecaSopenharmony_ci OH_VideoEncoder_SetParameter(venc_, format); 345da853ecaSopenharmony_ci OH_AVFormat_Destroy(format); 346da853ecaSopenharmony_ci} 347da853ecaSopenharmony_ci 348da853ecaSopenharmony_ciint32_t VEncFuzzSample::PushData(OH_AVMemory *buffer, uint32_t index, int32_t &result) 349da853ecaSopenharmony_ci{ 350da853ecaSopenharmony_ci int32_t res = -2; 351da853ecaSopenharmony_ci OH_AVCodecBufferAttr attr; 352da853ecaSopenharmony_ci uint8_t *fileBuffer = OH_AVMemory_GetAddr(buffer); 353da853ecaSopenharmony_ci if (fileBuffer == nullptr) { 354da853ecaSopenharmony_ci cout << "Fatal: no memory" << endl; 355da853ecaSopenharmony_ci return -1; 356da853ecaSopenharmony_ci } 357da853ecaSopenharmony_ci int32_t size = OH_AVMemory_GetSize(buffer); 358da853ecaSopenharmony_ci if (defaultPixFmt == AV_PIXEL_FORMAT_RGBA) { 359da853ecaSopenharmony_ci if (size < defaultHeight * stride_) { 360da853ecaSopenharmony_ci return -1; 361da853ecaSopenharmony_ci } 362da853ecaSopenharmony_ci ReadOneFrameRGBA8888(fileBuffer); 363da853ecaSopenharmony_ci attr.size = stride_ * defaultHeight; 364da853ecaSopenharmony_ci } else { 365da853ecaSopenharmony_ci if (size < (defaultHeight * stride_ + (defaultHeight * stride_ / DOUBLE))) { 366da853ecaSopenharmony_ci return -1; 367da853ecaSopenharmony_ci } 368da853ecaSopenharmony_ci attr.size = ReadOneFrameYUV420SP(fileBuffer); 369da853ecaSopenharmony_ci } 370da853ecaSopenharmony_ci if (inFile_->eof()) { 371da853ecaSopenharmony_ci SetEOS(index); 372da853ecaSopenharmony_ci return 0; 373da853ecaSopenharmony_ci } 374da853ecaSopenharmony_ci attr.pts = GetSystemTimeUs(); 375da853ecaSopenharmony_ci attr.offset = 0; 376da853ecaSopenharmony_ci attr.flags = AVCODEC_BUFFER_FLAGS_NONE; 377da853ecaSopenharmony_ci if (enableForceIDR && (frameCount % IDR_FRAME_INTERVAL == 0)) { 378da853ecaSopenharmony_ci SetForceIDR(); 379da853ecaSopenharmony_ci } 380da853ecaSopenharmony_ci result = OH_VideoEncoder_PushInputData(venc_, index, attr); 381da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 382da853ecaSopenharmony_ci signal_->inIdxQueue_.pop(); 383da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 384da853ecaSopenharmony_ci return res; 385da853ecaSopenharmony_ci} 386da853ecaSopenharmony_ci 387da853ecaSopenharmony_ciint32_t VEncFuzzSample::CheckResult(bool isRandomEosSuccess, int32_t pushResult) 388da853ecaSopenharmony_ci{ 389da853ecaSopenharmony_ci if (isRandomEosSuccess) { 390da853ecaSopenharmony_ci if (pushResult == 0) { 391da853ecaSopenharmony_ci errCount = errCount + 1; 392da853ecaSopenharmony_ci cout << "push input after eos should be failed! pushResult:" << pushResult << endl; 393da853ecaSopenharmony_ci } 394da853ecaSopenharmony_ci return -1; 395da853ecaSopenharmony_ci } else if (pushResult != 0) { 396da853ecaSopenharmony_ci errCount = errCount + 1; 397da853ecaSopenharmony_ci cout << "push input data failed, error:" << pushResult << endl; 398da853ecaSopenharmony_ci return -1; 399da853ecaSopenharmony_ci } 400da853ecaSopenharmony_ci return 0; 401da853ecaSopenharmony_ci} 402da853ecaSopenharmony_ci 403da853ecaSopenharmony_civoid VEncFuzzSample::InputDataFuzz(bool &runningFlag, uint32_t index) 404da853ecaSopenharmony_ci{ 405da853ecaSopenharmony_ci frameCount++; 406da853ecaSopenharmony_ci if (frameCount == defaultFuzzTime) { 407da853ecaSopenharmony_ci SetEOS(index); 408da853ecaSopenharmony_ci runningFlag = false; 409da853ecaSopenharmony_ci return; 410da853ecaSopenharmony_ci } 411da853ecaSopenharmony_ci OH_AVCodecBufferAttr attr; 412da853ecaSopenharmony_ci attr.pts = GetSystemTimeUs(); 413da853ecaSopenharmony_ci attr.offset = 0; 414da853ecaSopenharmony_ci attr.flags = AVCODEC_BUFFER_FLAGS_NONE; 415da853ecaSopenharmony_ci OH_VideoEncoder_PushInputData(venc_, index, attr); 416da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 417da853ecaSopenharmony_ci signal_->inIdxQueue_.pop(); 418da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 419da853ecaSopenharmony_ci} 420da853ecaSopenharmony_ci 421da853ecaSopenharmony_civoid VEncFuzzSample::InputFunc() 422da853ecaSopenharmony_ci{ 423da853ecaSopenharmony_ci errCount = 0; 424da853ecaSopenharmony_ci bool runningFlag = true; 425da853ecaSopenharmony_ci while (runningFlag) { 426da853ecaSopenharmony_ci if (!isRunning_.load()) { 427da853ecaSopenharmony_ci break; 428da853ecaSopenharmony_ci } 429da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 430da853ecaSopenharmony_ci signal_->inCond_.wait(lock, [this]() { 431da853ecaSopenharmony_ci if (!isRunning_.load()) { 432da853ecaSopenharmony_ci return true; 433da853ecaSopenharmony_ci } 434da853ecaSopenharmony_ci return signal_->inIdxQueue_.size() > 0; 435da853ecaSopenharmony_ci }); 436da853ecaSopenharmony_ci if (!isRunning_.load()) { 437da853ecaSopenharmony_ci break; 438da853ecaSopenharmony_ci } 439da853ecaSopenharmony_ci uint32_t index = signal_->inIdxQueue_.front(); 440da853ecaSopenharmony_ci lock.unlock(); 441da853ecaSopenharmony_ci InputDataFuzz(runningFlag, index); 442da853ecaSopenharmony_ci if (sleepOnFPS) { 443da853ecaSopenharmony_ci usleep(FRAME_INTERVAL); 444da853ecaSopenharmony_ci } 445da853ecaSopenharmony_ci } 446da853ecaSopenharmony_ci} 447da853ecaSopenharmony_ci 448da853ecaSopenharmony_ciint32_t VEncFuzzSample::CheckAttrFlag(OH_AVCodecBufferAttr attr) 449da853ecaSopenharmony_ci{ 450da853ecaSopenharmony_ci if (attr.flags & AVCODEC_BUFFER_FLAGS_EOS) { 451da853ecaSopenharmony_ci cout << "attr.flags == AVCODEC_BUFFER_FLAGS_EOS" << endl; 452da853ecaSopenharmony_ci unique_lock<mutex> inLock(signal_->inMutex_); 453da853ecaSopenharmony_ci isRunning_.store(false); 454da853ecaSopenharmony_ci signal_->inCond_.notify_all(); 455da853ecaSopenharmony_ci signal_->outCond_.notify_all(); 456da853ecaSopenharmony_ci inLock.unlock(); 457da853ecaSopenharmony_ci return -1; 458da853ecaSopenharmony_ci } 459da853ecaSopenharmony_ci if (attr.flags == AVCODEC_BUFFER_FLAGS_CODEC_DATA) { 460da853ecaSopenharmony_ci cout << "enc AVCODEC_BUFFER_FLAGS_CODEC_DATA" << attr.pts << endl; 461da853ecaSopenharmony_ci } 462da853ecaSopenharmony_ci outCount = outCount + 1; 463da853ecaSopenharmony_ci return 0; 464da853ecaSopenharmony_ci} 465da853ecaSopenharmony_ci 466da853ecaSopenharmony_civoid VEncFuzzSample::OutputFuncFail() 467da853ecaSopenharmony_ci{ 468da853ecaSopenharmony_ci cout << "errCount > 0" << endl; 469da853ecaSopenharmony_ci unique_lock<mutex> inLock(signal_->inMutex_); 470da853ecaSopenharmony_ci isRunning_.store(false); 471da853ecaSopenharmony_ci signal_->inCond_.notify_all(); 472da853ecaSopenharmony_ci signal_->outCond_.notify_all(); 473da853ecaSopenharmony_ci inLock.unlock(); 474da853ecaSopenharmony_ci (void)Stop(); 475da853ecaSopenharmony_ci Release(); 476da853ecaSopenharmony_ci} 477da853ecaSopenharmony_ci 478da853ecaSopenharmony_civoid VEncFuzzSample::OutputFunc() 479da853ecaSopenharmony_ci{ 480da853ecaSopenharmony_ci FILE *outFile = fopen(outDir, "wb"); 481da853ecaSopenharmony_ci 482da853ecaSopenharmony_ci while (true) { 483da853ecaSopenharmony_ci if (!isRunning_.load()) { 484da853ecaSopenharmony_ci break; 485da853ecaSopenharmony_ci } 486da853ecaSopenharmony_ci OH_AVCodecBufferAttr attr; 487da853ecaSopenharmony_ci uint32_t index; 488da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->outMutex_); 489da853ecaSopenharmony_ci signal_->outCond_.wait(lock, [this]() { 490da853ecaSopenharmony_ci if (!isRunning_.load()) { 491da853ecaSopenharmony_ci return true; 492da853ecaSopenharmony_ci } 493da853ecaSopenharmony_ci return signal_->outIdxQueue_.size() > 0; 494da853ecaSopenharmony_ci }); 495da853ecaSopenharmony_ci if (!isRunning_.load()) { 496da853ecaSopenharmony_ci break; 497da853ecaSopenharmony_ci } 498da853ecaSopenharmony_ci index = signal_->outIdxQueue_.front(); 499da853ecaSopenharmony_ci attr = signal_->attrQueue_.front(); 500da853ecaSopenharmony_ci OH_AVMemory *buffer = signal_->outBufferQueue_.front(); 501da853ecaSopenharmony_ci signal_->outBufferQueue_.pop(); 502da853ecaSopenharmony_ci signal_->outIdxQueue_.pop(); 503da853ecaSopenharmony_ci signal_->attrQueue_.pop(); 504da853ecaSopenharmony_ci lock.unlock(); 505da853ecaSopenharmony_ci if (CheckAttrFlag(attr) == -1) { 506da853ecaSopenharmony_ci break; 507da853ecaSopenharmony_ci } 508da853ecaSopenharmony_ci int size = attr.size; 509da853ecaSopenharmony_ci 510da853ecaSopenharmony_ci if (outFile == nullptr) { 511da853ecaSopenharmony_ci cout << "dump data fail" << endl; 512da853ecaSopenharmony_ci } else { 513da853ecaSopenharmony_ci fwrite(OH_AVMemory_GetAddr(buffer), 1, size, outFile); 514da853ecaSopenharmony_ci } 515da853ecaSopenharmony_ci 516da853ecaSopenharmony_ci if (OH_VideoEncoder_FreeOutputData(venc_, index) != AV_ERR_OK) { 517da853ecaSopenharmony_ci cout << "Fatal: ReleaseOutputBuffer fail" << endl; 518da853ecaSopenharmony_ci errCount = errCount + 1; 519da853ecaSopenharmony_ci } 520da853ecaSopenharmony_ci if (errCount > 0) { 521da853ecaSopenharmony_ci OutputFuncFail(); 522da853ecaSopenharmony_ci break; 523da853ecaSopenharmony_ci } 524da853ecaSopenharmony_ci } 525da853ecaSopenharmony_ci if (outFile) { 526da853ecaSopenharmony_ci (void)fclose(outFile); 527da853ecaSopenharmony_ci } 528da853ecaSopenharmony_ci} 529da853ecaSopenharmony_ci 530da853ecaSopenharmony_ciint32_t VEncFuzzSample::Flush() 531da853ecaSopenharmony_ci{ 532da853ecaSopenharmony_ci unique_lock<mutex> inLock(signal_->inMutex_); 533da853ecaSopenharmony_ci clearIntqueue(signal_->inIdxQueue_); 534da853ecaSopenharmony_ci signal_->inCond_.notify_all(); 535da853ecaSopenharmony_ci inLock.unlock(); 536da853ecaSopenharmony_ci unique_lock<mutex> outLock(signal_->outMutex_); 537da853ecaSopenharmony_ci clearIntqueue(signal_->outIdxQueue_); 538da853ecaSopenharmony_ci clearBufferqueue(signal_->attrQueue_); 539da853ecaSopenharmony_ci signal_->outCond_.notify_all(); 540da853ecaSopenharmony_ci outLock.unlock(); 541da853ecaSopenharmony_ci return OH_VideoEncoder_Flush(venc_); 542da853ecaSopenharmony_ci} 543da853ecaSopenharmony_ci 544da853ecaSopenharmony_ciint32_t VEncFuzzSample::Reset() 545da853ecaSopenharmony_ci{ 546da853ecaSopenharmony_ci isRunning_.store(false); 547da853ecaSopenharmony_ci StopInloop(); 548da853ecaSopenharmony_ci StopOutloop(); 549da853ecaSopenharmony_ci ReleaseInFile(); 550da853ecaSopenharmony_ci return OH_VideoEncoder_Reset(venc_); 551da853ecaSopenharmony_ci} 552da853ecaSopenharmony_ci 553da853ecaSopenharmony_ciint32_t VEncFuzzSample::Release() 554da853ecaSopenharmony_ci{ 555da853ecaSopenharmony_ci int ret = OH_VideoEncoder_Destroy(venc_); 556da853ecaSopenharmony_ci venc_ = nullptr; 557da853ecaSopenharmony_ci if (signal_ != nullptr) { 558da853ecaSopenharmony_ci delete signal_; 559da853ecaSopenharmony_ci signal_ = nullptr; 560da853ecaSopenharmony_ci } 561da853ecaSopenharmony_ci return ret; 562da853ecaSopenharmony_ci} 563da853ecaSopenharmony_ci 564da853ecaSopenharmony_ciint32_t VEncFuzzSample::Stop() 565da853ecaSopenharmony_ci{ 566da853ecaSopenharmony_ci StopInloop(); 567da853ecaSopenharmony_ci clearIntqueue(signal_->outIdxQueue_); 568da853ecaSopenharmony_ci clearBufferqueue(signal_->attrQueue_); 569da853ecaSopenharmony_ci ReleaseInFile(); 570da853ecaSopenharmony_ci return OH_VideoEncoder_Stop(venc_); 571da853ecaSopenharmony_ci} 572da853ecaSopenharmony_ci 573da853ecaSopenharmony_ciint32_t VEncFuzzSample::Start() 574da853ecaSopenharmony_ci{ 575da853ecaSopenharmony_ci return OH_VideoEncoder_Start(venc_); 576da853ecaSopenharmony_ci} 577da853ecaSopenharmony_ci 578da853ecaSopenharmony_civoid VEncFuzzSample::StopOutloop() 579da853ecaSopenharmony_ci{ 580da853ecaSopenharmony_ci if (outputLoop_ != nullptr && outputLoop_->joinable()) { 581da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->outMutex_); 582da853ecaSopenharmony_ci clearIntqueue(signal_->outIdxQueue_); 583da853ecaSopenharmony_ci clearBufferqueue(signal_->attrQueue_); 584da853ecaSopenharmony_ci signal_->outCond_.notify_all(); 585da853ecaSopenharmony_ci lock.unlock(); 586da853ecaSopenharmony_ci } 587da853ecaSopenharmony_ci} 588da853ecaSopenharmony_ci 589da853ecaSopenharmony_ciint32_t VEncFuzzSample::SetParameter(OH_AVFormat *format) 590da853ecaSopenharmony_ci{ 591da853ecaSopenharmony_ci if (venc_) { 592da853ecaSopenharmony_ci return OH_VideoEncoder_SetParameter(venc_, format); 593da853ecaSopenharmony_ci } 594da853ecaSopenharmony_ci return AV_ERR_UNKNOWN; 595da853ecaSopenharmony_ci}