• 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 "iconsumer_surface.h"
19 #include "native_buffer_inner.h"
20 #include "display_type.h"
21 #include "videoenc_api11_sample.h"
22 #include "native_avcapability.h"
23 using namespace OHOS;
24 using namespace OHOS::Media;
25 using namespace std;
26 namespace {
27 constexpr int64_t NANOS_IN_SECOND = 1000000000L;
28 constexpr int64_t NANOS_IN_MICRO = 1000L;
29 constexpr uint32_t FRAME_INTERVAL = 16666;
30 constexpr uint32_t MAX_PIXEL_FMT = 5;
31 constexpr uint8_t RGBA_SIZE = 4;
32 constexpr uint32_t IDR_FRAME_INTERVAL = 10;
33 constexpr uint32_t DOUBLE = 2;
34 constexpr uint32_t BADPOC = 1000;
35 constexpr uint32_t LTR_INTERVAL = 5;
36 sptr<Surface> cs = nullptr;
37 sptr<Surface> ps = nullptr;
38 OH_AVCapability *cap = nullptr;
39 VEncAPI11Sample *enc_sample = nullptr;
40 constexpr uint8_t FILE_END = -1;
41 constexpr uint8_t LOOP_END = 0;
42 int32_t g_picWidth;
43 int32_t g_picHeight;
44 int32_t g_keyWidth;
45 int32_t g_keyHeight;
46 
clearIntqueue(std::queue<uint32_t> & q)47 void clearIntqueue(std::queue<uint32_t> &q)
48 {
49     std::queue<uint32_t> empty;
50     swap(empty, q);
51 }
52 } // namespace
53 
~VEncAPI11Sample()54 VEncAPI11Sample::~VEncAPI11Sample()
55 {
56     if (SURF_INPUT && nativeWindow) {
57         OH_NativeWindow_DestroyNativeWindow(nativeWindow);
58         nativeWindow = nullptr;
59     }
60     Release();
61 }
62 
VencError(OH_AVCodec * codec,int32_t errorCode,void * userData)63 static void VencError(OH_AVCodec *codec, int32_t errorCode, void *userData)
64 {
65     cout << "Error errorCode=" << errorCode << endl;
66 }
67 
VencFormatChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)68 static void VencFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
69 {
70     cout << "Format Changed" << endl;
71     OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_PIC_WIDTH, &g_picWidth);
72     OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_PIC_HEIGHT, &g_picHeight);
73     OH_AVFormat_GetIntValue(format, OH_MD_KEY_WIDTH, &g_keyWidth);
74     OH_AVFormat_GetIntValue(format, OH_MD_KEY_HEIGHT, &g_keyHeight);
75     cout << "format info: " << OH_AVFormat_DumpInfo(format) << ", OH_MD_KEY_VIDEO_PIC_WIDTH: " << g_picWidth
76     << ", OH_MD_KEY_VIDEO_PIC_HEIGHT: "<< g_picHeight << ", OH_MD_KEY_WIDTH: " << g_keyWidth
77     << ", OH_MD_KEY_HEIGHT: " << g_keyHeight << endl;
78 }
79 
onEncInputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * buffer,void * userData)80 static void onEncInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
81 {
82     VEncAPI11Signal *signal = static_cast<VEncAPI11Signal *>(userData);
83     unique_lock<mutex> lock(signal->inMutex_);
84     signal->inIdxQueue_.push(index);
85     signal->inBufferQueue_.push(buffer);
86     signal->inCond_.notify_all();
87 }
88 
onEncOutputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * buffer,void * userData)89 static void onEncOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
90 {
91     VEncAPI11Signal *signal = static_cast<VEncAPI11Signal *>(userData);
92     unique_lock<mutex> lock(signal->outMutex_);
93     signal->outIdxQueue_.push(index);
94     signal->outBufferQueue_.push(buffer);
95     signal->outCond_.notify_all();
96 }
97 
onEncInputParam(OH_AVCodec * codec,uint32_t index,OH_AVFormat * parameter,void * userData)98 static void onEncInputParam(OH_AVCodec *codec, uint32_t index, OH_AVFormat *parameter, void *userData)
99 {
100     static bool useLtrOnce = false;
101     if (!parameter || !userData) {
102         return;
103     }
104     if (enc_sample->frameCount % enc_sample->ltrParam.ltrInterval == 0) {
105         OH_AVFormat_SetIntValue(parameter, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_MARK_LTR, 1);
106     }
107     if (!enc_sample->ltrParam.enableUseLtr) {
108         enc_sample->frameCount++;
109         OH_VideoEncoder_PushInputParameter(codec, index);
110         return;
111     }
112     static int32_t useLtrIndex = 0;
113     if (enc_sample->ltrParam.useLtrIndex == 0) {
114         useLtrIndex = LTR_INTERVAL;
115     } else if (enc_sample->ltrParam.useBadLtr) {
116         useLtrIndex = BADPOC;
117     } else {
118         uint32_t interval = enc_sample->ltrParam.ltrInterval;
119         if (interval > 0 && enc_sample->frameCount > 0 && (enc_sample->frameCount % interval == 0)) {
120             useLtrIndex = enc_sample->frameCount / interval * interval;
121         }
122     }
123     if (enc_sample->frameCount > useLtrIndex) {
124         if (!enc_sample->ltrParam.useLtrOnce) {
125             OH_AVFormat_SetIntValue(parameter, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, useLtrIndex);
126         } else {
127             if (!useLtrOnce) {
128                 OH_AVFormat_SetIntValue(parameter, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, useLtrIndex);
129                 useLtrOnce = true;
130             }
131         }
132     } else if (enc_sample->frameCount == useLtrIndex && enc_sample->frameCount > 0) {
133         int32_t sampleInterval = enc_sample->ltrParam.ltrInterval;
134         OH_AVFormat_SetIntValue(parameter, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, useLtrIndex - sampleInterval);
135     }
136     enc_sample->frameCount++;
137     OH_VideoEncoder_PushInputParameter(codec, index);
138 }
139 
DumpLtrInfo(OH_AVBuffer * buffer)140 void VEncAPI11Sample::DumpLtrInfo(OH_AVBuffer *buffer)
141 {
142     OH_AVFormat *format = OH_AVBuffer_GetParameter(buffer);
143     int32_t isLtr = 0;
144     int32_t framePoc = 0;
145     OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_PER_FRAME_IS_LTR, &isLtr);
146     OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_PER_FRAME_POC, &framePoc);
147 }
148 
DumpQPInfo(OH_AVBuffer * buffer)149 void VEncAPI11Sample::DumpQPInfo(OH_AVBuffer *buffer)
150 {
151     OH_AVFormat *format = OH_AVBuffer_GetParameter(buffer);
152     int32_t qp_average = 0;
153     double mse = 0;
154     OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_AVERAGE, &qp_average);
155     OH_AVFormat_GetDoubleValue(format, OH_MD_KEY_VIDEO_ENCODER_MSE, &mse);
156 }
157 
DumpInfo(OH_AVCodecBufferAttr attr,OH_AVBuffer * buffer)158 void VEncAPI11Sample::DumpInfo(OH_AVCodecBufferAttr attr, OH_AVBuffer *buffer)
159 {
160     if (enableLTR && attr.flags == AVCODEC_BUFFER_FLAGS_NONE) {
161         DumpLtrInfo(buffer);
162     }
163     if (getQpMse && attr.flags == AVCODEC_BUFFER_FLAGS_NONE) {
164         DumpQPInfo(buffer);
165     }
166 }
167 
GetSystemTimeUs()168 int64_t VEncAPI11Sample::GetSystemTimeUs()
169 {
170     struct timespec now;
171     (void)clock_gettime(CLOCK_BOOTTIME, &now);
172     int64_t nanoTime = (int64_t)now.tv_sec * NANOS_IN_SECOND + now.tv_nsec;
173 
174     return nanoTime / NANOS_IN_MICRO;
175 }
176 
ConfigureVideoEncoder()177 int32_t VEncAPI11Sample::ConfigureVideoEncoder()
178 {
179     OH_AVFormat *format = OH_AVFormat_Create();
180     if (format == nullptr) {
181         cout << "Fatal: Failed to create format" << endl;
182         return AV_ERR_UNKNOWN;
183     }
184     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, DEFAULT_WIDTH);
185     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, DEFAULT_HEIGHT);
186     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, DEFAULT_PIX_FMT);
187     (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
188     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_I_FRAME_INTERVAL, DEFAULT_KEY_FRAME_INTERVAL);
189     if (isAVCEncoder) {
190         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, avcProfile);
191     } else {
192         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, hevcProfile);
193     }
194     if (configMain10) {
195         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, HEVC_PROFILE_MAIN_10);
196     } else if (configMain) {
197         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, HEVC_PROFILE_MAIN);
198     }
199     if (DEFAULT_BITRATE_MODE == CQ) {
200         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_QUALITY, DEFAULT_QUALITY);
201     } else {
202         (void)OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, DEFAULT_BITRATE);
203     }
204     if (enableQP) {
205         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MAX, DEFAULT_QP);
206         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MIN, DEFAULT_QP);
207     }
208     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, DEFAULT_BITRATE_MODE);
209     if (enableLTR && (ltrParam.ltrCount >= 0)) {
210         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT, ltrParam.ltrCount);
211     }
212     if (enableColorSpaceParams) {
213         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_RANGE_FLAG, DEFAULT_RANGE_FLAG);
214         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_COLOR_PRIMARIES, DEFAULT_COLOR_PRIMARIES);
215         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_TRANSFER_CHARACTERISTICS, DEFAULT_TRANSFER_CHARACTERISTICS);
216         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_MATRIX_COEFFICIENTS, DEFAULT_MATRIX_COEFFICIENTS);
217     }
218     if (enableRepeat) {
219         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_REPEAT_PREVIOUS_FRAME_AFTER, DEFAULT_FRAME_AFTER);
220         if (setMaxCount) {
221             (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_REPEAT_PREVIOUS_MAX_COUNT, DEFAULT_MAX_COUNT);
222         }
223     }
224     int ret = OH_VideoEncoder_Configure(venc_, format);
225     OH_AVFormat_Destroy(format);
226     return ret;
227 }
228 
ConfigureVideoEncoder_Temporal(int32_t temporal_gop_size)229 int32_t VEncAPI11Sample::ConfigureVideoEncoder_Temporal(int32_t temporal_gop_size)
230 {
231     OH_AVFormat *format = OH_AVFormat_Create();
232     if (format == nullptr) {
233         cout << "Fatal: Failed to create format" << endl;
234         return AV_ERR_UNKNOWN;
235     }
236     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, DEFAULT_WIDTH);
237     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, DEFAULT_HEIGHT);
238     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, DEFAULT_PIX_FMT);
239     (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
240     (void)OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, DEFAULT_BITRATE);
241 
242     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_I_FRAME_INTERVAL, DEFAULT_KEY_FRAME_INTERVAL);
243 
244     if (TEMPORAL_CONFIG) {
245         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_SIZE, temporal_gop_size);
246         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_REFERENCE_MODE,
247             ADJACENT_REFERENCE);
248     }
249     if (TEMPORAL_ENABLE) {
250         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY, 1);
251     } else {
252         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY, 0);
253     }
254     if (TEMPORAL_JUMP_MODE) {
255         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_REFERENCE_MODE, JUMP_REFERENCE);
256     }
257     if (enableLTR && (ltrParam.ltrCount > 0)) {
258         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT, ltrParam.ltrCount);
259     }
260     if (TEMPORAL_UNIFORMLY) {
261         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_SIZE, temporal_gop_size);
262         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_REFERENCE_MODE,
263             UNIFORMLY_SCALED_REFERENCE);
264     }
265     int ret = OH_VideoEncoder_Configure(venc_, format);
266     OH_AVFormat_Destroy(format);
267     return ret;
268 }
269 
ConfigureVideoEncoder_fuzz(int32_t data)270 int32_t VEncAPI11Sample::ConfigureVideoEncoder_fuzz(int32_t data)
271 {
272     OH_AVFormat *format = OH_AVFormat_Create();
273     if (format == nullptr) {
274         cout << "Fatal: Failed to create format" << endl;
275         return AV_ERR_UNKNOWN;
276     }
277     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, data);
278     DEFAULT_WIDTH = data;
279     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, data);
280     DEFAULT_HEIGHT = data;
281     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, data % MAX_PIXEL_FMT);
282     double frameRate = data;
283     (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, frameRate);
284 
285     OH_AVFormat_SetIntValue(format, OH_MD_KEY_RANGE_FLAG, data);
286     OH_AVFormat_SetIntValue(format, OH_MD_KEY_COLOR_PRIMARIES, data);
287     OH_AVFormat_SetIntValue(format, OH_MD_KEY_TRANSFER_CHARACTERISTICS, data);
288     OH_AVFormat_SetIntValue(format, OH_MD_KEY_MATRIX_COEFFICIENTS, data);
289     OH_AVFormat_SetIntValue(format, OH_MD_KEY_I_FRAME_INTERVAL, data);
290     OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, data);
291     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, data);
292     OH_AVFormat_SetIntValue(format, OH_MD_KEY_QUALITY, data);
293 
294     int ret = OH_VideoEncoder_Configure(venc_, format);
295     OH_AVFormat_Destroy(format);
296     return ret;
297 }
298 
SetVideoEncoderCallback()299 int32_t VEncAPI11Sample::SetVideoEncoderCallback()
300 {
301     signal_ = new VEncAPI11Signal();
302     if (signal_ == nullptr) {
303         cout << "Failed to new VEncAPI11Signal" << endl;
304         return AV_ERR_UNKNOWN;
305     }
306     if (SURF_INPUT) {
307         int32_t ret = OH_VideoEncoder_RegisterParameterCallback(venc_, onEncInputParam, static_cast<void *>(this));
308         if (ret != AV_ERR_OK) {
309             return ret;
310         }
311     }
312     cb_.onError = VencError;
313     cb_.onStreamChanged = VencFormatChanged;
314     cb_.onNeedInputBuffer = onEncInputBufferAvailable;
315     cb_.onNewOutputBuffer = onEncOutputBufferAvailable;
316 
317     return OH_VideoEncoder_RegisterCallback(venc_, cb_, static_cast<void *>(signal_));
318 }
319 
state_EOS()320 int32_t VEncAPI11Sample::state_EOS()
321 {
322     unique_lock<mutex> lock(signal_->inMutex_);
323     signal_->inCond_.wait(lock, [this]() { return signal_->inIdxQueue_.size() > 0; });
324     uint32_t index = signal_->inIdxQueue_.front();
325     OH_AVBuffer *buffer = signal_->inBufferQueue_.front();
326     signal_->inIdxQueue_.pop();
327     signal_->inBufferQueue_.pop();
328     lock.unlock();
329     OH_AVCodecBufferAttr attr;
330     attr.pts = 0;
331     attr.size = 0;
332     attr.offset = 0;
333     attr.flags = AVCODEC_BUFFER_FLAGS_EOS;
334     OH_AVBuffer_SetBufferAttr(buffer, &attr);
335     return OH_VideoEncoder_PushInputBuffer(venc_, index);
336 }
ReleaseInFile()337 void VEncAPI11Sample::ReleaseInFile()
338 {
339     if (inFile_ != nullptr) {
340         if (inFile_->is_open()) {
341             inFile_->close();
342         }
343         inFile_.reset();
344         inFile_ = nullptr;
345     }
346 }
347 
StopInloop()348 void VEncAPI11Sample::StopInloop()
349 {
350     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
351         unique_lock<mutex> lock(signal_->inMutex_);
352         clearIntqueue(signal_->inIdxQueue_);
353         isRunning_.store(false);
354         signal_->inCond_.notify_all();
355         lock.unlock();
356 
357         inputLoop_->join();
358         inputLoop_ = nullptr;
359     }
360 }
361 
testApi()362 void VEncAPI11Sample::testApi()
363 {
364     OH_VideoEncoder_GetSurface(venc_, &nativeWindow);
365     OH_VideoEncoder_Prepare(venc_);
366     OH_VideoEncoder_GetInputDescription(venc_);
367     OH_VideoEncoder_Start(venc_);
368     OH_AVFormat *format = OH_AVFormat_Create();
369     OH_AVFormat_SetIntValue(format, OH_MD_KEY_REQUEST_I_FRAME, 1);
370     OH_VideoEncoder_SetParameter(venc_, format);
371     OH_VideoEncoder_NotifyEndOfStream(venc_);
372     OH_VideoEncoder_GetOutputDescription(venc_);
373     OH_AVFormat_Destroy(format);
374     OH_VideoEncoder_Flush(venc_);
375     bool isValid = false;
376     OH_VideoEncoder_IsValid(venc_, &isValid);
377     OH_VideoEncoder_Stop(venc_);
378     OH_VideoEncoder_Reset(venc_);
379 }
380 
CreateSurface()381 int32_t VEncAPI11Sample::CreateSurface()
382 {
383     int32_t ret = 0;
384     ret = OH_VideoEncoder_GetSurface(venc_, &nativeWindow);
385     if (ret != AV_ERR_OK) {
386         cout << "OH_VideoEncoder_GetSurface fail" << endl;
387         return ret;
388     }
389     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_420_SP);
390     if (ret != AV_ERR_OK) {
391         cout << "NativeWindowHandleOpt SET_FORMAT fail" << endl;
392         return ret;
393     }
394     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_BUFFER_GEOMETRY, DEFAULT_WIDTH, DEFAULT_HEIGHT);
395     if (ret != AV_ERR_OK) {
396         cout << "NativeWindowHandleOpt SET_BUFFER_GEOMETRY fail" << endl;
397         return ret;
398     }
399     return AV_ERR_OK;
400 }
401 
GetStride()402 void VEncAPI11Sample::GetStride()
403 {
404     OH_AVFormat *format = OH_VideoEncoder_GetInputDescription(venc_);
405     int32_t inputStride = 0;
406     OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_STRIDE, &inputStride);
407     stride_ = inputStride;
408     OH_AVFormat_Destroy(format);
409 }
410 
OpenFile()411 int32_t VEncAPI11Sample::OpenFile()
412 {
413     int32_t ret = AV_ERR_OK;
414     inFile_ = make_unique<ifstream>();
415     if (inFile_ == nullptr) {
416         isRunning_.store(false);
417         (void)OH_VideoEncoder_Stop(venc_);
418         return AV_ERR_UNKNOWN;
419     }
420     inFile_->open(INP_DIR, ios::in | ios::binary);
421     if (!inFile_->is_open()) {
422         ret = OpenFileFail();
423     }
424     return ret;
425 }
426 
StartVideoEncoder()427 int32_t VEncAPI11Sample::StartVideoEncoder()
428 {
429     isRunning_.store(true);
430     int32_t ret = 0;
431     if (SURF_INPUT) {
432         ret = CreateSurface();
433         if (ret != AV_ERR_OK) {
434             return ret;
435         }
436     }
437     ret = OH_VideoEncoder_Start(venc_);
438     GetStride();
439     if (ret != AV_ERR_OK) {
440         cout << "Failed to start codec" << endl;
441         isRunning_.store(false);
442         signal_->inCond_.notify_all();
443         signal_->outCond_.notify_all();
444         return ret;
445     }
446     inFile_ = make_unique<ifstream>();
447     if (inFile_ == nullptr) {
448         isRunning_.store(false);
449         (void)OH_VideoEncoder_Stop(venc_);
450         return AV_ERR_UNKNOWN;
451     }
452     readMultiFilesFunc();
453     if (SURF_INPUT) {
454         inputLoop_ = make_unique<thread>(&VEncAPI11Sample::InputFuncSurface, this);
455     } else {
456         inputLoop_ = make_unique<thread>(&VEncAPI11Sample::InputFunc, this);
457     }
458     if (inputLoop_ == nullptr) {
459         isRunning_.store(false);
460         (void)OH_VideoEncoder_Stop(venc_);
461         ReleaseInFile();
462         return AV_ERR_UNKNOWN;
463     }
464     outputLoop_ = make_unique<thread>(&VEncAPI11Sample::OutputFunc, this);
465     if (outputLoop_ == nullptr) {
466         isRunning_.store(false);
467         (void)OH_VideoEncoder_Stop(venc_);
468         ReleaseInFile();
469         StopInloop();
470         Release();
471         return AV_ERR_UNKNOWN;
472     }
473     return AV_ERR_OK;
474 }
475 
readMultiFilesFunc()476 void VEncAPI11Sample::readMultiFilesFunc()
477 {
478     if (!readMultiFiles) {
479         inFile_->open(INP_DIR, ios::in | ios::binary);
480         if (!inFile_->is_open()) {
481             OpenFileFail();
482         }
483     }
484 }
485 
CreateVideoEncoder(const char * codecName)486 int32_t VEncAPI11Sample::CreateVideoEncoder(const char *codecName)
487 {
488     cap = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true, HARDWARE);
489     const char *tmpCodecName = OH_AVCapability_GetName(cap);
490     if (!strcmp(codecName, tmpCodecName)) {
491         isAVCEncoder = true;
492     } else {
493         isAVCEncoder = false;
494     }
495     venc_ = OH_VideoEncoder_CreateByName(codecName);
496     enc_sample = this;
497     return venc_ == nullptr ? AV_ERR_UNKNOWN : AV_ERR_OK;
498 }
499 
WaitForEOS()500 void VEncAPI11Sample::WaitForEOS()
501 {
502     if (inputLoop_)
503         inputLoop_->join();
504     if (outputLoop_)
505         outputLoop_->join();
506     inputLoop_ = nullptr;
507     outputLoop_ = nullptr;
508 }
509 
ReturnZeroIfEOS(uint32_t expectedSize)510 uint32_t VEncAPI11Sample::ReturnZeroIfEOS(uint32_t expectedSize)
511 {
512     if (inFile_->gcount() != (expectedSize)) {
513         cout << "no more data" << endl;
514         return 0;
515     }
516     return 1;
517 }
518 
ReadOneFrameYUV420SP(uint8_t * dst)519 uint32_t VEncAPI11Sample::ReadOneFrameYUV420SP(uint8_t *dst)
520 {
521     uint8_t *start = dst;
522     // copy Y
523     for (uint32_t i = 0; i < DEFAULT_HEIGHT; i++) {
524         inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH);
525         if (!ReturnZeroIfEOS(DEFAULT_WIDTH))
526             return 0;
527         dst += stride_;
528     }
529     // copy UV
530     for (uint32_t i = 0; i < DEFAULT_HEIGHT / SAMPLE_RATIO; i++) {
531         inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH);
532         if (!ReturnZeroIfEOS(DEFAULT_WIDTH))
533             return 0;
534         dst += stride_;
535     }
536     return dst - start;
537 }
538 
ReadOneFrameYUVP010(uint8_t * dst)539 uint32_t VEncAPI11Sample::ReadOneFrameYUVP010(uint8_t *dst)
540 {
541     uint8_t *start = dst;
542     int32_t num = 2;
543     // copy Y
544     for (uint32_t i = 0; i < DEFAULT_HEIGHT; i++) {
545         inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH*num);
546         if (!ReturnZeroIfEOS(DEFAULT_WIDTH*num))
547             return 0;
548         dst += stride_;
549     }
550     // copy UV
551     for (uint32_t i = 0; i < DEFAULT_HEIGHT / SAMPLE_RATIO; i++) {
552         inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH*num);
553         if (!ReturnZeroIfEOS(DEFAULT_WIDTH*num))
554             return 0;
555         dst += stride_;
556     }
557     return dst - start;
558 }
559 
ReadOneFrameRGBA8888(uint8_t * dst)560 uint32_t VEncAPI11Sample::ReadOneFrameRGBA8888(uint8_t *dst)
561 {
562     uint8_t *start = dst;
563     for (uint32_t i = 0; i < DEFAULT_HEIGHT; i++) {
564         inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH * RGBA_SIZE);
565         if (inFile_->eof())
566             return 0;
567         dst += stride_;
568     }
569     return dst - start;
570 }
571 
FlushSurf(OHNativeWindowBuffer * ohNativeWindowBuffer,OH_NativeBuffer * nativeBuffer)572 uint32_t VEncAPI11Sample::FlushSurf(OHNativeWindowBuffer *ohNativeWindowBuffer, OH_NativeBuffer *nativeBuffer)
573 {
574     int32_t ret = 0;
575     struct Region region;
576     struct Region::Rect *rect = new Region::Rect();
577     rect->x = 0;
578     rect->y = 0;
579     rect->w = DEFAULT_WIDTH;
580     rect->h = DEFAULT_HEIGHT;
581     region.rects = rect;
582     NativeWindowHandleOpt(nativeWindow, SET_UI_TIMESTAMP, GetSystemTimeUs());
583     ret = OH_NativeBuffer_Unmap(nativeBuffer);
584     if (ret != 0) {
585         cout << "OH_NativeBuffer_Unmap failed" << endl;
586         delete rect;
587         return ret;
588     }
589     ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, ohNativeWindowBuffer, -1, region);
590     delete rect;
591     if (ret != 0) {
592         cout << "FlushBuffer failed" << endl;
593         return ret;
594     }
595     return ret;
596 }
597 
InputFuncSurface()598 void VEncAPI11Sample::InputFuncSurface()
599 {
600     int32_t readFileIndex = 0;
601     while (true) {
602         OHNativeWindowBuffer *ohNativeWindowBuffer;
603         OH_NativeBuffer *nativeBuffer = nullptr;
604         uint8_t *dst = nullptr;
605         int err = InitBuffer(ohNativeWindowBuffer, nativeBuffer, dst);
606         if (err == 0) {
607             break;
608         } else if (err == -1) {
609             continue;
610         }
611         if (readMultiFiles) {
612             err = ReadOneFrameFromList(dst, readFileIndex);
613             if (err == LOOP_END) {
614                 break;
615             } else if (err == FILE_END) {
616                 OH_NativeWindow_NativeWindowAbortBuffer(nativeWindow, ohNativeWindowBuffer);
617                 cout << "OH_NativeWindow_NativeWindowAbortBuffer" << endl;
618                 continue;
619             }
620         } else if (!ReadOneFrameYUV420SP(dst)) {
621             err = OH_VideoEncoder_NotifyEndOfStream(venc_);
622             if (err != 0) {
623                 cout << "OH_VideoEncoder_NotifyEndOfStream failed" << endl;
624             }
625             break;
626         }
627         err = FlushSurf(ohNativeWindowBuffer, nativeBuffer);
628         if (err != 0) {
629             break;
630         }
631         usleep(FRAME_INTERVAL);
632         InputEnableRepeatSleep();
633     }
634 }
635 
InputEnableRepeatSleep()636 void VEncAPI11Sample::InputEnableRepeatSleep()
637 {
638     inCount = inCount + 1;
639     int32_t inCountNum = 15;
640     if (enableRepeat && inCount == inCountNum) {
641         if (setMaxCount) {
642             int32_t sleepTimeMaxCount = 730000;
643             usleep(sleepTimeMaxCount);
644         } else {
645             int32_t sleepTime = 1000000;
646             usleep(sleepTime);
647         }
648         if (enableSeekEos) {
649             inFile_->clear();
650             inFile_->seekg(-1, ios::beg);
651         }
652     }
653 }
654 
InitBuffer(OHNativeWindowBuffer * & ohNativeWindowBuffer,OH_NativeBuffer * & nativeBuffer,uint8_t * & dst)655 int32_t VEncAPI11Sample::InitBuffer(OHNativeWindowBuffer *&ohNativeWindowBuffer,
656     OH_NativeBuffer *&nativeBuffer, uint8_t *&dst)
657 {
658     int fenceFd = -1;
659     if (nativeWindow == nullptr) {
660         return 0;
661     }
662     int32_t err = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &ohNativeWindowBuffer, &fenceFd);
663     if (err != 0) {
664         cout << "RequestBuffer failed, GSError=" << err << endl;
665         return -1;
666     }
667     if (fenceFd > 0) {
668         close(fenceFd);
669     }
670     nativeBuffer = OH_NativeBufferFromNativeWindowBuffer(ohNativeWindowBuffer);
671     void *virAddr = nullptr;
672     err = OH_NativeBuffer_Map(nativeBuffer, &virAddr);
673     if (err != 0) {
674         cout << "OH_NativeBuffer_Map failed, GSError=" << err << endl;
675         isRunning_.store(false);
676         return 0;
677     }
678     dst = (uint8_t *)virAddr;
679     const SurfaceBuffer *sbuffer = SurfaceBuffer::NativeBufferToSurfaceBuffer(nativeBuffer);
680     int32_t stride = sbuffer->GetStride();
681     if (dst == nullptr || stride < (int32_t)DEFAULT_WIDTH) {
682         cout << "invalid va or stride=" << stride << endl;
683         err = NativeWindowCancelBuffer(nativeWindow, ohNativeWindowBuffer);
684         isRunning_.store(false);
685         return 0;
686     }
687     stride_ = stride;
688     return 1;
689 }
690 
ReadOneFrameFromList(uint8_t * dst,int32_t & index)691 uint32_t VEncAPI11Sample::ReadOneFrameFromList(uint8_t *dst, int32_t &index)
692 {
693     int32_t ret = 0;
694     if (index >= fileInfos.size()) {
695         ret = OH_VideoEncoder_NotifyEndOfStream(venc_);
696         if (ret != 0) {
697             cout << "OH_VideoEncoder_NotifyEndOfStream failed" << endl;
698         }
699         return LOOP_END;
700     }
701     if (!inFile_->is_open()) {
702         inFile_->open(fileInfos[index].fileDir);
703         if (!inFile_->is_open()) {
704             return OpenFileFail();
705         }
706         DEFAULT_WIDTH = fileInfos[index].width;
707         DEFAULT_HEIGHT = fileInfos[index].height;
708         if (setFormatRbgx) {
709             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_RGBX_8888);
710         } else if (setFormat8Bit) {
711             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_420_SP);
712         } else if (setFormat10Bit) {
713             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_P010);
714         } else {
715             ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, fileInfos[index].format);
716         }
717         if (ret != AV_ERR_OK) {
718             return ret;
719         }
720         ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_BUFFER_GEOMETRY, DEFAULT_WIDTH, DEFAULT_HEIGHT);
721         if (ret != AV_ERR_OK) {
722             return ret;
723         }
724         cout << fileInfos[index].fileDir << endl;
725         cout << "set width:" << fileInfos[index].width << "height: " << fileInfos[index].height << endl;
726         return FILE_END;
727     }
728     ret = ReadOneFrameByType(dst, fileInfos[index].format);
729     if (!ret) {
730         if (inFile_->is_open()) {
731             inFile_->close();
732         }
733         index++;
734         if (index >= fileInfos.size()) {
735             OH_VideoEncoder_NotifyEndOfStream(venc_);
736             return LOOP_END;
737         }
738         return FILE_END;
739     }
740     return ret;
741 }
742 
ReadOneFrameByType(uint8_t * dst,OH_NativeBuffer_Format format)743 uint32_t VEncAPI11Sample::ReadOneFrameByType(uint8_t *dst, OH_NativeBuffer_Format format)
744 {
745     if (format == NATIVEBUFFER_PIXEL_FMT_RGBA_8888) {
746         return ReadOneFrameRGBA8888(dst);
747     } else if (format == NATIVEBUFFER_PIXEL_FMT_YCBCR_420_SP || format == NATIVEBUFFER_PIXEL_FMT_YCRCB_420_SP) {
748         return ReadOneFrameYUV420SP(dst);
749     } else if (format == NATIVEBUFFER_PIXEL_FMT_YCBCR_P010) {
750         return ReadOneFrameYUVP010(dst);
751     } else {
752         cout << "error fileType" << endl;
753         return 0;
754     }
755 }
756 
OpenFileFail()757 int32_t VEncAPI11Sample::OpenFileFail()
758 {
759     cout << "file open fail" << endl;
760     isRunning_.store(false);
761     (void)OH_VideoEncoder_Stop(venc_);
762     inFile_->close();
763     inFile_.reset();
764     inFile_ = nullptr;
765     return AV_ERR_UNKNOWN;
766 }
767 
Flush_buffer()768 void VEncAPI11Sample::Flush_buffer()
769 {
770     unique_lock<mutex> inLock(signal_->inMutex_);
771     clearIntqueue(signal_->inIdxQueue_);
772     std::queue<OH_AVBuffer *> empty;
773     swap(empty, signal_->inBufferQueue_);
774     signal_->inCond_.notify_all();
775     inLock.unlock();
776     unique_lock<mutex> outLock(signal_->outMutex_);
777     clearIntqueue(signal_->outIdxQueue_);
778     signal_->outCond_.notify_all();
779     outLock.unlock();
780 }
781 
RepeatStartBeforeEOS()782 void VEncAPI11Sample::RepeatStartBeforeEOS()
783 {
784     if (REPEAT_START_FLUSH_BEFORE_EOS > 0) {
785         REPEAT_START_FLUSH_BEFORE_EOS--;
786         OH_VideoEncoder_Flush(venc_);
787         Flush_buffer();
788         OH_VideoEncoder_Start(venc_);
789     }
790 
791     if (REPEAT_START_STOP_BEFORE_EOS > 0) {
792         REPEAT_START_STOP_BEFORE_EOS--;
793         OH_VideoEncoder_Stop(venc_);
794         Flush_buffer();
795         OH_VideoEncoder_Start(venc_);
796     }
797 }
798 
RandomEOS(uint32_t index)799 bool VEncAPI11Sample::RandomEOS(uint32_t index)
800 {
801     uint32_t random_eos = rand() % 25;
802     if (enable_random_eos && random_eos == frameCount) {
803         OH_VideoEncoder_NotifyEndOfStream(venc_);
804         cout << "random eos" << endl;
805         frameCount++;
806         unique_lock<mutex> lock(signal_->inMutex_);
807         signal_->inIdxQueue_.pop();
808         signal_->inBufferQueue_.pop();
809         return true;
810     }
811     return false;
812 }
813 
AutoSwitchParam()814 void VEncAPI11Sample::AutoSwitchParam()
815 {
816     int64_t currentBitrate = DEFAULT_BITRATE;
817     double currentFrameRate = DEFAULT_FRAME_RATE;
818     int32_t currentQP = DEFAULT_QP;
819     if (frameCount == switchParamsTimeSec * (int32_t)DEFAULT_FRAME_RATE) {
820         OH_AVFormat *format = OH_AVFormat_Create();
821         if (needResetBitrate) {
822             currentBitrate = DEFAULT_BITRATE >> 1;
823             (void)OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, currentBitrate);
824         }
825         if (needResetFrameRate) {
826             currentFrameRate = DEFAULT_FRAME_RATE * DOUBLE;
827             (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, currentFrameRate);
828         }
829         if (needResetQP) {
830             currentQP = DEFAULT_QP;
831             (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MAX, currentQP);
832             (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MIN, currentQP);
833         }
834         SetParameter(format) == AV_ERR_OK ? (0) : (errCount++);
835         OH_AVFormat_Destroy(format);
836     }
837     if (frameCount == switchParamsTimeSec * (int32_t)DEFAULT_FRAME_RATE * DOUBLE) {
838         OH_AVFormat *format = OH_AVFormat_Create();
839         if (needResetBitrate) {
840             currentBitrate = DEFAULT_BITRATE << 1;
841             cout<<"switch bitrate "<< currentBitrate;
842             (void)OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, currentBitrate);
843         }
844         if (needResetFrameRate) {
845             currentFrameRate = DEFAULT_FRAME_RATE / DOUBLE;
846             cout<< "switch framerate" << currentFrameRate << endl;
847             (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, currentFrameRate);
848         }
849         if (needResetQP) {
850             currentQP = DEFAULT_QP * DOUBLE;
851             (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MAX, currentQP);
852             (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MIN, currentQP);
853         }
854         SetParameter(format) == AV_ERR_OK ? (0) : (errCount++);
855         OH_AVFormat_Destroy(format);
856     }
857 }
858 
SetEOS(uint32_t index,OH_AVBuffer * buffer)859 void VEncAPI11Sample::SetEOS(uint32_t index, OH_AVBuffer *buffer)
860 {
861     OH_AVCodecBufferAttr attr;
862     attr.pts = 0;
863     attr.size = 0;
864     attr.offset = 0;
865     attr.flags = AVCODEC_BUFFER_FLAGS_EOS;
866     OH_AVBuffer_SetBufferAttr(buffer, &attr);
867     int32_t res = OH_VideoEncoder_PushInputBuffer(venc_, index);
868     cout << "OH_VideoEncoder_PushInputBuffer    EOS   res: " << res << endl;
869     unique_lock<mutex> lock(signal_->inMutex_);
870     signal_->inIdxQueue_.pop();
871     signal_->inBufferQueue_.pop();
872 }
873 
SetForceIDR()874 void VEncAPI11Sample::SetForceIDR()
875 {
876     OH_AVFormat *format = OH_AVFormat_Create();
877     OH_AVFormat_SetIntValue(format, OH_MD_KEY_REQUEST_I_FRAME, 1);
878     OH_VideoEncoder_SetParameter(venc_, format);
879     OH_AVFormat_Destroy(format);
880 }
881 
SetLTRParameter(OH_AVBuffer * buffer)882 void VEncAPI11Sample::SetLTRParameter(OH_AVBuffer *buffer)
883 {
884     if (!ltrParam.enableUseLtr) {
885         return;
886     }
887     OH_AVFormat *format = OH_AVFormat_Create();
888     if (frameCount % ltrParam.ltrInterval == 0) {
889         OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_MARK_LTR, 1);
890     }
891     if (!ltrParam.enableUseLtr) {
892         OH_AVBuffer_SetParameter(buffer, format) == AV_ERR_OK ? (0) : (errCount++);
893         OH_AVFormat_Destroy(format);
894         return;
895     }
896     static int32_t useLtrIndex = 0;
897     if (ltrParam.useLtrIndex == 0) {
898         useLtrIndex = LTR_INTERVAL;
899     } else if (ltrParam.useBadLtr) {
900         useLtrIndex = BADPOC;
901     } else {
902         uint32_t interval = ltrParam.ltrInterval;
903         if (interval > 0 && frameCount > 0 && (frameCount % interval == 0)) {
904             useLtrIndex = frameCount / interval * interval;
905         }
906     }
907     if (frameCount > useLtrIndex) {
908         if (!ltrParam.useLtrOnce) {
909             OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, useLtrIndex);
910         } else {
911             OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, useLtrIndex);
912             ltrParam.useLtrOnce = true;
913         }
914     } else if (frameCount == useLtrIndex && frameCount > 0) {
915         OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, useLtrIndex - ltrParam.ltrInterval);
916     }
917     OH_AVBuffer_SetParameter(buffer, format) == AV_ERR_OK ? (0) : (errCount++);
918     OH_AVFormat_Destroy(format);
919 }
920 
SetBufferParameter(OH_AVBuffer * buffer)921 void VEncAPI11Sample::SetBufferParameter(OH_AVBuffer *buffer)
922 {
923     int32_t currentQP = DEFAULT_QP;
924     if (!enableAutoSwitchBufferParam) {
925         return;
926     }
927     if (frameCount == switchParamsTimeSec * (int32_t)DEFAULT_FRAME_RATE) {
928         OH_AVFormat *format = OH_AVFormat_Create();
929         if (needResetQP) {
930             currentQP = DEFAULT_QP;
931             (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MAX, currentQP);
932             (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MIN, currentQP);
933         }
934         OH_AVBuffer_SetParameter(buffer, format) == AV_ERR_OK ? (0) : (errCount++);
935         OH_AVFormat_Destroy(format);
936     }
937     if (frameCount == switchParamsTimeSec * (int32_t)DEFAULT_FRAME_RATE * DOUBLE) {
938         OH_AVFormat *format = OH_AVFormat_Create();
939         if (needResetQP) {
940             currentQP = DEFAULT_QP * DOUBLE;
941             (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MAX, currentQP);
942             (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_QP_MIN, currentQP);
943         }
944         OH_AVBuffer_SetParameter(buffer, format) == AV_ERR_OK ? (0) : (errCount++);
945         OH_AVFormat_Destroy(format);
946     }
947 }
948 
PushData(OH_AVBuffer * buffer,uint32_t index,int32_t & result)949 int32_t VEncAPI11Sample::PushData(OH_AVBuffer *buffer, uint32_t index, int32_t &result)
950 {
951     int32_t res = -2;
952     OH_AVCodecBufferAttr attr;
953     uint8_t *fileBuffer = OH_AVBuffer_GetAddr(buffer);
954     if (fileBuffer == nullptr) {
955         cout << "Fatal: no memory" << endl;
956         return -1;
957     }
958     int32_t size = OH_AVBuffer_GetCapacity(buffer);
959     if (DEFAULT_PIX_FMT == AV_PIXEL_FORMAT_RGBA) {
960         if (size < DEFAULT_HEIGHT * stride_) {
961             return -1;
962         }
963         attr.size = ReadOneFrameRGBA8888(fileBuffer);
964     } else {
965         if (size < (DEFAULT_HEIGHT * stride_ + (DEFAULT_HEIGHT * stride_ / DOUBLE))) {
966             return -1;
967         }
968         attr.size = ReadOneFrameYUV420SP(fileBuffer);
969     }
970     if (repeatRun && inFile_->eof()) {
971         inFile_->clear();
972         inFile_->seekg(0, ios::beg);
973         encode_count++;
974         cout << "repeat"<< "   encode_count:" << encode_count << endl;
975         return -1;
976     }
977     if (inFile_->eof()) {
978         SetEOS(index, buffer);
979         return 0;
980     }
981     attr.pts = GetSystemTimeUs();
982     attr.offset = 0;
983     attr.flags = AVCODEC_BUFFER_FLAGS_NONE;
984     if (enableForceIDR && (frameCount % IDR_FRAME_INTERVAL == 0)) {
985         SetForceIDR();
986     }
987     OH_AVBuffer_SetBufferAttr(buffer, &attr);
988     SetBufferParameter(buffer);
989     SetLTRParameter(buffer);
990     result = OH_VideoEncoder_PushInputBuffer(venc_, index);
991     frameCount++;
992     unique_lock<mutex> lock(signal_->inMutex_);
993     signal_->inIdxQueue_.pop();
994     signal_->inBufferQueue_.pop();
995     return res;
996 }
997 
CheckResult(bool isRandomEosSuccess,int32_t pushResult)998 int32_t VEncAPI11Sample::CheckResult(bool isRandomEosSuccess, int32_t pushResult)
999 {
1000     if (isRandomEosSuccess) {
1001         if (pushResult == 0) {
1002             errCount = errCount + 1;
1003             cout << "push input after eos should be failed!  pushResult:" << pushResult << endl;
1004         }
1005         return -1;
1006     } else if (pushResult != 0) {
1007         errCount = errCount + 1;
1008         cout << "push input data failed, error:" << pushResult << endl;
1009         return -1;
1010     }
1011     return 0;
1012 }
1013 
InputFunc()1014 void VEncAPI11Sample::InputFunc()
1015 {
1016     errCount = 0;
1017     while (true) {
1018         if (!isRunning_.load()) {
1019             break;
1020         }
1021         RepeatStartBeforeEOS();
1022         unique_lock<mutex> lock(signal_->inMutex_);
1023         signal_->inCond_.wait(lock, [this]() {
1024             if (!isRunning_.load()) {
1025                 return true;
1026             }
1027             return signal_->inIdxQueue_.size() > 0;
1028         });
1029         if (!isRunning_.load()) {
1030             break;
1031         }
1032         uint32_t index = signal_->inIdxQueue_.front();
1033         auto buffer = signal_->inBufferQueue_.front();
1034         lock.unlock();
1035         if (!inFile_->eof()) {
1036             bool isRandomEosSuccess = RandomEOS(index);
1037             if (isRandomEosSuccess) {
1038                 continue;
1039             }
1040             int32_t pushResult = 0;
1041             int32_t ret = PushData(buffer, index, pushResult);
1042             if (ret == 0) {
1043                 break;
1044             } else if (ret == -1) {
1045                 continue;
1046             }
1047             if (CheckResult(isRandomEosSuccess, pushResult) == -1) {
1048                 break;
1049             }
1050             if (enableAutoSwitchParam) {
1051                 AutoSwitchParam();
1052             }
1053         }
1054         if (sleepOnFPS) {
1055             usleep(FRAME_INTERVAL);
1056         }
1057     }
1058 }
1059 
CheckAttrFlag(OH_AVCodecBufferAttr attr)1060 int32_t VEncAPI11Sample::CheckAttrFlag(OH_AVCodecBufferAttr attr)
1061 {
1062     if (attr.flags & AVCODEC_BUFFER_FLAGS_EOS) {
1063         cout << "attr.flags == AVCODEC_BUFFER_FLAGS_EOS" << endl;
1064         unique_lock<mutex> inLock(signal_->inMutex_);
1065         isRunning_.store(false);
1066         signal_->inCond_.notify_all();
1067         signal_->outCond_.notify_all();
1068         inLock.unlock();
1069         return -1;
1070     }
1071     if (attr.flags == AVCODEC_BUFFER_FLAGS_CODEC_DATA) {
1072         cout << "enc AVCODEC_BUFFER_FLAGS_CODEC_DATA" << attr.pts << endl;
1073         return 0;
1074     }
1075     outCount = outCount + 1;
1076     return 0;
1077 }
1078 
OutputFuncFail()1079 void VEncAPI11Sample::OutputFuncFail()
1080 {
1081     cout << "errCount > 0" << endl;
1082     unique_lock<mutex> inLock(signal_->inMutex_);
1083     isRunning_.store(false);
1084     signal_->inCond_.notify_all();
1085     signal_->outCond_.notify_all();
1086     inLock.unlock();
1087     (void)Stop();
1088     Release();
1089 }
1090 
OutputFunc()1091 void VEncAPI11Sample::OutputFunc()
1092 {
1093     FILE *outFile = fopen(OUT_DIR, "wb");
1094     while (true) {
1095         if (!isRunning_.load()) {
1096             break;
1097         }
1098         OH_AVCodecBufferAttr attr;
1099         unique_lock<mutex> lock(signal_->outMutex_);
1100         signal_->outCond_.wait(lock, [this]() {
1101             if (!isRunning_.load()) {
1102                 return true;
1103             }
1104             return signal_->outIdxQueue_.size() > 0;
1105         });
1106         if (!isRunning_.load()) {
1107             break;
1108         }
1109         uint32_t index = signal_->outIdxQueue_.front();
1110         OH_AVBuffer *buffer = signal_->outBufferQueue_.front();
1111         signal_->outBufferQueue_.pop();
1112         signal_->outIdxQueue_.pop();
1113         lock.unlock();
1114         DumpInfo(attr, buffer);
1115         if (OH_AVBuffer_GetBufferAttr(buffer, &attr) != AV_ERR_OK) {
1116             errCount = errCount + 1;
1117         }
1118         if (CheckAttrFlag(attr) == -1) {
1119             break;
1120         }
1121         int size = attr.size;
1122         if (outFile == nullptr) {
1123             cout << "dump data fail" << endl;
1124         } else {
1125             fwrite(OH_AVBuffer_GetAddr(buffer), 1, size, outFile);
1126         }
1127         if (OH_VideoEncoder_FreeOutputBuffer(venc_, index) != AV_ERR_OK) {
1128             cout << "Fatal: ReleaseOutputBuffer fail" << endl;
1129             errCount = errCount + 1;
1130         }
1131         if (errCount > 0) {
1132             OutputFuncFail();
1133             break;
1134         }
1135     }
1136     if (outFile) {
1137         (void)fclose(outFile);
1138     }
1139 }
1140 
Flush()1141 int32_t VEncAPI11Sample::Flush()
1142 {
1143     unique_lock<mutex> inLock(signal_->inMutex_);
1144     clearIntqueue(signal_->inIdxQueue_);
1145     signal_->inCond_.notify_all();
1146     inLock.unlock();
1147     unique_lock<mutex> outLock(signal_->outMutex_);
1148     clearIntqueue(signal_->outIdxQueue_);
1149     signal_->outCond_.notify_all();
1150     outLock.unlock();
1151     return OH_VideoEncoder_Flush(venc_);
1152 }
1153 
Reset()1154 int32_t VEncAPI11Sample::Reset()
1155 {
1156     isRunning_.store(false);
1157     StopInloop();
1158     StopOutloop();
1159     ReleaseInFile();
1160     return OH_VideoEncoder_Reset(venc_);
1161 }
1162 
Release()1163 int32_t VEncAPI11Sample::Release()
1164 {
1165     int ret = OH_VideoEncoder_Destroy(venc_);
1166     venc_ = nullptr;
1167     if (signal_ != nullptr) {
1168         delete signal_;
1169         signal_ = nullptr;
1170     }
1171     return ret;
1172 }
1173 
Stop()1174 int32_t VEncAPI11Sample::Stop()
1175 {
1176     StopInloop();
1177     clearIntqueue(signal_->outIdxQueue_);
1178     ReleaseInFile();
1179     return OH_VideoEncoder_Stop(venc_);
1180 }
1181 
Start()1182 int32_t VEncAPI11Sample::Start()
1183 {
1184     return OH_VideoEncoder_Start(venc_);
1185 }
1186 
StopOutloop()1187 void VEncAPI11Sample::StopOutloop()
1188 {
1189     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1190         unique_lock<mutex> lock(signal_->outMutex_);
1191         clearIntqueue(signal_->outIdxQueue_);
1192         signal_->outCond_.notify_all();
1193         lock.unlock();
1194     }
1195 }
1196 
SetParameter(OH_AVFormat * format)1197 int32_t VEncAPI11Sample::SetParameter(OH_AVFormat *format)
1198 {
1199     if (venc_) {
1200         return OH_VideoEncoder_SetParameter(venc_, format);
1201     }
1202     return AV_ERR_UNKNOWN;
1203 }