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