• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <arpa/inet.h>
16 #include <sys/time.h>
17 #include <utility>
18 #include "native_buffer_inner.h"
19 #include "iconsumer_surface.h"
20 #include "videoenc_inner_sample.h"
21 #include "meta/meta_key.h"
22 #include <random>
23 #include "avcodec_list.h"
24 #include "native_avcodec_base.h"
25 #include <string>
26 
27 using namespace OHOS;
28 using namespace OHOS::MediaAVCodec;
29 using namespace std;
30 
31 namespace {
32 const string MIME_TYPE = "video/avc";
33 constexpr int64_t NANOS_IN_SECOND = 1000000000L;
34 constexpr int64_t NANOS_IN_MICRO = 1000L;
35 constexpr uint32_t FRAME_INTERVAL = 16666;
36 constexpr uint32_t MAX_PIXEL_FMT = 5;
37 constexpr uint32_t IDR_FRAME_INTERVAL = 10;
38 std::random_device g_rd;
39 std::random_device g_eos;
40 constexpr uint32_t DOUBLE = 2;
41 constexpr uint32_t THREE = 3;
42 constexpr uint8_t RGBA_SIZE = 4;
43 constexpr uint8_t FILE_END = -1;
44 constexpr uint8_t LOOP_END = 0;
45 int32_t g_picWidth;
46 int32_t g_picHeight;
47 int32_t g_keyWidth;
48 int32_t g_keyHeight;
49 
clearIntqueue(std::queue<uint32_t> & q)50 void clearIntqueue(std::queue<uint32_t> &q)
51 {
52     std::queue<uint32_t> empty;
53     swap(empty, q);
54 }
55 
clearBufferqueue(std::queue<AVCodecBufferInfo> & q)56 void clearBufferqueue(std::queue<AVCodecBufferInfo> &q)
57 {
58     std::queue<AVCodecBufferInfo> empty;
59     swap(empty, q);
60 }
61 
clearFlagqueue(std::queue<AVCodecBufferFlag> & q)62 void clearFlagqueue(std::queue<AVCodecBufferFlag> &q)
63 {
64     std::queue<AVCodecBufferFlag> empty;
65     swap(empty, q);
66 }
67 } // namespace
68 
VEncNdkInnerFuzzSample(std::shared_ptr<VEncInnerSignal> signal)69 VEncNdkInnerFuzzSample::VEncNdkInnerFuzzSample(std::shared_ptr<VEncInnerSignal> signal)
70     : signal_(signal)
71 {
72 }
73 
VEncInnerCallback(std::shared_ptr<VEncInnerSignal> signal)74 VEncInnerCallback::VEncInnerCallback(std::shared_ptr<VEncInnerSignal> signal) : innersignal_(signal) {}
75 
OnError(AVCodecErrorType errorType,int32_t errorCode)76 void VEncInnerCallback::OnError(AVCodecErrorType errorType, int32_t errorCode)
77 {
78     cout << "Error errorType:" << errorType << " errorCode:" << errorCode << endl;
79 }
80 
OnOutputFormatChanged(const Format & format)81 void VEncInnerCallback::OnOutputFormatChanged(const Format& format)
82 {
83     cout << "Format Changed" << endl;
84     format.GetIntValue(OH_MD_KEY_VIDEO_PIC_WIDTH, g_picWidth);
85     format.GetIntValue(OH_MD_KEY_VIDEO_PIC_HEIGHT, g_picHeight);
86     format.GetIntValue(OH_MD_KEY_WIDTH, g_keyWidth);
87     format.GetIntValue(OH_MD_KEY_HEIGHT, g_keyHeight);
88     cout << "format info: " << format.Stringify() << ", OH_MD_KEY_VIDEO_PIC_WIDTH: " << g_picWidth
89     << ", OH_MD_KEY_VIDEO_PIC_HEIGHT: "<< g_picHeight << ", OH_MD_KEY_WIDTH: " << g_keyWidth
90     << ", OH_MD_KEY_HEIGHT: " << g_keyHeight << endl;
91 }
92 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)93 void VEncInnerCallback::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
94 {
95     if (innersignal_ == nullptr) {
96         std::cout << "buffer is null 1" << endl;
97         return;
98     }
99     unique_lock<mutex> lock(innersignal_->inMutex_);
100     innersignal_->inIdxQueue_.push(index);
101     innersignal_->inBufferQueue_.push(buffer);
102     innersignal_->inCond_.notify_all();
103 }
104 
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)105 void VEncInnerCallback::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info,
106     AVCodecBufferFlag flag, std::shared_ptr<AVSharedMemory> buffer)
107 {
108     unique_lock<mutex> lock(innersignal_->outMutex_);
109     innersignal_->outIdxQueue_.push(index);
110     innersignal_->infoQueue_.push(info);
111     innersignal_->flagQueue_.push(flag);
112     innersignal_->outBufferQueue_.push(buffer);
113     innersignal_->outCond_.notify_all();
114 }
115 
VEncParamWithAttrCallbackTest(std::shared_ptr<VEncInnerSignal> signal)116 VEncParamWithAttrCallbackTest::VEncParamWithAttrCallbackTest(
117     std::shared_ptr<VEncInnerSignal> signal) : signal_(signal) {}
118 
~VEncParamWithAttrCallbackTest()119 VEncParamWithAttrCallbackTest::~VEncParamWithAttrCallbackTest()
120 {
121     signal_ = nullptr;
122 }
123 
OnInputParameterWithAttrAvailable(uint32_t index,std::shared_ptr<Format> attribute,std::shared_ptr<Format> parameter)124 void VEncParamWithAttrCallbackTest::OnInputParameterWithAttrAvailable(uint32_t index,
125                                                                       std::shared_ptr<Format> attribute,
126                                                                       std::shared_ptr<Format> parameter)
127 {
128     if (signal_ == nullptr) {
129         return;
130     }
131     unique_lock<mutex> lock(signal_->inMutex_);
132     cout << "OnInputParameterWithAttrAvailable" <<endl;
133     signal_->inIdxQueue_.push(index);
134     signal_->inAttrQueue_.push(attribute);
135     signal_->inFormatQueue_.push(parameter);
136     signal_->inCond_.notify_all();
137 }
138 
~VEncNdkInnerFuzzSample()139 VEncNdkInnerFuzzSample::~VEncNdkInnerFuzzSample()
140 {
141     Release();
142 }
143 
GetSystemTimeUs()144 int64_t VEncNdkInnerFuzzSample::GetSystemTimeUs()
145 {
146     struct timespec now;
147     (void)clock_gettime(CLOCK_BOOTTIME, &now);
148     int64_t nanoTime = static_cast<int64_t>(now.tv_sec) * NANOS_IN_SECOND + now.tv_nsec;
149 
150     return nanoTime / NANOS_IN_MICRO;
151 }
152 
CreateByMime(const std::string & mime)153 int32_t VEncNdkInnerFuzzSample::CreateByMime(const std::string &mime)
154 {
155     venc_ = VideoEncoderFactory::CreateByMime(mime);
156     return venc_ == nullptr ? AVCS_ERR_INVALID_OPERATION : AVCS_ERR_OK;
157 }
158 
CreateByName(const std::string & name)159 int32_t VEncNdkInnerFuzzSample::CreateByName(const std::string &name)
160 {
161     venc_ = VideoEncoderFactory::CreateByName(name);
162     return venc_ == nullptr ? AVCS_ERR_INVALID_OPERATION : AVCS_ERR_OK;
163 }
164 
Configure()165 int32_t VEncNdkInnerFuzzSample::Configure()
166 {
167     Format format;
168     format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, defaultWidth);
169     format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, defaultHeight);
170     format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
171     format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, defaultFrameRate);
172     format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, defaultBitrate);
173     if (configMain10) {
174         format.PutIntValue(OH_MD_KEY_PROFILE, HEVC_PROFILE_MAIN_10);
175     } else if (configMain) {
176         format.PutIntValue(OH_MD_KEY_PROFILE, HEVC_PROFILE_MAIN);
177     }
178     format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE, DEFAULT_BITRATE_MODE);
179     if (enableRepeat) {
180         format.PutIntValue(Media::Tag::VIDEO_ENCODER_REPEAT_PREVIOUS_FRAME_AFTER, defaultFrameAfter);
181         if (setMaxCount) {
182             format.PutIntValue(Media::Tag::VIDEO_ENCODER_REPEAT_PREVIOUS_MAX_COUNT, defaultMaxCount);
183         }
184     }
185     if (isDiscardFrame) {
186         format.PutIntValue(Media::Tag::VIDEO_I_FRAME_INTERVAL, defaultKeyIFrameInterval);
187     }
188     return venc_->Configure(format);
189 }
190 
ConfigureFuzz(int32_t data)191 int32_t VEncNdkInnerFuzzSample::ConfigureFuzz(int32_t data)
192 {
193     Format format;
194     double frameRate = data;
195     format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, data);
196     format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, data);
197     format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, data % MAX_PIXEL_FMT);
198     format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, frameRate);
199     format.PutIntValue(MediaDescriptionKey::MD_KEY_RANGE_FLAG, data);
200     format.PutIntValue(MediaDescriptionKey::MD_KEY_COLOR_PRIMARIES, data);
201     format.PutIntValue(MediaDescriptionKey::MD_KEY_TRANSFER_CHARACTERISTICS, data);
202     format.PutIntValue(MediaDescriptionKey::MD_KEY_MATRIX_COEFFICIENTS, data);
203     format.PutIntValue(MediaDescriptionKey::MD_KEY_I_FRAME_INTERVAL, data);
204     format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE, data);
205     format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, data);
206     format.PutIntValue(MediaDescriptionKey::MD_KEY_QUALITY, data);
207 
208     return venc_->Configure(format);
209 }
210 
Prepare()211 int32_t VEncNdkInnerFuzzSample::Prepare()
212 {
213     return venc_->Prepare();
214 }
215 
Start()216 int32_t VEncNdkInnerFuzzSample::Start()
217 {
218     return venc_->Start();
219 }
220 
Stop()221 int32_t VEncNdkInnerFuzzSample::Stop()
222 {
223     StopInloop();
224     clearIntqueue(signal_->outIdxQueue_);
225     clearBufferqueue(signal_->infoQueue_);
226     clearFlagqueue(signal_->flagQueue_);
227     ReleaseInFile();
228 
229     return venc_->Stop();
230 }
231 
Flush()232 int32_t VEncNdkInnerFuzzSample::Flush()
233 {
234     unique_lock<mutex> inLock(signal_->inMutex_);
235     clearIntqueue(signal_->inIdxQueue_);
236     signal_->inCond_.notify_all();
237     inLock.unlock();
238     unique_lock<mutex> outLock(signal_->outMutex_);
239     clearIntqueue(signal_->outIdxQueue_);
240     clearBufferqueue(signal_->infoQueue_);
241     clearFlagqueue(signal_->flagQueue_);
242     signal_->outCond_.notify_all();
243     outLock.unlock();
244 
245     return venc_->Flush();
246 }
247 
NotifyEos()248 int32_t VEncNdkInnerFuzzSample::NotifyEos()
249 {
250     return venc_->NotifyEos();
251 }
252 
Reset()253 int32_t VEncNdkInnerFuzzSample::Reset()
254 {
255     isRunning_.store(false);
256     StopInloop();
257     StopOutloop();
258     ReleaseInFile();
259 
260     if (venc_ == nullptr) {
261         std::cout << "InnerEncoder create failed!" << std::endl;
262         return AVCS_ERR_INVALID_OPERATION;
263     }
264     return venc_->Reset();
265 }
266 
Release()267 int32_t VEncNdkInnerFuzzSample::Release()
268 {
269     int32_t ret = 0;
270     if (venc_) {
271         ret = venc_->Release();
272         venc_ = nullptr;
273     }
274     if (signal_ != nullptr) {
275         signal_ = nullptr;
276     }
277     return ret;
278 }
279 
CreateInputSurface()280 int32_t VEncNdkInnerFuzzSample::CreateInputSurface()
281 {
282     sptr<Surface> surface = venc_->CreateInputSurface();
283     if (surface == nullptr) {
284         cout << "CreateInputSurface fail" << endl;
285         return AVCS_ERR_INVALID_OPERATION;
286     }
287 
288     nativeWindow = CreateNativeWindowFromSurface(&surface);
289     if (nativeWindow == nullptr) {
290         cout << "CreateNativeWindowFromSurface failed!" << endl;
291         return AVCS_ERR_INVALID_VAL;
292     }
293 
294     int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_420_SP);
295     if (ret != AVCS_ERR_OK) {
296         cout << "NativeWindowHandleOpt SET_FORMAT fail" << endl;
297         return ret;
298     }
299 
300     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_BUFFER_GEOMETRY, defaultWidth, defaultHeight);
301     if (ret != AVCS_ERR_OK) {
302         cout << "NativeWindowHandleOpt SET_BUFFER_GEOMETRY fail" << endl;
303         return ret;
304     }
305     return AVCS_ERR_OK;
306 }
307 
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)308 int32_t VEncNdkInnerFuzzSample::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
309 {
310     return venc_->QueueInputBuffer(index, info, flag);
311 }
312 
GetOutputFormat(Format & format)313 int32_t VEncNdkInnerFuzzSample::GetOutputFormat(Format &format)
314 {
315     return venc_->GetOutputFormat(format);
316 }
317 
ReleaseOutputBuffer(uint32_t index)318 int32_t VEncNdkInnerFuzzSample::ReleaseOutputBuffer(uint32_t index)
319 {
320     return venc_->ReleaseOutputBuffer(index);
321 }
322 
SetParameter(const Format & format)323 int32_t VEncNdkInnerFuzzSample::SetParameter(const Format &format)
324 {
325     return venc_->SetParameter(format);
326 }
327 
SetCallback()328 int32_t VEncNdkInnerFuzzSample::SetCallback()
329 {
330     if (signal_ == nullptr) {
331         signal_ = make_shared<VEncInnerSignal>();
332     }
333     if (signal_ == nullptr) {
334         cout << "Failed to new VEncInnerSignal" << endl;
335         return AVCS_ERR_UNKNOWN;
336     }
337 
338     cb_ = make_shared<VEncInnerCallback>(signal_);
339     return venc_->SetCallback(cb_);
340 }
341 
SetCallback(std::shared_ptr<MediaCodecParameterWithAttrCallback> cb)342 int32_t VEncNdkInnerFuzzSample::SetCallback(std::shared_ptr<MediaCodecParameterWithAttrCallback> cb)
343 {
344     if (venc_ == nullptr) {
345         return AV_ERR_UNKNOWN;
346     }
347     int32_t ret = venc_->SetCallback(cb);
348     isSetParamCallback_ = ret == AV_ERR_OK;
349     return ret;
350 }
351 
352 
GetInputFormat(Format & format)353 int32_t VEncNdkInnerFuzzSample::GetInputFormat(Format &format)
354 {
355     return venc_->GetInputFormat(format);
356 }
357 
358 
StartEncoder()359 int32_t VEncNdkInnerFuzzSample::StartEncoder()
360 {
361     isRunning_.store(true);
362     int32_t ret = 0;
363     if (surfaceInput) {
364         ret = CreateInputSurface();
365         if (ret != AVCS_ERR_OK) {
366             return ret;
367         }
368     }
369     ret = venc_->Start();
370     if (ret != AVCS_ERR_OK) {
371         isRunning_.store(false);
372         signal_->inCond_.notify_all();
373         signal_->outCond_.notify_all();
374         return ret;
375     }
376     inFile_ = make_unique<ifstream>();
377     if (inFile_ == nullptr) {
378         isRunning_.store(false);
379         venc_->Stop();
380         return AVCS_ERR_UNKNOWN;
381     }
382     ret = ReadMultiFilesFunc();
383     if (ret == AVCS_ERR_UNKNOWN) {
384         isRunning_.store(false);
385         venc_->Stop();
386         return AVCS_ERR_UNKNOWN;
387     }
388     return AVCS_ERR_OK;
389 }
390 
StartVideoEncoder()391 int32_t VEncNdkInnerFuzzSample::StartVideoEncoder()
392 {
393     int32_t ret = StartEncoder();
394     if (ret != AVCS_ERR_OK) {
395         return ret;
396     }
397     if (surfaceInput) {
398         inputLoop_ = make_unique<thread>(&VEncNdkInnerFuzzSample::InputFuncSurface, this);
399         inputParamLoop_ = isSetParamCallback_ ? make_unique<thread>(&VEncNdkInnerFuzzSample::InputParamLoopFunc,
400          this):nullptr;
401     } else {
402         inputLoop_ = make_unique<thread>(&VEncNdkInnerFuzzSample::InputFunc, this);
403     }
404 
405     if (inputLoop_ == nullptr) {
406         isRunning_.store(false);
407         venc_->Stop();
408         ReleaseInFile();
409         return AVCS_ERR_UNKNOWN;
410     }
411     outputLoop_ = make_unique<thread>(&VEncNdkInnerFuzzSample::OutputFunc, this);
412     if (outputLoop_ == nullptr) {
413         isRunning_.store(false);
414         venc_->Stop();
415         ReleaseInFile();
416         StopInloop();
417         Release();
418         return AVCS_ERR_UNKNOWN;
419     }
420     return AVCS_ERR_OK;
421 }
422 
ReadMultiFilesFunc()423 int32_t VEncNdkInnerFuzzSample::ReadMultiFilesFunc()
424 {
425     if (!readMultiFiles) {
426         inFile_->open(inpDir, ios::in | ios::binary);
427         if (!inFile_->is_open()) {
428             return OpenFileFail();
429         }
430     }
431     return AVCS_ERR_OK;
432 }
433 
TestApi()434 int32_t VEncNdkInnerFuzzSample::TestApi()
435 {
436     if (venc_ == nullptr) {
437         std::cout << "InnerEncoder create failed!" << std::endl;
438         return AVCS_ERR_INVALID_OPERATION;
439     }
440 
441     Format format;
442     format.PutIntValue(MediaDescriptionKey::MD_KEY_REQUEST_I_FRAME, 1);
443     venc_->CreateInputSurface();
444     venc_->Prepare();
445     venc_->GetInputFormat(format);
446     venc_->Start();
447     venc_->SetParameter(format);
448     venc_->NotifyEos();
449     venc_->GetOutputFormat(format);
450     venc_->Flush();
451     venc_->Stop();
452     venc_->Reset();
453 
454     return AVCS_ERR_OK;
455 }
456 
PushData(std::shared_ptr<AVSharedMemory> buffer,uint32_t index,int32_t & result)457 int32_t VEncNdkInnerFuzzSample::PushData(std::shared_ptr<AVSharedMemory> buffer, uint32_t index, int32_t &result)
458 {
459     int32_t res = -2;
460     uint32_t yuvSize = (defaultWidth * defaultHeight * THREE) / DOUBLE;
461     uint8_t *fileBuffer = buffer->GetBase();
462     if (fileBuffer == nullptr) {
463         cout << "Fatal: no memory" << endl;
464         return -1;
465     }
466     (void)inFile_->read((char *)fileBuffer, yuvSize);
467 
468     if (repeatRun && inFile_->eof()) {
469         inFile_->clear();
470         inFile_->seekg(0, ios::beg);
471         encodeCount++;
472         cout << "repeat" << "  encodeCount:" << encodeCount << endl;
473         return -1;
474     }
475 
476     if (inFile_->eof()) {
477         SetEOS(index);
478         return 0;
479     }
480 
481     AVCodecBufferInfo info;
482     info.presentationTimeUs = GetSystemTimeUs();
483     info.size = yuvSize;
484     info.offset = 0;
485     AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_NONE;
486 
487     int32_t size = buffer->GetSize();
488     if (size < static_cast<int32_t>(yuvSize)) {
489         cout << "bufferSize smaller than yuv size" << endl;
490         return -1;
491     }
492 
493     if (enableForceIDR && (frameCount % IDR_FRAME_INTERVAL == 0)) {
494         Format format;
495         format.PutIntValue(MediaDescriptionKey::MD_KEY_REQUEST_I_FRAME, 1);
496         venc_->SetParameter(format);
497     }
498     result = venc_->QueueInputBuffer(index, info, flag);
499     unique_lock<mutex> lock(signal_->inMutex_);
500     signal_->inIdxQueue_.pop();
501     signal_->inBufferQueue_.pop();
502 
503     return res;
504 }
505 
OpenFileFail()506 int32_t VEncNdkInnerFuzzSample::OpenFileFail()
507 {
508     cout << "file open fail" << endl;
509     isRunning_.store(false);
510     venc_->Stop();
511     inFile_->close();
512     inFile_.reset();
513     inFile_ = nullptr;
514     return AVCS_ERR_UNKNOWN;
515 }
516 
CheckResult(bool isRandomEosSuccess,int32_t pushResult)517 int32_t VEncNdkInnerFuzzSample::CheckResult(bool isRandomEosSuccess, int32_t pushResult)
518 {
519     if (isRandomEosSuccess) {
520         if (pushResult == 0) {
521             errCount = errCount + 1;
522             cout << "push input after eos should be failed!  pushResult:" << pushResult << endl;
523         }
524         return -1;
525     } else if (pushResult != 0) {
526         errCount = errCount + 1;
527         cout << "push input data failed, error:" << pushResult << endl;
528         return -1;
529     }
530     return 0;
531 }
532 
CheckFlag(AVCodecBufferFlag flag)533 int32_t VEncNdkInnerFuzzSample::CheckFlag(AVCodecBufferFlag flag)
534 {
535     if (flag == AVCODEC_BUFFER_FLAG_EOS) {
536         cout << "flag == AVCODEC_BUFFER_FLAG_EOS" << endl;
537         unique_lock<mutex> inLock(signal_->inMutex_);
538         isRunning_.store(false);
539         signal_->inCond_.notify_all();
540         signal_->outCond_.notify_all();
541         inLock.unlock();
542         return -1;
543     }
544 
545     if (flag == AVCODEC_BUFFER_FLAG_CODEC_DATA) {
546         cout << "enc AVCODEC_BUFFER_FLAG_CODEC_DATA" << endl;
547     } else {
548         outCount = outCount + 1;
549     }
550     return 0;
551 }
552 
InputProcess(OH_NativeBuffer * nativeBuffer,OHNativeWindowBuffer * ohNativeWindowBuffer)553 int32_t VEncNdkInnerFuzzSample::InputProcess(OH_NativeBuffer *nativeBuffer, OHNativeWindowBuffer *ohNativeWindowBuffer)
554 {
555     int32_t ret = 0;
556     struct Region region;
557     struct Region::Rect *rect = new Region::Rect();
558     rect->x = 0;
559     rect->y = 0;
560     rect->w = defaultWidth;
561     rect->h = defaultHeight;
562     region.rects = rect;
563     NativeWindowHandleOpt(nativeWindow, SET_UI_TIMESTAMP, GetSystemTimeUs());
564     ret = OH_NativeBuffer_Unmap(nativeBuffer);
565     if (ret != 0) {
566         cout << "OH_NativeBuffer_Unmap failed" << endl;
567         delete rect;
568         return ret;
569     }
570 
571     ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, ohNativeWindowBuffer, -1, region);
572     delete rect;
573     if (ret != 0) {
574         cout << "FlushBuffer failed" << endl;
575         return ret;
576     }
577     return ret;
578 }
579 
StateEOS()580 int32_t VEncNdkInnerFuzzSample::StateEOS()
581 {
582     unique_lock<mutex> lock(signal_->inMutex_);
583     signal_->inCond_.wait(lock, [this]() { return signal_->inIdxQueue_.size() > 0; });
584     uint32_t index = signal_->inIdxQueue_.front();
585     signal_->inIdxQueue_.pop();
586     signal_->inBufferQueue_.pop();
587     lock.unlock();
588 
589     AVCodecBufferInfo info;
590     info.presentationTimeUs = 0;
591     info.size = 0;
592     info.offset = 0;
593     AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
594 
595     return venc_->QueueInputBuffer(index, info, flag);
596 }
597 
ReturnZeroIfEOS(uint32_t expectedSize)598 uint32_t VEncNdkInnerFuzzSample::ReturnZeroIfEOS(uint32_t expectedSize)
599 {
600     if (inFile_->gcount() != static_cast<int32_t>(expectedSize)) {
601         cout << "no more data" << endl;
602         return 0;
603     }
604     return 1;
605 }
606 
ReadOneFrameYUV420SP(uint8_t * dst)607 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameYUV420SP(uint8_t *dst)
608 {
609     uint8_t *start = dst;
610     // copy Y
611     for (uint32_t i = 0; i < defaultHeight; i++) {
612         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth);
613         if (!ReturnZeroIfEOS(defaultWidth)) {
614             return 0;
615         }
616         dst += stride_;
617     }
618     // copy UV
619     for (uint32_t i = 0; i < defaultHeight / sampleRatio; i++) {
620         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth);
621         if (!ReturnZeroIfEOS(defaultWidth)) {
622             return 0;
623         }
624         dst += stride_;
625     }
626     return dst - start;
627 }
628 
ReadOneFrameYUVP010(uint8_t * dst)629 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameYUVP010(uint8_t *dst)
630 {
631     uint8_t *start = dst;
632     int32_t num = 2;
633     // copy Y
634     for (uint32_t i = 0; i < defaultHeight; i++) {
635         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth * num);
636         if (!ReturnZeroIfEOS(defaultWidth * num)) {
637             return 0;
638         }
639         dst += stride_;
640     }
641     // copy UV
642     for (uint32_t i = 0; i < defaultHeight / sampleRatio; i++) {
643         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth * num);
644         if (!ReturnZeroIfEOS(defaultWidth * num)) {
645             return 0;
646         }
647         dst += stride_;
648     }
649     return dst - start;
650 }
651 
ReadOneFrameFromList(uint8_t * dst,int32_t & index)652 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameFromList(uint8_t *dst, int32_t &index)
653 {
654     int32_t ret = 0;
655     if (index >= fileInfos.size()) {
656         ret = venc_->NotifyEos();
657         if (ret != 0) {
658             cout << "OH_VideoEncoder_NotifyEndOfStream failed" << endl;
659         }
660         return LOOP_END;
661     }
662     if (!inFile_->is_open()) {
663         inFile_->open(fileInfos[index].fileDir);
664         if (!inFile_->is_open()) {
665             return OpenFileFail();
666         }
667         defaultWidth = fileInfos[index].width;
668         defaultHeight = fileInfos[index].height;
669         if (setFormatRbgx) {
670             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_RGBX_8888);
671         } else if (setFormat8Bit) {
672             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_420_SP);
673         } else if (setFormat10Bit) {
674             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_P010);
675         } else {
676             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, fileInfos[index].format);
677         }
678         if (ret != AVCS_ERR_OK) {
679             return ret;
680         }
681         ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_BUFFER_GEOMETRY, defaultWidth, defaultHeight);
682         if (ret != AVCS_ERR_OK) {
683             return ret;
684         }
685         cout << fileInfos[index].fileDir << endl;
686         cout << "set width:" << fileInfos[index].width << "height: " << fileInfos[index].height << endl;
687         return FILE_END;
688     }
689     ret = ReadOneFrameByType(dst, fileInfos[index].format);
690     if (!ret) {
691         if (inFile_->is_open()) {
692             inFile_->close();
693         }
694         index++;
695         if (index >= fileInfos.size()) {
696             venc_->NotifyEos();
697             return LOOP_END;
698         }
699         return FILE_END;
700     }
701     return ret;
702 }
703 
ReadOneFrameByType(uint8_t * dst,std::string & fileType)704 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameByType(uint8_t *dst, std::string &fileType)
705 {
706     if (fileType == "rgba") {
707         return ReadOneFrameRGBA8888(dst);
708     } else if (fileType == "nv12" || fileType == "nv21") {
709         return ReadOneFrameYUV420SP(dst);
710     } else {
711         cout << "error fileType" << endl;
712         return 0;
713     }
714 }
715 
ReadOneFrameByType(uint8_t * dst,GraphicPixelFormat format)716 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameByType(uint8_t *dst, GraphicPixelFormat format)
717 {
718     if (format == GRAPHIC_PIXEL_FMT_RGBA_8888) {
719         return ReadOneFrameRGBA8888(dst);
720     } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_420_SP || format == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) {
721         return ReadOneFrameYUV420SP(dst);
722     } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_P010) {
723         return ReadOneFrameYUVP010(dst);
724     } else {
725         cout << "error fileType" << endl;
726         return 0;
727     }
728 }
729 
ReadOneFrameRGBA8888(uint8_t * dst)730 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameRGBA8888(uint8_t *dst)
731 {
732     uint8_t *start = dst;
733     for (uint32_t i = 0; i < defaultHeight; i++) {
734         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth * RGBA_SIZE);
735         if (inFile_->eof()) {
736             return 0;
737         }
738         dst += stride_;
739     }
740     return dst - start;
741 }
742 
RandomEOS(uint32_t index)743 bool VEncNdkInnerFuzzSample::RandomEOS(uint32_t index)
744 {
745     uint32_t randomEos = g_eos() % 25;
746     if (enableRandomEos && randomEos == frameCount) {
747         AVCodecBufferInfo info;
748         info.presentationTimeUs = 0;
749         info.size = 0;
750         info.offset = 0;
751         AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
752 
753         venc_->QueueInputBuffer(index, info, flag);
754         cout << "random eos" << endl;
755         frameCount++;
756         unique_lock<mutex> lock(signal_->inMutex_);
757         signal_->inIdxQueue_.pop();
758         signal_->inBufferQueue_.pop();
759         return true;
760     }
761     return false;
762 }
763 
RepeatStartBeforeEOS()764 void VEncNdkInnerFuzzSample::RepeatStartBeforeEOS()
765 {
766     if (repeatStartFlushBeforeEos > 0) {
767         repeatStartFlushBeforeEos--;
768         venc_->Flush();
769         FlushBuffer();
770         venc_->Start();
771     }
772 
773     if (repeatStartStopBeforeEos > 0) {
774         repeatStartStopBeforeEos--;
775         venc_->Stop();
776         FlushBuffer();
777         venc_->Start();
778     }
779 }
780 
SetEOS(uint32_t index)781 void VEncNdkInnerFuzzSample::SetEOS(uint32_t index)
782 {
783     AVCodecBufferInfo info;
784     info.presentationTimeUs = 0;
785     info.size = 0;
786     info.offset = 0;
787     AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
788 
789     int32_t res = venc_->QueueInputBuffer(index, info, flag);
790     cout << "QueueInputBuffer EOS res: " << res << endl;
791     unique_lock<mutex> lock(signal_->inMutex_);
792     signal_->inIdxQueue_.pop();
793     signal_->inBufferQueue_.pop();
794 }
795 
WaitForEOS()796 void VEncNdkInnerFuzzSample::WaitForEOS()
797 {
798     if (inputLoop_)
799         inputLoop_->join();
800     if (outputLoop_)
801         outputLoop_->join();
802     if (inputParamLoop_)
803         inputParamLoop_->join();
804     inputLoop_ = nullptr;
805     outputLoop_ = nullptr;
806     inputParamLoop_ = nullptr;
807 }
808 
InputFuncSurface()809 void VEncNdkInnerFuzzSample::InputFuncSurface()
810 {
811     int32_t readFileIndex = 0;
812     bool enableInputFunc = true;
813     while (enableInputFunc) {
814         OHNativeWindowBuffer *ohNativeWindowBuffer = nullptr;
815         OH_NativeBuffer *nativeBuffer = nullptr;
816         uint8_t *dst = nullptr;
817         int err = InitBuffer(ohNativeWindowBuffer, nativeBuffer, dst);
818         if (err == 0) {
819             enableInputFunc = false;
820             break;
821         } else if (err == -1) {
822             continue;
823         }
824         if (readMultiFiles) {
825             err = ReadOneFrameFromList(dst, readFileIndex);
826             if (err == LOOP_END) {
827                 break;
828             } else if (err == FILE_END) {
829                 OH_NativeWindow_NativeWindowAbortBuffer(nativeWindow, ohNativeWindowBuffer);
830                 continue;
831             }
832         } else if (!ReadOneFrameYUV420SP(dst)) {
833             err = venc_->NotifyEos();
834             if (err != 0) {
835                 cout << "OH_VideoEncoder_NotifyEndOfStream failed" << endl;
836             }
837             break;
838         }
839         inputFrameCount++;
840         err = InputProcess(nativeBuffer, ohNativeWindowBuffer);
841         if (err != 0) {
842             break;
843         }
844         usleep(FRAME_INTERVAL);
845         InputEnableRepeatSleep();
846     }
847 }
848 
InitBuffer(OHNativeWindowBuffer * & ohNativeWindowBuffer,OH_NativeBuffer * & nativeBuffer,uint8_t * & dst)849 int32_t VEncNdkInnerFuzzSample::InitBuffer(OHNativeWindowBuffer *&ohNativeWindowBuffer,
850     OH_NativeBuffer *&nativeBuffer, uint8_t *&dst)
851 {
852     int fenceFd = -1;
853     if (nativeWindow == nullptr) {
854         return 0;
855     }
856     int32_t err = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &ohNativeWindowBuffer, &fenceFd);
857     if (err != 0) {
858         cout << "RequestBuffer failed, GSError=" << err << endl;
859         return -1;
860     }
861     if (fenceFd > 0) {
862         close(fenceFd);
863     }
864     nativeBuffer = OH_NativeBufferFromNativeWindowBuffer(ohNativeWindowBuffer);
865     void *virAddr = nullptr;
866     err = OH_NativeBuffer_Map(nativeBuffer, &virAddr);
867     if (err != 0) {
868         cout << "OH_NativeBuffer_Map failed, GSError=" << err << endl;
869         isRunning_.store(false);
870         return 0;
871     }
872     dst = (uint8_t *)virAddr;
873     const SurfaceBuffer *sbuffer = SurfaceBuffer::NativeBufferToSurfaceBuffer(nativeBuffer);
874     int32_t stride = sbuffer->GetStride();
875     if (dst == nullptr || stride < static_cast<int32_t>(defaultWidth)) {
876         cout << "invalid va or stride=" << stride << endl;
877         err = NativeWindowCancelBuffer(nativeWindow, ohNativeWindowBuffer);
878         isRunning_.store(false);
879         return 0;
880     }
881     stride_ = stride;
882     return 1;
883 }
884 
InputEnableRepeatSleep()885 void VEncNdkInnerFuzzSample::InputEnableRepeatSleep()
886 {
887     inCount = inCount + 1;
888     int32_t inCountNum = 15;
889     if (enableRepeat && inCount == inCountNum) {
890         if (setMaxCount) {
891             int32_t sleepTimeMaxCount = 730000;
892             usleep(sleepTimeMaxCount);
893         } else {
894             int32_t sleepTime = 1000000;
895             usleep(sleepTime);
896         }
897         if (enableSeekEos) {
898             inFile_->clear();
899             inFile_->seekg(-1, ios::beg);
900         }
901     }
902 }
903 
InputParamLoopFunc()904 void VEncNdkInnerFuzzSample::InputParamLoopFunc()
905 {
906     if (signal_ == nullptr || venc_ == nullptr) {
907         cout << "signal or venc is null" << endl;
908         return;
909     }
910     cout<< "InputParamLoopFunc" <<endl;
911     while (isRunning_.load()) {
912         unique_lock<mutex> lock(signal_->inMutex_);
913         signal_->inCond_.wait(
914             lock, [this]() { return (signal_->inIdxQueue_.size() > 0) || (!isRunning_.load()); });
915         if (!isRunning_.load()) {
916             cout << "InputLoopFunc stop running" << endl;
917             break;
918         }
919         int32_t index = signal_->inIdxQueue_.front();
920         auto format = signal_->inFormatQueue_.front();
921         auto attr = signal_->inAttrQueue_.front();
922         signal_->inIdxQueue_.pop();
923         signal_->inFormatQueue_.pop();
924         signal_->inAttrQueue_.pop();
925         if (attr != nullptr) {
926             int64_t pts = 0;
927             if (true != attr->GetLongValue(Media::Tag::MEDIA_TIME_STAMP, pts)) {
928                 return;
929             }
930         }
931         if (IsFrameDiscard(inputFrameCount)) {
932             discardFrameCount++;
933             format->PutIntValue(Media::Tag::VIDEO_ENCODER_PER_FRAME_DISCARD, 1);
934         }
935         int32_t ret = PushInputParameter(index);
936         if (ret != AV_ERR_OK) {
937             cout << "Fatal: PushInputData fail, exit" << endl;
938         }
939     }
940 }
941 
InputFunc()942 void VEncNdkInnerFuzzSample::InputFunc()
943 {
944     errCount = 0;
945     bool enableInput = true;
946     while (enableInput) {
947         if (!isRunning_.load()) {
948             enableInput = false;
949             break;
950         }
951         RepeatStartBeforeEOS();
952         unique_lock<mutex> lock(signal_->inMutex_);
953         signal_->inCond_.wait(lock, [this]() {
954             if (!isRunning_.load()) {
955                 return true;
956             }
957             return signal_->inIdxQueue_.size() > 0;
958         });
959         if (!isRunning_.load()) {
960             break;
961         }
962         uint32_t index = signal_->inIdxQueue_.front();
963         auto buffer = signal_->inBufferQueue_.front();
964 
965         lock.unlock();
966         if (!inFile_->eof()) {
967             bool isRandomEosSuccess = RandomEOS(index);
968             if (isRandomEosSuccess) {
969                 continue;
970             }
971             int32_t pushResult = 0;
972             int32_t ret = PushData(buffer, index, pushResult);
973             if (ret == 0) {
974                 break;
975             } else if (ret == -1) {
976                 continue;
977             }
978 
979             if (CheckResult(isRandomEosSuccess, pushResult) == -1) {
980                 break;
981             }
982             frameCount++;
983         }
984         if (sleepOnFPS) {
985             usleep(FRAME_INTERVAL);
986         }
987     }
988 }
989 
OutputFunc()990 void VEncNdkInnerFuzzSample::OutputFunc()
991 {
992     bool enableOutput = true;
993     while (enableOutput) {
994         if (!isRunning_.load()) {
995             enableOutput = false;
996             break;
997         }
998 
999         unique_lock<mutex> lock(signal_->outMutex_);
1000         signal_->outCond_.wait(lock, [this]() {
1001             if (!isRunning_.load()) {
1002                 return true;
1003             }
1004             return signal_->outIdxQueue_.size() > 0;
1005         });
1006 
1007         if (!isRunning_.load()) {
1008             break;
1009         }
1010 
1011         std::shared_ptr<AVSharedMemory> buffer = signal_->outBufferQueue_.front();
1012         AVCodecBufferFlag flag = signal_->flagQueue_.front();
1013         uint32_t index = signal_->outIdxQueue_.front();
1014 
1015         signal_->outBufferQueue_.pop();
1016         signal_->outIdxQueue_.pop();
1017         signal_->infoQueue_.pop();
1018         signal_->flagQueue_.pop();
1019         lock.unlock();
1020 
1021         if (CheckFlag(flag) == -1) {
1022             break;
1023         }
1024 
1025         if (venc_->ReleaseOutputBuffer(index) != AVCS_ERR_OK) {
1026             cout << "Fatal: ReleaseOutputBuffer fail" << endl;
1027             errCount = errCount + 1;
1028         }
1029         if (errCount > 0) {
1030             OutputFuncFail();
1031             break;
1032         }
1033     }
1034 }
1035 
OutputFuncFail()1036 void VEncNdkInnerFuzzSample::OutputFuncFail()
1037 {
1038     cout << "errCount > 0" << endl;
1039     unique_lock<mutex> inLock(signal_->inMutex_);
1040     isRunning_.store(false);
1041     signal_->inCond_.notify_all();
1042     signal_->outCond_.notify_all();
1043     inLock.unlock();
1044     (void)Stop();
1045     Release();
1046 }
1047 
FlushBuffer()1048 void VEncNdkInnerFuzzSample::FlushBuffer()
1049 {
1050     std::queue<std::shared_ptr<AVSharedMemory>> empty;
1051     unique_lock<mutex> inLock(signal_->inMutex_);
1052     clearIntqueue(signal_->inIdxQueue_);
1053     swap(empty, signal_->inBufferQueue_);
1054     signal_->inCond_.notify_all();
1055     inLock.unlock();
1056 
1057     unique_lock<mutex> outLock(signal_->outMutex_);
1058     clearIntqueue(signal_->outIdxQueue_);
1059     clearBufferqueue(signal_->infoQueue_);
1060     clearFlagqueue(signal_->flagQueue_);
1061     signal_->outCond_.notify_all();
1062     outLock.unlock();
1063 }
1064 
StopInloop()1065 void VEncNdkInnerFuzzSample::StopInloop()
1066 {
1067     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
1068         unique_lock<mutex> lock(signal_->inMutex_);
1069         clearIntqueue(signal_->inIdxQueue_);
1070         isRunning_.store(false);
1071         signal_->inCond_.notify_all();
1072         lock.unlock();
1073 
1074         inputLoop_->join();
1075         inputLoop_ = nullptr;
1076     }
1077 }
1078 
StopOutloop()1079 void VEncNdkInnerFuzzSample::StopOutloop()
1080 {
1081     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1082         unique_lock<mutex> lock(signal_->outMutex_);
1083         clearIntqueue(signal_->outIdxQueue_);
1084         clearBufferqueue(signal_->infoQueue_);
1085         clearFlagqueue(signal_->flagQueue_);
1086         signal_->outCond_.notify_all();
1087         lock.unlock();
1088     }
1089 }
1090 
ReleaseInFile()1091 void VEncNdkInnerFuzzSample::ReleaseInFile()
1092 {
1093     if (inFile_ != nullptr) {
1094         if (inFile_->is_open()) {
1095             inFile_->close();
1096         }
1097         inFile_.reset();
1098         inFile_ = nullptr;
1099     }
1100 }
1101 
IsFrameDiscard(uint32_t index)1102 bool VEncNdkInnerFuzzSample::IsFrameDiscard(uint32_t index)
1103 {
1104     if (!isDiscardFrame) {
1105         return false;
1106     }
1107     if (discardMinIndex > -1 && discardMaxIndex >= discardMinIndex) {
1108         if (index >= discardMinIndex && index <= discardMaxIndex) {
1109             return true;
1110         }
1111     }
1112     if (find(discardFrameIndex.begin(), discardFrameIndex.end(), index) != discardFrameIndex.end()) {
1113         return true;
1114     }
1115     if (discardInterval > 0 && index % discardInterval == 0) {
1116         return true;
1117     }
1118     return false;
1119 }
1120 
CheckOutputFrameCount()1121 bool VEncNdkInnerFuzzSample::CheckOutputFrameCount()
1122 {
1123     cout << "checooutpuframecount" << inputFrameCount << ", " << discardFrameCount<< ", " << outCount << endl;
1124     if (inputFrameCount - discardFrameCount == outCount) {
1125         return true;
1126     }
1127     return false;
1128 }
1129 
PushInputParameter(uint32_t index)1130 int32_t VEncNdkInnerFuzzSample::PushInputParameter(uint32_t index)
1131 {
1132     if (venc_ == nullptr) {
1133         return AV_ERR_UNKNOWN;
1134     }
1135     return venc_->QueueInputParameter(index);
1136 }
1137 
SetCustomBuffer(BufferRequestConfig bufferConfig,uint8_t * data,size_t size)1138 int32_t VEncNdkInnerFuzzSample::SetCustomBuffer(BufferRequestConfig bufferConfig, uint8_t *data, size_t size)
1139 {
1140     int32_t waterMarkFlag = enableWaterMark ? 1 : 0;
1141     auto allocator = Media::AVAllocatorFactory::CreateSurfaceAllocator(bufferConfig);
1142     std::shared_ptr<AVBuffer> avbuffer = AVBuffer::CreateAVBuffer(allocator);
1143     if (avbuffer == nullptr) {
1144         cout << "avbuffer is nullptr" << endl;
1145         return AVCS_ERR_INVALID_VAL;
1146     }
1147     ReadCustomDataToAVBuffer(data, avbuffer, size);
1148     Format format;
1149     format.SetMeta(avbuffer->meta_);
1150     format.PutIntValue(Media::Tag::VIDEO_ENCODER_ENABLE_WATERMARK, waterMarkFlag);
1151     format.PutIntValue(Media::Tag::VIDEO_COORDINATE_X, videoCoordinateX);
1152     format.PutIntValue(Media::Tag::VIDEO_COORDINATE_Y, videoCoordinateY);
1153     format.PutIntValue(Media::Tag::VIDEO_COORDINATE_W, videoCoordinateWidth);
1154     format.PutIntValue(Media::Tag::VIDEO_COORDINATE_H, videoCoordinateHeight);
1155     *(avbuffer->meta_) = *(format.GetMeta());
1156     int32_t ret = venc_->SetCustomBuffer(avbuffer);
1157     return ret;
1158 }
1159 
ReadCustomDataToAVBuffer(uint8_t * data,std::shared_ptr<AVBuffer> buffer,size_t size)1160 bool VEncNdkInnerFuzzSample::ReadCustomDataToAVBuffer(uint8_t *data, std::shared_ptr<AVBuffer> buffer, size_t size)
1161 {
1162     sptr<SurfaceBuffer> surfaceBuffer = buffer->memory_->GetSurfaceBuffer();
1163     if (surfaceBuffer == nullptr) {
1164         cout << "in is nullptr" << endl;
1165         return false;
1166     }
1167     uint8_t *dstAddr = (uint8_t *)surfaceBuffer->GetVirAddr();
1168     int32_t dstSize = static_cast<int32_t>(surfaceBuffer->GetSize());
1169     if (dstAddr == nullptr) {
1170         cout << "dst is nullptr" << endl;
1171     }
1172     uint8_t *inStream = data;
1173     if (dstSize >= size) {
1174         if (memcpy_s(dstAddr, dstSize, inStream, size)) {
1175             cout << "memcpy_s failed" <<endl;
1176         }
1177     } else {
1178         if (memcpy_s(dstAddr, dstSize, inStream, dstSize)) {
1179             cout << "memcpy_s failed" <<endl;
1180         }
1181     }
1182     return true;
1183 }
1184 
GetWaterMarkCapability(std::string codecMimeType)1185 bool VEncNdkInnerFuzzSample::GetWaterMarkCapability(std::string codecMimeType)
1186 {
1187     std::shared_ptr<AVCodecList> codecCapability = AVCodecListFactory::CreateAVCodecList();
1188     CapabilityData *capabilityData = nullptr;
1189     capabilityData = codecCapability->GetCapability(codecMimeType, true, AVCodecCategory::AVCODEC_HARDWARE);
1190     if (capabilityData->featuresMap.count(static_cast<int32_t>(AVCapabilityFeature::VIDEO_WATERMARK))) {
1191         std::cout << "Support watermark" << std::endl;
1192         return true;
1193     } else {
1194         std::cout << " Not support watermark" << std::endl;
1195         return false;
1196     }
1197     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capabilityData);
1198     (void)codecInfo->GetSupportedMaxBitrate();
1199     (void)codecInfo->GetSupportedSqrFactor();
1200 }