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 }