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