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}