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