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 "AudioDecoderDemoCommon.h"
17 #include <iostream>
18 #include <fstream>
19 #include <cstdio>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <dlfcn.h>
23 #include "avcodec_errors.h"
24 #include "media_description.h"
25
26 using namespace OHOS;
27 using namespace OHOS::MediaAVCodec;
28 using namespace std;
29
30 namespace OHOS {
31 namespace MediaAVCodec {
OnError(OH_AVCodec * codec,int32_t errorCode,void * userData)32 void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData)
33 {
34 (void)codec;
35 (void)errorCode;
36 (void)userData;
37 cout << "Error received, errorCode:" << errorCode << endl;
38 }
39
OnOutputFormatChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)40 void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
41 {
42 (void)codec;
43 (void)format;
44 (void)userData;
45 cout << "OnOutputFormatChanged received" << endl;
46 }
47
OnInputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,void * userData)48 void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, void *userData)
49 {
50 (void)codec;
51 ADecSignal *signal_ = static_cast<ADecSignal *>(userData);
52 cout << "OnInputBufferAvailable received, index:" << index << endl;
53 unique_lock<mutex> lock(signal_->inMutex_);
54 signal_->inQueue_.push(index);
55 signal_->inBufferQueue_.push(data);
56 signal_->inCond_.notify_all();
57 }
58
OnOutputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,OH_AVCodecBufferAttr * attr,void * userData)59 void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, OH_AVCodecBufferAttr *attr,
60 void *userData)
61 {
62 (void)codec;
63 ADecSignal *signal_ = static_cast<ADecSignal *>(userData);
64 cout << "OnOutputBufferAvailable received, index:" << index << endl;
65 unique_lock<mutex> lock(signal_->outMutex_);
66 signal_->outQueue_.push(index);
67 signal_->outBufferQueue_.push(data);
68 if (attr) {
69 cout << "OnOutputBufferAvailable received, index:" << index << ", attr->size:" << attr->size << endl;
70 signal_->attrQueue_.push(*attr);
71 } else {
72 cout << "OnOutputBufferAvailable error, attr is nullptr!" << endl;
73 }
74 signal_->outCond_.notify_all();
75 }
76 } // namespace MediaAVCodec
77 } // namespace OHOS
78
AudioDecoderDemo()79 AudioDecoderDemo::AudioDecoderDemo()
80 {
81 signal_ = new ADecSignal();
82 innersignal_ = make_shared<ADecSignal>();
83 }
84
~AudioDecoderDemo()85 AudioDecoderDemo::~AudioDecoderDemo()
86 {
87 if (signal_) {
88 delete signal_;
89 signal_ = nullptr;
90 }
91 }
92
setTimerFlag(int32_t flag)93 void AudioDecoderDemo::setTimerFlag(int32_t flag)
94 {
95 timerFlag = flag;
96 }
97
NativeCreateByMime(const char * mime)98 OH_AVCodec *AudioDecoderDemo::NativeCreateByMime(const char *mime)
99 {
100 return OH_AudioDecoder_CreateByMime(mime);
101 }
102
NativeCreateByName(const char * name)103 OH_AVCodec *AudioDecoderDemo::NativeCreateByName(const char *name)
104 {
105 return OH_AudioDecoder_CreateByName(name);
106 }
107
NativeDestroy(OH_AVCodec * codec)108 OH_AVErrCode AudioDecoderDemo::NativeDestroy(OH_AVCodec *codec)
109 {
110 stopThread();
111 return OH_AudioDecoder_Destroy(codec);
112 }
113
NativeSetCallback(OH_AVCodec * codec,OH_AVCodecAsyncCallback callback)114 OH_AVErrCode AudioDecoderDemo::NativeSetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback)
115 {
116 return OH_AudioDecoder_SetCallback(codec, callback, signal_);
117 }
118
NativeConfigure(OH_AVCodec * codec,OH_AVFormat * format)119 OH_AVErrCode AudioDecoderDemo::NativeConfigure(OH_AVCodec *codec, OH_AVFormat *format)
120 {
121 return OH_AudioDecoder_Configure(codec, format);
122 }
123
NativePrepare(OH_AVCodec * codec)124 OH_AVErrCode AudioDecoderDemo::NativePrepare(OH_AVCodec *codec)
125 {
126 return OH_AudioDecoder_Prepare(codec);
127 }
128
NativeStart(OH_AVCodec * codec)129 OH_AVErrCode AudioDecoderDemo::NativeStart(OH_AVCodec *codec)
130 {
131 if (!isRunning_.load()) {
132 cout << "Native Start!!!" << endl;
133 isRunning_.store(true);
134 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::updateInputData, this);
135 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::updateOutputData, this);
136 }
137 OH_AVErrCode ret = OH_AudioDecoder_Start(codec);
138 sleep(1);
139 return ret;
140 }
141
NativeStop(OH_AVCodec * codec)142 OH_AVErrCode AudioDecoderDemo::NativeStop(OH_AVCodec *codec)
143 {
144 stopThread();
145 return OH_AudioDecoder_Stop(codec);
146 }
147
NativeFlush(OH_AVCodec * codec)148 OH_AVErrCode AudioDecoderDemo::NativeFlush(OH_AVCodec *codec)
149 {
150 stopThread();
151 return OH_AudioDecoder_Flush(codec);
152 }
153
NativeReset(OH_AVCodec * codec)154 OH_AVErrCode AudioDecoderDemo::NativeReset(OH_AVCodec *codec)
155 {
156 stopThread();
157 return OH_AudioDecoder_Reset(codec);
158 }
159
NativeGetOutputDescription(OH_AVCodec * codec)160 OH_AVFormat *AudioDecoderDemo::NativeGetOutputDescription(OH_AVCodec *codec)
161 {
162 return OH_AudioDecoder_GetOutputDescription(codec);
163 }
164
NativeSetParameter(OH_AVCodec * codec,OH_AVFormat * format)165 OH_AVErrCode AudioDecoderDemo::NativeSetParameter(OH_AVCodec *codec, OH_AVFormat *format)
166 {
167 return OH_AudioDecoder_SetParameter(codec, format);
168 }
169
NativePushInputData(OH_AVCodec * codec,uint32_t index,OH_AVCodecBufferAttr attr)170 OH_AVErrCode AudioDecoderDemo::NativePushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr)
171 {
172 return OH_AudioDecoder_PushInputData(codec, index, attr);
173 }
174
NativeFreeOutputData(OH_AVCodec * codec,uint32_t index)175 OH_AVErrCode AudioDecoderDemo::NativeFreeOutputData(OH_AVCodec *codec, uint32_t index)
176 {
177 return OH_AudioDecoder_FreeOutputData(codec, index);
178 }
179
NativeIsValid(OH_AVCodec * codec,bool * isVaild)180 OH_AVErrCode AudioDecoderDemo::NativeIsValid(OH_AVCodec *codec, bool *isVaild)
181 {
182 return OH_AudioDecoder_IsValid(codec, isVaild);
183 }
184
stopThread()185 void AudioDecoderDemo::stopThread()
186 {
187 isRunning_.store(false);
188 if (inputLoop_ != nullptr && inputLoop_->joinable()) {
189 unique_lock<mutex> lock(signal_->inMutex_);
190 signal_->inCond_.notify_all();
191 lock.unlock();
192 inputLoop_->join();
193 inputLoop_ = nullptr;
194 }
195
196 if (outputLoop_ != nullptr && outputLoop_->joinable()) {
197 unique_lock<mutex> lock(signal_->outMutex_);
198 signal_->outCond_.notify_all();
199 lock.unlock();
200 outputLoop_->join();
201 outputLoop_ = nullptr;
202 }
203
204 while (!signal_->inQueue_.empty())
205 signal_->inQueue_.pop();
206 while (!signal_->outQueue_.empty())
207 signal_->outQueue_.pop();
208 while (!signal_->inBufferQueue_.empty())
209 signal_->inBufferQueue_.pop();
210 while (!signal_->outBufferQueue_.empty())
211 signal_->outBufferQueue_.pop();
212 while (!signal_->attrQueue_.empty())
213 signal_->attrQueue_.pop();
214
215 while (!inIndexQueue_.empty())
216 inIndexQueue_.pop();
217 while (!inBufQueue_.empty())
218 inBufQueue_.pop();
219 while (!outIndexQueue_.empty())
220 outIndexQueue_.pop();
221 }
222
updateInputData()223 void AudioDecoderDemo::updateInputData()
224 {
225 while (isRunning_.load()) {
226 unique_lock<mutex> lock(signal_->inMutex_);
227 signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); });
228
229 if (!isRunning_.load()) {
230 cout << "input wait to stop, exit" << endl;
231 break;
232 }
233
234 cout << "inQueue_ size is " << signal_->inQueue_.size() << endl;
235 cout << "inputBuf size is " << signal_->inBufferQueue_.size() << endl;
236 uint32_t inputIndex = signal_->inQueue_.front();
237 inIndexQueue_.push(inputIndex);
238 signal_->inQueue_.pop();
239
240 uint8_t *inputBuf = OH_AVMemory_GetAddr(signal_->inBufferQueue_.front());
241 inBufQueue_.push(inputBuf);
242 signal_->inBufferQueue_.pop();
243 cout << "input index is " << inputIndex << endl;
244 }
245 }
246
updateOutputData()247 void AudioDecoderDemo::updateOutputData()
248 {
249 while (isRunning_.load()) {
250 unique_lock<mutex> lock(signal_->outMutex_);
251 signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); });
252
253 if (!isRunning_.load()) {
254 cout << "output wait to stop, exit" << endl;
255 break;
256 }
257 cout << "outQueue_ size is " << signal_->outQueue_.size() << ", outBufferQueue_ size is "
258 << signal_->outBufferQueue_.size() << ", attrQueue_ size is " << signal_->attrQueue_.size() << endl;
259 uint32_t outputIndex = signal_->outQueue_.front();
260 outIndexQueue_.push(outputIndex);
261 signal_->outBufferQueue_.pop();
262 signal_->attrQueue_.pop();
263 signal_->outQueue_.pop();
264 cout << "output index is " << outputIndex << endl;
265 }
266 }
267
InnerUpdateInputData()268 void AudioDecoderDemo::InnerUpdateInputData()
269 {
270 while (isRunning_.load()) {
271 unique_lock<mutex> lock(innersignal_->inMutex_);
272 innersignal_->inCond_.wait(lock,
273 [this]() { return (innersignal_->inQueue_.size() > 0 || !isRunning_.load()); });
274
275 if (!isRunning_.load()) {
276 cout << "input wait to stop, exit" << endl;
277 break;
278 }
279
280 uint32_t inputIndex = innersignal_->inQueue_.front();
281 inIndexQueue_.push(inputIndex);
282 innersignal_->inQueue_.pop();
283 cout << "input index is " << inputIndex << endl;
284 }
285 }
286
InnerUpdateOutputData()287 void AudioDecoderDemo::InnerUpdateOutputData()
288 {
289 while (isRunning_.load()) {
290 unique_lock<mutex> lock(innersignal_->outMutex_);
291 innersignal_->outCond_.wait(lock,
292 [this]() { return (innersignal_->outQueue_.size() > 0 || !isRunning_.load()); });
293
294 if (!isRunning_.load()) {
295 cout << "output wait to stop, exit" << endl;
296 break;
297 }
298
299 uint32_t outputIndex = innersignal_->outQueue_.front();
300 outIndexQueue_.push(outputIndex);
301 innersignal_->outQueue_.pop();
302 innersignal_->infoQueue_.pop();
303 innersignal_->flagQueue_.pop();
304 cout << "output index is " << outputIndex << endl;
305 }
306 }
307
NativeGetInputIndex()308 uint32_t AudioDecoderDemo::NativeGetInputIndex()
309 {
310 while (inIndexQueue_.empty())
311 sleep(1);
312 uint32_t inputIndex = inIndexQueue_.front();
313 inIndexQueue_.pop();
314 return inputIndex;
315 }
316
NativeGetInputBuf()317 uint8_t *AudioDecoderDemo::NativeGetInputBuf()
318 {
319 while (inBufQueue_.empty())
320 sleep(1);
321 uint8_t *inputBuf = inBufQueue_.front();
322 inBufQueue_.pop();
323 return inputBuf;
324 }
325
NativeGetOutputIndex()326 uint32_t AudioDecoderDemo::NativeGetOutputIndex()
327 {
328 if (outIndexQueue_.empty()) {
329 return ERROR_INDEX;
330 }
331 uint32_t outputIndex = outIndexQueue_.front();
332 outIndexQueue_.pop();
333 return outputIndex;
334 }
335
HandleEOS(const uint32_t & index)336 void AudioDecoderDemo::HandleEOS(const uint32_t &index)
337 {
338 OH_AVCodecBufferAttr info;
339 info.size = 0;
340 info.offset = 0;
341 info.pts = 0;
342 info.flags = AVCODEC_BUFFER_FLAGS_EOS;
343
344 gettimeofday(&inputStart, NULL);
345 av_packet_unref(&pkt);
346 gettimeofday(&inputEnd, NULL);
347 otherTime += (inputEnd.tv_sec - inputStart.tv_sec) + (inputEnd.tv_usec - inputStart.tv_usec) / DEFAULT_TIME_NUM;
348
349 if (timerFlag == TIMER_INPUT) {
350 gettimeofday(&start, NULL);
351 }
352 OH_AudioDecoder_PushInputData(audioDec_, index, info);
353 if (timerFlag == TIMER_INPUT) {
354 gettimeofday(&end, NULL);
355 totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / DEFAULT_TIME_NUM;
356 runTimes++;
357 }
358 }
359
NativePushInput(uint32_t index,OH_AVMemory * buffer)360 int32_t AudioDecoderDemo::NativePushInput(uint32_t index, OH_AVMemory *buffer)
361 {
362 OH_AVCodecBufferAttr info;
363 info.size = pkt.size;
364 info.offset = 0;
365 info.pts = pkt.pts;
366 memcpy_s(OH_AVMemory_GetAddr(buffer), pkt.size, pkt.data, pkt.size);
367
368 int32_t ret = AV_ERR_OK;
369 if (isFirstFrame_) {
370 info.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
371 if (timerFlag == TIMER_INPUT) {
372 gettimeofday(&start, NULL);
373 }
374 ret = OH_AudioDecoder_PushInputData(audioDec_, index, info);
375 if (timerFlag == TIMER_INPUT) {
376 gettimeofday(&end, NULL);
377 totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / DEFAULT_TIME_NUM;
378 runTimes++;
379 }
380 isFirstFrame_ = false;
381 } else {
382 info.flags = AVCODEC_BUFFER_FLAGS_NONE;
383 if (timerFlag == TIMER_INPUT) {
384 gettimeofday(&start, NULL);
385 }
386 ret = OH_AudioDecoder_PushInputData(audioDec_, index, info);
387 if (timerFlag == TIMER_INPUT) {
388 gettimeofday(&end, NULL);
389 totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / DEFAULT_TIME_NUM;
390 runTimes++;
391 }
392 }
393 return ret;
394 }
395
NativeInputFunc()396 void AudioDecoderDemo::NativeInputFunc()
397 {
398 while (isRunning_.load()) {
399 unique_lock<mutex> lock(signal_->inMutex_);
400 cout << "input wait !!!" << endl;
401 signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); });
402
403 if (!isRunning_.load()) {
404 break;
405 }
406
407 uint32_t index = signal_->inQueue_.front();
408 auto buffer = signal_->inBufferQueue_.front();
409
410 gettimeofday(&inputStart, NULL);
411 int32_t ret = av_read_frame(fmpt_ctx, &pkt);
412 gettimeofday(&inputEnd, NULL);
413 otherTime += (inputEnd.tv_sec - inputStart.tv_sec) + (inputEnd.tv_usec - inputStart.tv_usec) / DEFAULT_TIME_NUM;
414
415 if (ret < 0) {
416 HandleEOS(index);
417 signal_->inBufferQueue_.pop();
418 signal_->inQueue_.pop();
419 std::cout << "end buffer\n";
420 break;
421 }
422 std::cout << "start read frame: size:" << pkt.size << ",pts:" << pkt.pts << "\n";
423
424 ret = NativePushInput(index, buffer);
425
426 av_packet_unref(&pkt);
427 signal_->inQueue_.pop();
428 signal_->inBufferQueue_.pop();
429
430 if (ret != AV_ERR_OK) {
431 cout << "Fatal error, exit! ret = " << ret << endl;
432 break;
433 }
434 }
435 }
436
NativeGetDescription()437 void AudioDecoderDemo::NativeGetDescription()
438 {
439 if (isGetOutputDescription && curFormat == nullptr) {
440 cout << "before GetOutputDescription" << endl;
441 curFormat = OH_AudioDecoder_GetOutputDescription(audioDec_);
442 }
443 if (timerFlag == TIMER_GETOUTPUTDESCRIPTION) {
444 gettimeofday(&start, NULL);
445 curFormat = OH_AudioDecoder_GetOutputDescription(audioDec_);
446 gettimeofday(&end, NULL);
447 totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / DEFAULT_TIME_NUM;
448 runTimes++;
449 }
450 }
451
NativeWriteOutput(std::ofstream & pcmFile,uint32_t index,OH_AVCodecBufferAttr attr,OH_AVMemory * data)452 void AudioDecoderDemo::NativeWriteOutput(std::ofstream &pcmFile, uint32_t index, OH_AVCodecBufferAttr attr,
453 OH_AVMemory *data)
454 {
455 if (data != nullptr) {
456 cout << "OutputFunc write file,buffer index" << index << ", data size = :" << attr.size << endl;
457
458 gettimeofday(&outputStart, NULL);
459 pcmFile.write(reinterpret_cast<char *>(OH_AVMemory_GetAddr(data)), attr.size);
460 gettimeofday(&outputEnd, NULL);
461 totalTime +=
462 (outputEnd.tv_sec - outputStart.tv_sec) + (outputEnd.tv_usec - outputStart.tv_usec) / DEFAULT_TIME_NUM;
463 runTimes++;
464 }
465
466 if (attr.flags == AVCODEC_BUFFER_FLAGS_EOS) {
467 cout << "decode eos" << endl;
468 isRunning_.store(false);
469 }
470 }
471
NativeOutputFunc()472 void AudioDecoderDemo::NativeOutputFunc()
473 {
474 std::ofstream pcmFile;
475 pcmFile.open(outputFilePath, std::ios::out | std::ios::binary);
476 if (!pcmFile.is_open()) {
477 std::cout << "open " << outputFilePath << " failed!" << std::endl;
478 }
479
480 while (isRunning_.load()) {
481 unique_lock<mutex> lock(signal_->outMutex_);
482 cout << "output wait !!!" << endl;
483 signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); });
484
485 if (!isRunning_.load()) {
486 cout << "wait to stop, exit" << endl;
487 break;
488 }
489
490 uint32_t index = signal_->outQueue_.front();
491 OH_AVCodecBufferAttr attr = signal_->attrQueue_.front();
492 OH_AVMemory *data = signal_->outBufferQueue_.front();
493
494 NativeWriteOutput(pcmFile, index, attr, data);
495
496 signal_->outBufferQueue_.pop();
497 signal_->attrQueue_.pop();
498 signal_->outQueue_.pop();
499
500 if (timerFlag == TIMER_FREEOUTPUT) {
501 gettimeofday(&start, NULL);
502 }
503 OH_AVErrCode ret = OH_AudioDecoder_FreeOutputData(audioDec_, index);
504 if (timerFlag == TIMER_FREEOUTPUT) {
505 gettimeofday(&end, NULL);
506 totalTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / DEFAULT_TIME_NUM;
507 runTimes++;
508 }
509 if (ret != AV_ERR_OK) {
510 cout << "Fatal: FreeOutputData fail" << endl;
511 break;
512 }
513 NativeGetDescription();
514 }
515 pcmFile.close();
516 }
517
NativeGetVorbisConf(OH_AVFormat * format)518 void AudioDecoderDemo::NativeGetVorbisConf(OH_AVFormat *format)
519 {
520 int32_t ret = 0;
521 int audio_stream_index = -1;
522 for (uint32_t i = 0; i < fmpt_ctx->nb_streams; i++) {
523 if (fmpt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
524 audio_stream_index = i;
525 break;
526 }
527 }
528 if (audio_stream_index == -1) {
529 cout << "Error: Cannot find audio stream" << endl;
530 exit(1);
531 }
532 AVCodecParameters *codec_params = fmpt_ctx->streams[audio_stream_index]->codecpar;
533 const AVCodec *codec = avcodec_find_decoder(codec_params->codec_id);
534 if (codec == NULL) {
535 cout << "Error: Cannot find decoder for codec " << codec_params->codec_id << endl;
536 exit(1);
537 }
538 codec_ctx = avcodec_alloc_context3(codec);
539 if (codec_ctx == NULL) {
540 cout << "Error: Cannot allocate codec context" << endl;
541 exit(1);
542 }
543 ret = avcodec_parameters_to_context(codec_ctx, codec_params);
544 if (ret < 0) {
545 cout << "Error: Cannot set codec context parameters" << endl;
546 exit(1);
547 }
548 ret = avcodec_open2(codec_ctx, codec, NULL);
549 if (ret < 0) {
550 cout << "Error: Cannot open codec" << endl;
551 exit(1);
552 }
553 OH_AVFormat_SetBuffer(format, OH_MD_KEY_CODEC_CONFIG, (uint8_t *)(codec_ctx->extradata), codec_ctx->extradata_size);
554 }
555
NativeCreateToStart(const char * name,OH_AVFormat * format)556 void AudioDecoderDemo::NativeCreateToStart(const char *name, OH_AVFormat *format)
557 {
558 OH_AVErrCode result;
559 int32_t ret = 0;
560 audioDec_ = OH_AudioDecoder_CreateByName(name);
561 if (audioDec_ == nullptr) {
562 cout << "create fail!!" << endl;
563 return;
564 }
565
566 ret = avformat_open_input(&fmpt_ctx, inputFilePath.c_str(), NULL, NULL);
567 if (ret < 0) {
568 std::cout << "open " << inputFilePath << " failed!!!" << ret << "\n";
569 exit(1);
570 }
571 if (avformat_find_stream_info(fmpt_ctx, NULL) < 0) {
572 std::cout << "get file stream failed"
573 << "\n";
574 exit(1);
575 }
576
577 cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
578 result = OH_AudioDecoder_SetCallback(audioDec_, cb_, signal_);
579 cout << "SetCallback ret is: " << result << endl;
580
581 if (strcmp(name, "OH.Media.Codec.Decoder.Audio.Vorbis") == 0) {
582 NativeGetVorbisConf(format);
583 }
584
585 result = OH_AudioDecoder_Configure(audioDec_, format);
586 cout << "Configure ret is: " << result << endl;
587 if (result < 0) {
588 cout << "Configure fail! ret is " << result << endl;
589 return;
590 }
591
592 frame = av_frame_alloc();
593 av_init_packet(&pkt);
594 pkt.data = NULL;
595 pkt.size = 0;
596
597 result = OH_AudioDecoder_Prepare(audioDec_);
598 cout << "Prepare ret is: " << result << endl;
599
600 // Start
601 isRunning_.store(true);
602 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeInputFunc, this);
603 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeOutputFunc, this);
604 result = OH_AudioDecoder_Start(audioDec_);
605 cout << "Start ret is: " << result << endl;
606 }
607
NativeStopDec()608 void AudioDecoderDemo::NativeStopDec()
609 {
610 OH_AVErrCode result;
611
612 result = OH_AudioDecoder_Stop(audioDec_);
613 cout << "Stop ret is: " << result << endl;
614
615 result = OH_AudioDecoder_Destroy(audioDec_);
616 cout << "Destroy ret is: " << result << endl;
617
618 stopThread();
619 }
620
NativeCloseFFmpeg()621 void AudioDecoderDemo::NativeCloseFFmpeg()
622 {
623 av_frame_free(&frame);
624 if (codec_ctx != nullptr) {
625 avcodec_free_context(&codec_ctx);
626 }
627 avformat_close_input(&fmpt_ctx);
628 }
629
NativeFFmpegConf(const char * name,OH_AVFormat * format)630 void AudioDecoderDemo::NativeFFmpegConf(const char *name, OH_AVFormat *format)
631 {
632 int ret = avformat_open_input(&fmpt_ctx, inputFilePath.c_str(), NULL, NULL);
633 if (ret < 0) {
634 std::cout << "open " << inputFilePath << " failed!!!" << ret << "\n";
635 exit(1);
636 }
637 if (avformat_find_stream_info(fmpt_ctx, NULL) < 0) {
638 std::cout << "get file stream failed"
639 << "\n";
640 exit(1);
641 }
642
643 if (strcmp(name, "OH.Media.Codec.Decoder.Audio.Vorbis") == 0) {
644 NativeGetVorbisConf(format);
645 }
646
647 frame = av_frame_alloc();
648 av_init_packet(&pkt);
649 pkt.data = NULL;
650 pkt.size = 0;
651 }
652
NativeStopAndClear()653 void AudioDecoderDemo::NativeStopAndClear()
654 {
655 NativeStopDec();
656 NativeCloseFFmpeg();
657 }
658
NativeRunCase(std::string inputFile,std::string outputFile,const char * name,OH_AVFormat * format)659 void AudioDecoderDemo::NativeRunCase(std::string inputFile, std::string outputFile, const char *name,
660 OH_AVFormat *format)
661 {
662 inputFilePath = inputFile;
663 outputFilePath = outputFile;
664
665 NativeCreateToStart(name, format);
666
667 while (isRunning_.load()) {
668 sleep(1);
669 }
670
671 NativeStopAndClear();
672
673 if (timerFlag != 0) {
674 cout << "total time is " << totalTime << ", run times is " << runTimes << endl;
675 }
676 }
677
NativeRunCaseWithoutCreate(OH_AVCodec * handle,std::string inputFile,std::string outputFile,OH_AVFormat * format,const char * name,bool needConfig)678 void AudioDecoderDemo::NativeRunCaseWithoutCreate(OH_AVCodec *handle, std::string inputFile, std::string outputFile,
679 OH_AVFormat *format, const char *name, bool needConfig)
680 {
681 inputFilePath = inputFile;
682 outputFilePath = outputFile;
683
684 audioDec_ = handle;
685 OH_AVErrCode result;
686
687 int32_t ret = avformat_open_input(&fmpt_ctx, inputFilePath.c_str(), NULL, NULL);
688 if (ret < 0) {
689 std::cout << "open " << inputFilePath << " failed!!!" << ret << "\n";
690 exit(1);
691 }
692 if (avformat_find_stream_info(fmpt_ctx, NULL) < 0) {
693 std::cout << "get file stream failed"
694 << "\n";
695 exit(1);
696 }
697
698 if (needConfig) {
699 result = OH_AudioDecoder_Configure(audioDec_, format);
700 cout << "Configure ret is: " << result << endl;
701 if (result < 0) {
702 cout << "Configure fail! ret is " << result << endl;
703 return;
704 }
705
706 result = OH_AudioDecoder_Prepare(audioDec_);
707 cout << "Prepare ret is: " << result << endl;
708 }
709
710 frame = av_frame_alloc();
711 av_init_packet(&pkt);
712 pkt.data = NULL;
713 pkt.size = 0;
714
715 // Start
716 isRunning_.store(true);
717 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeInputFunc, this);
718 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeOutputFunc, this);
719 result = OH_AudioDecoder_Start(audioDec_);
720 cout << "Start ret is: " << result << endl;
721
722 while (isRunning_.load()) {
723 sleep(1);
724 }
725
726 stopThread();
727
728 NativeCloseFFmpeg();
729 }
730
NativeRunCasePerformance(std::string inputFile,std::string outputFile,const char * name,OH_AVFormat * format)731 void AudioDecoderDemo::NativeRunCasePerformance(std::string inputFile, std::string outputFile, const char *name,
732 OH_AVFormat *format)
733 {
734 inputFilePath = inputFile;
735 outputFilePath = outputFile;
736
737 gettimeofday(&startTime, NULL);
738 audioDec_ = OH_AudioDecoder_CreateByName(name);
739 gettimeofday(&start, NULL);
740 if (audioDec_ == nullptr) {
741 cout << "create fail!!" << endl;
742 return;
743 }
744
745 OH_AVErrCode result;
746 NativeFFmpegConf(name, format);
747
748 cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
749 gettimeofday(&end, NULL);
750 otherTime += (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / DEFAULT_TIME_NUM;
751
752 result = OH_AudioDecoder_SetCallback(audioDec_, cb_, signal_);
753 cout << "SetCallback ret is: " << result << endl;
754
755 result = OH_AudioDecoder_Configure(audioDec_, format);
756 cout << "Configure ret is: " << result << endl;
757 if (result < 0) {
758 cout << "Configure fail! ret is " << result << endl;
759 return;
760 }
761
762 result = OH_AudioDecoder_Prepare(audioDec_);
763 cout << "Prepare ret is: " << result << endl;
764
765 // Start
766 isRunning_.store(true);
767 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeInputFunc, this);
768 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeOutputFunc, this);
769 result = OH_AudioDecoder_Start(audioDec_);
770 cout << "Start ret is: " << result << endl;
771
772 while (isRunning_.load()) {
773 sleep(1);
774 }
775
776 NativeStopDec();
777 gettimeofday(&endTime, NULL);
778 totalTime = (endTime.tv_sec - start.tv_sec) + (startTime.tv_usec - start.tv_usec) / DEFAULT_TIME_NUM - otherTime;
779
780 NativeCloseFFmpeg();
781 cout << "cur decoder is " << name << ", total time is " << totalTime << endl;
782 }
783
NativeRunCaseFlush(std::string inputFile,std::string outputFileFirst,std::string outputFileSecond,const char * name,OH_AVFormat * format)784 void AudioDecoderDemo::NativeRunCaseFlush(std::string inputFile, std::string outputFileFirst,
785 std::string outputFileSecond, const char *name, OH_AVFormat *format)
786 {
787 inputFilePath = inputFile;
788 outputFilePath = outputFileFirst;
789
790 OH_AVErrCode result;
791 NativeCreateToStart(name, format);
792
793 while (isRunning_.load()) {
794 sleep(1);
795 }
796
797 // Stop
798 stopThread();
799 NativeCloseFFmpeg();
800
801 // Flush
802 result = OH_AudioDecoder_Flush(audioDec_);
803 inputFilePath = inputFile;
804 outputFilePath = outputFileSecond;
805
806 NativeFFmpegConf(name, format);
807
808 isRunning_.store(true);
809 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeInputFunc, this);
810 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeOutputFunc, this);
811 result = OH_AudioDecoder_Start(audioDec_);
812 cout << "Start ret is: " << result << endl;
813
814 while (isRunning_.load()) {
815 sleep(1);
816 }
817
818 NativeStopAndClear();
819 }
820
NativeRunCaseReset(std::string inputFile,std::string outputFileFirst,std::string outputFileSecond,const char * name,OH_AVFormat * format)821 void AudioDecoderDemo::NativeRunCaseReset(std::string inputFile, std::string outputFileFirst,
822 std::string outputFileSecond, const char *name, OH_AVFormat *format)
823 {
824 inputFilePath = inputFile;
825 outputFilePath = outputFileFirst;
826
827 OH_AVErrCode result;
828 NativeCreateToStart(name, format);
829
830 while (isRunning_.load()) {
831 sleep(1);
832 }
833
834 // Stop
835 stopThread();
836 NativeCloseFFmpeg();
837
838 // Reset
839 result = OH_AudioDecoder_Reset(audioDec_);
840
841 inputFilePath = inputFile;
842 outputFilePath = outputFileSecond;
843
844 NativeFFmpegConf(name, format);
845
846 result = OH_AudioDecoder_Configure(audioDec_, format);
847 if (result < 0) {
848 cout << "Configure fail! ret is " << result << endl;
849 return;
850 }
851
852 result = OH_AudioDecoder_Prepare(audioDec_);
853 cout << "Prepare ret is: " << result << endl;
854
855 isRunning_.store(true);
856 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeInputFunc, this);
857 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeOutputFunc, this);
858 result = OH_AudioDecoder_Start(audioDec_);
859 cout << "Start ret is: " << result << endl;
860
861 while (isRunning_.load()) {
862 sleep(1);
863 }
864
865 NativeStopAndClear();
866 }
867
NativeRunCaseGetOutputDescription(std::string inputFile,std::string outputFile,const char * name,OH_AVFormat * format)868 OH_AVFormat *AudioDecoderDemo::NativeRunCaseGetOutputDescription(std::string inputFile, std::string outputFile,
869 const char *name, OH_AVFormat *format)
870 {
871 inputFilePath = inputFile;
872 outputFilePath = outputFile;
873 isGetOutputDescription = true;
874
875 NativeCreateToStart(name, format);
876
877 while (isRunning_.load()) {
878 sleep(1);
879 }
880
881 NativeStopAndClear();
882 return curFormat;
883 }
884
TestReadDatFile(uint32_t index,OH_AVMemory * buffer)885 int32_t AudioDecoderDemo::TestReadDatFile(uint32_t index, OH_AVMemory *buffer)
886 {
887 int64_t size;
888 int64_t pts;
889
890 inputFile_.read(reinterpret_cast<char *>(&size), sizeof(size));
891 if (inputFile_.eof() || inputFile_.gcount() == 0) {
892 OH_AVCodecBufferAttr info;
893 info.size = 0;
894 info.offset = 0;
895 info.pts = 0;
896 info.flags = AVCODEC_BUFFER_FLAGS_EOS;
897
898 OH_AudioDecoder_PushInputData(audioDec_, index, info);
899 signal_->inBufferQueue_.pop();
900 signal_->inQueue_.pop();
901 std::cout << "end buffer\n";
902 return CODE_ERROR;
903 }
904 if (inputFile_.gcount() != sizeof(size)) {
905 cout << "Fatal: read size fail" << endl;
906 return CODE_ERROR;
907 }
908 inputFile_.read(reinterpret_cast<char *>(&pts), sizeof(pts));
909 if (inputFile_.gcount() != sizeof(pts)) {
910 cout << "Fatal: read pts fail" << endl;
911 return CODE_ERROR;
912 }
913 inputFile_.read((char *)OH_AVMemory_GetAddr(buffer), size);
914 if (inputFile_.gcount() != size) {
915 cout << "Fatal: read buffer fail" << endl;
916 return CODE_ERROR;
917 }
918
919 OH_AVCodecBufferAttr info;
920 info.size = size;
921 info.offset = 0;
922 info.pts = pts;
923
924 int32_t ret = AVCS_ERR_OK;
925 if (isFirstFrame_) {
926 info.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
927 ret = OH_AudioDecoder_PushInputData(audioDec_, index, info);
928 isFirstFrame_ = false;
929 } else {
930 info.flags = AVCODEC_BUFFER_FLAGS_NONE;
931 ret = OH_AudioDecoder_PushInputData(audioDec_, index, info);
932 }
933 return ret;
934 }
935
TestInputFunc()936 void AudioDecoderDemo::TestInputFunc()
937 {
938 while (isRunning_.load()) {
939 unique_lock<mutex> lock(signal_->inMutex_);
940 signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); });
941
942 if (!isRunning_.load()) {
943 break;
944 }
945
946 uint32_t index = signal_->inQueue_.front();
947 auto buffer = signal_->inBufferQueue_.front();
948
949 int32_t ret = TestReadDatFile(index, buffer);
950
951 signal_->inQueue_.pop();
952 signal_->inBufferQueue_.pop();
953 frameCount_++;
954
955 if (ret != AVCS_ERR_OK) {
956 cout << "Fatal error, exit!!! ret is " << ret << endl;
957 break;
958 }
959 }
960 inputFile_.close();
961 }
962
TestRunCase(std::string inputFile,std::string outputFile,const char * name,OH_AVFormat * format)963 void AudioDecoderDemo::TestRunCase(std::string inputFile, std::string outputFile, const char *name, OH_AVFormat *format)
964 {
965 inputFilePath = inputFile;
966 outputFilePath = outputFile;
967
968 inputFile_.open(inputFilePath, std::ios::binary);
969
970 audioDec_ = OH_AudioDecoder_CreateByName(name);
971 if (audioDec_ == nullptr) {
972 cout << "create fail!!" << endl;
973 return;
974 }
975 OH_AVErrCode result;
976
977 cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
978 result = OH_AudioDecoder_SetCallback(audioDec_, cb_, signal_);
979 cout << "SetCallback ret is: " << result << endl;
980
981 result = OH_AudioDecoder_Configure(audioDec_, format);
982 cout << "Configure ret is: " << result << endl;
983 if (result < 0) {
984 cout << "Configure fail! ret is " << result << endl;
985 return;
986 }
987
988 result = OH_AudioDecoder_Prepare(audioDec_);
989 cout << "Prepare ret is: " << result << endl;
990
991 // Start
992 isRunning_.store(true);
993 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::TestInputFunc, this);
994 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::NativeOutputFunc, this);
995 result = OH_AudioDecoder_Start(audioDec_);
996 cout << "Start ret is: " << result << endl;
997
998 while (isRunning_.load()) {
999 sleep(1);
1000 }
1001
1002 NativeStopAndClear();
1003 }
1004
TestFFmpeg(std::string inputFile)1005 void AudioDecoderDemo::TestFFmpeg(std::string inputFile)
1006 {
1007 int32_t ret = 0;
1008 ret = avformat_open_input(&fmpt_ctx, inputFile.c_str(), NULL, NULL);
1009 if (ret < 0) {
1010 std::cout << "open " << inputFile << " failed!!!" << ret << "\n";
1011 exit(1);
1012 }
1013 if (avformat_find_stream_info(fmpt_ctx, NULL) < 0) {
1014 std::cout << "get file stream failed"
1015 << "\n";
1016 exit(1);
1017 }
1018
1019 frame = av_frame_alloc();
1020 av_init_packet(&pkt);
1021 pkt.data = NULL;
1022 pkt.size = 0;
1023
1024 while (true) {
1025 ret = av_read_frame(fmpt_ctx, &pkt);
1026 if (ret < 0) {
1027 av_packet_unref(&pkt);
1028 break;
1029 }
1030 av_packet_unref(&pkt);
1031 }
1032
1033 av_frame_free(&frame);
1034 if (codec_ctx != nullptr) {
1035 avcodec_free_context(&codec_ctx);
1036 }
1037 avformat_close_input(&fmpt_ctx);
1038 }
1039
1040 // inner
1041
InnerCreateByMime(const std::string & mime)1042 int32_t AudioDecoderDemo::InnerCreateByMime(const std::string &mime)
1043 {
1044 inneraudioDec_ = AudioDecoderFactory::CreateByMime(mime);
1045 if (inneraudioDec_ == nullptr) {
1046 std::cout << "InnerDecoder create failed!" << std::endl;
1047 return AVCS_ERR_INVALID_OPERATION;
1048 }
1049 std::cout << "InnerCreateByMime" << endl;
1050 return AVCS_ERR_OK;
1051 }
1052
InnerCreateByName(const std::string & name)1053 int32_t AudioDecoderDemo::InnerCreateByName(const std::string &name)
1054 {
1055 inneraudioDec_ = AudioDecoderFactory::CreateByName(name);
1056 if (inneraudioDec_ == nullptr) {
1057 std::cout << "InnerDecoder create failed!" << std::endl;
1058 return AVCS_ERR_INVALID_OPERATION;
1059 }
1060 std::cout << "InnerCreateByName" << endl;
1061 return AVCS_ERR_OK;
1062 }
1063
InnerSetCallback(const std::shared_ptr<AVCodecCallback> & callback)1064 int32_t AudioDecoderDemo::InnerSetCallback(const std::shared_ptr<AVCodecCallback> &callback)
1065 {
1066 return inneraudioDec_->SetCallback(callback);
1067 }
1068
InnerConfigure(const Format & format)1069 int32_t AudioDecoderDemo::InnerConfigure(const Format &format)
1070 {
1071 cout << "InnerConfigure" << endl;
1072 if (inneraudioDec_ == nullptr) {
1073 std::cout << "InnerDecoder create failed!" << std::endl;
1074 return AVCS_ERR_INVALID_OPERATION;
1075 }
1076 return inneraudioDec_->Configure(format);
1077 }
1078
InnerStart()1079 int32_t AudioDecoderDemo::InnerStart()
1080 {
1081 if (!isRunning_.load()) {
1082 cout << "InnerStart" << endl;
1083 isRunning_.store(true);
1084 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerUpdateInputData, this);
1085 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerUpdateOutputData, this);
1086 }
1087 int32_t ret = inneraudioDec_->Start();
1088 sleep(1);
1089 return ret;
1090 }
1091
InnerPrepare()1092 int32_t AudioDecoderDemo::InnerPrepare()
1093 {
1094 cout << "InnerPrepare" << endl;
1095 if (inneraudioDec_ == nullptr) {
1096 std::cout << "InnerDecoder create failed!" << std::endl;
1097 return AVCS_ERR_INVALID_OPERATION;
1098 }
1099 return inneraudioDec_->Prepare();
1100 }
1101
InnerStop()1102 int32_t AudioDecoderDemo::InnerStop()
1103 {
1104 cout << "InnerStop" << endl;
1105 InnerStopThread();
1106 return inneraudioDec_->Stop();
1107 }
1108
InnerFlush()1109 int32_t AudioDecoderDemo::InnerFlush()
1110 {
1111 cout << "InnerFlush" << endl;
1112 if (inneraudioDec_ == nullptr) {
1113 std::cout << "InnerDecoder create failed!" << std::endl;
1114 return AVCS_ERR_INVALID_OPERATION;
1115 }
1116 int32_t ret = inneraudioDec_->Flush();
1117
1118 while (!innersignal_->inQueue_.empty())
1119 innersignal_->inQueue_.pop();
1120 while (!innersignal_->inInnerBufQueue_.empty())
1121 innersignal_->inInnerBufQueue_.pop();
1122 while (!innersignal_->outInnerBufQueue_.empty())
1123 innersignal_->outInnerBufQueue_.pop();
1124 while (!innersignal_->outQueue_.empty())
1125 innersignal_->outQueue_.pop();
1126 while (!innersignal_->infoQueue_.empty())
1127 innersignal_->infoQueue_.pop();
1128 while (!innersignal_->flagQueue_.empty())
1129 innersignal_->flagQueue_.pop();
1130
1131 while (!inIndexQueue_.empty())
1132 inIndexQueue_.pop();
1133 while (!inBufQueue_.empty())
1134 inBufQueue_.pop();
1135 while (!outIndexQueue_.empty())
1136 outIndexQueue_.pop();
1137
1138 return ret;
1139 }
1140
InnerReset()1141 int32_t AudioDecoderDemo::InnerReset()
1142 {
1143 InnerStopThread();
1144 cout << "InnerReset" << endl;
1145 if (inneraudioDec_ == nullptr) {
1146 std::cout << "InnerDecoder create failed!" << std::endl;
1147 return AVCS_ERR_INVALID_OPERATION;
1148 }
1149 return inneraudioDec_->Reset();
1150 }
1151
InnerRelease()1152 int32_t AudioDecoderDemo::InnerRelease()
1153 {
1154 cout << "InnerRelease" << endl;
1155 if (inneraudioDec_ == nullptr) {
1156 std::cout << "InnerDecoder create failed!" << std::endl;
1157 return AVCS_ERR_INVALID_OPERATION;
1158 }
1159 return inneraudioDec_->Release();
1160 }
1161
InnerSetParameter(const Format & format)1162 int32_t AudioDecoderDemo::InnerSetParameter(const Format &format)
1163 {
1164 cout << "InnerSetParameter" << endl;
1165 if (inneraudioDec_ == nullptr) {
1166 std::cout << "InnerDecoder create failed!" << std::endl;
1167 return AVCS_ERR_INVALID_OPERATION;
1168 }
1169 return inneraudioDec_->SetParameter(format);
1170 }
1171
InnerDestroy()1172 int32_t AudioDecoderDemo::InnerDestroy()
1173 {
1174 int32_t ret = AVCS_ERR_INVALID_OPERATION;
1175 InnerStopThread();
1176 if (inneraudioDec_ != nullptr) {
1177 ret = inneraudioDec_->Release();
1178 }
1179 inneraudioDec_ = nullptr;
1180 return ret;
1181 }
1182
InnerQueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)1183 int32_t AudioDecoderDemo::InnerQueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
1184 {
1185 cout << "InnerQueueInputBuffer" << endl;
1186 return inneraudioDec_->QueueInputBuffer(index, info, flag);
1187 }
1188
InnerGetOutputFormat(Format & format)1189 int32_t AudioDecoderDemo::InnerGetOutputFormat(Format &format)
1190 {
1191 cout << "InnerGetOutputFormat" << endl;
1192 return inneraudioDec_->GetOutputFormat(format);
1193 }
1194
InnerReleaseOutputBuffer(uint32_t index)1195 int32_t AudioDecoderDemo::InnerReleaseOutputBuffer(uint32_t index)
1196 {
1197 cout << "InnerReleaseOutputBuffer" << endl;
1198 return inneraudioDec_->ReleaseOutputBuffer(index);
1199 }
1200
InnerStopThread()1201 void AudioDecoderDemo::InnerStopThread()
1202 {
1203 isRunning_.store(false);
1204 if (inputLoop_ != nullptr && inputLoop_->joinable()) {
1205 unique_lock<mutex> lock(innersignal_->inMutex_);
1206 innersignal_->inCond_.notify_all();
1207 lock.unlock();
1208 inputLoop_->join();
1209 inputLoop_ = nullptr;
1210 }
1211
1212 if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1213 unique_lock<mutex> lock(innersignal_->outMutex_);
1214 innersignal_->outCond_.notify_all();
1215 lock.unlock();
1216 outputLoop_->join();
1217 outputLoop_ = nullptr;
1218 }
1219
1220 while (!innersignal_->inQueue_.empty())
1221 innersignal_->inQueue_.pop();
1222 while (!innersignal_->inInnerBufQueue_.empty())
1223 innersignal_->inInnerBufQueue_.pop();
1224 while (!innersignal_->outInnerBufQueue_.empty())
1225 innersignal_->outInnerBufQueue_.pop();
1226 while (!innersignal_->outQueue_.empty())
1227 innersignal_->outQueue_.pop();
1228 while (!innersignal_->infoQueue_.empty())
1229 innersignal_->infoQueue_.pop();
1230 while (!innersignal_->flagQueue_.empty())
1231 innersignal_->flagQueue_.pop();
1232
1233 while (!inIndexQueue_.empty())
1234 inIndexQueue_.pop();
1235 while (!inBufQueue_.empty())
1236 inBufQueue_.pop();
1237 while (!outIndexQueue_.empty())
1238 outIndexQueue_.pop();
1239 }
1240
InnerInputFuncRead(uint32_t index)1241 uint32_t AudioDecoderDemo::InnerInputFuncRead(uint32_t index)
1242 {
1243 int32_t ret = av_read_frame(fmpt_ctx, &pkt);
1244 if (ret < 0) {
1245 AVCodecBufferInfo info;
1246 AVCodecBufferFlag flag;
1247 info.size = 0;
1248 info.offset = 0;
1249 info.presentationTimeUs = 0;
1250 flag = AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_EOS;
1251 av_packet_unref(&pkt);
1252 inneraudioDec_->QueueInputBuffer(index, info, flag);
1253 innersignal_->inQueue_.pop();
1254 std::cout << "end buffer\n";
1255 return 1;
1256 }
1257 std::cout << "start read frame: size:" << pkt.size << ", pts:" << pkt.pts << ", index:" << index << "\n";
1258 return 0;
1259 }
1260
InnerInputFunc()1261 void AudioDecoderDemo::InnerInputFunc()
1262 {
1263 while (isRunning_.load()) {
1264 std::unique_lock<std::mutex> lock(innersignal_->inMutex_);
1265 cout << "input wait !!!" << endl;
1266 innersignal_->inCond_.wait(lock,
1267 [this]() { return (innersignal_->inQueue_.size() > 0 || !isRunning_.load()); });
1268
1269 if (!isRunning_.load()) {
1270 break;
1271 }
1272
1273 uint32_t index = innersignal_->inQueue_.front();
1274 auto buffer = innersignal_->inInnerBufQueue_.front();
1275 if (buffer == nullptr) {
1276 cout << "buffer is nullptr" << endl;
1277 isRunning_ = false;
1278 break;
1279 }
1280
1281 uint32_t ret = InnerInputFuncRead(index);
1282 if (ret != 0)
1283 break;
1284
1285 AVCodecBufferInfo info;
1286 AVCodecBufferFlag flag;
1287
1288 info.size = pkt.size;
1289 info.offset = 0;
1290 info.presentationTimeUs = pkt.pts;
1291 std::cout << "start read frame: size:" << &pkt.data << "\n";
1292 memcpy_s(buffer->GetBase(), pkt.size, pkt.data, pkt.size);
1293
1294 ret = AVCS_ERR_OK;
1295 if (isFirstFrame_) {
1296 flag = AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_NONE;
1297 ret = inneraudioDec_->QueueInputBuffer(index, info, flag);
1298 isFirstFrame_ = false;
1299 } else {
1300 flag = AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_NONE;
1301 ret = inneraudioDec_->QueueInputBuffer(index, info, flag);
1302 }
1303
1304 innersignal_->inQueue_.pop();
1305 innersignal_->inInnerBufQueue_.pop();
1306 std::cout << "QueueInputBuffer " << index << "\n";
1307 if (ret != AVCS_ERR_OK) {
1308 cout << "Fatal error, exit" << endl;
1309 isRunning_ = false;
1310 break;
1311 }
1312 }
1313 }
1314
InnerOutputFunc()1315 void AudioDecoderDemo::InnerOutputFunc()
1316 {
1317 std::ofstream pcmFile;
1318 pcmFile.open(outputFilePath, std::ios::out | std::ios::binary);
1319 if (!pcmFile.is_open()) {
1320 std::cout << "open " << outputFilePath << " failed!" << std::endl;
1321 }
1322 while (isRunning_.load()) {
1323 unique_lock<mutex> lock(innersignal_->outMutex_);
1324 cout << "output wait !!!" << endl;
1325 innersignal_->outCond_.wait(lock,
1326 [this]() { return (innersignal_->outQueue_.size() > 0 || !isRunning_.load()); });
1327
1328 if (!isRunning_.load()) {
1329 cout << "wait to stop, exit" << endl;
1330 break;
1331 }
1332 uint32_t index = innersignal_->outQueue_.front();
1333 auto buffer = innersignal_->outInnerBufQueue_.front();
1334 auto attr = innersignal_->infoQueue_.front();
1335 auto flag = innersignal_->flagQueue_.front();
1336 std::cout << "GetOutputBuffer : " << buffer << "\n";
1337 if (buffer != nullptr) {
1338 cout << "OutputFunc write file, buffer index = " << index << ", data size = " << attr.size << endl;
1339 pcmFile.write(reinterpret_cast<char *>(buffer->GetBase()), attr.size);
1340 }
1341 if (flag == AVCODEC_BUFFER_FLAG_EOS) {
1342 cout << "decode eos" << endl;
1343 isRunning_.store(false);
1344 }
1345 innersignal_->outQueue_.pop();
1346 innersignal_->outInnerBufQueue_.pop();
1347 innersignal_->infoQueue_.pop();
1348 innersignal_->flagQueue_.pop();
1349 if (inneraudioDec_->ReleaseOutputBuffer(index) != AVCS_ERR_OK) {
1350 cout << "Fatal: ReleaseOutputBuffer fail" << endl;
1351 break;
1352 }
1353 }
1354 pcmFile.close();
1355 }
1356
InnerRunCaseOHVorbis(const std::string & name,Format & format)1357 void AudioDecoderDemo::InnerRunCaseOHVorbis(const std::string &name, Format &format)
1358 {
1359 int ret;
1360 if (name == "OH.Media.Codec.Decoder.Audio.Vorbis") {
1361 cout << "vorbis" << endl;
1362 int audio_stream_index = -1;
1363 for (uint32_t i = 0; i < fmpt_ctx->nb_streams; i++) {
1364 if (fmpt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
1365 audio_stream_index = i;
1366 break;
1367 }
1368 }
1369 if (audio_stream_index == -1) {
1370 cout << "Error: Cannot find audio stream" << endl;
1371 exit(1);
1372 }
1373
1374 cout << "audio_stream_index " << audio_stream_index << endl;
1375 AVCodecParameters *codec_params = fmpt_ctx->streams[audio_stream_index]->codecpar;
1376 const AVCodec *codec = avcodec_find_decoder(codec_params->codec_id);
1377 if (codec == NULL) {
1378 cout << "Error: Cannot find decoder for codec " << codec_params->codec_id << endl;
1379 exit(1);
1380 }
1381
1382 codec_ctx = avcodec_alloc_context3(codec);
1383 if (codec_ctx == NULL) {
1384 cout << "Error: Cannot allocate codec context" << endl;
1385 exit(1);
1386 }
1387 ret = avcodec_parameters_to_context(codec_ctx, codec_params);
1388 if (ret < 0) {
1389 cout << "Error: Cannot set codec context parameters" << endl;
1390 exit(1);
1391 }
1392 ret = avcodec_open2(codec_ctx, codec, NULL);
1393 if (ret < 0) {
1394 cout << "Error: Cannot open codec" << endl;
1395 exit(1);
1396 }
1397
1398 format.PutBuffer(MediaDescriptionKey::MD_KEY_CODEC_CONFIG, (uint8_t *)(codec_ctx->extradata),
1399 codec_ctx->extradata_size);
1400 }
1401 frame = av_frame_alloc();
1402 av_init_packet(&pkt);
1403 pkt.data = NULL;
1404 pkt.size = 0;
1405 }
1406
InnerRunCasePre()1407 int AudioDecoderDemo::InnerRunCasePre()
1408 {
1409 int result;
1410
1411 result = InnerPrepare();
1412 cout << "InnerPrepare ret is: " << result << endl;
1413
1414 // Start
1415 isRunning_.store(true);
1416 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerInputFunc, this);
1417 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerOutputFunc, this);
1418 result = inneraudioDec_->Start();
1419 cout << "Start ret is: " << result << endl;
1420
1421 while (isRunning_.load()) {
1422 sleep(1);
1423 }
1424
1425 // Stop
1426 isRunning_.store(false);
1427 if (inputLoop_ != nullptr && inputLoop_->joinable()) {
1428 unique_lock<mutex> lock(innersignal_->inMutex_);
1429 innersignal_->inCond_.notify_all();
1430 lock.unlock();
1431 inputLoop_->join();
1432 }
1433
1434 if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1435 unique_lock<mutex> lock(innersignal_->outMutex_);
1436 innersignal_->outCond_.notify_all();
1437 lock.unlock();
1438 outputLoop_->join();
1439 }
1440 result = inneraudioDec_->Stop();
1441 cout << "Stop ret is: " << result << endl;
1442
1443 result = InnerDestroy();
1444 cout << "Destroy ret is: " << result << endl;
1445 InnerStopThread();
1446 av_frame_free(&frame);
1447 avcodec_free_context(&codec_ctx);
1448 avformat_close_input(&fmpt_ctx);
1449
1450 return 0;
1451 }
1452
InnerRunCase(std::string inputFile,std::string outputFile,const std::string & name,Format & format)1453 void AudioDecoderDemo::InnerRunCase(std::string inputFile, std::string outputFile, const std::string &name,
1454 Format &format)
1455 {
1456 inputFilePath = inputFile;
1457 outputFilePath = outputFile;
1458
1459 InnerCreateByName(name);
1460 if (inneraudioDec_ == nullptr) {
1461 cout << "create fail!!" << endl;
1462 return;
1463 }
1464
1465 int32_t ret = 0;
1466 int32_t result;
1467 ret = avformat_open_input(&fmpt_ctx, inputFilePath.c_str(), NULL, NULL);
1468 if (ret < 0) {
1469 std::cout << "open " << inputFilePath << " failed!!!" << ret << "\n";
1470 exit(1);
1471 }
1472 if (avformat_find_stream_info(fmpt_ctx, NULL) < 0) {
1473 std::cout << "get file stream failed"
1474 << "\n";
1475 exit(1);
1476 }
1477 InnerRunCaseOHVorbis(name, format);
1478
1479 innersignal_ = getSignal();
1480 cout << "innersignal_: " << innersignal_ << endl;
1481 innercb_ = make_unique<InnerADecDemoCallback>(innersignal_);
1482 result = InnerSetCallback(innercb_);
1483 cout << "SetCallback ret is: " << result << endl;
1484
1485 result = InnerConfigure(format);
1486 cout << "Configure ret is: " << result << endl;
1487 if (result != 0) {
1488 cout << "Configure fail!!" << endl;
1489 return;
1490 }
1491 ret = InnerRunCasePre();
1492 if (ret != 0)
1493 return;
1494 }
1495
InnerRunCaseFlushAlloc(Format & format)1496 void AudioDecoderDemo::InnerRunCaseFlushAlloc(Format &format)
1497 {
1498 int result;
1499 frame = av_frame_alloc();
1500 av_init_packet(&pkt);
1501 pkt.data = NULL;
1502 pkt.size = 0;
1503
1504 innersignal_ = getSignal();
1505 cout << "innersignal_: " << innersignal_ << endl;
1506 innercb_ = make_unique<InnerADecDemoCallback>(innersignal_);
1507 result = InnerSetCallback(innercb_);
1508 cout << "SetCallback ret is: " << result << endl;
1509
1510 result = InnerConfigure(format);
1511 cout << "Configure ret is: " << result << endl;
1512 if (result != 0) {
1513 cout << "Configure fail!!" << endl;
1514 }
1515 }
1516
InnerRunCaseFlushOHVorbis(const std::string & name,Format & format)1517 void AudioDecoderDemo::InnerRunCaseFlushOHVorbis(const std::string &name, Format &format)
1518 {
1519 int ret;
1520 if (name == "OH.Media.Codec.Decoder.Audio.Vorbis") {
1521 int audio_stream_index = -1;
1522 for (uint32_t i = 0; i < fmpt_ctx->nb_streams; i++) {
1523 if (fmpt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
1524 audio_stream_index = i;
1525 break;
1526 }
1527 }
1528 if (audio_stream_index == -1) {
1529 cout << "Error: Cannot find audio stream" << endl;
1530 exit(1);
1531 }
1532
1533 AVCodecParameters *codec_params = fmpt_ctx->streams[audio_stream_index]->codecpar;
1534 const AVCodec *codec = avcodec_find_decoder(codec_params->codec_id);
1535 if (codec == NULL) {
1536 cout << "Error: Cannot find decoder for codec " << codec_params->codec_id << endl;
1537 exit(1);
1538 }
1539
1540 codec_ctx = avcodec_alloc_context3(codec);
1541 if (codec_ctx == NULL) {
1542 cout << "Error: Cannot allocate codec context" << endl;
1543 exit(1);
1544 }
1545 ret = avcodec_parameters_to_context(codec_ctx, codec_params);
1546 if (ret < 0) {
1547 cout << "Error: Cannot set codec context parameters" << endl;
1548 exit(1);
1549 }
1550 ret = avcodec_open2(codec_ctx, codec, NULL);
1551 if (ret < 0) {
1552 cout << "Error: Cannot open codec" << endl;
1553 exit(1);
1554 }
1555
1556 format.PutBuffer(MediaDescriptionKey::MD_KEY_CODEC_CONFIG.data(), (uint8_t *)(codec_ctx->extradata),
1557 codec_ctx->extradata_size);
1558 }
1559 InnerRunCaseFlushAlloc(format);
1560 }
1561
InnerRunCaseFlushPre()1562 int AudioDecoderDemo::InnerRunCaseFlushPre()
1563 {
1564 int result = InnerPrepare();
1565 cout << "InnerPrepare ret is: " << result << endl;
1566
1567 isRunning_.store(true);
1568 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerInputFunc, this);
1569 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerOutputFunc, this);
1570 result = inneraudioDec_->Start();
1571 cout << "Start ret is: " << result << endl;
1572
1573 while (isRunning_.load()) {
1574 sleep(1);
1575 }
1576
1577 isRunning_.store(false);
1578 if (inputLoop_ != nullptr && inputLoop_->joinable()) {
1579 unique_lock<mutex> lock(innersignal_->inMutex_);
1580 innersignal_->inCond_.notify_all();
1581 lock.unlock();
1582 inputLoop_->join();
1583 }
1584
1585 if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1586 unique_lock<mutex> lock(innersignal_->outMutex_);
1587 innersignal_->outCond_.notify_all();
1588 lock.unlock();
1589 outputLoop_->join();
1590 }
1591 InnerStopThread();
1592 av_frame_free(&frame);
1593 avcodec_free_context(&codec_ctx);
1594 avformat_close_input(&fmpt_ctx);
1595 return 0;
1596 }
1597
InnerRunCaseFlushPost()1598 void AudioDecoderDemo::InnerRunCaseFlushPost()
1599 {
1600 int result;
1601 frame = av_frame_alloc();
1602 av_init_packet(&pkt);
1603 pkt.data = NULL;
1604 pkt.size = 0;
1605
1606 isRunning_.store(true);
1607 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerInputFunc, this);
1608 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerOutputFunc, this);
1609 result = inneraudioDec_->Start();
1610 cout << "Start ret is: " << result << endl;
1611
1612 while (isRunning_.load()) {
1613 sleep(1);
1614 }
1615
1616 isRunning_.store(false);
1617 if (inputLoop_ != nullptr && inputLoop_->joinable()) {
1618 unique_lock<mutex> lock(innersignal_->inMutex_);
1619
1620 innersignal_->inCond_.notify_all();
1621 lock.unlock();
1622 inputLoop_->join();
1623 }
1624
1625 if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1626 unique_lock<mutex> lock(innersignal_->outMutex_);
1627 innersignal_->outCond_.notify_all();
1628 lock.unlock();
1629 outputLoop_->join();
1630 }
1631 result = inneraudioDec_->Stop();
1632 cout << "Stop ret is: " << result << endl;
1633
1634 result = InnerDestroy();
1635 cout << "Destroy ret is: " << result << endl;
1636
1637 av_frame_free(&frame);
1638 avcodec_free_context(&codec_ctx);
1639 avformat_close_input(&fmpt_ctx);
1640 }
1641
InnerRunCaseFlush(std::string inputFile,std::string outputFileFirst,std::string outputFileSecond,const std::string & name,Format & format)1642 void AudioDecoderDemo::InnerRunCaseFlush(std::string inputFile, std::string outputFileFirst,
1643 std::string outputFileSecond, const std::string &name, Format &format)
1644 {
1645 inputFilePath = inputFile;
1646 outputFilePath = outputFileFirst;
1647
1648 InnerCreateByName(name);
1649 if (inneraudioDec_ == nullptr) {
1650 cout << "create fail!!" << endl;
1651 return;
1652 }
1653
1654 int32_t ret = 0;
1655 ret = avformat_open_input(&fmpt_ctx, inputFilePath.c_str(), NULL, NULL);
1656 if (ret < 0) {
1657 std::cout << "open " << inputFilePath << " failed!!!" << ret << "\n";
1658 exit(1);
1659 }
1660 if (avformat_find_stream_info(fmpt_ctx, NULL) < 0) {
1661 std::cout << "get file stream failed"
1662 << "\n";
1663 exit(1);
1664 }
1665 InnerRunCaseFlushOHVorbis(name, format);
1666
1667 ret = InnerRunCaseFlushPre();
1668 if (ret != 0)
1669 return;
1670
1671 InnerFlush();
1672 inputFilePath = inputFile;
1673 outputFilePath = outputFileSecond;
1674 ret = avformat_open_input(&fmpt_ctx, inputFilePath.c_str(), NULL, NULL);
1675 if (ret < 0) {
1676 std::cout << "open " << inputFilePath << " failed!!!" << ret << "\n";
1677 exit(1);
1678 }
1679
1680 if (avformat_find_stream_info(fmpt_ctx, NULL) < 0) {
1681 std::cout << "get file stream failed"
1682 << "\n";
1683 exit(1);
1684 }
1685 InnerRunCaseFlushPost();
1686 }
1687
InnerRunCaseResetAlloc(Format & format)1688 void AudioDecoderDemo::InnerRunCaseResetAlloc(Format &format)
1689 {
1690 int result;
1691 frame = av_frame_alloc();
1692 av_init_packet(&pkt);
1693 pkt.data = NULL;
1694 pkt.size = 0;
1695
1696 innersignal_ = getSignal();
1697 cout << "innersignal_: " << innersignal_ << endl;
1698 innercb_ = make_unique<InnerADecDemoCallback>(innersignal_);
1699 result = InnerSetCallback(innercb_);
1700 cout << "SetCallback ret is: " << result << endl;
1701
1702 result = InnerConfigure(format);
1703 cout << "Configure ret is: " << result << endl;
1704 if (result != 0) {
1705 cout << "Configure fail!!" << endl;
1706 return;
1707 }
1708 }
1709
InnerRunCaseResetOHVorbis(const std::string & name,Format & format)1710 void AudioDecoderDemo::InnerRunCaseResetOHVorbis(const std::string &name, Format &format)
1711 {
1712 int ret;
1713 if (name == "OH.Media.Codec.Decoder.Audio.Vorbis") {
1714 int audio_stream_index = -1;
1715 for (uint32_t i = 0; i < fmpt_ctx->nb_streams; i++) {
1716 if (fmpt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
1717 audio_stream_index = i;
1718 break;
1719 }
1720 }
1721 if (audio_stream_index == -1) {
1722 cout << "Error: Cannot find audio stream" << endl;
1723 exit(1);
1724 }
1725 AVCodecParameters *codec_params = fmpt_ctx->streams[audio_stream_index]->codecpar;
1726 const AVCodec *codec = avcodec_find_decoder(codec_params->codec_id);
1727 if (codec == NULL) {
1728 cout << "Error: Cannot find decoder for codec " << codec_params->codec_id << endl;
1729 exit(1);
1730 }
1731
1732 codec_ctx = avcodec_alloc_context3(codec);
1733 if (codec_ctx == NULL) {
1734 cout << "Error: Cannot allocate codec context" << endl;
1735 exit(1);
1736 }
1737 ret = avcodec_parameters_to_context(codec_ctx, codec_params);
1738 if (ret < 0) {
1739 cout << "Error: Cannot set codec context parameters" << endl;
1740 exit(1);
1741 }
1742 ret = avcodec_open2(codec_ctx, codec, NULL);
1743 if (ret < 0) {
1744 cout << "Error: Cannot open codec" << endl;
1745 exit(1);
1746 }
1747
1748 format.PutBuffer(MediaDescriptionKey::MD_KEY_CODEC_CONFIG.data(), (uint8_t *)(codec_ctx->extradata),
1749 codec_ctx->extradata_size);
1750 }
1751
1752 InnerRunCaseResetAlloc(format);
1753 }
InnerRunCaseResetPre()1754 int AudioDecoderDemo::InnerRunCaseResetPre()
1755 {
1756 int result = InnerPrepare();
1757 cout << "InnerPrepare ret is: " << result << endl;
1758
1759 isRunning_.store(true);
1760 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerInputFunc, this);
1761 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerOutputFunc, this);
1762 result = inneraudioDec_->Start();
1763 cout << "Start ret is: " << result << endl;
1764
1765 while (isRunning_.load()) {
1766 sleep(1);
1767 }
1768
1769 isRunning_.store(false);
1770 if (inputLoop_ != nullptr && inputLoop_->joinable()) {
1771 unique_lock<mutex> lock(innersignal_->inMutex_);
1772 innersignal_->inCond_.notify_all();
1773 lock.unlock();
1774 inputLoop_->join();
1775 }
1776
1777 if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1778 unique_lock<mutex> lock(innersignal_->outMutex_);
1779 innersignal_->outCond_.notify_all();
1780 lock.unlock();
1781 outputLoop_->join();
1782 }
1783
1784 av_frame_free(&frame);
1785 avcodec_free_context(&codec_ctx);
1786 avformat_close_input(&fmpt_ctx);
1787
1788 return 0;
1789 }
1790
InnerRunCaseResetInPut()1791 void AudioDecoderDemo::InnerRunCaseResetInPut()
1792 {
1793 int ret = avformat_open_input(&fmpt_ctx, inputFilePath.c_str(), NULL, NULL);
1794 if (ret < 0) {
1795 std::cout << "open " << inputFilePath << " failed!!!" << ret << "\n";
1796 exit(1);
1797 }
1798 if (avformat_find_stream_info(fmpt_ctx, NULL) < 0) {
1799 std::cout << "get file stream failed"
1800 << "\n";
1801 exit(1);
1802 }
1803
1804 frame = av_frame_alloc();
1805 av_init_packet(&pkt);
1806 pkt.data = NULL;
1807 pkt.size = 0;
1808 }
1809
InnerRunCaseResetPost()1810 void AudioDecoderDemo::InnerRunCaseResetPost()
1811 {
1812 int result = InnerPrepare();
1813 cout << "InnerPrepare ret is: " << result << endl;
1814
1815 isRunning_.store(true);
1816 inputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerInputFunc, this);
1817 outputLoop_ = make_unique<thread>(&AudioDecoderDemo::InnerOutputFunc, this);
1818 result = inneraudioDec_->Start();
1819 cout << "Start ret is: " << result << endl;
1820
1821 while (isRunning_.load()) {
1822 sleep(1);
1823 }
1824
1825 isRunning_.store(false);
1826 if (inputLoop_ != nullptr && inputLoop_->joinable()) {
1827 unique_lock<mutex> lock(innersignal_->inMutex_);
1828 innersignal_->inCond_.notify_all();
1829 lock.unlock();
1830 inputLoop_->join();
1831 }
1832
1833 if (outputLoop_ != nullptr && outputLoop_->joinable()) {
1834 unique_lock<mutex> lock(innersignal_->outMutex_);
1835 innersignal_->outCond_.notify_all();
1836 lock.unlock();
1837 outputLoop_->join();
1838 }
1839 result = inneraudioDec_->Stop();
1840 cout << "Stop ret is: " << result << endl;
1841
1842 result = InnerDestroy();
1843 cout << "Destroy ret is: " << result << endl;
1844
1845 av_frame_free(&frame);
1846 avcodec_free_context(&codec_ctx);
1847 avformat_close_input(&fmpt_ctx);
1848 }
1849
InnerRunCaseReset(std::string inputFile,std::string outputFileFirst,std::string outputFileSecond,const std::string & name,Format & format)1850 void AudioDecoderDemo::InnerRunCaseReset(std::string inputFile, std::string outputFileFirst,
1851 std::string outputFileSecond, const std::string &name, Format &format)
1852 {
1853 int32_t result;
1854 inputFilePath = inputFile;
1855 outputFilePath = outputFileFirst;
1856
1857 InnerCreateByName(name);
1858 if (inneraudioDec_ == nullptr) {
1859 cout << "create fail!!" << endl;
1860 return;
1861 }
1862
1863 int32_t ret = 0;
1864 ret = avformat_open_input(&fmpt_ctx, inputFilePath.c_str(), NULL, NULL);
1865 if (ret < 0) {
1866 std::cout << "open " << inputFilePath << " failed!!!" << ret << "\n";
1867 exit(1);
1868 }
1869 if (avformat_find_stream_info(fmpt_ctx, NULL) < 0) {
1870 std::cout << "get file stream failed"
1871 << "\n";
1872 exit(1);
1873 }
1874 InnerRunCaseResetOHVorbis(name, format);
1875
1876 ret = InnerRunCaseResetPre();
1877 if (ret != 0)
1878 return;
1879
1880 result = InnerReset();
1881 inputFilePath = inputFile;
1882 outputFilePath = outputFileSecond;
1883
1884 InnerRunCaseResetInPut();
1885 result = InnerConfigure(format);
1886 cout << "Configure ret is: " << result << endl;
1887 if (result != 0) {
1888 cout << "Configure fail!!" << endl;
1889 return;
1890 }
1891
1892 InnerRunCaseResetPost();
1893 }
1894
getSignal()1895 std::shared_ptr<ADecSignal> AudioDecoderDemo::getSignal()
1896 {
1897 return innersignal_;
1898 }
1899
InnerADecDemoCallback(shared_ptr<ADecSignal> signal)1900 InnerADecDemoCallback::InnerADecDemoCallback(shared_ptr<ADecSignal> signal) : innersignal_(signal) {}
1901
OnError(AVCodecErrorType errorType,int32_t errorCode)1902 void InnerADecDemoCallback::OnError(AVCodecErrorType errorType, int32_t errorCode)
1903 {
1904 cout << "Error received, errorType:" << errorType << " errorCode:" << errorCode << endl;
1905 }
1906
OnOutputFormatChanged(const Format & format)1907 void InnerADecDemoCallback::OnOutputFormatChanged(const Format &format)
1908 {
1909 (void)format;
1910 cout << "OnOutputFormatChanged received" << endl;
1911 }
1912
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)1913 void InnerADecDemoCallback::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
1914 {
1915 cout << "OnInputBufferAvailable received, index:" << index << endl;
1916 if (innersignal_ == nullptr) {
1917 std::cout << "buffer is null 1" << endl;
1918 }
1919 unique_lock<mutex> lock(innersignal_->inMutex_);
1920
1921 innersignal_->inQueue_.push(index);
1922 innersignal_->inInnerBufQueue_.push(buffer);
1923 if (innersignal_ == nullptr) {
1924 std::cout << "buffer is null 2" << endl;
1925 }
1926 innersignal_->inCond_.notify_all();
1927 if (innersignal_ == nullptr) {
1928 std::cout << "buffer is null 3" << endl;
1929 }
1930 }
1931
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)1932 void InnerADecDemoCallback::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
1933 std::shared_ptr<AVSharedMemory> buffer)
1934 {
1935 (void)info;
1936 (void)flag;
1937 cout << "OnOutputBufferAvailable received, index:" << index << endl;
1938 unique_lock<mutex> lock(innersignal_->outMutex_);
1939 innersignal_->outQueue_.push(index);
1940 innersignal_->infoQueue_.push(info);
1941 innersignal_->flagQueue_.push(flag);
1942 innersignal_->outInnerBufQueue_.push(buffer);
1943 innersignal_->outCond_.notify_all();
1944 }