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