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 }