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