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