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