• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }