1 /*
2 * Copyright (C) 2022 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
16 #include "gtest/gtest.h"
17 #include "audio_info.h"
18 #include "av_common.h"
19 #include "native_avcodec_base.h"
20 #include "avcodec_video_encoder.h"
21 #include "avcodec_video_decoder.h"
22 #include "native_avmemory.h"
23 #include "VDecEncNdkSample.h"
24
25 using namespace OHOS;
26 using namespace OHOS::Media;
27 using namespace std;
28
29 namespace {
30 constexpr uint32_t SAMPLE_DURATION_US = 23000;
31 constexpr uint32_t ES[] = {
32 2106, 11465, 321, 72, 472, 68, 76, 79, 509, 90, 677, 88, 956, 99, 347, 77, 452, 681, 81, 1263, 94, 106, 97,
33 998, 97, 797, 93, 1343, 150, 116, 117, 926, 1198, 128, 110, 78, 1582, 158, 135, 112, 1588, 165, 132,
34 128, 1697, 168, 149, 117, 1938, 170, 141, 142, 1830, 106, 161, 122, 1623, 160, 154, 156, 1998, 230,
35 177, 139, 1650, 186, 128, 134, 1214, 122, 1411, 120, 1184, 128, 1591, 195, 145, 105, 1587, 169, 140,
36 118, 1952, 177, 150, 161, 1437, 159, 123, 1758, 180, 165, 144, 1936, 214, 191, 175, 2122, 180, 179,
37 160, 1927, 161, 184, 119, 1973, 218, 210, 129, 1962, 196, 127, 154, 2308, 173, 127, 1572, 142, 122};
38 constexpr uint32_t ES_LENGTH = sizeof(ES) / sizeof(uint32_t);
39 constexpr int32_t STOPNUM = 10000;
40
VdecAsyncError(OH_AVCodec * codec,int32_t errorCode,void * userData)41 void VdecAsyncError(OH_AVCodec *codec, int32_t errorCode, void *userData)
42 {
43 cout << "DEC Error errorCode=" << errorCode << endl;
44 VDecEncSignal* vcodecSignal_ = static_cast<VDecEncSignal *>(userData);
45 vcodecSignal_->errorNum_ += 1;
46 }
47
VdecAsyncStreamChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)48 void VdecAsyncStreamChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
49 {
50 cout << "DEC Format Changed" << endl;
51 }
VdecAsyncNeedInputData(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,void * userData)52 void VdecAsyncNeedInputData(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, void *userData)
53 {
54 VDecEncSignal* vcodecSignal_ = static_cast<VDecEncSignal *>(userData);
55 unique_lock<mutex> lock(vcodecSignal_->inMutexDec_);
56 if (vcodecSignal_->isVdecFlushing_.load()) {
57 cout << "VdecAsyncNeedInputData isVdecFlushing_ is true, return" << endl;
58 return;
59 }
60 vcodecSignal_->inQueueDec_.push(index);
61 vcodecSignal_->inBufferQueueDec_.push(data);
62 vcodecSignal_->inCondDec_.notify_all();
63 }
64
VdecAsyncNewOutputData(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,OH_AVCodecBufferAttr * attr,void * userData)65 void VdecAsyncNewOutputData(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data,
66 OH_AVCodecBufferAttr *attr, void *userData)
67 {
68 VDecEncSignal* vcodecSignal_ = static_cast<VDecEncSignal *>(userData);
69 unique_lock<mutex> lock(vcodecSignal_->outMutexDec_);
70 if (vcodecSignal_->isVdecFlushing_.load()) {
71 cout << "VdecAsyncNeedInputData isVdecFlushing_ is true, return" << endl;
72 return;
73 }
74 vcodecSignal_->outQueueDec_.push(index);
75 vcodecSignal_->flagQueueDec_.push(attr->flags);
76 vcodecSignal_->outCondDec_.notify_all();
77 }
78
79
VencAsyncError(OH_AVCodec * codec,int32_t errorCode,void * userData)80 void VencAsyncError(OH_AVCodec *codec, int32_t errorCode, void *userData)
81 {
82 cout << "ENC Error errorCode=" << errorCode << endl;
83 VDecEncSignal* vcodecSignal_ = static_cast<VDecEncSignal *>(userData);
84 vcodecSignal_->errorNum_ += 1;
85 }
86
VencAsyncStreamChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)87 void VencAsyncStreamChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
88 {
89 cout << "ENC Format Changed" << endl;
90 }
91
VencAsyncNewOutputData(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,OH_AVCodecBufferAttr * attr,void * userData)92 void VencAsyncNewOutputData(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data,
93 OH_AVCodecBufferAttr *attr, void *userData)
94 {
95 VDecEncSignal* vcodecSignal_ = static_cast<VDecEncSignal *>(userData);
96 unique_lock<mutex> lock(vcodecSignal_->outMutexEnc_);
97 if (vcodecSignal_->isVencFlushing_.load()) {
98 cout << "VdecAsyncNeedInputData isVencFlushing_ is true, return" << endl;
99 return;
100 }
101 vcodecSignal_->outQueueEnc_.push(index);
102 vcodecSignal_->sizeQueueEnc_.push(attr->size);
103 vcodecSignal_->flagQueueEnc_.push(attr->flags);
104 vcodecSignal_->outBufferQueueEnc_.push(data);
105 vcodecSignal_->outCondEnc_.notify_all();
106 }
107
clearIntqueue(std::queue<uint32_t> & q)108 void clearIntqueue (std::queue<uint32_t>& q)
109 {
110 std::queue<uint32_t> empty;
111 swap(empty, q);
112 }
113
clearBufferqueue(std::queue<OH_AVMemory * > & q)114 void clearBufferqueue (std::queue<OH_AVMemory *>& q)
115 {
116 std::queue<OH_AVMemory *> empty;
117 swap(empty, q);
118 }
119 }
120
~VDecEncNdkSample()121 VDecEncNdkSample::~VDecEncNdkSample()
122 {
123 OH_VideoDecoder_Destroy(vdec_);
124 OH_VideoEncoder_Destroy(venc_);
125
126 delete vcodecSignal_;
127 vcodecSignal_ = nullptr;
128 }
129
SetReadPath(std::string filepath)130 void VDecEncNdkSample::SetReadPath(std::string filepath)
131 {
132 inFile_ = filepath;
133 if (testFile_ == nullptr) {
134 testFile_ = std::make_unique<std::ifstream>();
135 }
136 testFile_->open(inFile_, std::ios::in | std::ios::binary);
137 }
138
SetSavePath(std::string filepath)139 void VDecEncNdkSample::SetSavePath(std::string filepath)
140 {
141 outFile_ = filepath;
142 }
143
SetEosState(bool needSetEos)144 void VDecEncNdkSample::SetEosState(bool needSetEos)
145 {
146 setEos = needSetEos;
147 }
148
ReRead()149 void VDecEncNdkSample::ReRead()
150 {
151 if (testFile_ != nullptr) {
152 testFile_->close();
153 cout << "ReRead close before file success " << endl;
154 }
155 cout << "ReRead inFile is " << inFile_ << endl;
156 testFile_->open(inFile_, std::ios::in | std::ios::binary);
157 if (testFile_ != nullptr) {
158 cout << "testFile open success" << endl;
159 }
160 decInCnt_ = 0;
161 isFirstDecFrame_ = true;
162 timeStampDec_ = 0;
163 }
164
ResetDecParam()165 void VDecEncNdkSample::ResetDecParam()
166 {
167 decInCnt_ = 0;
168 decOutCnt_ = 0;
169 isDecInputEOS = false;
170 isDecOutputEOS = false;
171 unique_lock<mutex> lockIn(vcodecSignal_->inMutexDec_);
172 clearIntqueue(vcodecSignal_->inQueueDec_);
173 clearBufferqueue(vcodecSignal_->inBufferQueueDec_);
174 vcodecSignal_->inCondDec_.notify_all();
175 unique_lock<mutex> lockOut(vcodecSignal_->outMutexDec_);
176 clearIntqueue(vcodecSignal_->outQueueDec_);
177 clearIntqueue(vcodecSignal_->flagQueueDec_);
178 clearBufferqueue(vcodecSignal_->outBufferQueueDec_);
179 vcodecSignal_->outCondDec_.notify_all();
180 isDecRunning_.store(true);
181 cout << "isDecRunning_.load() is " << isDecRunning_.load() << endl;
182 }
ResetEncParam()183 void VDecEncNdkSample::ResetEncParam()
184 {
185 encOutCnt_ = 0;
186 isEncInputEOS = false;
187 isEncOutputEOS = false;
188 unique_lock<mutex> lockOut(vcodecSignal_->outMutexEnc_);
189 clearIntqueue(vcodecSignal_->outQueueEnc_);
190 clearIntqueue(vcodecSignal_->sizeQueueEnc_);
191 clearIntqueue(vcodecSignal_->flagQueueEnc_);
192 clearBufferqueue(vcodecSignal_->outBufferQueueEnc_);
193 vcodecSignal_->outCondEnc_.notify_all();
194 isEncRunning_.store(true);
195 cout << "isEncRunning_.load() is " << isEncRunning_.load() << endl;
196 }
197
CreateVideoDecoderByMime(std::string mimetype)198 struct OH_AVCodec* VDecEncNdkSample::CreateVideoDecoderByMime(std::string mimetype)
199 {
200 if (mimetype == "video/avc") {
201 cout << "mimetype == 'video/avc'" << endl;
202 vdec_ = OH_VideoDecoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC);
203 } else {
204 vdec_ = OH_VideoDecoder_CreateByMime(mimetype.c_str());
205 }
206 NDK_CHECK_AND_RETURN_RET_LOG(vdec_ != nullptr, nullptr, "Fatal: OH_VideoDecoder_CreateByMime");
207 if (vcodecSignal_ == nullptr) {
208 vcodecSignal_ = new VDecEncSignal();
209 NDK_CHECK_AND_RETURN_RET_LOG(vcodecSignal_ != nullptr, nullptr, "Fatal: No Memory");
210 }
211 cbDec_.onError = VdecAsyncError;
212 cbDec_.onStreamChanged = VdecAsyncStreamChanged;
213 cbDec_.onNeedInputData = VdecAsyncNeedInputData;
214 cbDec_.onNeedOutputData = VdecAsyncNewOutputData;
215 int32_t ret = OH_VideoDecoder_SetCallback(vdec_, cbDec_, static_cast<void *>(vcodecSignal_));
216 NDK_CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, NULL, "Fatal: OH_VideoDecoder_SetCallback");
217 return vdec_;
218 }
219
CreateVideoDecoderByName(std::string name)220 struct OH_AVCodec* VDecEncNdkSample::CreateVideoDecoderByName(std::string name)
221 {
222 vdec_ = OH_VideoDecoder_CreateByName(name.c_str());
223 NDK_CHECK_AND_RETURN_RET_LOG(vdec_ != nullptr, nullptr, "Fatal: OH_VideoDecoder_CreateByName");
224 if (vcodecSignal_ == nullptr) {
225 vcodecSignal_ = new VDecEncSignal();
226 NDK_CHECK_AND_RETURN_RET_LOG(vcodecSignal_ != nullptr, nullptr, "Fatal: No Memory");
227 }
228 cbDec_.onError = VdecAsyncError;
229 cbDec_.onStreamChanged = VdecAsyncStreamChanged;
230 cbDec_.onNeedInputData = VdecAsyncNeedInputData;
231 cbDec_.onNeedOutputData = VdecAsyncNewOutputData;
232 int32_t ret = OH_VideoDecoder_SetCallback(vdec_, cbDec_, static_cast<void *>(vcodecSignal_));
233 NDK_CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, NULL, "Fatal: OH_VideoDecoder_SetCallback");
234 return vdec_;
235 }
236
ConfigureDec(struct OH_AVFormat * format)237 int32_t VDecEncNdkSample::ConfigureDec(struct OH_AVFormat *format)
238 {
239 return OH_VideoDecoder_Configure(vdec_, format);
240 }
241
SetParameterDec(struct OH_AVFormat * format)242 int32_t VDecEncNdkSample::SetParameterDec(struct OH_AVFormat *format)
243 {
244 return OH_VideoDecoder_SetParameter(vdec_, format);
245 }
246
PrepareDec()247 int32_t VDecEncNdkSample::PrepareDec()
248 {
249 return OH_VideoDecoder_Prepare(vdec_);
250 }
251
StartDec()252 int32_t VDecEncNdkSample::StartDec()
253 {
254 cout << "Enter dec start" << endl;
255 isDecRunning_.store(true);
256
257 if (inputLoopDec_ == nullptr) {
258 inputLoopDec_ = make_unique<thread>(&VDecEncNdkSample::InputFuncDec, this);
259 NDK_CHECK_AND_RETURN_RET_LOG(inputLoopDec_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory");
260 }
261 if (outputLoopDec_ == nullptr) {
262 outputLoopDec_ = make_unique<thread>(&VDecEncNdkSample::OutputFuncDec, this);
263 NDK_CHECK_AND_RETURN_RET_LOG(outputLoopDec_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory");
264 }
265 cout << "Exit dec start" << endl;
266 return OH_VideoDecoder_Start(vdec_);
267 }
268
StopDec()269 int32_t VDecEncNdkSample::StopDec()
270 {
271 cout << "ENTER DEC stop" << endl;
272 unique_lock<mutex> lock(vcodecSignal_->inMutexDec_);
273 unique_lock<mutex> lock2(vcodecSignal_->outMutexDec_);
274 vcodecSignal_->isVdecFlushing_.store(true);
275 lock.unlock();
276 lock2.unlock();
277 int32_t ret = OH_VideoDecoder_Stop(vdec_);
278 unique_lock<mutex> lockIn(vcodecSignal_->inMutexDec_);
279 clearIntqueue(vcodecSignal_->inQueueDec_);
280 clearBufferqueue(vcodecSignal_->inBufferQueueDec_);
281 vcodecSignal_->inCondDec_.notify_all();
282 lockIn.unlock();
283 unique_lock<mutex> lockOut(vcodecSignal_->outMutexDec_);
284 clearIntqueue(vcodecSignal_->outQueueDec_);
285 clearIntqueue(vcodecSignal_->flagQueueDec_);
286 clearBufferqueue(vcodecSignal_->outBufferQueueDec_);
287 vcodecSignal_->outCondDec_.notify_all();
288 lockOut.unlock();
289 vcodecSignal_->isVdecFlushing_.store(false);
290 cout << "EXIT DEC stop" << endl;
291 return ret;
292 }
293
FlushDec()294 int32_t VDecEncNdkSample::FlushDec()
295 {
296 cout << "ENTER DEC FLUSH" << endl;
297 unique_lock<mutex> lock(vcodecSignal_->inMutexDec_);
298 unique_lock<mutex> lock2(vcodecSignal_->outMutexDec_);
299 vcodecSignal_->isVdecFlushing_.store(true);
300 lock.unlock();
301 lock2.unlock();
302 int32_t ret = OH_VideoDecoder_Flush(vdec_);
303 unique_lock<mutex> lockIn(vcodecSignal_->inMutexDec_);
304 clearIntqueue(vcodecSignal_->inQueueDec_);
305 clearBufferqueue(vcodecSignal_->inBufferQueueDec_);
306 vcodecSignal_->inCondDec_.notify_all();
307 lockIn.unlock();
308 unique_lock<mutex> lockOut(vcodecSignal_->outMutexDec_);
309 clearIntqueue(vcodecSignal_->outQueueDec_);
310 clearIntqueue(vcodecSignal_->flagQueueDec_);
311 clearBufferqueue(vcodecSignal_->outBufferQueueDec_);
312 vcodecSignal_->outCondDec_.notify_all();
313 lockOut.unlock();
314 vcodecSignal_->isVdecFlushing_.store(false);
315 cout << "EXIT DEC FLUSH" << endl;
316 return ret;
317 }
318
ResetDec()319 int32_t VDecEncNdkSample::ResetDec()
320 {
321 cout << "Enter DEC reset" << endl;
322 unique_lock<mutex> lock(vcodecSignal_->inMutexDec_);
323 unique_lock<mutex> lock2(vcodecSignal_->outMutexDec_);
324 vcodecSignal_->isVdecFlushing_.store(true);
325 lock.unlock();
326 lock2.unlock();
327 int32_t ret = OH_VideoDecoder_Reset(vdec_);
328 unique_lock<mutex> lockIn(vcodecSignal_->inMutexDec_);
329 clearIntqueue(vcodecSignal_->inQueueDec_);
330 clearBufferqueue(vcodecSignal_->inBufferQueueDec_);
331 vcodecSignal_->inCondDec_.notify_all();
332 lockIn.unlock();
333 unique_lock<mutex> lockOut(vcodecSignal_->outMutexDec_);
334 clearIntqueue(vcodecSignal_->outQueueDec_);
335 clearIntqueue(vcodecSignal_->flagQueueDec_);
336 clearBufferqueue(vcodecSignal_->outBufferQueueDec_);
337 vcodecSignal_->outCondDec_.notify_all();
338 lockOut.unlock();
339 vcodecSignal_->isVdecFlushing_.store(false);
340 cout << "Exit DEC reset" << endl;
341 return ret;
342 }
343
ReleaseDec()344 int32_t VDecEncNdkSample::ReleaseDec()
345 {
346 cout << "Enter DEC release" << endl;
347 isDecRunning_.store(false);
348 if (inputLoopDec_ != nullptr && inputLoopDec_->joinable()) {
349 unique_lock<mutex> lock(vcodecSignal_->inMutexDec_);
350 vcodecSignal_->inQueueDec_.push(STOPNUM);
351 vcodecSignal_->inCondDec_.notify_all();
352 lock.unlock();
353 inputLoopDec_->join();
354 inputLoopDec_.reset();
355 }
356 if (outputLoopDec_ != nullptr && outputLoopDec_->joinable()) {
357 unique_lock<mutex> lock(vcodecSignal_->outMutexDec_);
358 vcodecSignal_->outQueueDec_.push(STOPNUM);
359 vcodecSignal_->outCondDec_.notify_all();
360 lock.unlock();
361 outputLoopDec_->join();
362 outputLoopDec_.reset();
363 }
364 OH_VideoDecoder_Destroy(vdec_);
365 cout << "Exit DEC release" << endl;
366 return AV_ERR_OK;
367 }
368
PopInqueueDec()369 void VDecEncNdkSample::PopInqueueDec()
370 {
371 if (vcodecSignal_ == nullptr) {
372 return;
373 }
374 vcodecSignal_->inQueueDec_.pop();
375 vcodecSignal_->inBufferQueueDec_.pop();
376 }
377
PushInbufferDec(uint32_t index,uint32_t bufferSize)378 int32_t VDecEncNdkSample::PushInbufferDec(uint32_t index, uint32_t bufferSize)
379 {
380 if (vdec_ == nullptr) {
381 return AV_ERR_INVALID_VAL;
382 }
383 struct OH_AVCodecBufferAttr attr;
384 attr.offset = 0;
385 if (decInCnt_ == ES_LENGTH) {
386 attr.flags = AVCODEC_BUFFER_FLAGS_EOS;
387 attr.pts = 0;
388 attr.size = 0;
389 cout << "EOS Frame, frameCount = " << decInCnt_ << endl;
390 isDecInputEOS = true;
391 } else {
392 attr.pts = timeStampDec_;
393 attr.size = bufferSize;
394 if (isFirstDecFrame_) {
395 attr.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
396 isFirstDecFrame_ = false;
397 } else {
398 attr.flags = AVCODEC_BUFFER_FLAGS_NONE;
399 }
400 }
401 return OH_VideoDecoder_PushInputData(vdec_, index, attr);
402 }
403
InputFuncDec()404 void VDecEncNdkSample::InputFuncDec()
405 {
406 while (true) {
407 cout << "ENTER DEC IN" << endl;
408 if (!isDecRunning_.load()) {
409 break;
410 }
411 unique_lock<mutex> lock(vcodecSignal_->inMutexDec_);
412 vcodecSignal_->inCondDec_.wait(lock, [this]() { return vcodecSignal_->inQueueDec_.size() > 0; });
413 if (!isDecRunning_.load()) {
414 break;
415 }
416
417 uint32_t index = vcodecSignal_->inQueueDec_.front();
418 OH_AVMemory *buffer = reinterpret_cast<OH_AVMemory *>(vcodecSignal_->inBufferQueueDec_.front());
419 if (vcodecSignal_->isVdecFlushing_.load() || isDecInputEOS || buffer == nullptr) {
420 PopInqueueDec();
421 continue;
422 }
423 NDK_CHECK_AND_RETURN_LOG(testFile_ != nullptr && testFile_->is_open(), "Fatal: open file fail");
424 uint32_t bufferSize = 0;
425 if (decInCnt_ < ES_LENGTH) {
426 bufferSize = ES[decInCnt_];
427 char *fileBuffer = (char *)malloc(sizeof(char) * bufferSize + 1);
428 NDK_CHECK_AND_RETURN_LOG(fileBuffer != nullptr, "Fatal: malloc fail");
429 (void)testFile_->read(fileBuffer, bufferSize);
430 if (testFile_->eof()) {
431 free(fileBuffer);
432 cout << "Finish" << endl;
433 break;
434 }
435 if (memcpy_s(OH_AVMemory_GetAddr(buffer), OH_AVMemory_GetSize(buffer), fileBuffer, bufferSize) != EOK
436 || buffer == nullptr) {
437 free(fileBuffer);
438 PopInqueueDec();
439 continue;
440 }
441 free(fileBuffer);
442 }
443 if (PushInbufferDec(index, bufferSize) != AV_ERR_OK) {
444 cout << "Fatal: OH_VideoDecoder_PushInputData fail, exit" << endl;
445 vcodecSignal_->errorNum_ += 1;
446 } else {
447 decInCnt_++;
448 }
449 timeStampDec_ += SAMPLE_DURATION_US;
450 PopInqueueDec();
451 }
452 }
453
PopOutqueueDec()454 void VDecEncNdkSample::PopOutqueueDec()
455 {
456 if (vcodecSignal_ == nullptr) {
457 return;
458 }
459 vcodecSignal_->outQueueDec_.pop();
460 vcodecSignal_->flagQueueDec_.pop();
461 }
462
SendEncEos()463 void VDecEncNdkSample::SendEncEos()
464 {
465 if (vcodecSignal_ == nullptr || venc_== nullptr) {
466 return;
467 }
468 if (setEos) {
469 int32_t ret = OH_VideoEncoder_NotifyEndOfStream(venc_);
470 if (ret == 0) {
471 cout << "ENC IN: input EOS " << endl;
472 isEncInputEOS = true;
473 } else {
474 cout << "ENC IN: input EOS fail" << endl;
475 vcodecSignal_->errorNum_ += 1;
476 }
477 }
478 }
479
OutputFuncDec()480 void VDecEncNdkSample::OutputFuncDec()
481 {
482 while (true) {
483 if (!isDecRunning_.load()) {
484 break;
485 }
486 unique_lock<mutex> lock(vcodecSignal_->outMutexDec_);
487 vcodecSignal_->outCondDec_.wait(lock, [this]() { return vcodecSignal_->outQueueDec_.size() > 0; });
488 if (!isDecRunning_.load()) {
489 break;
490 }
491 if (vcodecSignal_->isVdecFlushing_.load() || vcodecSignal_->isVencFlushing_.load() || isEncInputEOS) {
492 PopOutqueueDec();
493 continue;
494 }
495
496 uint32_t index = vcodecSignal_->outQueueDec_.front();
497 uint32_t outflag = vcodecSignal_->flagQueueDec_.front();
498 if (outflag == 0) {
499 uint32_t ret;
500 if (needRender) {
501 ret = OH_VideoDecoder_RenderOutputData(vdec_, index);
502 } else {
503 ret = OH_VideoDecoder_FreeOutputData(vdec_, index);
504 }
505 if (ret == 0) {
506 decOutCnt_ += 1;
507 cout << "DEC OUT.: render output success, decOutCnt_ is " << decOutCnt_ << endl;
508 } else {
509 cout << "DEC OUT. Fatal: ReleaseOutputBuffer fail" << endl;
510 vcodecSignal_->errorNum_ += 1;
511 break;
512 }
513 } else {
514 cout << "DEC OUT.: output EOS" << endl;
515 isDecOutputEOS = true;
516 SendEncEos();
517 }
518 PopOutqueueDec();
519 }
520 }
521
CreateVideoEncoderByMime(std::string mimetype)522 struct OH_AVCodec* VDecEncNdkSample::CreateVideoEncoderByMime(std::string mimetype)
523 {
524 if (mimetype == "video/avc") {
525 venc_ = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC);
526 } else {
527 venc_ = OH_VideoEncoder_CreateByMime(mimetype.c_str());
528 }
529 NDK_CHECK_AND_RETURN_RET_LOG(venc_ != nullptr, nullptr, "Fatal: OH_VideoEncoder_CreateByMime");
530
531 if (vcodecSignal_ == nullptr) {
532 vcodecSignal_ = new VDecEncSignal();
533 NDK_CHECK_AND_RETURN_RET_LOG(vcodecSignal_ != nullptr, nullptr, "Fatal: No Memory");
534 }
535 cbEnc_.onError = VencAsyncError;
536 cbEnc_.onStreamChanged = VencAsyncStreamChanged;
537 cbEnc_.onNeedOutputData = VencAsyncNewOutputData;
538 int32_t ret = OH_VideoEncoder_SetCallback(venc_, cbEnc_, static_cast<void *>(vcodecSignal_));
539 NDK_CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, NULL, "Fatal: OH_VideoEncoder_SetCallback");
540 return venc_;
541 }
542
CreateVideoEncoderByName(std::string name)543 struct OH_AVCodec* VDecEncNdkSample::CreateVideoEncoderByName(std::string name)
544 {
545 venc_ = OH_VideoEncoder_CreateByName(name.c_str());
546 NDK_CHECK_AND_RETURN_RET_LOG(venc_ != nullptr, nullptr, "Fatal: OH_VideoEncoder_CreateByName");
547
548 if (vcodecSignal_ == nullptr) {
549 vcodecSignal_ = new VDecEncSignal();
550 NDK_CHECK_AND_RETURN_RET_LOG(vcodecSignal_ != nullptr, nullptr, "Fatal: No Memory");
551 }
552 cbEnc_.onError = VencAsyncError;
553 cbEnc_.onStreamChanged = VencAsyncStreamChanged;
554 cbEnc_.onNeedOutputData = VencAsyncNewOutputData;
555 int32_t ret = OH_VideoEncoder_SetCallback(venc_, cbEnc_, static_cast<void *>(vcodecSignal_));
556 NDK_CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, NULL, "Fatal: OH_VideoEncoder_SetCallback");
557 return venc_;
558 }
559
ConfigureEnc(struct OH_AVFormat * format)560 int32_t VDecEncNdkSample::ConfigureEnc(struct OH_AVFormat *format)
561 {
562 return OH_VideoEncoder_Configure(venc_, format);
563 }
564
SetParameterEnc(struct OH_AVFormat * format)565 int32_t VDecEncNdkSample::SetParameterEnc(struct OH_AVFormat *format)
566 {
567 return OH_VideoEncoder_SetParameter(venc_, format);
568 }
569
570
GetSurface()571 int32_t VDecEncNdkSample::GetSurface()
572 {
573 return OH_VideoEncoder_GetSurface(venc_, &nativeWindow_);
574 }
575
SetOutputSurface()576 int32_t VDecEncNdkSample::SetOutputSurface()
577 {
578 return OH_VideoDecoder_SetSurface(vdec_, nativeWindow_);
579 }
580
PrepareEnc()581 int32_t VDecEncNdkSample::PrepareEnc()
582 {
583 return OH_VideoEncoder_Prepare(venc_);
584 }
585
StartEnc()586 int32_t VDecEncNdkSample::StartEnc()
587 {
588 cout << "Enter enc start" << endl;
589 isEncRunning_.store(true);
590 if (outputLoopEnc_ == nullptr) {
591 outputLoopEnc_ = make_unique<thread>(&VDecEncNdkSample::OutputFuncEnc, this);
592 NDK_CHECK_AND_RETURN_RET_LOG(outputLoopEnc_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory");
593 }
594 cout << "Exit enc start" << endl;
595 return OH_VideoEncoder_Start(venc_);
596 }
597
StopEnc()598 int32_t VDecEncNdkSample::StopEnc()
599 {
600 cout << "Enter enc stop" << endl;
601 unique_lock<mutex> lock(vcodecSignal_->outMutexEnc_);
602 vcodecSignal_->isVencFlushing_.store(true);
603 lock.unlock();
604 int32_t ret = OH_VideoEncoder_Stop(venc_);
605 unique_lock<mutex> lockOut(vcodecSignal_->outMutexEnc_);
606 clearIntqueue(vcodecSignal_->outQueueEnc_);
607 clearIntqueue(vcodecSignal_->sizeQueueEnc_);
608 clearIntqueue(vcodecSignal_->flagQueueEnc_);
609 clearBufferqueue(vcodecSignal_->outBufferQueueEnc_);
610 vcodecSignal_->outCondEnc_.notify_all();
611 lockOut.unlock();
612 vcodecSignal_->isVencFlushing_.store(false);
613 cout << "Exit enc stop" << endl;
614 return ret;
615 }
616
FlushEnc()617 int32_t VDecEncNdkSample::FlushEnc()
618 {
619 cout << "Enter enc flush" << endl;
620 unique_lock<mutex> lock(vcodecSignal_->outMutexEnc_);
621 vcodecSignal_->isVencFlushing_.store(true);
622 lock.unlock();
623 int32_t ret = OH_VideoEncoder_Flush(venc_);
624 unique_lock<mutex> lockOut(vcodecSignal_->outMutexEnc_);
625 clearIntqueue(vcodecSignal_->outQueueEnc_);
626 clearIntqueue(vcodecSignal_->sizeQueueEnc_);
627 clearIntqueue(vcodecSignal_->flagQueueEnc_);
628 clearBufferqueue(vcodecSignal_->outBufferQueueEnc_);
629 vcodecSignal_->outCondEnc_.notify_all();
630 lockOut.unlock();
631 vcodecSignal_->isVencFlushing_.store(false);
632 cout << "Exit enc flush" << endl;
633 return ret;
634 }
635
ResetEnc()636 int32_t VDecEncNdkSample::ResetEnc()
637 {
638 cout << "Enter enc reset" << endl;
639 unique_lock<mutex> lock(vcodecSignal_->outMutexEnc_);
640 vcodecSignal_->isVencFlushing_.store(true);
641 lock.unlock();
642 int32_t ret = OH_VideoEncoder_Reset(venc_);
643 unique_lock<mutex> lockOut(vcodecSignal_->outMutexEnc_);
644 clearIntqueue(vcodecSignal_->outQueueEnc_);
645 clearIntqueue(vcodecSignal_->sizeQueueEnc_);
646 clearIntqueue(vcodecSignal_->flagQueueEnc_);
647 clearBufferqueue(vcodecSignal_->outBufferQueueEnc_);
648 vcodecSignal_->outCondEnc_.notify_all();
649 lockOut.unlock();
650 vcodecSignal_->isVencFlushing_.store(false);
651 cout << "exit enc reset" << endl;
652 return ret;
653 }
654
ReleaseEnc()655 int32_t VDecEncNdkSample::ReleaseEnc()
656 {
657 cout << "Enter enc release" << endl;
658 isEncRunning_.store(false);
659 if (outputLoopEnc_ != nullptr && outputLoopEnc_->joinable()) {
660 unique_lock<mutex> lock(vcodecSignal_->outMutexEnc_);
661 vcodecSignal_->outQueueEnc_.push(STOPNUM);
662 vcodecSignal_->outCondEnc_.notify_all();
663 lock.unlock();
664 outputLoopEnc_->join();
665 outputLoopEnc_.reset();
666 }
667 cout << "exit enc release" << endl;
668 OH_VideoEncoder_Destroy(venc_);
669 cout << "exit enc destroy" << endl;
670 return AV_ERR_OK;
671 }
672
PopOutqueueEnc()673 void VDecEncNdkSample::PopOutqueueEnc()
674 {
675 if (vcodecSignal_ == nullptr) {
676 return;
677 }
678 vcodecSignal_->outQueueEnc_.pop();
679 vcodecSignal_->sizeQueueEnc_.pop();
680 vcodecSignal_->flagQueueEnc_.pop();
681 vcodecSignal_->outBufferQueueEnc_.pop();
682 }
683
WriteToFile()684 int32_t VDecEncNdkSample::WriteToFile()
685 {
686 auto buffer = vcodecSignal_->outBufferQueueEnc_.front();
687 uint32_t size = vcodecSignal_->sizeQueueEnc_.front();
688 if (buffer == nullptr) {
689 cout << "getOutPut Buffer fail" << endl;
690 return AV_ERR_INVALID_VAL;
691 }
692 FILE *outFile = fopen(outFile_.c_str(), "a");
693 if (outFile == nullptr) {
694 cout << "dump data fail" << endl;
695 return AV_ERR_INVALID_VAL;
696 } else {
697 fwrite(OH_AVMemory_GetAddr(buffer), 1, size, outFile);
698 }
699 return fclose(outFile);
700 }
701
OutputFuncEnc()702 void VDecEncNdkSample::OutputFuncEnc()
703 {
704 while (true) {
705 if (!isEncRunning_.load()) {
706 break;
707 }
708 unique_lock<mutex> lock(vcodecSignal_->outMutexEnc_);
709 vcodecSignal_->outCondEnc_.wait(lock, [this]() { return vcodecSignal_->outQueueEnc_.size() > 0; });
710 if (!isEncRunning_.load()) {
711 break;
712 }
713 if (vcodecSignal_->isVencFlushing_.load() || isEncOutputEOS) {
714 PopOutqueueEnc();
715 continue;
716 }
717
718 uint32_t index = vcodecSignal_->outQueueEnc_.front();
719 uint32_t encOutflag = vcodecSignal_->flagQueueEnc_.front();
720 if (encOutflag == 1) {
721 cout << "ENC get output EOS" << endl;
722 isEncOutputEOS = true;
723 } else {
724 if (WriteToFile() != 0) {
725 PopOutqueueEnc();
726 continue;
727 }
728 uint32_t ret = OH_VideoEncoder_FreeOutputData(venc_, index);
729 if (ret != 0) {
730 cout << "Fatal: ReleaseOutputBuffer fail" << endl;
731 vcodecSignal_->errorNum_ += 1;
732 } else {
733 encOutCnt_ += 1;
734 cout << "ENC OUT.: output success, encOutCnt_ is " << encOutCnt_ << endl;
735 }
736 }
737 PopOutqueueEnc();
738 }
739 }
740
CalcuError()741 int32_t VDecEncNdkSample::CalcuError()
742 {
743 cout << "errorNum_ is :" << vcodecSignal_->errorNum_ << endl;
744 cout << "decInCnt_ is :" << decInCnt_ << endl;
745 cout << "decOutCnt_ is :" << decOutCnt_ << endl;
746 cout << "encOutCnt_ is :" << encOutCnt_ << endl;
747 cout << "DEC inQueueDec_.size() is " << vcodecSignal_->inQueueDec_.size() << endl;
748 cout << "DEC outQueueDec_.size() is " << vcodecSignal_->outQueueDec_.size() << endl;
749 cout << "DEC outBufferQueueDec_.size() is " << vcodecSignal_->outBufferQueueDec_.size() << endl;
750 cout << "DEC outQueueEnc_.size() is " << vcodecSignal_->outQueueEnc_.size() << endl;
751 return vcodecSignal_->errorNum_ ;
752 }
753
GetFrameCount()754 int32_t VDecEncNdkSample::GetFrameCount()
755 {
756 return encOutCnt_;
757 }
GetEncEosState()758 bool VDecEncNdkSample::GetEncEosState()
759 {
760 return isEncOutputEOS;
761 }
GetDecEosState()762 bool VDecEncNdkSample::GetDecEosState()
763 {
764 return isDecOutputEOS;
765 }