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