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