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 "native_buffer_inner.h"
19 #include "iconsumer_surface.h"
20 #include "videoenc_inner_sample.h"
21 #include "meta/meta_key.h"
22 #include <random>
23 #include "avcodec_list.h"
24 #include "native_avcodec_base.h"
25
26 using namespace OHOS;
27 using namespace OHOS::MediaAVCodec;
28 using namespace std;
29
30 namespace {
31 const string MIME_TYPE = "video/avc";
32 constexpr int64_t NANOS_IN_SECOND = 1000000000L;
33 constexpr int64_t NANOS_IN_MICRO = 1000L;
34 constexpr uint32_t FRAME_INTERVAL = 16666;
35 constexpr uint32_t MAX_PIXEL_FMT = 5;
36 constexpr uint32_t IDR_FRAME_INTERVAL = 10;
37 constexpr uint32_t MILLION = 1000000;
38 std::random_device rd;
39 constexpr uint8_t RGBA_SIZE = 4;
40 constexpr uint8_t THREE = 3;
41 constexpr uint8_t TWO = 3;
42 constexpr uint8_t FILE_END = -1;
43 constexpr uint8_t LOOP_END = 0;
44 constexpr uint32_t FIVE = 5;
45 VEncNdkInnerSample *enc_sample = nullptr;
46 int32_t g_picWidth;
47 int32_t g_picHeight;
48 int32_t g_keyWidth;
49 int32_t g_keyHeight;
50
clearIntqueue(std::queue<uint32_t> & q)51 void clearIntqueue(std::queue<uint32_t> &q)
52 {
53 std::queue<uint32_t> empty;
54 swap(empty, q);
55 }
56
clearBufferqueue(std::queue<AVCodecBufferInfo> & q)57 void clearBufferqueue(std::queue<AVCodecBufferInfo> &q)
58 {
59 std::queue<AVCodecBufferInfo> empty;
60 swap(empty, q);
61 }
62
clearFlagqueue(std::queue<AVCodecBufferFlag> & q)63 void clearFlagqueue(std::queue<AVCodecBufferFlag> &q)
64 {
65 std::queue<AVCodecBufferFlag> empty;
66 swap(empty, q);
67 }
68 } // namespace
69
VEncNdkInnerSample(std::shared_ptr<VEncInnerSignal> signal)70 VEncNdkInnerSample::VEncNdkInnerSample(std::shared_ptr<VEncInnerSignal> signal)
71 : signal_(signal)
72 {
73 }
74
VEncInnerCallback(std::shared_ptr<VEncInnerSignal> signal)75 VEncInnerCallback::VEncInnerCallback(std::shared_ptr<VEncInnerSignal> signal) : innersignal_(signal) {}
76
OnError(AVCodecErrorType errorType,int32_t errorCode)77 void VEncInnerCallback::OnError(AVCodecErrorType errorType, int32_t errorCode)
78 {
79 if (enc_sample == nullptr) {
80 return;
81 }
82 if (errorCode == AVCS_ERR_INPUT_DATA_ERROR) {
83 enc_sample->errCount += 1;
84 enc_sample->isRunning_.store(false);
85 enc_sample->signal_->inCond_.notify_all();
86 enc_sample->signal_->outCond_.notify_all();
87 }
88 cout << "Error errorType:" << errorType << " errorCode:" << errorCode << endl;
89 }
90
OnOutputFormatChanged(const Format & format)91 void VEncInnerCallback::OnOutputFormatChanged(const Format& format)
92 {
93 cout << "Format Changed" << endl;
94 format.GetIntValue(OH_MD_KEY_VIDEO_PIC_WIDTH, g_picWidth);
95 format.GetIntValue(OH_MD_KEY_VIDEO_PIC_HEIGHT, g_picHeight);
96 format.GetIntValue(OH_MD_KEY_WIDTH, g_keyWidth);
97 format.GetIntValue(OH_MD_KEY_HEIGHT, g_keyHeight);
98 cout << "format info: " << format.Stringify() << ", OH_MD_KEY_VIDEO_PIC_WIDTH: " << g_picWidth
99 << ", OH_MD_KEY_VIDEO_PIC_HEIGHT: "<< g_picHeight << ", OH_MD_KEY_WIDTH: " << g_keyWidth
100 << ", OH_MD_KEY_HEIGHT: " << g_keyHeight << endl;
101 }
102
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)103 void VEncInnerCallback::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
104 {
105 if (innersignal_ == nullptr) {
106 std::cout << "buffer is null 1" << endl;
107 return;
108 }
109 unique_lock<mutex> lock(innersignal_->inMutex_);
110 innersignal_->inIdxQueue_.push(index);
111 innersignal_->inBufferQueue_.push(buffer);
112 innersignal_->inCond_.notify_all();
113 }
114
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)115 void VEncInnerCallback::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info,
116 AVCodecBufferFlag flag, std::shared_ptr<AVSharedMemory> buffer)
117 {
118 unique_lock<mutex> lock(innersignal_->outMutex_);
119 innersignal_->outIdxQueue_.push(index);
120 innersignal_->infoQueue_.push(info);
121 innersignal_->flagQueue_.push(flag);
122 innersignal_->outBufferQueue_.push(buffer);
123 innersignal_->outCond_.notify_all();
124 }
125
VEncParamWithAttrCallbackTest(std::shared_ptr<VEncInnerSignal> signal)126 VEncParamWithAttrCallbackTest::VEncParamWithAttrCallbackTest(
127 std::shared_ptr<VEncInnerSignal> signal) : signal_(signal) {}
128
~VEncParamWithAttrCallbackTest()129 VEncParamWithAttrCallbackTest::~VEncParamWithAttrCallbackTest()
130 {
131 signal_ = nullptr;
132 }
133
OnInputParameterWithAttrAvailable(uint32_t index,std::shared_ptr<Format> attribute,std::shared_ptr<Format> parameter)134 void VEncParamWithAttrCallbackTest::OnInputParameterWithAttrAvailable(uint32_t index,
135 std::shared_ptr<Format> attribute,
136 std::shared_ptr<Format> parameter)
137 {
138 if (signal_ == nullptr) {
139 return;
140 }
141 unique_lock<mutex> lock(signal_->inMutex_);
142 cout << "OnInputParameterWithAttrAvailable" <<endl;
143 signal_->inIdxQueue_.push(index);
144 signal_->inAttrQueue_.push(attribute);
145 signal_->inFormatQueue_.push(parameter);
146 signal_->inCond_.notify_all();
147 }
148
~VEncNdkInnerSample()149 VEncNdkInnerSample::~VEncNdkInnerSample()
150 {
151 Release();
152 }
153
GetSystemTimeUs()154 int64_t VEncNdkInnerSample::GetSystemTimeUs()
155 {
156 struct timespec now;
157 (void)clock_gettime(CLOCK_BOOTTIME, &now);
158 int64_t nanoTime = (int64_t)now.tv_sec * NANOS_IN_SECOND + now.tv_nsec;
159
160 return nanoTime / NANOS_IN_MICRO;
161 }
162
CreateByMime(const std::string & mime)163 int32_t VEncNdkInnerSample::CreateByMime(const std::string &mime)
164 {
165 venc_ = VideoEncoderFactory::CreateByMime(mime);
166 enc_sample = this;
167 return venc_ == nullptr ? AVCS_ERR_INVALID_OPERATION : AVCS_ERR_OK;
168 }
169
CreateByName(const std::string & name)170 int32_t VEncNdkInnerSample::CreateByName(const std::string &name)
171 {
172 venc_ = VideoEncoderFactory::CreateByName(name);
173 enc_sample = this;
174 return venc_ == nullptr ? AVCS_ERR_INVALID_OPERATION : AVCS_ERR_OK;
175 }
176
ConfigureVideoEncoderSqr()177 int32_t VEncNdkInnerSample::ConfigureVideoEncoderSqr()
178 {
179 Format format;
180 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
181 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
182 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, DEFAULT_PIX_FMT);
183 if (MODE_ENABLE) {
184 format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE, DEFAULT_BITRATE_MODE);
185 }
186 if (SETBIRATE) {
187 format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, DEFAULT_BITRATE);
188 }
189 if (QUALITY_ENABLE) {
190 format.PutIntValue(MediaDescriptionKey::MD_KEY_QUALITY, DEFAULT_QUALITY);
191 }
192 if (B_ENABLE) {
193 format.PutIntValue(Media::Tag::VIDEO_ENCODER_ENABLE_B_FRAME, DEFAULT_BFRAME);
194 }
195 if (GOPMODE_ENABLE) {
196 format.PutIntValue(Media::Tag::VIDEO_ENCODE_B_FRAME_GOP_MODE, DEFAULT_GOP_MODE);
197 }
198 if (MAXBITE_ENABLE) {
199 format.PutLongValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODER_MAX_BITRATE, DEFAULT_MAX_BITERATE);
200 }
201 if (FACTOR_ENABLE) {
202 format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODER_SQR_FACTOR, DEFAULT_SQR_FACTOR);
203 }
204 if (MAXBFRAMES_ENABLE) {
205 format.PutIntValue(Media::Tag::VIDEO_ENCODER_MAX_B_FRAME, DEFAULT_MAX_B_FRAMES);
206 }
207 return venc_->Configure(format);
208 }
209
Configure()210 int32_t VEncNdkInnerSample::Configure()
211 {
212 Format format;
213 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_WIDTH);
214 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_HEIGHT);
215 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, DEFAULT_PIX_FMT);
216 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
217 format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, DEFAULT_BITRATE);
218 if (configMain10) {
219 format.PutIntValue(OH_MD_KEY_PROFILE, HEVC_PROFILE_MAIN_10);
220 } else if (configMain) {
221 format.PutIntValue(OH_MD_KEY_PROFILE, HEVC_PROFILE_MAIN);
222 }
223 format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE, DEFAULT_BITRATE_MODE);
224 if (enableRepeat) {
225 format.PutIntValue(Media::Tag::VIDEO_ENCODER_REPEAT_PREVIOUS_FRAME_AFTER, DEFAULT_FRAME_AFTER);
226 if (setMaxCount) {
227 format.PutIntValue(Media::Tag::VIDEO_ENCODER_REPEAT_PREVIOUS_MAX_COUNT, DEFAULT_MAX_COUNT);
228 }
229 }
230 if (isDiscardFrame) {
231 format.PutIntValue(Media::Tag::VIDEO_I_FRAME_INTERVAL, DEFAULT_KEY_I_FRAME_INTERVAL);
232 }
233 format.PutIntValue(Media::Tag::AV_CODEC_ENABLE_SYNC_MODE, enbleSyncMode);
234 if (enbleBFrameMode) {
235 format.PutIntValue(Media::Tag::VIDEO_ENCODER_ENABLE_B_FRAME, enbleBFrameMode);
236 format.PutIntValue(Media::Tag::VIDEO_ENCODE_B_FRAME_GOP_MODE,
237 static_cast<int32_t>(Media::Plugins::VideoEncodeBFrameGopMode::VIDEO_ENCODE_GOP_H3B_MODE));
238 }
239 return venc_->Configure(format);
240 }
241
ConfigureFuzz(int32_t data)242 int32_t VEncNdkInnerSample::ConfigureFuzz(int32_t data)
243 {
244 Format format;
245 double frameRate = data;
246 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, data);
247 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, data);
248 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, data % MAX_PIXEL_FMT);
249 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, frameRate);
250 format.PutIntValue(MediaDescriptionKey::MD_KEY_RANGE_FLAG, data);
251 format.PutIntValue(MediaDescriptionKey::MD_KEY_COLOR_PRIMARIES, data);
252 format.PutIntValue(MediaDescriptionKey::MD_KEY_TRANSFER_CHARACTERISTICS, data);
253 format.PutIntValue(MediaDescriptionKey::MD_KEY_MATRIX_COEFFICIENTS, data);
254 format.PutIntValue(MediaDescriptionKey::MD_KEY_I_FRAME_INTERVAL, data);
255 format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE, data);
256 format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, data);
257 format.PutIntValue(MediaDescriptionKey::MD_KEY_QUALITY, data);
258
259 return venc_->Configure(format);
260 }
261
Prepare()262 int32_t VEncNdkInnerSample::Prepare()
263 {
264 return venc_->Prepare();
265 }
266
Start()267 int32_t VEncNdkInnerSample::Start()
268 {
269 return venc_->Start();
270 }
271
Stop()272 int32_t VEncNdkInnerSample::Stop()
273 {
274 StopInloop();
275 clearIntqueue(signal_->outIdxQueue_);
276 clearBufferqueue(signal_->infoQueue_);
277 clearFlagqueue(signal_->flagQueue_);
278 ReleaseInFile();
279
280 return venc_->Stop();
281 }
282
Flush()283 int32_t VEncNdkInnerSample::Flush()
284 {
285 unique_lock<mutex> inLock(signal_->inMutex_);
286 clearIntqueue(signal_->inIdxQueue_);
287 signal_->inCond_.notify_all();
288 inLock.unlock();
289 unique_lock<mutex> outLock(signal_->outMutex_);
290 clearIntqueue(signal_->outIdxQueue_);
291 clearBufferqueue(signal_->infoQueue_);
292 clearFlagqueue(signal_->flagQueue_);
293 signal_->outCond_.notify_all();
294 outLock.unlock();
295
296 return venc_->Flush();
297 }
298
NotifyEos()299 int32_t VEncNdkInnerSample::NotifyEos()
300 {
301 return venc_->NotifyEos();
302 }
303
Reset()304 int32_t VEncNdkInnerSample::Reset()
305 {
306 isRunning_.store(false);
307 StopInloop();
308 StopOutloop();
309 ReleaseInFile();
310
311 if (venc_ == nullptr) {
312 std::cout << "InnerEncoder create failed!" << std::endl;
313 return AVCS_ERR_INVALID_OPERATION;
314 }
315 return venc_->Reset();
316 }
317
Release()318 int32_t VEncNdkInnerSample::Release()
319 {
320 int32_t ret = 0;
321 if (venc_) {
322 ret = venc_->Release();
323 venc_ = nullptr;
324 }
325 if (signal_ != nullptr) {
326 signal_ = nullptr;
327 }
328 return ret;
329 }
330
CreateInputSurface()331 int32_t VEncNdkInnerSample::CreateInputSurface()
332 {
333 int32_t ret = 0;
334 sptr<Surface> surface = venc_->CreateInputSurface();
335 if (surface == nullptr) {
336 cout << "CreateInputSurface fail" << endl;
337 return AVCS_ERR_INVALID_OPERATION;
338 }
339
340 nativeWindow = CreateNativeWindowFromSurface(&surface);
341 if (nativeWindow == nullptr) {
342 cout << "CreateNativeWindowFromSurface failed!" << endl;
343 return AVCS_ERR_INVALID_VAL;
344 }
345 if (DEFAULT_PIX_FMT == static_cast<int32_t>(VideoPixelFormat::RGBA1010102)) {
346 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, NATIVEBUFFER_PIXEL_FMT_RGBA_1010102);
347 } else {
348 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_420_SP);
349 }
350
351 if (ret != AVCS_ERR_OK) {
352 cout << "NativeWindowHandleOpt SET_FORMAT fail" << endl;
353 return ret;
354 }
355
356 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_BUFFER_GEOMETRY, DEFAULT_WIDTH, DEFAULT_HEIGHT);
357 if (ret != AVCS_ERR_OK) {
358 cout << "NativeWindowHandleOpt SET_BUFFER_GEOMETRY fail" << endl;
359 return ret;
360 }
361 return AVCS_ERR_OK;
362 }
363
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)364 int32_t VEncNdkInnerSample::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
365 {
366 return venc_->QueueInputBuffer(index, info, flag);
367 }
368
GetOutputFormat(Format & format)369 int32_t VEncNdkInnerSample::GetOutputFormat(Format &format)
370 {
371 return venc_->GetOutputFormat(format);
372 }
373
ReleaseOutputBuffer(uint32_t index)374 int32_t VEncNdkInnerSample::ReleaseOutputBuffer(uint32_t index)
375 {
376 return venc_->ReleaseOutputBuffer(index);
377 }
378
SetParameter(const Format & format)379 int32_t VEncNdkInnerSample::SetParameter(const Format &format)
380 {
381 return venc_->SetParameter(format);
382 }
383
SetCallback()384 int32_t VEncNdkInnerSample::SetCallback()
385 {
386 if (signal_ == nullptr) {
387 signal_ = make_shared<VEncInnerSignal>();
388 }
389 if (signal_ == nullptr) {
390 cout << "Failed to new VEncInnerSignal" << endl;
391 return AVCS_ERR_UNKNOWN;
392 }
393
394 cb_ = make_shared<VEncInnerCallback>(signal_);
395 return venc_->SetCallback(cb_);
396 }
397
SetCallback(std::shared_ptr<MediaCodecParameterWithAttrCallback> cb)398 int32_t VEncNdkInnerSample::SetCallback(std::shared_ptr<MediaCodecParameterWithAttrCallback> cb)
399 {
400 if (venc_ == nullptr) {
401 return AV_ERR_UNKNOWN;
402 }
403 int32_t ret = venc_->SetCallback(cb);
404 isSetParamCallback_ = ret == AV_ERR_OK;
405 return ret;
406 }
407
408
GetInputFormat(Format & format)409 int32_t VEncNdkInnerSample::GetInputFormat(Format &format)
410 {
411 return venc_->GetInputFormat(format);
412 }
413
StartVideoEncoder()414 int32_t VEncNdkInnerSample::StartVideoEncoder()
415 {
416 isRunning_.store(true);
417 int32_t ret = 0;
418 if (surfaceInput) {
419 ret = CreateInputSurface();
420 if (ret != AVCS_ERR_OK) {
421 return ret;
422 }
423 }
424 ret = venc_->Start();
425 if (ret != AVCS_ERR_OK) {
426 isRunning_.store(false);
427 signal_->inCond_.notify_all();
428 signal_->outCond_.notify_all();
429 return ret;
430 }
431
432 inFile_ = make_unique<ifstream>();
433 if (inFile_ == nullptr) {
434 isRunning_.store(false);
435 venc_->Stop();
436 return AVCS_ERR_UNKNOWN;
437 }
438 readMultiFilesFunc();
439 if (VideoEncoder() != AVCS_ERR_OK) {
440 return AVCS_ERR_UNKNOWN;
441 }
442 return AVCS_ERR_OK;
443 }
444
VideoEncoder()445 int32_t VEncNdkInnerSample::VideoEncoder()
446 {
447 if (surfaceInput) {
448 inputLoop_ = make_unique<thread>(&VEncNdkInnerSample::InputFuncSurface, this);
449 inputParamLoop_ = isSetParamCallback_ ? make_unique<thread>(&VEncNdkInnerSample::InputParamLoopFunc,
450 this):nullptr;
451 } else {
452 if (enbleSyncMode == 0) {
453 inputLoop_ = make_unique<thread>(&VEncNdkInnerSample::InputFunc, this);
454 } else {
455 inputLoop_ = make_unique<thread>(&VEncNdkInnerSample::SyncInputFunc, this);
456 }
457 }
458 if (inputLoop_ == nullptr) {
459 isRunning_.store(false);
460 venc_->Stop();
461 ReleaseInFile();
462 return AVCS_ERR_UNKNOWN;
463 }
464 if (enbleSyncMode == 0) {
465 outputLoop_ = make_unique<thread>(&VEncNdkInnerSample::OutputFunc, this);
466 } else {
467 outputLoop_ = make_unique<thread>(&VEncNdkInnerSample::SyncOutputFunc, this);
468 }
469 if (outputLoop_ == nullptr) {
470 isRunning_.store(false);
471 venc_->Stop();
472 ReleaseInFile();
473 StopInloop();
474 Release();
475 return AVCS_ERR_UNKNOWN;
476 }
477 return AVCS_ERR_OK;
478 }
479
readMultiFilesFunc()480 void VEncNdkInnerSample::readMultiFilesFunc()
481 {
482 if (!readMultiFiles) {
483 inFile_->open(INP_DIR, ios::in | ios::binary);
484 if (!inFile_->is_open()) {
485 OpenFileFail();
486 }
487 }
488 }
489
testApi()490 int32_t VEncNdkInnerSample::testApi()
491 {
492 if (venc_ == nullptr) {
493 std::cout << "InnerEncoder create failed!" << std::endl;
494 return AVCS_ERR_INVALID_OPERATION;
495 }
496
497 Format format;
498 format.PutIntValue(MediaDescriptionKey::MD_KEY_REQUEST_I_FRAME, 1);
499 venc_->CreateInputSurface();
500 venc_->Prepare();
501 venc_->GetInputFormat(format);
502 venc_->Start();
503 venc_->SetParameter(format);
504 venc_->NotifyEos();
505 venc_->GetOutputFormat(format);
506 venc_->Flush();
507 venc_->Stop();
508 venc_->Reset();
509
510 return AVCS_ERR_OK;
511 }
512
PushData(std::shared_ptr<AVSharedMemory> buffer,uint32_t index,int32_t & result)513 int32_t VEncNdkInnerSample::PushData(std::shared_ptr<AVSharedMemory> buffer, uint32_t index, int32_t &result)
514 {
515 int32_t res = -2;
516 uint32_t yuvSize = 0;
517 if (DEFAULT_PIX_FMT == static_cast<int32_t>(VideoPixelFormat::RGBA1010102) ||
518 DEFAULT_PIX_FMT == static_cast<int32_t>(VideoPixelFormat::RGBA)) {
519 yuvSize = DEFAULT_WIDTH * DEFAULT_HEIGHT * RGBA_SIZE;
520 } else {
521 yuvSize = DEFAULT_WIDTH * DEFAULT_HEIGHT * THREE / TWO;
522 }
523 uint8_t *fileBuffer = buffer->GetBase();
524 if (fileBuffer == nullptr) {
525 cout << "Fatal: no memory" << endl;
526 return -1;
527 }
528 (void)inFile_->read((char *)fileBuffer, yuvSize);
529
530 if (repeatRun && inFile_->eof()) {
531 inFile_->clear();
532 inFile_->seekg(0, ios::beg);
533 encodeCount++;
534 cout << "repeat" << " encodeCount:" << encodeCount << endl;
535 return -1;
536 }
537
538 if (inFile_->eof()) {
539 SetEOS(index);
540 return 0;
541 }
542
543 AVCodecBufferInfo info;
544 info.presentationTimeUs = GetSystemTimeUs();
545 info.size = yuvSize;
546 info.offset = 0;
547 AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_NONE;
548
549 int32_t size = buffer->GetSize();
550 if (size < (int32_t)yuvSize) {
551 cout << "bufferSize smaller than yuv size" << endl;
552 return -1;
553 }
554
555 if (enableForceIDR && (frameCount % IDR_FRAME_INTERVAL == 0)) {
556 Format format;
557 format.PutIntValue(MediaDescriptionKey::MD_KEY_REQUEST_I_FRAME, 1);
558 venc_->SetParameter(format);
559 }
560 result = venc_->QueueInputBuffer(index, info, flag);
561 if (enbleSyncMode == 0) {
562 unique_lock<mutex> lock(signal_->inMutex_);
563 signal_->inIdxQueue_.pop();
564 signal_->inBufferQueue_.pop();
565 }
566
567 return res;
568 }
569
SyncPushData(std::shared_ptr<AVBuffer> buffer,uint32_t index,int32_t & result)570 int32_t VEncNdkInnerSample::SyncPushData(std::shared_ptr<AVBuffer> buffer, uint32_t index, int32_t &result)
571 {
572 int32_t res = -2;
573 uint32_t yuvSize = DEFAULT_WIDTH * DEFAULT_HEIGHT * 3 / 2;
574 uint8_t *fileBuffer = buffer->memory_->GetAddr();
575 if (fileBuffer == nullptr) {
576 cout << "Fatal: no memory" << endl;
577 return -1;
578 }
579 (void)inFile_->read((char *)fileBuffer, yuvSize);
580
581 if (repeatRun && inFile_->eof()) {
582 inFile_->clear();
583 inFile_->seekg(0, ios::beg);
584 encodeCount++;
585 cout << "repeat" << " encodeCount:" << encodeCount << endl;
586 return -1;
587 }
588
589 if (inFile_->eof()) {
590 SetEOS(index);
591 return 0;
592 }
593
594 AVCodecBufferInfo info;
595 info.presentationTimeUs = GetSystemTimeUs();
596 info.size = yuvSize;
597 info.offset = 0;
598 AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_NONE;
599
600 int32_t size = buffer->memory_->GetCapacity();
601 if (size < (int32_t)yuvSize) {
602 cout << "bufferSize smaller than yuv size" << endl;
603 return -1;
604 }
605
606 if (enableForceIDR && (frameCount % IDR_FRAME_INTERVAL == 0)) {
607 Format format;
608 format.PutIntValue(MediaDescriptionKey::MD_KEY_REQUEST_I_FRAME, 1);
609 venc_->SetParameter(format);
610 }
611 result = venc_->QueueInputBuffer(index, info, flag);
612 if (enbleSyncMode == 0) {
613 unique_lock<mutex> lock(signal_->inMutex_);
614 signal_->inIdxQueue_.pop();
615 signal_->inBufferQueue_.pop();
616 }
617
618 return res;
619 }
620
OpenFileFail()621 int32_t VEncNdkInnerSample::OpenFileFail()
622 {
623 cout << "file open fail" << endl;
624 isRunning_.store(false);
625 venc_->Stop();
626 inFile_->close();
627 inFile_.reset();
628 inFile_ = nullptr;
629 return AVCS_ERR_UNKNOWN;
630 }
631
CheckResult(bool isRandomEosSuccess,int32_t pushResult)632 int32_t VEncNdkInnerSample::CheckResult(bool isRandomEosSuccess, int32_t pushResult)
633 {
634 if (isRandomEosSuccess) {
635 if (pushResult == 0) {
636 errCount = errCount + 1;
637 cout << "push input after eos should be failed! pushResult:" << pushResult << endl;
638 }
639 return -1;
640 } else if (pushResult != 0) {
641 errCount = errCount + 1;
642 cout << "push input data failed, error:" << pushResult << endl;
643 return -1;
644 }
645 return 0;
646 }
647
CheckFlag(AVCodecBufferFlag flag)648 int32_t VEncNdkInnerSample::CheckFlag(AVCodecBufferFlag flag)
649 {
650 if (flag & AVCODEC_BUFFER_FLAG_EOS) {
651 cout << "flag == AVCODEC_BUFFER_FLAG_EOS" << endl;
652 if (enbleSyncMode == 0) {
653 unique_lock<mutex> inLock(signal_->inMutex_);
654 isRunning_.store(false);
655 signal_->inCond_.notify_all();
656 signal_->outCond_.notify_all();
657 inLock.unlock();
658 }
659 return -1;
660 }
661
662 if (flag == AVCODEC_BUFFER_FLAG_CODEC_DATA) {
663 cout << "enc AVCODEC_BUFFER_FLAG_CODEC_DATA" << endl;
664 } else {
665 outCount = outCount + 1;
666 }
667 return 0;
668 }
669
InputProcess(OH_NativeBuffer * nativeBuffer,OHNativeWindowBuffer * ohNativeWindowBuffer)670 int32_t VEncNdkInnerSample::InputProcess(OH_NativeBuffer *nativeBuffer, OHNativeWindowBuffer *ohNativeWindowBuffer)
671 {
672 int32_t ret = 0;
673 struct Region region;
674 struct Region::Rect *rect = new Region::Rect();
675 rect->x = 0;
676 rect->y = 0;
677 rect->w = DEFAULT_WIDTH;
678 rect->h = DEFAULT_HEIGHT;
679 region.rects = rect;
680 NativeWindowHandleOpt(nativeWindow, SET_UI_TIMESTAMP, GetSystemTimeUs());
681 ret = OH_NativeBuffer_Unmap(nativeBuffer);
682 if (ret != 0) {
683 cout << "OH_NativeBuffer_Unmap failed" << endl;
684 delete rect;
685 return ret;
686 }
687
688 ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, ohNativeWindowBuffer, -1, region);
689 delete rect;
690 if (ret != 0) {
691 cout << "FlushBuffer failed" << endl;
692 return ret;
693 }
694 return ret;
695 }
696
StateEOS()697 int32_t VEncNdkInnerSample::StateEOS()
698 {
699 unique_lock<mutex> lock(signal_->inMutex_);
700 signal_->inCond_.wait(lock, [this]() { return signal_->inIdxQueue_.size() > 0; });
701 uint32_t index = signal_->inIdxQueue_.front();
702 signal_->inIdxQueue_.pop();
703 signal_->inBufferQueue_.pop();
704 lock.unlock();
705
706 AVCodecBufferInfo info;
707 info.presentationTimeUs = 0;
708 info.size = 0;
709 info.offset = 0;
710 AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
711
712 return venc_->QueueInputBuffer(index, info, flag);
713 }
714
ReturnZeroIfEOS(uint32_t expectedSize)715 uint32_t VEncNdkInnerSample::ReturnZeroIfEOS(uint32_t expectedSize)
716 {
717 if (inFile_->gcount() != (int32_t)expectedSize) {
718 cout << "no more data" << endl;
719 return 0;
720 }
721 return 1;
722 }
723
ReadOneFrameYUV420SP(uint8_t * dst)724 uint32_t VEncNdkInnerSample::ReadOneFrameYUV420SP(uint8_t *dst)
725 {
726 uint8_t *start = dst;
727 // copy Y
728 for (uint32_t i = 0; i < DEFAULT_HEIGHT; i++) {
729 inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH);
730 if (!ReturnZeroIfEOS(DEFAULT_WIDTH))
731 return 0;
732 dst += stride_;
733 }
734 // copy UV
735 for (uint32_t i = 0; i < DEFAULT_HEIGHT / SAMPLE_RATIO; i++) {
736 inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH);
737 if (!ReturnZeroIfEOS(DEFAULT_WIDTH))
738 return 0;
739 dst += stride_;
740 }
741 return dst - start;
742 }
743
ReadOneFrameYUVP010(uint8_t * dst)744 uint32_t VEncNdkInnerSample::ReadOneFrameYUVP010(uint8_t *dst)
745 {
746 uint8_t *start = dst;
747 int32_t num = 2;
748 // copy Y
749 for (uint32_t i = 0; i < DEFAULT_HEIGHT; i++) {
750 inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH*num);
751 if (!ReturnZeroIfEOS(DEFAULT_WIDTH*num))
752 return 0;
753 dst += stride_;
754 }
755 // copy UV
756 for (uint32_t i = 0; i < DEFAULT_HEIGHT / SAMPLE_RATIO; i++) {
757 inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH*num);
758 if (!ReturnZeroIfEOS(DEFAULT_WIDTH*num))
759 return 0;
760 dst += stride_;
761 }
762 return dst - start;
763 }
764
ReadOneFrameFromList(uint8_t * dst,int32_t & index)765 uint32_t VEncNdkInnerSample::ReadOneFrameFromList(uint8_t *dst, int32_t &index)
766 {
767 int32_t ret = 0;
768 if (index >= fileInfos.size()) {
769 ret = venc_->NotifyEos();
770 if (ret != 0) {
771 cout << "OH_VideoEncoder_NotifyEndOfStream failed" << endl;
772 }
773 return LOOP_END;
774 }
775 if (!inFile_->is_open()) {
776 inFile_->open(fileInfos[index].fileDir);
777 if (!inFile_->is_open()) {
778 return OpenFileFail();
779 }
780 DEFAULT_WIDTH = fileInfos[index].width;
781 DEFAULT_HEIGHT = fileInfos[index].height;
782 if (setFormatRbgx) {
783 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_RGBX_8888);
784 } else if (setFormat8Bit) {
785 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_420_SP);
786 } else if (setFormat10Bit) {
787 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, GRAPHIC_PIXEL_FMT_YCBCR_P010);
788 } else {
789 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_FORMAT, fileInfos[index].format);
790 }
791 if (ret != AVCS_ERR_OK) {
792 return ret;
793 }
794 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_BUFFER_GEOMETRY, DEFAULT_WIDTH, DEFAULT_HEIGHT);
795 if (ret != AVCS_ERR_OK) {
796 return ret;
797 }
798 cout << fileInfos[index].fileDir << endl;
799 cout << "set width:" << fileInfos[index].width << "height: " << fileInfos[index].height << endl;
800 return FILE_END;
801 }
802 ret = ReadOneFrameByType(dst, fileInfos[index].format);
803 if (!ret) {
804 if (inFile_->is_open()) {
805 inFile_->close();
806 }
807 index++;
808 if (index >= fileInfos.size()) {
809 venc_->NotifyEos();
810 return LOOP_END;
811 }
812 return FILE_END;
813 }
814 return ret;
815 }
816
ReadOneFrameByType(uint8_t * dst,std::string & fileType)817 uint32_t VEncNdkInnerSample::ReadOneFrameByType(uint8_t *dst, std::string &fileType)
818 {
819 if (fileType == "rgba") {
820 return ReadOneFrameRGBA8888(dst);
821 } else if (fileType == "nv12" || fileType == "nv21") {
822 return ReadOneFrameYUV420SP(dst);
823 } else {
824 cout << "error fileType" << endl;
825 return 0;
826 }
827 }
828
ReadOneFrameByType(uint8_t * dst,GraphicPixelFormat format)829 uint32_t VEncNdkInnerSample::ReadOneFrameByType(uint8_t *dst, GraphicPixelFormat format)
830 {
831 if (format == GRAPHIC_PIXEL_FMT_RGBA_8888) {
832 return ReadOneFrameRGBA8888(dst);
833 } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_420_SP || format == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) {
834 return ReadOneFrameYUV420SP(dst);
835 } else if (format == GRAPHIC_PIXEL_FMT_YCBCR_P010) {
836 return ReadOneFrameYUVP010(dst);
837 } else {
838 cout << "error fileType" << endl;
839 return 0;
840 }
841 }
842
ReadOneFrameRGBA8888(uint8_t * dst)843 uint32_t VEncNdkInnerSample::ReadOneFrameRGBA8888(uint8_t *dst)
844 {
845 uint8_t *start = dst;
846 for (uint32_t i = 0; i < DEFAULT_HEIGHT; i++) {
847 inFile_->read(reinterpret_cast<char *>(dst), DEFAULT_WIDTH * RGBA_SIZE);
848 if (inFile_->eof())
849 return 0;
850 dst += stride_;
851 }
852 return dst - start;
853 }
854
RandomEOS(uint32_t index)855 bool VEncNdkInnerSample::RandomEOS(uint32_t index)
856 {
857 uint32_t random_eos = rand() % 25;
858 if (enableRandomEos && random_eos == frameCount) {
859 AVCodecBufferInfo info;
860 info.presentationTimeUs = 0;
861 info.size = 0;
862 info.offset = 0;
863 AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
864
865 venc_->QueueInputBuffer(index, info, flag);
866 cout << "random eos" << endl;
867 frameCount++;
868 unique_lock<mutex> lock(signal_->inMutex_);
869 signal_->inIdxQueue_.pop();
870 signal_->inBufferQueue_.pop();
871 return true;
872 }
873 return false;
874 }
875
RepeatStartBeforeEOS()876 void VEncNdkInnerSample::RepeatStartBeforeEOS()
877 {
878 if (REPEAT_START_FLUSH_BEFORE_EOS > 0) {
879 REPEAT_START_FLUSH_BEFORE_EOS--;
880 venc_->Flush();
881 FlushBuffer();
882 venc_->Start();
883 }
884
885 if (REPEAT_START_STOP_BEFORE_EOS > 0) {
886 REPEAT_START_STOP_BEFORE_EOS--;
887 venc_->Stop();
888 FlushBuffer();
889 venc_->Start();
890 }
891 }
892
SetEOS(uint32_t index)893 void VEncNdkInnerSample::SetEOS(uint32_t index)
894 {
895 AVCodecBufferInfo info;
896 info.presentationTimeUs = 0;
897 info.size = 0;
898 info.offset = 0;
899 AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_EOS;
900
901 int32_t res = venc_->QueueInputBuffer(index, info, flag);
902 cout << "QueueInputBuffer EOS res: " << res << endl;
903 if (enbleSyncMode == 0) {
904 unique_lock<mutex> lock(signal_->inMutex_);
905 signal_->inIdxQueue_.pop();
906 signal_->inBufferQueue_.pop();
907 }
908 }
909
WaitForEOS()910 void VEncNdkInnerSample::WaitForEOS()
911 {
912 if (inputLoop_)
913 inputLoop_->join();
914 if (outputLoop_)
915 outputLoop_->join();
916 if (inputParamLoop_)
917 inputParamLoop_->join();
918 inputLoop_ = nullptr;
919 outputLoop_ = nullptr;
920 inputParamLoop_ = nullptr;
921 }
922
InputFuncSurface()923 void VEncNdkInnerSample::InputFuncSurface()
924 {
925 int32_t readFileIndex = 0;
926 while (true) {
927 if (!isRunning_.load()) {
928 break;
929 }
930 OHNativeWindowBuffer *ohNativeWindowBuffer = nullptr;
931 OH_NativeBuffer *nativeBuffer = nullptr;
932 uint8_t *dst = nullptr;
933 int err = InitBuffer(ohNativeWindowBuffer, nativeBuffer, dst);
934 if (err == 0) {
935 break;
936 } else if (err == -1) {
937 continue;
938 }
939 if (readMultiFiles) {
940 err = ReadOneFrameFromList(dst, readFileIndex);
941 if (err == LOOP_END) {
942 break;
943 } else if (err == FILE_END) {
944 OH_NativeWindow_NativeWindowAbortBuffer(nativeWindow, ohNativeWindowBuffer);
945 continue;
946 }
947 } else if (DEFAULT_PIX_FMT == static_cast<int32_t>(VideoPixelFormat::NV12) && !ReadOneFrameYUV420SP(dst)) {
948 err = venc_->NotifyEos();
949 if (err != 0) {
950 cout << "OH_VideoEncoder_NotifyEndOfStream failed" << endl;
951 }
952 break;
953 } else if (DEFAULT_PIX_FMT == static_cast<int32_t>(VideoPixelFormat::RGBA1010102) &&
954 !ReadOneFrameRGBA8888(dst)) {
955 err = venc_->NotifyEos();
956 if (err != 0) {
957 cout << "OH_VideoEncoder_NotifyEndOfStream failed" << endl;
958 }
959 break;
960 }
961 if (inputFrameCount == FIVE && !isParamSet && enableParameter) {
962 SetParameter();
963 isParamSet = true;
964 }
965 inputFrameCount++;
966 err = InputProcess(nativeBuffer, ohNativeWindowBuffer);
967 if (err != 0) {
968 break;
969 }
970 usleep(FRAME_INTERVAL);
971 InputEnableRepeatSleep();
972 }
973 }
974
InitBuffer(OHNativeWindowBuffer * & ohNativeWindowBuffer,OH_NativeBuffer * & nativeBuffer,uint8_t * & dst)975 int32_t VEncNdkInnerSample::InitBuffer(OHNativeWindowBuffer *&ohNativeWindowBuffer,
976 OH_NativeBuffer *&nativeBuffer, uint8_t *&dst)
977 {
978 int fenceFd = -1;
979 if (nativeWindow == nullptr) {
980 return 0;
981 }
982 int32_t err = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &ohNativeWindowBuffer, &fenceFd);
983 if (err != 0) {
984 cout << "RequestBuffer failed, GSError=" << err << endl;
985 return -1;
986 }
987 if (fenceFd > 0) {
988 close(fenceFd);
989 }
990 nativeBuffer = OH_NativeBufferFromNativeWindowBuffer(ohNativeWindowBuffer);
991 void *virAddr = nullptr;
992 err = OH_NativeBuffer_Map(nativeBuffer, &virAddr);
993 if (err != 0) {
994 cout << "OH_NativeBuffer_Map failed, GSError=" << err << endl;
995 isRunning_.store(false);
996 return 0;
997 }
998 dst = (uint8_t *)virAddr;
999 const SurfaceBuffer *sbuffer = SurfaceBuffer::NativeBufferToSurfaceBuffer(nativeBuffer);
1000 int32_t stride = sbuffer->GetStride();
1001 if (dst == nullptr || stride < (int32_t)DEFAULT_WIDTH) {
1002 cout << "invalid va or stride=" << stride << endl;
1003 err = NativeWindowCancelBuffer(nativeWindow, ohNativeWindowBuffer);
1004 isRunning_.store(false);
1005 return 0;
1006 }
1007 stride_ = stride;
1008 return 1;
1009 }
1010
InputEnableRepeatSleep()1011 void VEncNdkInnerSample::InputEnableRepeatSleep()
1012 {
1013 inCount = inCount + 1;
1014 int32_t inCountNum = 15;
1015 if (enableRepeat && inCount == inCountNum) {
1016 if (setMaxCount) {
1017 int32_t sleepTimeMaxCount = 730000;
1018 usleep(sleepTimeMaxCount);
1019 } else {
1020 int32_t sleepTime = 1000000;
1021 usleep(sleepTime);
1022 }
1023 if (enableSeekEos) {
1024 inFile_->clear();
1025 inFile_->seekg(-1, ios::beg);
1026 }
1027 }
1028 }
1029
InputParamLoopFunc()1030 void VEncNdkInnerSample::InputParamLoopFunc()
1031 {
1032 if (signal_ == nullptr || venc_ == nullptr) {
1033 cout << "signal or venc is null" << endl;
1034 return;
1035 }
1036 cout<< "InputParamLoopFunc" <<endl;
1037 while (isRunning_.load()) {
1038 unique_lock<mutex> lock(signal_->inMutex_);
1039 signal_->inCond_.wait(
1040 lock, [this]() { return (signal_->inIdxQueue_.size() > 0) || (!isRunning_.load()); });
1041 if (!isRunning_.load()) {
1042 cout << "InputLoopFunc stop running" << endl;
1043 break;
1044 }
1045 int32_t index = signal_->inIdxQueue_.front();
1046 auto format = signal_->inFormatQueue_.front();
1047 auto attr = signal_->inAttrQueue_.front();
1048 signal_->inIdxQueue_.pop();
1049 signal_->inFormatQueue_.pop();
1050 signal_->inAttrQueue_.pop();
1051 if (attr != nullptr) {
1052 int64_t pts = 0;
1053 if (true != attr->GetLongValue(Media::Tag::MEDIA_TIME_STAMP, pts)) {
1054 return;
1055 }
1056 }
1057 if (IsFrameDiscard(inputFrameCount)) {
1058 discardFrameCount++;
1059 format->PutIntValue(Media::Tag::VIDEO_ENCODER_PER_FRAME_DISCARD, 1);
1060 }
1061 int32_t ret = PushInputParameter(index);
1062 if (ret != AV_ERR_OK) {
1063 cout << "Fatal: PushInputData fail, exit" << endl;
1064 }
1065 }
1066 }
1067
InputFunc()1068 void VEncNdkInnerSample::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
1089 lock.unlock();
1090 if (!inFile_->eof()) {
1091 bool isRandomEosSuccess = RandomEOS(index);
1092 if (isRandomEosSuccess) {
1093 continue;
1094 }
1095 int32_t pushResult = 0;
1096 int32_t ret = PushData(buffer, index, pushResult);
1097 if (ret == 0) {
1098 break;
1099 } else if (ret == -1) {
1100 continue;
1101 }
1102 if (CheckResult(isRandomEosSuccess, pushResult) == -1) {
1103 break;
1104 }
1105 if (frameCount == FIVE && !isParamSet && enableParameter) {
1106 SetParameter();
1107 isParamSet = true;
1108 }
1109 frameCount++;
1110 }
1111 if (sleepOnFPS) {
1112 usleep(FRAME_INTERVAL);
1113 }
1114 }
1115 }
1116
SetParameter()1117 int32_t VEncNdkInnerSample::SetParameter()
1118 {
1119 Format format;
1120 if (SETBIRATE_RUN) {
1121 format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, DEFAULT_BITRATE_RUN);
1122 }
1123 if (MAXBITE_ENABLE_RUN) {
1124 format.PutLongValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODER_MAX_BITRATE, DEFAULT_MAX_BITERATE_RUN);
1125 }
1126 if (FACTOR_ENABLE_RUN) {
1127 format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODER_SQR_FACTOR, DEFAULT_SQR_FACTOR_RUN);
1128 }
1129 return venc_->SetParameter(format);
1130 }
1131
SyncInputFunc()1132 void VEncNdkInnerSample::SyncInputFunc()
1133 {
1134 errCount = 0;
1135 while (isRunning_.load()) {
1136 uint32_t index;
1137 if (venc_->QueryInputBuffer(index, syncInputWaitTime) != AVCS_ERR_OK) {
1138 cout << "QueryInputBuffer faile" << endl;
1139 continue;
1140 }
1141 std::shared_ptr<AVBuffer> buffer = venc_->GetInputBuffer(index);
1142 if (buffer == nullptr) {
1143 cout << "GetInputBuffer fail" << endl;
1144 errCount = errCount + 1;
1145 continue;
1146 }
1147 if (!inFile_->eof()) {
1148 bool isRandomEosSuccess = RandomEOS(index);
1149 if (isRandomEosSuccess) {
1150 continue;
1151 }
1152 int32_t pushResult = 0;
1153 int32_t ret = SyncPushData(buffer, index, pushResult);
1154 if (ret == 0) {
1155 isRunning_.store(false);
1156 break;
1157 } else if (ret == -1) {
1158 continue;
1159 }
1160
1161 if (CheckResult(isRandomEosSuccess, pushResult) == -1) {
1162 isRunning_.store(false);
1163 break;
1164 }
1165 frameCount++;
1166 }
1167 if (sleepOnFPS) {
1168 usleep(FRAME_INTERVAL);
1169 }
1170 }
1171 }
1172
OutputFunc()1173 void VEncNdkInnerSample::OutputFunc()
1174 {
1175 FILE *outFile = fopen(OUT_DIR, "wb");
1176
1177 while (true) {
1178 if (!isRunning_.load()) {
1179 break;
1180 }
1181
1182 unique_lock<mutex> lock(signal_->outMutex_);
1183 signal_->outCond_.wait(lock, [this]() {
1184 if (!isRunning_.load()) {
1185 return true;
1186 }
1187 return signal_->outIdxQueue_.size() > 0;
1188 });
1189
1190 if (!isRunning_.load()) {
1191 break;
1192 }
1193
1194 std::shared_ptr<AVSharedMemory> buffer = signal_->outBufferQueue_.front();
1195 AVCodecBufferInfo info = signal_->infoQueue_.front();
1196 AVCodecBufferFlag flag = signal_->flagQueue_.front();
1197 uint32_t index = signal_->outIdxQueue_.front();
1198
1199 signal_->outBufferQueue_.pop();
1200 signal_->outIdxQueue_.pop();
1201 signal_->infoQueue_.pop();
1202 signal_->flagQueue_.pop();
1203 lock.unlock();
1204
1205 if (CheckFlag(flag) == -1) {
1206 break;
1207 }
1208
1209 int size = info.size;
1210 if (outFile == nullptr) {
1211 cout << "dump data fail" << endl;
1212 } else {
1213 fwrite(buffer->GetBase(), 1, size, outFile);
1214 }
1215
1216 if (venc_->ReleaseOutputBuffer(index) != AVCS_ERR_OK) {
1217 cout << "Fatal: ReleaseOutputBuffer fail" << endl;
1218 errCount = errCount + 1;
1219 }
1220 if (errCount > 0) {
1221 OutputFuncFail();
1222 break;
1223 }
1224 }
1225 (void)fclose(outFile);
1226 }
1227
SyncOutputFunc()1228 void VEncNdkInnerSample::SyncOutputFunc()
1229 {
1230 FILE *outFile = fopen(OUT_DIR, "wb");
1231
1232 while (isRunning_.load()) {
1233 uint32_t index = 0;
1234 cout << "QueryOutputBuffer start" << endl;
1235 if (venc_->QueryOutputBuffer(index, syncOutputWaitTime) != AVCS_ERR_OK) {
1236 cout << "QueryOutputBuffer fail" << endl;
1237 continue;
1238 }
1239 cout << "QueryOutputBuffer succ" << endl;
1240 std::shared_ptr<AVBuffer> buffer = venc_->GetOutputBuffer(index);
1241 if (buffer == nullptr) {
1242 cout << "GetOutputBuffer fail" << endl;
1243 errCount = errCount + 1;
1244 continue;
1245 }
1246 AVCodecBufferFlag flag = static_cast<AVCodecBufferFlag>(buffer->flag_);
1247 if (SyncOutputFuncEos(flag, index) != AVCS_ERR_OK) {
1248 isRunning_.store(false);
1249 break;
1250 }
1251 int size = buffer->memory_->GetSize();
1252 if (outFile == nullptr) {
1253 cout << "dump data fail" << endl;
1254 } else {
1255 fwrite(buffer->memory_->GetAddr(), 1, size, outFile);
1256 }
1257
1258 if (venc_->ReleaseOutputBuffer(index) != AVCS_ERR_OK) {
1259 cout << "Fatal: ReleaseOutputBuffer fail" << endl;
1260 errCount = errCount + 1;
1261 }
1262 if (errCount > 0) {
1263 OutputFuncFail();
1264 isRunning_.store(false);
1265 break;
1266 }
1267 }
1268 (void)fclose(outFile);
1269 }
1270
SyncOutputFuncEos(AVCodecBufferFlag flag,uint32_t index)1271 int32_t VEncNdkInnerSample::SyncOutputFuncEos(AVCodecBufferFlag flag, uint32_t index)
1272 {
1273 if (CheckFlag(flag) == -1) {
1274 if (queryInputBufferEOS) {
1275 venc_->QueryInputBuffer(index, 0);
1276 venc_->QueryInputBuffer(index, MILLION);
1277 venc_->QueryInputBuffer(index, -1);
1278 }
1279 if (queryOutputBufferEOS) {
1280 venc_->QueryOutputBuffer(index, 0);
1281 venc_->QueryOutputBuffer(index, MILLION);
1282 venc_->QueryOutputBuffer(index, -1);
1283 }
1284 return AVCS_ERR_UNKNOWN;
1285 }
1286 return AV_ERR_OK;
1287 }
1288
OutputFuncFail()1289 void VEncNdkInnerSample::OutputFuncFail()
1290 {
1291 cout << "errCount > 0" << endl;
1292 unique_lock<mutex> inLock(signal_->inMutex_);
1293 isRunning_.store(false);
1294 signal_->inCond_.notify_all();
1295 signal_->outCond_.notify_all();
1296 inLock.unlock();
1297 (void)Stop();
1298 Release();
1299 }
1300
FlushBuffer()1301 void VEncNdkInnerSample::FlushBuffer()
1302 {
1303 std::queue<std::shared_ptr<AVSharedMemory>> empty;
1304 unique_lock<mutex> inLock(signal_->inMutex_);
1305 clearIntqueue(signal_->inIdxQueue_);
1306 swap(empty, signal_->inBufferQueue_);
1307 signal_->inCond_.notify_all();
1308 inLock.unlock();
1309
1310 unique_lock<mutex> outLock(signal_->outMutex_);
1311 clearIntqueue(signal_->outIdxQueue_);
1312 clearBufferqueue(signal_->infoQueue_);
1313 clearFlagqueue(signal_->flagQueue_);
1314 signal_->outCond_.notify_all();
1315 outLock.unlock();
1316 }
1317
StopInloop()1318 void VEncNdkInnerSample::StopInloop()
1319 {
1320 if (inputLoop_ != nullptr && inputLoop_->joinable()) {
1321 unique_lock<mutex> lock(signal_->inMutex_);
1322 clearIntqueue(signal_->inIdxQueue_);
1323 isRunning_.store(false);
1324 signal_->inCond_.notify_all();
1325 lock.unlock();
1326
1327 inputLoop_->join();
1328 inputLoop_ = nullptr;
1329 }
1330 }
1331
StopOutloop()1332 void VEncNdkInnerSample::StopOutloop()
1333 {
1334 if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1335 unique_lock<mutex> lock(signal_->outMutex_);
1336 clearIntqueue(signal_->outIdxQueue_);
1337 clearBufferqueue(signal_->infoQueue_);
1338 clearFlagqueue(signal_->flagQueue_);
1339 signal_->outCond_.notify_all();
1340 lock.unlock();
1341 }
1342 }
1343
ReleaseInFile()1344 void VEncNdkInnerSample::ReleaseInFile()
1345 {
1346 if (inFile_ != nullptr) {
1347 if (inFile_->is_open()) {
1348 inFile_->close();
1349 }
1350 inFile_.reset();
1351 inFile_ = nullptr;
1352 }
1353 }
1354
PushRandomDiscardIndex(uint32_t count,uint32_t max,uint32_t min)1355 void VEncNdkInnerSample::PushRandomDiscardIndex(uint32_t count, uint32_t max, uint32_t min)
1356 {
1357 cout << "random farame index :";
1358 while (discardFrameIndex.size() < count) {
1359 uint32_t num = 0;
1360 if (max != 0) {
1361 num = rd() % max + min;
1362 }
1363 if (find(discardFrameIndex.begin(), discardFrameIndex.end(), num) == discardFrameIndex.end()) {
1364 cout << num << ",";
1365 discardFrameIndex.push_back(num);
1366 }
1367 cout << endl;
1368 }
1369 }
1370
IsFrameDiscard(uint32_t index)1371 bool VEncNdkInnerSample::IsFrameDiscard(uint32_t index)
1372 {
1373 if (!isDiscardFrame) {
1374 return false;
1375 }
1376 if (discardMinIndex > -1 && discardMaxIndex >= discardMinIndex) {
1377 if (index >= discardMinIndex && index <= discardMaxIndex) {
1378 return true;
1379 }
1380 }
1381 if (find(discardFrameIndex.begin(), discardFrameIndex.end(), index) != discardFrameIndex.end()) {
1382 return true;
1383 }
1384 if (discardInterval > 0 && index % discardInterval == 0) {
1385 return true;
1386 }
1387 return false;
1388 }
1389
CheckOutputFrameCount()1390 bool VEncNdkInnerSample::CheckOutputFrameCount()
1391 {
1392 cout << "checooutpuframecount" << inputFrameCount << ", " << discardFrameCount<< ", " << outCount << endl;
1393 if (inputFrameCount - discardFrameCount == outCount) {
1394 return true;
1395 }
1396 return false;
1397 }
1398
PushInputParameter(uint32_t index)1399 int32_t VEncNdkInnerSample::PushInputParameter(uint32_t index)
1400 {
1401 if (venc_ == nullptr) {
1402 return AV_ERR_UNKNOWN;
1403 }
1404 return venc_->QueueInputParameter(index);
1405 }
1406
SetCustomBuffer(BufferRequestConfig bufferConfig)1407 int32_t VEncNdkInnerSample::SetCustomBuffer(BufferRequestConfig bufferConfig)
1408 {
1409 int32_t waterMarkFlag = enableWaterMark ? 1 : 0;
1410 auto allocator = Media::AVAllocatorFactory::CreateSurfaceAllocator(bufferConfig);
1411 std::shared_ptr<AVBuffer> avbuffer = AVBuffer::CreateAVBuffer(allocator);
1412 if (avbuffer == nullptr) {
1413 cout << "avbuffer is nullptr" << endl;
1414 return AVCS_ERR_INVALID_VAL;
1415 }
1416 cout << WATER_MARK_DIR << endl;
1417 ReadCustomDataToAVBuffer(WATER_MARK_DIR, avbuffer);
1418 Format format;
1419 format.SetMeta(avbuffer->meta_);
1420 format.PutIntValue(Media::Tag::VIDEO_ENCODER_ENABLE_WATERMARK, waterMarkFlag);
1421 format.PutIntValue(Media::Tag::VIDEO_COORDINATE_X, videoCoordinateX);
1422 format.PutIntValue(Media::Tag::VIDEO_COORDINATE_Y, videoCoordinateY);
1423 format.PutIntValue(Media::Tag::VIDEO_COORDINATE_W, videoCoordinateWidth);
1424 format.PutIntValue(Media::Tag::VIDEO_COORDINATE_H, videoCoordinateHeight);
1425 *(avbuffer->meta_) = *(format.GetMeta());
1426 int32_t ret = venc_->SetCustomBuffer(avbuffer);
1427 return ret;
1428 }
1429
ReadCustomDataToAVBuffer(const std::string & fileName,std::shared_ptr<AVBuffer> buffer)1430 bool VEncNdkInnerSample::ReadCustomDataToAVBuffer(const std::string &fileName, std::shared_ptr<AVBuffer> buffer)
1431 {
1432 std::unique_ptr<std::ifstream> inFile = std::make_unique<std::ifstream>();
1433 inFile->open(fileName.c_str(), std::ios::in | std::ios::binary);
1434 if (!inFile->is_open()) {
1435 cout << "open file filed,filename:" << fileName.c_str() << endl;
1436 }
1437 sptr<SurfaceBuffer> surfaceBuffer = buffer->memory_->GetSurfaceBuffer();
1438 if (surfaceBuffer == nullptr) {
1439 cout << "in is nullptr" << endl;
1440 return false;
1441 }
1442 int32_t width = surfaceBuffer->GetWidth();
1443 int32_t height = surfaceBuffer->GetHeight();
1444 int32_t bufferSize = width * height * 4;
1445 uint8_t *in = (uint8_t *)malloc(bufferSize);
1446 if (in == nullptr) {
1447 cout << "in is nullptr" <<endl;
1448 }
1449 inFile->read(reinterpret_cast<char *>(in), bufferSize);
1450 int32_t dstWidthStride = surfaceBuffer->GetStride();
1451 uint8_t *dstAddr = (uint8_t *)surfaceBuffer->GetVirAddr();
1452 if (dstAddr == nullptr) {
1453 cout << "dst is nullptr" << endl;
1454 }
1455 const int32_t srcWidthStride = width << 2;
1456 uint8_t *inStream = in;
1457 for (uint32_t i = 0; i < height; ++i) {
1458 if (memcpy_s(dstAddr, dstWidthStride, inStream, srcWidthStride)) {
1459 cout << "memcpy_s failed" <<endl;
1460 };
1461 dstAddr += dstWidthStride;
1462 inStream += srcWidthStride;
1463 }
1464 inFile->close();
1465 if (in) {
1466 free(in);
1467 in = nullptr;
1468 }
1469 return true;
1470 }
1471
GetWaterMarkCapability(std::string codecMimeType)1472 bool VEncNdkInnerSample::GetWaterMarkCapability(std::string codecMimeType)
1473 {
1474 std::shared_ptr<AVCodecList> codecCapability = AVCodecListFactory::CreateAVCodecList();
1475 CapabilityData *capabilityData = nullptr;
1476 capabilityData = codecCapability->GetCapability(codecMimeType, true, AVCodecCategory::AVCODEC_HARDWARE);
1477 if (capabilityData->featuresMap.count(static_cast<int32_t>(AVCapabilityFeature::VIDEO_WATERMARK))) {
1478 std::cout << "Support watermark" << std::endl;
1479 return true;
1480 } else {
1481 std::cout << " Not support watermark" << std::endl;
1482 return false;
1483 }
1484 }