• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }