• 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 
StartVideoEncoder()358 int32_t VEncNdkInnerFuzzSample::StartVideoEncoder()
359 {
360     isRunning_.store(true);
361     int32_t ret = 0;
362     if (surfaceInput) {
363         ret = CreateInputSurface();
364         if (ret != AVCS_ERR_OK) {
365             return ret;
366         }
367     }
368     ret = venc_->Start();
369     if (ret != AVCS_ERR_OK) {
370         isRunning_.store(false);
371         signal_->inCond_.notify_all();
372         signal_->outCond_.notify_all();
373         return ret;
374     }
375 
376     inFile_ = make_unique<ifstream>();
377     if (inFile_ == nullptr) {
378         isRunning_.store(false);
379         venc_->Stop();
380         return AVCS_ERR_UNKNOWN;
381     }
382     ReadMultiFilesFunc();
383     if (surfaceInput) {
384         inputLoop_ = make_unique<thread>(&VEncNdkInnerFuzzSample::InputFuncSurface, this);
385         inputParamLoop_ = isSetParamCallback_ ? make_unique<thread>(&VEncNdkInnerFuzzSample::InputParamLoopFunc,
386          this):nullptr;
387     } else {
388         inputLoop_ = make_unique<thread>(&VEncNdkInnerFuzzSample::InputFunc, this);
389     }
390 
391     if (inputLoop_ == nullptr) {
392         isRunning_.store(false);
393         venc_->Stop();
394         ReleaseInFile();
395         return AVCS_ERR_UNKNOWN;
396     }
397 
398     outputLoop_ = make_unique<thread>(&VEncNdkInnerFuzzSample::OutputFunc, this);
399     if (outputLoop_ == nullptr) {
400         isRunning_.store(false);
401         venc_->Stop();
402         ReleaseInFile();
403         StopInloop();
404         Release();
405         return AVCS_ERR_UNKNOWN;
406     }
407     return AVCS_ERR_OK;
408 }
409 
ReadMultiFilesFunc()410 void VEncNdkInnerFuzzSample::ReadMultiFilesFunc()
411 {
412     if (!readMultiFiles) {
413         inFile_->open(inpDir, ios::in | ios::binary);
414         if (!inFile_->is_open()) {
415             OpenFileFail();
416         }
417     }
418 }
419 
TestApi()420 int32_t VEncNdkInnerFuzzSample::TestApi()
421 {
422     if (venc_ == nullptr) {
423         std::cout << "InnerEncoder create failed!" << std::endl;
424         return AVCS_ERR_INVALID_OPERATION;
425     }
426 
427     Format format;
428     format.PutIntValue(MediaDescriptionKey::MD_KEY_REQUEST_I_FRAME, 1);
429     venc_->CreateInputSurface();
430     venc_->Prepare();
431     venc_->GetInputFormat(format);
432     venc_->Start();
433     venc_->SetParameter(format);
434     venc_->NotifyEos();
435     venc_->GetOutputFormat(format);
436     venc_->Flush();
437     venc_->Stop();
438     venc_->Reset();
439 
440     return AVCS_ERR_OK;
441 }
442 
PushData(std::shared_ptr<AVSharedMemory> buffer,uint32_t index,int32_t & result)443 int32_t VEncNdkInnerFuzzSample::PushData(std::shared_ptr<AVSharedMemory> buffer, uint32_t index, int32_t &result)
444 {
445     int32_t res = -2;
446     uint32_t yuvSize = (defaultWidth * defaultHeight * THREE) / DOUBLE;
447     uint8_t *fileBuffer = buffer->GetBase();
448     if (fileBuffer == nullptr) {
449         cout << "Fatal: no memory" << endl;
450         return -1;
451     }
452     (void)inFile_->read((char *)fileBuffer, yuvSize);
453 
454     if (repeatRun && inFile_->eof()) {
455         inFile_->clear();
456         inFile_->seekg(0, ios::beg);
457         encodeCount++;
458         cout << "repeat" << "  encodeCount:" << encodeCount << endl;
459         return -1;
460     }
461 
462     if (inFile_->eof()) {
463         SetEOS(index);
464         return 0;
465     }
466 
467     AVCodecBufferInfo info;
468     info.presentationTimeUs = GetSystemTimeUs();
469     info.size = yuvSize;
470     info.offset = 0;
471     AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_NONE;
472 
473     int32_t size = buffer->GetSize();
474     if (size < static_cast<int32_t>(yuvSize)) {
475         cout << "bufferSize smaller than yuv size" << endl;
476         return -1;
477     }
478 
479     if (enableForceIDR && (frameCount % IDR_FRAME_INTERVAL == 0)) {
480         Format format;
481         format.PutIntValue(MediaDescriptionKey::MD_KEY_REQUEST_I_FRAME, 1);
482         venc_->SetParameter(format);
483     }
484     result = venc_->QueueInputBuffer(index, info, flag);
485     unique_lock<mutex> lock(signal_->inMutex_);
486     signal_->inIdxQueue_.pop();
487     signal_->inBufferQueue_.pop();
488 
489     return res;
490 }
491 
OpenFileFail()492 int32_t VEncNdkInnerFuzzSample::OpenFileFail()
493 {
494     cout << "file open fail" << endl;
495     isRunning_.store(false);
496     venc_->Stop();
497     inFile_->close();
498     inFile_.reset();
499     inFile_ = nullptr;
500     return AVCS_ERR_UNKNOWN;
501 }
502 
CheckResult(bool isRandomEosSuccess,int32_t pushResult)503 int32_t VEncNdkInnerFuzzSample::CheckResult(bool isRandomEosSuccess, int32_t pushResult)
504 {
505     if (isRandomEosSuccess) {
506         if (pushResult == 0) {
507             errCount = errCount + 1;
508             cout << "push input after eos should be failed!  pushResult:" << pushResult << endl;
509         }
510         return -1;
511     } else if (pushResult != 0) {
512         errCount = errCount + 1;
513         cout << "push input data failed, error:" << pushResult << endl;
514         return -1;
515     }
516     return 0;
517 }
518 
CheckFlag(AVCodecBufferFlag flag)519 int32_t VEncNdkInnerFuzzSample::CheckFlag(AVCodecBufferFlag flag)
520 {
521     if (flag == AVCODEC_BUFFER_FLAG_EOS) {
522         cout << "flag == AVCODEC_BUFFER_FLAG_EOS" << endl;
523         unique_lock<mutex> inLock(signal_->inMutex_);
524         isRunning_.store(false);
525         signal_->inCond_.notify_all();
526         signal_->outCond_.notify_all();
527         inLock.unlock();
528         return -1;
529     }
530 
531     if (flag == AVCODEC_BUFFER_FLAG_CODEC_DATA) {
532         cout << "enc AVCODEC_BUFFER_FLAG_CODEC_DATA" << endl;
533     } else {
534         outCount = outCount + 1;
535     }
536     return 0;
537 }
538 
InputProcess(OH_NativeBuffer * nativeBuffer,OHNativeWindowBuffer * ohNativeWindowBuffer)539 int32_t VEncNdkInnerFuzzSample::InputProcess(OH_NativeBuffer *nativeBuffer, OHNativeWindowBuffer *ohNativeWindowBuffer)
540 {
541     int32_t ret = 0;
542     struct Region region;
543     struct Region::Rect *rect = new Region::Rect();
544     rect->x = 0;
545     rect->y = 0;
546     rect->w = defaultWidth;
547     rect->h = defaultHeight;
548     region.rects = rect;
549     NativeWindowHandleOpt(nativeWindow, SET_UI_TIMESTAMP, GetSystemTimeUs());
550     ret = OH_NativeBuffer_Unmap(nativeBuffer);
551     if (ret != 0) {
552         cout << "OH_NativeBuffer_Unmap failed" << endl;
553         delete rect;
554         return ret;
555     }
556 
557     ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, ohNativeWindowBuffer, -1, region);
558     delete rect;
559     if (ret != 0) {
560         cout << "FlushBuffer failed" << endl;
561         return ret;
562     }
563     return ret;
564 }
565 
StateEOS()566 int32_t VEncNdkInnerFuzzSample::StateEOS()
567 {
568     unique_lock<mutex> lock(signal_->inMutex_);
569     signal_->inCond_.wait(lock, [this]() { return signal_->inIdxQueue_.size() > 0; });
570     uint32_t index = signal_->inIdxQueue_.front();
571     signal_->inIdxQueue_.pop();
572     signal_->inBufferQueue_.pop();
573     lock.unlock();
574 
575     AVCodecBufferInfo info;
576     info.presentationTimeUs = 0;
577     info.size = 0;
578     info.offset = 0;
579     AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
580 
581     return venc_->QueueInputBuffer(index, info, flag);
582 }
583 
ReturnZeroIfEOS(uint32_t expectedSize)584 uint32_t VEncNdkInnerFuzzSample::ReturnZeroIfEOS(uint32_t expectedSize)
585 {
586     if (inFile_->gcount() != static_cast<int32_t>(expectedSize)) {
587         cout << "no more data" << endl;
588         return 0;
589     }
590     return 1;
591 }
592 
ReadOneFrameYUV420SP(uint8_t * dst)593 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameYUV420SP(uint8_t *dst)
594 {
595     uint8_t *start = dst;
596     // copy Y
597     for (uint32_t i = 0; i < defaultHeight; i++) {
598         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth);
599         if (!ReturnZeroIfEOS(defaultWidth)) {
600             return 0;
601         }
602         dst += stride_;
603     }
604     // copy UV
605     for (uint32_t i = 0; i < defaultHeight / sampleRatio; i++) {
606         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth);
607         if (!ReturnZeroIfEOS(defaultWidth)) {
608             return 0;
609         }
610         dst += stride_;
611     }
612     return dst - start;
613 }
614 
ReadOneFrameYUVP010(uint8_t * dst)615 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameYUVP010(uint8_t *dst)
616 {
617     uint8_t *start = dst;
618     int32_t num = 2;
619     // copy Y
620     for (uint32_t i = 0; i < defaultHeight; i++) {
621         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth * num);
622         if (!ReturnZeroIfEOS(defaultWidth * num)) {
623             return 0;
624         }
625         dst += stride_;
626     }
627     // copy UV
628     for (uint32_t i = 0; i < defaultHeight / sampleRatio; i++) {
629         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth * num);
630         if (!ReturnZeroIfEOS(defaultWidth * num)) {
631             return 0;
632         }
633         dst += stride_;
634     }
635     return dst - start;
636 }
637 
ReadOneFrameFromList(uint8_t * dst,int32_t & index)638 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameFromList(uint8_t *dst, int32_t &index)
639 {
640     int32_t ret = 0;
641     if (index >= fileInfos.size()) {
642         ret = venc_->NotifyEos();
643         if (ret != 0) {
644             cout << "OH_VideoEncoder_NotifyEndOfStream failed" << endl;
645         }
646         return LOOP_END;
647     }
648     if (!inFile_->is_open()) {
649         inFile_->open(fileInfos[index].fileDir);
650         if (!inFile_->is_open()) {
651             return OpenFileFail();
652         }
653         defaultWidth = fileInfos[index].width;
654         defaultHeight = fileInfos[index].height;
655         if (setFormatRbgx) {
656             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_RGBX_8888);
657         } else if (setFormat8Bit) {
658             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_420_SP);
659         } else if (setFormat10Bit) {
660             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_P010);
661         } else {
662             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, fileInfos[index].format);
663         }
664         if (ret != AVCS_ERR_OK) {
665             return ret;
666         }
667         ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_BUFFER_GEOMETRY, defaultWidth, defaultHeight);
668         if (ret != AVCS_ERR_OK) {
669             return ret;
670         }
671         cout << fileInfos[index].fileDir << endl;
672         cout << "set width:" << fileInfos[index].width << "height: " << fileInfos[index].height << endl;
673         return FILE_END;
674     }
675     ret = ReadOneFrameByType(dst, fileInfos[index].format);
676     if (!ret) {
677         if (inFile_->is_open()) {
678             inFile_->close();
679         }
680         index++;
681         if (index >= fileInfos.size()) {
682             venc_->NotifyEos();
683             return LOOP_END;
684         }
685         return FILE_END;
686     }
687     return ret;
688 }
689 
ReadOneFrameByType(uint8_t * dst,std::string & fileType)690 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameByType(uint8_t *dst, std::string &fileType)
691 {
692     if (fileType == "rgba") {
693         return ReadOneFrameRGBA8888(dst);
694     } else if (fileType == "nv12" || fileType == "nv21") {
695         return ReadOneFrameYUV420SP(dst);
696     } else {
697         cout << "error fileType" << endl;
698         return 0;
699     }
700 }
701 
ReadOneFrameByType(uint8_t * dst,GraphicPixelFormat format)702 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameByType(uint8_t *dst, GraphicPixelFormat format)
703 {
704     if (format == GRAPHIC_PIXEL_FMT_RGBA_8888) {
705         return ReadOneFrameRGBA8888(dst);
706     } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_420_SP || format == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) {
707         return ReadOneFrameYUV420SP(dst);
708     } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_P010) {
709         return ReadOneFrameYUVP010(dst);
710     } else {
711         cout << "error fileType" << endl;
712         return 0;
713     }
714 }
715 
ReadOneFrameRGBA8888(uint8_t * dst)716 uint32_t VEncNdkInnerFuzzSample::ReadOneFrameRGBA8888(uint8_t *dst)
717 {
718     uint8_t *start = dst;
719     for (uint32_t i = 0; i < defaultHeight; i++) {
720         inFile_->read(reinterpret_cast<char *>(dst), defaultWidth * RGBA_SIZE);
721         if (inFile_->eof()) {
722             return 0;
723         }
724         dst += stride_;
725     }
726     return dst - start;
727 }
728 
RandomEOS(uint32_t index)729 bool VEncNdkInnerFuzzSample::RandomEOS(uint32_t index)
730 {
731     uint32_t randomEos = g_eos() % 25;
732     if (enableRandomEos && randomEos == frameCount) {
733         AVCodecBufferInfo info;
734         info.presentationTimeUs = 0;
735         info.size = 0;
736         info.offset = 0;
737         AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
738 
739         venc_->QueueInputBuffer(index, info, flag);
740         cout << "random eos" << endl;
741         frameCount++;
742         unique_lock<mutex> lock(signal_->inMutex_);
743         signal_->inIdxQueue_.pop();
744         signal_->inBufferQueue_.pop();
745         return true;
746     }
747     return false;
748 }
749 
RepeatStartBeforeEOS()750 void VEncNdkInnerFuzzSample::RepeatStartBeforeEOS()
751 {
752     if (repeatStartFlushBeforeEos > 0) {
753         repeatStartFlushBeforeEos--;
754         venc_->Flush();
755         FlushBuffer();
756         venc_->Start();
757     }
758 
759     if (repeatStartStopBeforeEos > 0) {
760         repeatStartStopBeforeEos--;
761         venc_->Stop();
762         FlushBuffer();
763         venc_->Start();
764     }
765 }
766 
SetEOS(uint32_t index)767 void VEncNdkInnerFuzzSample::SetEOS(uint32_t index)
768 {
769     AVCodecBufferInfo info;
770     info.presentationTimeUs = 0;
771     info.size = 0;
772     info.offset = 0;
773     AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
774 
775     int32_t res = venc_->QueueInputBuffer(index, info, flag);
776     cout << "QueueInputBuffer EOS res: " << res << endl;
777     unique_lock<mutex> lock(signal_->inMutex_);
778     signal_->inIdxQueue_.pop();
779     signal_->inBufferQueue_.pop();
780 }
781 
WaitForEOS()782 void VEncNdkInnerFuzzSample::WaitForEOS()
783 {
784     if (inputLoop_)
785         inputLoop_->join();
786     if (outputLoop_)
787         outputLoop_->join();
788     if (inputParamLoop_)
789         inputParamLoop_->join();
790     inputLoop_ = nullptr;
791     outputLoop_ = nullptr;
792     inputParamLoop_ = nullptr;
793 }
794 
InputFuncSurface()795 void VEncNdkInnerFuzzSample::InputFuncSurface()
796 {
797     int32_t readFileIndex = 0;
798     bool enableInputFunc = true;
799     while (enableInputFunc) {
800         OHNativeWindowBuffer *ohNativeWindowBuffer = nullptr;
801         OH_NativeBuffer *nativeBuffer = nullptr;
802         uint8_t *dst = nullptr;
803         int err = InitBuffer(ohNativeWindowBuffer, nativeBuffer, dst);
804         if (err == 0) {
805             enableInputFunc = false;
806             break;
807         } else if (err == -1) {
808             continue;
809         }
810         if (readMultiFiles) {
811             err = ReadOneFrameFromList(dst, readFileIndex);
812             if (err == LOOP_END) {
813                 break;
814             } else if (err == FILE_END) {
815                 OH_NativeWindow_NativeWindowAbortBuffer(nativeWindow, ohNativeWindowBuffer);
816                 continue;
817             }
818         } else if (!ReadOneFrameYUV420SP(dst)) {
819             err = venc_->NotifyEos();
820             if (err != 0) {
821                 cout << "OH_VideoEncoder_NotifyEndOfStream failed" << endl;
822             }
823             break;
824         }
825         inputFrameCount++;
826         err = InputProcess(nativeBuffer, ohNativeWindowBuffer);
827         if (err != 0) {
828             break;
829         }
830         usleep(FRAME_INTERVAL);
831         InputEnableRepeatSleep();
832     }
833 }
834 
InitBuffer(OHNativeWindowBuffer * & ohNativeWindowBuffer,OH_NativeBuffer * & nativeBuffer,uint8_t * & dst)835 int32_t VEncNdkInnerFuzzSample::InitBuffer(OHNativeWindowBuffer *&ohNativeWindowBuffer,
836     OH_NativeBuffer *&nativeBuffer, uint8_t *&dst)
837 {
838     int fenceFd = -1;
839     if (nativeWindow == nullptr) {
840         return 0;
841     }
842     int32_t err = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &ohNativeWindowBuffer, &fenceFd);
843     if (err != 0) {
844         cout << "RequestBuffer failed, GSError=" << err << endl;
845         return -1;
846     }
847     if (fenceFd > 0) {
848         close(fenceFd);
849     }
850     nativeBuffer = OH_NativeBufferFromNativeWindowBuffer(ohNativeWindowBuffer);
851     void *virAddr = nullptr;
852     err = OH_NativeBuffer_Map(nativeBuffer, &virAddr);
853     if (err != 0) {
854         cout << "OH_NativeBuffer_Map failed, GSError=" << err << endl;
855         isRunning_.store(false);
856         return 0;
857     }
858     dst = (uint8_t *)virAddr;
859     const SurfaceBuffer *sbuffer = SurfaceBuffer::NativeBufferToSurfaceBuffer(nativeBuffer);
860     int32_t stride = sbuffer->GetStride();
861     if (dst == nullptr || stride < static_cast<int32_t>(defaultWidth)) {
862         cout << "invalid va or stride=" << stride << endl;
863         err = NativeWindowCancelBuffer(nativeWindow, ohNativeWindowBuffer);
864         isRunning_.store(false);
865         return 0;
866     }
867     stride_ = stride;
868     return 1;
869 }
870 
InputEnableRepeatSleep()871 void VEncNdkInnerFuzzSample::InputEnableRepeatSleep()
872 {
873     inCount = inCount + 1;
874     int32_t inCountNum = 15;
875     if (enableRepeat && inCount == inCountNum) {
876         if (setMaxCount) {
877             int32_t sleepTimeMaxCount = 730000;
878             usleep(sleepTimeMaxCount);
879         } else {
880             int32_t sleepTime = 1000000;
881             usleep(sleepTime);
882         }
883         if (enableSeekEos) {
884             inFile_->clear();
885             inFile_->seekg(-1, ios::beg);
886         }
887     }
888 }
889 
InputParamLoopFunc()890 void VEncNdkInnerFuzzSample::InputParamLoopFunc()
891 {
892     if (signal_ == nullptr || venc_ == nullptr) {
893         cout << "signal or venc is null" << endl;
894         return;
895     }
896     cout<< "InputParamLoopFunc" <<endl;
897     while (isRunning_.load()) {
898         unique_lock<mutex> lock(signal_->inMutex_);
899         signal_->inCond_.wait(
900             lock, [this]() { return (signal_->inIdxQueue_.size() > 0) || (!isRunning_.load()); });
901         if (!isRunning_.load()) {
902             cout << "InputLoopFunc stop running" << endl;
903             break;
904         }
905         int32_t index = signal_->inIdxQueue_.front();
906         auto format = signal_->inFormatQueue_.front();
907         auto attr = signal_->inAttrQueue_.front();
908         signal_->inIdxQueue_.pop();
909         signal_->inFormatQueue_.pop();
910         signal_->inAttrQueue_.pop();
911         if (attr != nullptr) {
912             int64_t pts = 0;
913             if (true != attr->GetLongValue(Media::Tag::MEDIA_TIME_STAMP, pts)) {
914                 return;
915             }
916         }
917         if (IsFrameDiscard(inputFrameCount)) {
918             discardFrameCount++;
919             format->PutIntValue(Media::Tag::VIDEO_ENCODER_PER_FRAME_DISCARD, 1);
920         }
921         int32_t ret = PushInputParameter(index);
922         if (ret != AV_ERR_OK) {
923             cout << "Fatal: PushInputData fail, exit" << endl;
924         }
925     }
926 }
927 
InputFunc()928 void VEncNdkInnerFuzzSample::InputFunc()
929 {
930     errCount = 0;
931     bool enableInput = true;
932     while (enableInput) {
933         if (!isRunning_.load()) {
934             enableInput = false;
935             break;
936         }
937         RepeatStartBeforeEOS();
938         unique_lock<mutex> lock(signal_->inMutex_);
939         signal_->inCond_.wait(lock, [this]() {
940             if (!isRunning_.load()) {
941                 return true;
942             }
943             return signal_->inIdxQueue_.size() > 0;
944         });
945         if (!isRunning_.load()) {
946             break;
947         }
948         uint32_t index = signal_->inIdxQueue_.front();
949         auto buffer = signal_->inBufferQueue_.front();
950 
951         lock.unlock();
952         if (!inFile_->eof()) {
953             bool isRandomEosSuccess = RandomEOS(index);
954             if (isRandomEosSuccess) {
955                 continue;
956             }
957             int32_t pushResult = 0;
958             int32_t ret = PushData(buffer, index, pushResult);
959             if (ret == 0) {
960                 break;
961             } else if (ret == -1) {
962                 continue;
963             }
964 
965             if (CheckResult(isRandomEosSuccess, pushResult) == -1) {
966                 break;
967             }
968             frameCount++;
969         }
970         if (sleepOnFPS) {
971             usleep(FRAME_INTERVAL);
972         }
973     }
974 }
975 
OutputFunc()976 void VEncNdkInnerFuzzSample::OutputFunc()
977 {
978     bool enableOutput = true;
979     while (enableOutput) {
980         if (!isRunning_.load()) {
981             enableOutput = false;
982             break;
983         }
984 
985         unique_lock<mutex> lock(signal_->outMutex_);
986         signal_->outCond_.wait(lock, [this]() {
987             if (!isRunning_.load()) {
988                 return true;
989             }
990             return signal_->outIdxQueue_.size() > 0;
991         });
992 
993         if (!isRunning_.load()) {
994             break;
995         }
996 
997         std::shared_ptr<AVSharedMemory> buffer = signal_->outBufferQueue_.front();
998         AVCodecBufferFlag flag = signal_->flagQueue_.front();
999         uint32_t index = signal_->outIdxQueue_.front();
1000 
1001         signal_->outBufferQueue_.pop();
1002         signal_->outIdxQueue_.pop();
1003         signal_->infoQueue_.pop();
1004         signal_->flagQueue_.pop();
1005         lock.unlock();
1006 
1007         if (CheckFlag(flag) == -1) {
1008             break;
1009         }
1010 
1011         if (venc_->ReleaseOutputBuffer(index) != AVCS_ERR_OK) {
1012             cout << "Fatal: ReleaseOutputBuffer fail" << endl;
1013             errCount = errCount + 1;
1014         }
1015         if (errCount > 0) {
1016             OutputFuncFail();
1017             break;
1018         }
1019     }
1020 }
1021 
OutputFuncFail()1022 void VEncNdkInnerFuzzSample::OutputFuncFail()
1023 {
1024     cout << "errCount > 0" << endl;
1025     unique_lock<mutex> inLock(signal_->inMutex_);
1026     isRunning_.store(false);
1027     signal_->inCond_.notify_all();
1028     signal_->outCond_.notify_all();
1029     inLock.unlock();
1030     (void)Stop();
1031     Release();
1032 }
1033 
FlushBuffer()1034 void VEncNdkInnerFuzzSample::FlushBuffer()
1035 {
1036     std::queue<std::shared_ptr<AVSharedMemory>> empty;
1037     unique_lock<mutex> inLock(signal_->inMutex_);
1038     clearIntqueue(signal_->inIdxQueue_);
1039     swap(empty, signal_->inBufferQueue_);
1040     signal_->inCond_.notify_all();
1041     inLock.unlock();
1042 
1043     unique_lock<mutex> outLock(signal_->outMutex_);
1044     clearIntqueue(signal_->outIdxQueue_);
1045     clearBufferqueue(signal_->infoQueue_);
1046     clearFlagqueue(signal_->flagQueue_);
1047     signal_->outCond_.notify_all();
1048     outLock.unlock();
1049 }
1050 
StopInloop()1051 void VEncNdkInnerFuzzSample::StopInloop()
1052 {
1053     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
1054         unique_lock<mutex> lock(signal_->inMutex_);
1055         clearIntqueue(signal_->inIdxQueue_);
1056         isRunning_.store(false);
1057         signal_->inCond_.notify_all();
1058         lock.unlock();
1059 
1060         inputLoop_->join();
1061         inputLoop_ = nullptr;
1062     }
1063 }
1064 
StopOutloop()1065 void VEncNdkInnerFuzzSample::StopOutloop()
1066 {
1067     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1068         unique_lock<mutex> lock(signal_->outMutex_);
1069         clearIntqueue(signal_->outIdxQueue_);
1070         clearBufferqueue(signal_->infoQueue_);
1071         clearFlagqueue(signal_->flagQueue_);
1072         signal_->outCond_.notify_all();
1073         lock.unlock();
1074     }
1075 }
1076 
ReleaseInFile()1077 void VEncNdkInnerFuzzSample::ReleaseInFile()
1078 {
1079     if (inFile_ != nullptr) {
1080         if (inFile_->is_open()) {
1081             inFile_->close();
1082         }
1083         inFile_.reset();
1084         inFile_ = nullptr;
1085     }
1086 }
1087 
PushRandomDiscardIndex(uint32_t count,uint32_t max,uint32_t min)1088 void VEncNdkInnerFuzzSample::PushRandomDiscardIndex(uint32_t count, uint32_t max, uint32_t min)
1089 {
1090     cout << "random farame index :";
1091     while (discardFrameIndex.size() < count) {
1092         uint32_t num = 0;
1093         if (max != 0) {
1094             num = g_rd() % max + min;
1095         }
1096         if (find(discardFrameIndex.begin(), discardFrameIndex.end(), num) == discardFrameIndex.end()) {
1097             cout << num << ",";
1098             discardFrameIndex.push_back(num);
1099         }
1100         cout << endl;
1101     }
1102 }
1103 
IsFrameDiscard(uint32_t index)1104 bool VEncNdkInnerFuzzSample::IsFrameDiscard(uint32_t index)
1105 {
1106     if (!isDiscardFrame) {
1107         return false;
1108     }
1109     if (discardMinIndex > -1 && discardMaxIndex >= discardMinIndex) {
1110         if (index >= discardMinIndex && index <= discardMaxIndex) {
1111             return true;
1112         }
1113     }
1114     if (find(discardFrameIndex.begin(), discardFrameIndex.end(), index) != discardFrameIndex.end()) {
1115         return true;
1116     }
1117     if (discardInterval > 0 && index % discardInterval == 0) {
1118         return true;
1119     }
1120     return false;
1121 }
1122 
CheckOutputFrameCount()1123 bool VEncNdkInnerFuzzSample::CheckOutputFrameCount()
1124 {
1125     cout << "checooutpuframecount" << inputFrameCount << ", " << discardFrameCount<< ", " << outCount << endl;
1126     if (inputFrameCount - discardFrameCount == outCount) {
1127         return true;
1128     }
1129     return false;
1130 }
1131 
PushInputParameter(uint32_t index)1132 int32_t VEncNdkInnerFuzzSample::PushInputParameter(uint32_t index)
1133 {
1134     if (venc_ == nullptr) {
1135         return AV_ERR_UNKNOWN;
1136     }
1137     return venc_->QueueInputParameter(index);
1138 }
1139 
SetCustomBuffer(BufferRequestConfig bufferConfig,uint8_t * data)1140 int32_t VEncNdkInnerFuzzSample::SetCustomBuffer(BufferRequestConfig bufferConfig, uint8_t *data)
1141 {
1142     int32_t waterMarkFlag = enableWaterMark ? 1 : 0;
1143     auto allocator = Media::AVAllocatorFactory::CreateSurfaceAllocator(bufferConfig);
1144     std::shared_ptr<AVBuffer> avbuffer = AVBuffer::CreateAVBuffer(allocator);
1145     if (avbuffer == nullptr) {
1146         cout << "avbuffer is nullptr" << endl;
1147         return AVCS_ERR_INVALID_VAL;
1148     }
1149     ReadCustomDataToAVBuffer(data, avbuffer);
1150     Format format;
1151     format.SetMeta(avbuffer->meta_);
1152     format.PutIntValue(Media::Tag::VIDEO_ENCODER_ENABLE_WATERMARK, waterMarkFlag);
1153     format.PutIntValue(Media::Tag::VIDEO_COORDINATE_X, videoCoordinateX);
1154     format.PutIntValue(Media::Tag::VIDEO_COORDINATE_Y, videoCoordinateY);
1155     format.PutIntValue(Media::Tag::VIDEO_COORDINATE_W, videoCoordinateWidth);
1156     format.PutIntValue(Media::Tag::VIDEO_COORDINATE_H, videoCoordinateHeight);
1157     *(avbuffer->meta_) = *(format.GetMeta());
1158     int32_t ret = venc_->SetCustomBuffer(avbuffer);
1159     return ret;
1160 }
1161 
ReadCustomDataToAVBuffer(uint8_t * data,std::shared_ptr<AVBuffer> buffer)1162 bool VEncNdkInnerFuzzSample::ReadCustomDataToAVBuffer(uint8_t *data, std::shared_ptr<AVBuffer> buffer)
1163 {
1164     sptr<SurfaceBuffer> surfaceBuffer = buffer->memory_->GetSurfaceBuffer();
1165     if (surfaceBuffer == nullptr) {
1166         cout << "in is nullptr" << endl;
1167         return false;
1168     }
1169     int32_t width = surfaceBuffer->GetWidth();
1170     int32_t height = surfaceBuffer->GetHeight();
1171     int32_t dstWidthStride = surfaceBuffer->GetStride();
1172     uint8_t *dstAddr = (uint8_t *)surfaceBuffer->GetVirAddr();
1173     if (dstAddr == nullptr) {
1174         cout << "dst is nullptr" << endl;
1175     }
1176     const int32_t srcWidthStride = width << 2;
1177     uint8_t *inStream = data;
1178     for (uint32_t i = 0; i < height; ++i) {
1179         if (memcpy_s(dstAddr, dstWidthStride, inStream, srcWidthStride)) {
1180             cout << "memcpy_s failed" <<endl;
1181         };
1182         dstAddr += dstWidthStride;
1183         inStream += srcWidthStride;
1184     }
1185     return true;
1186 }
1187 
GetWaterMarkCapability(std::string codecMimeType)1188 bool VEncNdkInnerFuzzSample::GetWaterMarkCapability(std::string codecMimeType)
1189 {
1190     std::shared_ptr<AVCodecList> codecCapability = AVCodecListFactory::CreateAVCodecList();
1191     CapabilityData *capabilityData = nullptr;
1192     capabilityData = codecCapability->GetCapability(codecMimeType, true, AVCodecCategory::AVCODEC_HARDWARE);
1193     if (capabilityData->featuresMap.count(static_cast<int32_t>(AVCapabilityFeature::VIDEO_WATERMARK))) {
1194         std::cout << "Support watermark" << std::endl;
1195         return true;
1196     } else {
1197         std::cout << " Not support watermark" << std::endl;
1198         return false;
1199     }
1200     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capabilityData);
1201     (void)codecInfo->GetSupportedMaxBitrate();
1202     (void)codecInfo->GetSupportedSqrFactor();
1203 }