1 /*
2  * Copyright (C) 2024 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 "audio_decoder_reset_demo.h"
17 #include <iostream>
18 #include <fstream>
19 #include <unistd.h>
20 #include <sys/stat.h>
21 #include <chrono>
22 #include <fcntl.h>
23 #include "avcodec_codec_name.h"
24 #include "avcodec_common.h"
25 #include "avcodec_errors.h"
26 #include "demo_log.h"
27 #include "media_description.h"
28 #include "native_avcodec_base.h"
29 #include "native_avformat.h"
30 #include "native_avbuffer.h"
31 #include "native_avmemory.h"
32 #include "securec.h"
33 
34 using namespace OHOS;
35 using namespace OHOS::MediaAVCodec;
36 using namespace OHOS::MediaAVCodec::AudioBufferDemo;
37 
38 using namespace std;
39 namespace {
40 constexpr uint32_t CHANNEL_COUNT = 2;
41 constexpr uint32_t SAMPLE_RATE = 44100;
42 constexpr uint32_t DEFAULT_AAC_TYPE = 1;
43 constexpr uint32_t AMRWB_SAMPLE_RATE = 16000;
44 constexpr uint32_t AMRNB_SAMPLE_RATE = 8000;
45 } // namespace
46 
OnError(OH_AVCodec * codec,int32_t errorCode,void * userData)47 static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData)
48 {
49     (void)codec;
50     (void)errorCode;
51     (void)userData;
52 }
53 
OnOutputFormatChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)54 static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
55 {
56     (void)codec;
57     (void)format;
58     (void)userData;
59     cout << "OnOutputFormatChanged received" << endl;
60 }
61 
OnInputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)62 static void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
63 {
64     (void)codec;
65     ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData);
66     unique_lock<mutex> lock(signal->inMutex_);
67     signal->inQueue_.push(index);
68     signal->inBufferQueue_.push(data);
69     signal->inCond_.notify_all();
70 }
71 
OnOutputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)72 static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
73 {
74     (void)codec;
75     ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData);
76     unique_lock<mutex> lock(signal->outMutex_);
77     signal->outQueue_.push(index);
78     signal->outBufferQueue_.push(data);
79     signal->outCond_.notify_all();
80 }
81 
SplitStringFully(const string & str,const string & separator)82 vector<string> SplitStringFully(const string& str, const string& separator)
83 {
84     vector<string> dest;
85     string substring;
86     string::size_type start = 0;
87     string::size_type index = str.find_first_of(separator, start);
88 
89     while (index != string::npos) {
90         substring = str.substr(start, index - start);
91         dest.push_back(substring);
92         start = str.find_first_not_of(separator, index);
93         if (start == string::npos) {
94             return dest;
95         }
96         index = str.find_first_of(separator, start);
97     }
98     substring = str.substr(start);
99     dest.push_back(substring);
100 
101     return dest;
102 }
103 
StringReplace(std::string & strBig,const std::string & strsrc,const std::string & strdst)104 void StringReplace(std::string& strBig, const std::string& strsrc, const std::string& strdst)
105 {
106     std::string::size_type pos = 0;
107     std::string::size_type srclen = strsrc.size();
108     std::string::size_type dstlen = strdst.size();
109 
110     while ((pos = strBig.find(strsrc, pos)) != std::string::npos) {
111         strBig.replace(pos, srclen, strdst);
112         pos += dstlen;
113     }
114 }
115 
InitFormat(OH_AVFormat * format)116 bool ADecBufferDemo::InitFormat(OH_AVFormat *format)
117 {
118     int32_t channelCount = CHANNEL_COUNT;
119     int32_t sampleRate = SAMPLE_RATE;
120     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
121         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AAC_IS_ADTS.data(),
122                                 DEFAULT_AAC_TYPE);
123         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
124                                 OH_BitsPerSample::SAMPLE_S16LE);
125     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRNB || audioType_ == AudioBufferFormatType::TYPE_G711MU) {
126         channelCount = 1;
127         sampleRate = AMRNB_SAMPLE_RATE;
128         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
129             OH_BitsPerSample::SAMPLE_S16LE);
130     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRWB || audioType_ == AudioBufferFormatType::TYPE_LBVC) {
131         channelCount = 1;
132         sampleRate = AMRWB_SAMPLE_RATE;
133         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
134             OH_BitsPerSample::SAMPLE_S16LE);
135     } else if (audioType_ == AudioBufferFormatType::TYPE_OPUS) {
136         int32_t channelCounttmp = 1;
137         int32_t sampleRatetmp = 8000;
138         channelCount = channelCounttmp;
139         sampleRate = sampleRatetmp;
140     } else if (audioType_ == AudioBufferFormatType::TYPE_MP3) {
141         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
142                                 OH_BitsPerSample::SAMPLE_S16LE);
143     }
144     OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), channelCount);
145     OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), sampleRate);
146     if (audioType_ == AudioBufferFormatType::TYPE_VORBIS) {
147         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
148             OH_BitsPerSample::SAMPLE_S16LE);
149     } else if (audioType_ == AudioBufferFormatType::TYPE_VIVID) {
150         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
151             OH_BitsPerSample::SAMPLE_S16LE);
152         DEMO_CHECK_AND_RETURN_RET_LOG(Configure(format) == AVCS_ERR_OK, false,
153             "Fatal: Configure fail");
154     } else if (audioType_ == AudioBufferFormatType::TYPE_APE) {
155         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
156                                 OH_BitsPerSample::SAMPLE_S16LE);
157         DEMO_CHECK_AND_RETURN_RET_LOG(Configure(format) == AVCS_ERR_OK, false,
158             "Fatal: Configure fail");
159     } else {
160         DEMO_CHECK_AND_RETURN_RET_LOG(Configure(format) == AVCS_ERR_OK, false,
161             "Fatal: Configure fail");
162     }
163     return true;
164 }
165 
InitFile(const std::string & inputFile)166 bool ADecBufferDemo::InitFile(const std::string& inputFile)
167 {
168     if (inputFile.find("mp4") != std::string::npos || inputFile.find("m4a") != std::string::npos ||
169         inputFile.find("vivid") != std::string::npos || inputFile.find("ts") != std::string::npos) {
170         audioType_ = AudioBufferFormatType::TYPE_VIVID;
171     } else if (inputFile.find("aac") != std::string::npos) {
172         audioType_ = AudioBufferFormatType::TYPE_AAC;
173     } else if (inputFile.find("flac") != std::string::npos) {
174         audioType_ = AudioBufferFormatType::TYPE_FLAC;
175     } else if (inputFile.find("mp3") != std::string::npos) {
176         audioType_ = AudioBufferFormatType::TYPE_MP3;
177     } else if (inputFile.find("vorbis") != std::string::npos) {
178         audioType_ = AudioBufferFormatType::TYPE_VORBIS;
179     } else if (inputFile.find("amrnb") != std::string::npos) {
180         audioType_ = AudioBufferFormatType::TYPE_AMRNB;
181     } else if (inputFile.find("amrwb") != std::string::npos) {
182         audioType_ = AudioBufferFormatType::TYPE_AMRWB;
183     } else if (inputFile.find("opus") != std::string::npos) {
184         audioType_ = AudioBufferFormatType::TYPE_OPUS;
185     } else if (inputFile.find("g711mu") != std::string::npos) {
186         audioType_ = AudioBufferFormatType::TYPE_G711MU;
187     } else if (inputFile.find("ape") != std::string::npos) {
188         audioType_ = AudioBufferFormatType::TYPE_APE;
189     } else if (inputFile.find("lbvc") != std::string::npos) {
190         audioType_ = AudioBufferFormatType::TYPE_LBVC;
191     } else {
192         audioType_ = AudioBufferFormatType::TYPE_AAC;
193     }
194     return true;
195 }
196 
ADecBufferDemo()197 ADecBufferDemo::ADecBufferDemo() : audioDec_(nullptr), signal_(nullptr), audioType_(AudioBufferFormatType::TYPE_AAC)
198 {
199     signal_ = new ADecBufferSignal();
200     DEMO_CHECK_AND_RETURN_LOG(signal_ != nullptr, "Fatal: No memory");
201 }
202 
~ADecBufferDemo()203 ADecBufferDemo::~ADecBufferDemo()
204 {
205     if (signal_) {
206         delete signal_;
207         signal_ = nullptr;
208     }
209 }
210 
CreateDec()211 int32_t ADecBufferDemo::CreateDec()
212 {
213     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
214         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AAC_NAME).data());
215         std::cout << "CreateDec TYPE_AAC!" << endl;
216     } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
217         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_FLAC_NAME).data());
218         std::cout << "CreateDec TYPE_FLAC!" << endl;
219     } else if (audioType_ == AudioBufferFormatType::TYPE_MP3) {
220         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_MP3_NAME).data());
221         std::cout << "CreateDec TYPE_MP3!" << endl;
222     } else if (audioType_ == AudioBufferFormatType::TYPE_VORBIS) {
223         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_VORBIS_NAME).data());
224         std::cout << "CreateDec TYPE_VORBIS!" << endl;
225     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRNB) {
226         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AMRNB_NAME).data());
227         std::cout << "CreateDec TYPE_AMRNB!" << endl;
228     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
229         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AMRWB_NAME).data());
230         std::cout << "CreateDec TYPE_AMRWB!" << endl;
231     } else if (audioType_ == AudioBufferFormatType::TYPE_VIVID) {
232         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_VIVID_NAME).data());
233         std::cout << "CreateDec TYPE_VIVID!" << endl;
234     } else if (audioType_ == AudioBufferFormatType::TYPE_OPUS) {
235         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_OPUS_NAME).data());
236         std::cout << "CreateDec TYPE_OPUS!" << endl;
237     } else if (audioType_ == AudioBufferFormatType::TYPE_G711MU) {
238         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_G711MU_NAME).data());
239         std::cout << "CreateDec TYPE_G711MU!" << endl;
240     } else if (audioType_ == AudioBufferFormatType::TYPE_APE) {
241         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_APE_NAME).data());
242         std::cout << "CreateDec TYPE_APE!" << endl;
243     } else if (audioType_ == AudioBufferFormatType::TYPE_LBVC) {
244         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_LBVC_NAME).data());
245         std::cout << "CreateDec TYPE_LBVC!" << endl;
246     } else {
247         return AVCS_ERR_INVALID_VAL;
248     }
249     DEMO_CHECK_AND_RETURN_RET_LOG(audioDec_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByName fail");
250     if (audioDec_ == nullptr) {
251         return AVCS_ERR_UNKNOWN;
252     }
253     if (signal_ == nullptr) {
254         signal_ = new ADecBufferSignal();
255         DEMO_CHECK_AND_RETURN_RET_LOG(signal_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
256     }
257     cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
258     int32_t ret = OH_AudioCodec_RegisterCallback(audioDec_, cb_, signal_);
259     DEMO_CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_UNKNOWN, "Fatal: SetCallback fail");
260     return AVCS_ERR_OK;
261 }
262 
Configure(OH_AVFormat * format)263 int32_t ADecBufferDemo::Configure(OH_AVFormat *format)
264 {
265     return OH_AudioCodec_Configure(audioDec_, format);
266 }
267 
Start()268 int32_t ADecBufferDemo::Start()
269 {
270     isRunning_.store(true);
271 
272     inputLoop_ = make_unique<thread>(&ADecBufferDemo::InputFunc, this);
273     DEMO_CHECK_AND_RETURN_RET_LOG(inputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
274 
275     outputLoop_ = make_unique<thread>(&ADecBufferDemo::OutputFunc, this);
276     DEMO_CHECK_AND_RETURN_RET_LOG(outputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
277 
278     return OH_AudioCodec_Start(audioDec_);
279 }
280 
Stop()281 int32_t ADecBufferDemo::Stop()
282 {
283     isRunning_.store(false);
284     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
285         {
286             unique_lock<mutex> lock(signal_->inMutex_);
287             signal_->inCond_.notify_all();
288         }
289         inputLoop_->join();
290         inputLoop_ = nullptr;
291         while (!signal_->inQueue_.empty()) {
292             signal_->inQueue_.pop();
293         }
294         while (!signal_->inBufferQueue_.empty()) {
295             signal_->inBufferQueue_.pop();
296         }
297     }
298 
299     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
300         {
301             unique_lock<mutex> lock(signal_->outMutex_);
302             signal_->outCond_.notify_all();
303         }
304         outputLoop_->join();
305         outputLoop_ = nullptr;
306         while (!signal_->outQueue_.empty()) {
307             signal_->outQueue_.pop();
308         }
309         while (!signal_->outBufferQueue_.empty()) {
310             signal_->outBufferQueue_.pop();
311         }
312     }
313     std::cout << "start stop!\n";
314     return OH_AudioCodec_Stop(audioDec_);
315 }
316 
Flush()317 int32_t ADecBufferDemo::Flush()
318 {
319     isRunning_.store(false);
320     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
321         {
322             unique_lock<mutex> lock(signal_->inMutex_);
323             signal_->inCond_.notify_all();
324         }
325         inputLoop_->join();
326         inputLoop_ = nullptr;
327         while (!signal_->inQueue_.empty()) {
328             signal_->inQueue_.pop();
329         }
330         while (!signal_->inBufferQueue_.empty()) {
331             signal_->inBufferQueue_.pop();
332         }
333         std::cout << "clear input buffer!\n";
334     }
335 
336     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
337         {
338             unique_lock<mutex> lock(signal_->outMutex_);
339             signal_->outCond_.notify_all();
340         }
341         outputLoop_->join();
342         outputLoop_ = nullptr;
343         while (!signal_->outQueue_.empty()) {
344             signal_->outQueue_.pop();
345         }
346         while (!signal_->outBufferQueue_.empty()) {
347             signal_->outBufferQueue_.pop();
348         }
349         std::cout << "clear output buffer!\n";
350     }
351     return OH_AudioCodec_Flush(audioDec_);
352 }
353 
Reset()354 int32_t ADecBufferDemo::Reset()
355 {
356     return OH_AudioCodec_Reset(audioDec_);
357 }
358 
Release()359 int32_t ADecBufferDemo::Release()
360 {
361     return OH_AudioCodec_Destroy(audioDec_);
362 }
363 
HandleInputEOS(const uint32_t index)364 void ADecBufferDemo::HandleInputEOS(const uint32_t index)
365 {
366     OH_AudioCodec_PushInputBuffer(audioDec_, index);
367     signal_->inBufferQueue_.pop();
368     signal_->inQueue_.pop();
369 }
370 
InputFunc()371 void ADecBufferDemo::InputFunc()
372 {
373     size_t frameBytes = 1152;
374     if (audioType_ == AudioBufferFormatType::TYPE_OPUS) {
375         size_t opussize = 960;
376         frameBytes = opussize;
377     } else if (audioType_ == AudioBufferFormatType::TYPE_G711MU) {
378         size_t gmusize = 320;
379         frameBytes = gmusize;
380     } else if (audioType_ == AudioBufferFormatType::TYPE_LBVC) {
381         size_t lbvcsize = 640;
382         frameBytes = lbvcsize;
383     } else if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
384         size_t aacsize = 1024;
385         frameBytes = aacsize;
386     }
387     size_t currentSize = inputdatasize < frameBytes ? inputdatasize : frameBytes;
388     while (isRunning_.load()) {
389         unique_lock<mutex> lock(signal_->inMutex_);
390         signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); });
391         if (!isRunning_.load()) {
392             break;
393         }
394         uint32_t index = signal_->inQueue_.front();
395         auto buffer = signal_->inBufferQueue_.front();
396         DEMO_CHECK_AND_BREAK_LOG(buffer != nullptr, "Fatal: GetInputBuffer fail");
397         int ret;
398         strncpy_s(reinterpret_cast<char*>(OH_AVBuffer_GetAddr(buffer)), currentSize, inputdata.c_str(), currentSize);
399         buffer->buffer_->memory_->SetSize(currentSize);
400         if (isFirstFrame_) {
401             buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
402             ret = OH_AudioCodec_PushInputBuffer(audioDec_, index);
403             isFirstFrame_ = false;
404         } else {
405             buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_NONE;
406             ret = OH_AudioCodec_PushInputBuffer(audioDec_, index);
407             isRunning_.store(false);
408             break;
409         }
410         signal_->inQueue_.pop();
411         signal_->inBufferQueue_.pop();
412         frameCount_++;
413         if (ret != AVCS_ERR_OK) {
414             isRunning_.store(false);
415             break;
416         }
417     }
418     signal_->startCond_.notify_all();
419 }
420 
OutputFunc()421 void ADecBufferDemo::OutputFunc()
422 {
423     while (isRunning_.load()) {
424         unique_lock<mutex> lock(signal_->outMutex_);
425         signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); });
426         if (!isRunning_.load()) {
427             cout << "wait to stop, exit" << endl;
428             break;
429         }
430 
431         uint32_t index = signal_->outQueue_.front();
432         OH_AVBuffer *data = signal_->outBufferQueue_.front();
433         cout << "OutputFunc index:" << index << endl;
434         if (data == nullptr) {
435             cout << "OutputFunc OH_AVBuffer is nullptr" << endl;
436             continue;
437         }
438         if (data != nullptr &&
439             (data->buffer_->flag_ == AVCODEC_BUFFER_FLAGS_EOS || data->buffer_->memory_->GetSize() == 0)) {
440             cout << "decode eos" << endl;
441             isRunning_.store(false);
442             signal_->startCond_.notify_all();
443         }
444         signal_->outBufferQueue_.pop();
445         signal_->outQueue_.pop();
446         if (OH_AudioCodec_FreeOutputBuffer(audioDec_, index) != AV_ERR_OK) {
447             cout << "Fatal: FreeOutputData fail" << endl;
448             break;
449         }
450         if (data->buffer_->flag_ == AVCODEC_BUFFER_FLAGS_EOS) {
451             cout << "decode eos" << endl;
452             isRunning_.store(false);
453             signal_->startCond_.notify_all();
454         }
455     }
456     signal_->startCond_.notify_all();
457 }
458 
SetCallback(OH_AVCodec * codec)459 OH_AVErrCode ADecBufferDemo::SetCallback(OH_AVCodec* codec)
460 {
461     cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
462     return OH_AudioCodec_RegisterCallback(codec, cb_, signal_);
463 }
464 
CreateByMime(const char * mime)465 OH_AVCodec* ADecBufferDemo::CreateByMime(const char* mime)
466 {
467     if (mime != nullptr) {
468         if (strcmp(mime, "audio/mp4a-latm") == 0) {
469             audioType_ = AudioBufferFormatType::TYPE_AAC;
470         } else if (strcmp(mime, "audio/flac") == 0) {
471             audioType_ = AudioBufferFormatType::TYPE_FLAC;
472         } else if (strcmp(mime, "audio/x-ape") == 0) {
473             audioType_ = AudioBufferFormatType::TYPE_APE;
474         } else if (strcmp(mime, OH_AVCODEC_MIMETYPE_AUDIO_LBVC) == 0) {
475             audioType_ = AudioBufferFormatType::TYPE_LBVC;
476         } else {
477             audioType_ = AudioBufferFormatType::TYPE_VIVID;
478         }
479     }
480     return OH_AudioCodec_CreateByMime(mime, false);
481 }
482 
CreateByName(const char * name)483 OH_AVCodec* ADecBufferDemo::CreateByName(const char* name)
484 {
485     return OH_AudioCodec_CreateByName(name);
486 }
487 
Destroy(OH_AVCodec * codec)488 OH_AVErrCode ADecBufferDemo::Destroy(OH_AVCodec* codec)
489 {
490     OH_AVErrCode ret = OH_AudioCodec_Destroy(codec);
491     return ret;
492 }
493 
IsValid(OH_AVCodec * codec,bool * isValid)494 OH_AVErrCode ADecBufferDemo::IsValid(OH_AVCodec* codec, bool* isValid)
495 {
496     return OH_AudioCodec_IsValid(codec, isValid);
497 }
498 
Prepare(OH_AVCodec * codec)499 OH_AVErrCode ADecBufferDemo::Prepare(OH_AVCodec* codec)
500 {
501     return OH_AudioCodec_Prepare(codec);
502 }
503 
Start(OH_AVCodec * codec)504 OH_AVErrCode ADecBufferDemo::Start(OH_AVCodec* codec)
505 {
506     return OH_AudioCodec_Start(codec);
507 }
508 
Stop(OH_AVCodec * codec)509 OH_AVErrCode ADecBufferDemo::Stop(OH_AVCodec* codec)
510 {
511     OH_AVErrCode ret = OH_AudioCodec_Stop(codec);
512     return ret;
513 }
514 
Flush(OH_AVCodec * codec)515 OH_AVErrCode ADecBufferDemo::Flush(OH_AVCodec* codec)
516 {
517     OH_AVErrCode ret = OH_AudioCodec_Flush(codec);
518     return ret;
519 }
520 
Reset(OH_AVCodec * codec)521 OH_AVErrCode ADecBufferDemo::Reset(OH_AVCodec* codec)
522 {
523     return OH_AudioCodec_Reset(codec);
524 }
525 
GetOutputDescription(OH_AVCodec * codec)526 OH_AVFormat* ADecBufferDemo::GetOutputDescription(OH_AVCodec* codec)
527 {
528     return OH_AudioCodec_GetOutputDescription(codec);
529 }
530 
FreeOutputData(OH_AVCodec * codec,uint32_t index)531 OH_AVErrCode ADecBufferDemo::FreeOutputData(OH_AVCodec* codec, uint32_t index)
532 {
533     return OH_AudioCodec_FreeOutputBuffer(codec, index);
534 }
535 
PushInputData(OH_AVCodec * codec,uint32_t index)536 OH_AVErrCode ADecBufferDemo::PushInputData(OH_AVCodec* codec, uint32_t index)
537 {
538     OH_AVCodecBufferAttr info;
539     if (!eosFlag) {
540         if (!signal_->inBufferQueue_.empty()) {
541             int32_t size = 100;
542             unique_lock<mutex> lock(signal_->inMutex_);
543             auto buffer = signal_->inBufferQueue_.front();
544             info.size = size;
545             info.pts = 0;
546             info.flags = AVCODEC_BUFFER_FLAGS_NONE;
547             OH_AVErrCode ret = OH_AVBuffer_SetBufferAttr(buffer, &info);
548             std::cout <<"info.size:" << info.size <<"   ADecBufferDemo::PushInputData : = "<< (int32_t)ret<<std::endl;
549             if (ret != AV_ERR_OK) {
550                 return ret;
551             }
552         }
553     }
554     return OH_AudioCodec_PushInputBuffer(codec, index);
555 }
556 
GetInputIndex()557 uint32_t ADecBufferDemo::GetInputIndex()
558 {
559     int32_t sleepTime = 0;
560     int32_t condTime = 5;
561     uint32_t index;
562     while (signal_->inQueue_.empty() && sleepTime < condTime) {
563         sleep(1);
564         sleepTime++;
565     }
566     if (sleepTime >= condTime) {
567         return 0;
568     } else {
569         index = signal_->inQueue_.front();
570         signal_->inQueue_.pop();
571     }
572     return index;
573 }
574 
GetOutputIndex()575 uint32_t ADecBufferDemo::GetOutputIndex()
576 {
577     int32_t sleepTime = 0;
578     int32_t condTime = 5;
579     uint32_t index;
580     while (signal_->outQueue_.empty() && sleepTime < condTime) {
581         sleep(1);
582         sleepTime++;
583     }
584     if (sleepTime >= condTime) {
585         return 0;
586     } else {
587         index = signal_->outQueue_.front();
588         signal_->outQueue_.pop();
589     }
590     return index;
591 }
592 
PushInputDataEOS(OH_AVCodec * codec,uint32_t index)593 OH_AVErrCode ADecBufferDemo::PushInputDataEOS(OH_AVCodec* codec, uint32_t index)
594 {
595     OH_AVCodecBufferAttr info;
596     info.size = 0;
597     info.offset = 0;
598     info.pts = 0;
599     info.flags = AVCODEC_BUFFER_FLAGS_EOS;
600     eosFlag = true;
601     if (!signal_->inBufferQueue_.empty()) {
602         auto buffer = signal_->inBufferQueue_.front();
603         OH_AVBuffer_SetBufferAttr(buffer, &info);
604     }
605     return OH_AudioCodec_PushInputBuffer(codec, index);
606 }
607 
Configure(OH_AVCodec * codec,OH_AVFormat * format,int32_t channel,int32_t sampleRate)608 OH_AVErrCode ADecBufferDemo::Configure(OH_AVCodec* codec, OH_AVFormat* format, int32_t channel, int32_t sampleRate)
609 {
610     if (format == nullptr) {
611         std::cout<<" Configure format nullptr"<< std::endl;
612         return OH_AudioCodec_Configure(codec, format);
613     }
614     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channel);
615     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate);
616     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
617         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
618     } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
619     }
620     std::cout<<" Configure format :"<< format << std::endl;
621     if (format == nullptr) {
622         std::cout<<" Configure format end is nullptr"<< std::endl;
623     }
624     OH_AVErrCode ret = OH_AudioCodec_Configure(codec, format);
625     return ret;
626 }
627 
SetParameter(OH_AVCodec * codec,OH_AVFormat * format,int32_t channel,int32_t sampleRate)628 OH_AVErrCode ADecBufferDemo::SetParameter(OH_AVCodec* codec, OH_AVFormat* format, int32_t channel, int32_t sampleRate)
629 {
630     if (format == nullptr) {
631         std::cout<<" SetParameter format nullptr"<< std::endl;
632         return OH_AudioCodec_SetParameter(codec, format);
633     }
634     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channel);
635     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate);
636     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
637         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
638     } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
639     }
640     std::cout<<" SetParameter format :"<< format << std::endl;
641     if (format == nullptr) {
642         std::cout<<" SetParameter format end is nullptr"<< std::endl;
643     }
644     OH_AVErrCode ret = OH_AudioCodec_SetParameter(codec, format);
645     return ret;
646 }
647 
RunCaseReset(const uint8_t * data,size_t size)648 bool ADecBufferDemo::RunCaseReset(const uint8_t *data, size_t size)
649 {
650     std::string codecdata(reinterpret_cast<const char *>(data), size);
651     inputdata = codecdata;
652     inputdatasize = size;
653 
654     DEMO_CHECK_AND_RETURN_RET_LOG(CreateDec() == AVCS_ERR_OK, false, "Fatal: CreateDec fail");
655 
656     OH_AVFormat* format = OH_AVFormat_Create();
657     auto res = InitFormat(format);
658     if (res == false) {
659         return false;
660     }
661 
662     DEMO_CHECK_AND_RETURN_RET_LOG(Start() == AVCS_ERR_OK, false, "Fatal: Start fail");
663 
664     auto start = chrono::steady_clock::now();
665     {
666         unique_lock<mutex> lock(signal_->startMutex_);
667         signal_->startCond_.wait(lock, [this]() { return (!(isRunning_.load())); });
668     }
669 
670     auto end = chrono::steady_clock::now();
671     std::cout << "decode finished, time = " << std::chrono::duration_cast<chrono::milliseconds>(end - start).count()
672         << " ms" << std::endl;
673 
674     DEMO_CHECK_AND_RETURN_RET_LOG(Stop() == AVCS_ERR_OK, false, "Fatal: Stop fail");
675     //reset
676     if (AV_ERR_OK != Reset(audioDec_)) {
677         return false;
678     }
679 
680     //reset
681     DEMO_CHECK_AND_RETURN_RET_LOG(Release() == AVCS_ERR_OK, false, "Fatal: Release fail");
682     OH_AVFormat_Destroy(format);
683     sleep(1);
684     return true;
685 }