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