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