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 }