1da853ecaSopenharmony_ci/*
2da853ecaSopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
3da853ecaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4da853ecaSopenharmony_ci * you may not use this file except in compliance with the License.
5da853ecaSopenharmony_ci * You may obtain a copy of the License at
6da853ecaSopenharmony_ci *
7da853ecaSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8da853ecaSopenharmony_ci *
9da853ecaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10da853ecaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11da853ecaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12da853ecaSopenharmony_ci * See the License for the specific language governing permissions and
13da853ecaSopenharmony_ci * limitations under the License.
14da853ecaSopenharmony_ci */
15da853ecaSopenharmony_ci
16da853ecaSopenharmony_ci#include <iostream>
17da853ecaSopenharmony_ci#include <unistd.h>
18da853ecaSopenharmony_ci#include <chrono>
19da853ecaSopenharmony_ci#include "avcodec_codec_name.h"
20da853ecaSopenharmony_ci#include "avcodec_common.h"
21da853ecaSopenharmony_ci#include "avcodec_errors.h"
22da853ecaSopenharmony_ci#include "demo_log.h"
23da853ecaSopenharmony_ci#include "avcodec_mime_type.h"
24da853ecaSopenharmony_ci#include "media_description.h"
25da853ecaSopenharmony_ci#include "native_avcodec_base.h"
26da853ecaSopenharmony_ci#include "native_avformat.h"
27da853ecaSopenharmony_ci#include "securec.h"
28da853ecaSopenharmony_ci#include "audiodecoderdemo.h"
29da853ecaSopenharmony_ci
30da853ecaSopenharmony_ciusing namespace OHOS;
31da853ecaSopenharmony_ciusing namespace OHOS::MediaAVCodec;
32da853ecaSopenharmony_ciusing namespace OHOS::MediaAVCodec::AudioDemoAuto;
33da853ecaSopenharmony_ciusing namespace std;
34da853ecaSopenharmony_ci
35da853ecaSopenharmony_cinamespace OHOS {
36da853ecaSopenharmony_cinamespace MediaAVCodec {
37da853ecaSopenharmony_cinamespace AudioDemoAuto {
38da853ecaSopenharmony_ci    constexpr uint32_t CHANNEL_COUNT = 2;
39da853ecaSopenharmony_ci    constexpr uint32_t CHANNEL_COUNT1 = 1;
40da853ecaSopenharmony_ci    constexpr uint32_t SAMPLE_RATE = 44100;
41da853ecaSopenharmony_ci    constexpr uint32_t DEFAULT_AAC_TYPE = 1;
42da853ecaSopenharmony_ci    constexpr uint32_t AMRWB_SAMPLE_RATE = 16000;
43da853ecaSopenharmony_ci    constexpr uint32_t AMRNB_SAMPLE_RATE = 8000;
44da853ecaSopenharmony_ci
45da853ecaSopenharmony_ci    void OnError(OH_AVCodec* codec, int32_t errorCode, void* userData)
46da853ecaSopenharmony_ci    {
47da853ecaSopenharmony_ci        (void)codec;
48da853ecaSopenharmony_ci        (void)errorCode;
49da853ecaSopenharmony_ci        (void)userData;
50da853ecaSopenharmony_ci    }
51da853ecaSopenharmony_ci
52da853ecaSopenharmony_ci    void OnOutputFormatChanged(OH_AVCodec* codec, OH_AVFormat* format, void* userData)
53da853ecaSopenharmony_ci    {
54da853ecaSopenharmony_ci        (void)codec;
55da853ecaSopenharmony_ci        (void)format;
56da853ecaSopenharmony_ci        (void)userData;
57da853ecaSopenharmony_ci        cout << "OnOutputFormatChanged received" << endl;
58da853ecaSopenharmony_ci    }
59da853ecaSopenharmony_ci
60da853ecaSopenharmony_ci    void OnInputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data, void* userData)
61da853ecaSopenharmony_ci    {
62da853ecaSopenharmony_ci        (void)codec;
63da853ecaSopenharmony_ci        ADecSignal* signal = static_cast<ADecSignal*>(userData);
64da853ecaSopenharmony_ci        unique_lock<mutex> lock(signal->inMutex_);
65da853ecaSopenharmony_ci        signal->inQueue_.push(index);
66da853ecaSopenharmony_ci        signal->inBufferQueue_.push(data);
67da853ecaSopenharmony_ci        signal->inCond_.notify_all();
68da853ecaSopenharmony_ci    }
69da853ecaSopenharmony_ci
70da853ecaSopenharmony_ci    void OnOutputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data, OH_AVCodecBufferAttr* attr,
71da853ecaSopenharmony_ci        void* userData)
72da853ecaSopenharmony_ci    {
73da853ecaSopenharmony_ci        (void)codec;
74da853ecaSopenharmony_ci        ADecSignal* signal = static_cast<ADecSignal*>(userData);
75da853ecaSopenharmony_ci        unique_lock<mutex> lock(signal->outMutex_);
76da853ecaSopenharmony_ci        signal->outQueue_.push(index);
77da853ecaSopenharmony_ci        signal->outBufferQueue_.push(data);
78da853ecaSopenharmony_ci        if (attr) {
79da853ecaSopenharmony_ci            signal->attrQueue_.push(*attr);
80da853ecaSopenharmony_ci        } else {
81da853ecaSopenharmony_ci            cout << "OnOutputBufferAvailable, attr is nullptr!" << endl;
82da853ecaSopenharmony_ci        }
83da853ecaSopenharmony_ci        signal->outCond_.notify_all();
84da853ecaSopenharmony_ci    }
85da853ecaSopenharmony_ci}
86da853ecaSopenharmony_ci}
87da853ecaSopenharmony_ci}
88da853ecaSopenharmony_ci
89da853ecaSopenharmony_ciOH_AVCodec* ADecDemoAuto::CreateByMime(const char* mime)
90da853ecaSopenharmony_ci{
91da853ecaSopenharmony_ci    return OH_AudioDecoder_CreateByMime(mime);
92da853ecaSopenharmony_ci}
93da853ecaSopenharmony_ci
94da853ecaSopenharmony_ciOH_AVCodec* ADecDemoAuto::CreateByName(const char* name)
95da853ecaSopenharmony_ci{
96da853ecaSopenharmony_ci    return OH_AudioDecoder_CreateByName(name);
97da853ecaSopenharmony_ci}
98da853ecaSopenharmony_ci
99da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::Destroy(OH_AVCodec* codec)
100da853ecaSopenharmony_ci{
101da853ecaSopenharmony_ci    if (format_ != nullptr) {
102da853ecaSopenharmony_ci        OH_AVFormat_Destroy(format_);
103da853ecaSopenharmony_ci        format_ = nullptr;
104da853ecaSopenharmony_ci    }
105da853ecaSopenharmony_ci    OH_AVErrCode ret = OH_AudioDecoder_Destroy(codec);
106da853ecaSopenharmony_ci    ClearQueue();
107da853ecaSopenharmony_ci    return ret;
108da853ecaSopenharmony_ci}
109da853ecaSopenharmony_ci
110da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::SetCallback(OH_AVCodec* codec)
111da853ecaSopenharmony_ci{
112da853ecaSopenharmony_ci    cb_ = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable };
113da853ecaSopenharmony_ci    return OH_AudioDecoder_SetCallback(codec, cb_, signal_);
114da853ecaSopenharmony_ci}
115da853ecaSopenharmony_ci
116da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::Prepare(OH_AVCodec* codec)
117da853ecaSopenharmony_ci{
118da853ecaSopenharmony_ci    return OH_AudioDecoder_Prepare(codec);
119da853ecaSopenharmony_ci}
120da853ecaSopenharmony_ci
121da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::Start(OH_AVCodec* codec)
122da853ecaSopenharmony_ci{
123da853ecaSopenharmony_ci    return OH_AudioDecoder_Start(codec);
124da853ecaSopenharmony_ci}
125da853ecaSopenharmony_ci
126da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::Stop(OH_AVCodec* codec)
127da853ecaSopenharmony_ci{
128da853ecaSopenharmony_ci    OH_AVErrCode ret = OH_AudioDecoder_Stop(codec);
129da853ecaSopenharmony_ci    ClearQueue();
130da853ecaSopenharmony_ci    return ret;
131da853ecaSopenharmony_ci}
132da853ecaSopenharmony_ci
133da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::Flush(OH_AVCodec* codec)
134da853ecaSopenharmony_ci{
135da853ecaSopenharmony_ci    OH_AVErrCode ret = OH_AudioDecoder_Flush(codec);
136da853ecaSopenharmony_ci    ClearQueue();
137da853ecaSopenharmony_ci    return ret;
138da853ecaSopenharmony_ci}
139da853ecaSopenharmony_ci
140da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::Reset(OH_AVCodec* codec)
141da853ecaSopenharmony_ci{
142da853ecaSopenharmony_ci    return OH_AudioDecoder_Reset(codec);
143da853ecaSopenharmony_ci}
144da853ecaSopenharmony_ci
145da853ecaSopenharmony_ciOH_AVFormat* ADecDemoAuto::GetOutputDescription(OH_AVCodec* codec)
146da853ecaSopenharmony_ci{
147da853ecaSopenharmony_ci    return OH_AudioDecoder_GetOutputDescription(codec);
148da853ecaSopenharmony_ci}
149da853ecaSopenharmony_ci
150da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::PushInputData(OH_AVCodec* codec, uint32_t index, int32_t size, int32_t offset)
151da853ecaSopenharmony_ci{
152da853ecaSopenharmony_ci    OH_AVCodecBufferAttr info;
153da853ecaSopenharmony_ci    info.size = size;
154da853ecaSopenharmony_ci    info.offset = offset;
155da853ecaSopenharmony_ci    info.pts = 0;
156da853ecaSopenharmony_ci    info.flags = AVCODEC_BUFFER_FLAGS_NONE;
157da853ecaSopenharmony_ci
158da853ecaSopenharmony_ci    return OH_AudioDecoder_PushInputData(codec, index, info);
159da853ecaSopenharmony_ci}
160da853ecaSopenharmony_ci
161da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::PushInputDataEOS(OH_AVCodec* codec, uint32_t index)
162da853ecaSopenharmony_ci{
163da853ecaSopenharmony_ci    OH_AVCodecBufferAttr info;
164da853ecaSopenharmony_ci    info.size = 0;
165da853ecaSopenharmony_ci    info.offset = 0;
166da853ecaSopenharmony_ci    info.pts = 0;
167da853ecaSopenharmony_ci    info.flags = AVCODEC_BUFFER_FLAGS_EOS;
168da853ecaSopenharmony_ci
169da853ecaSopenharmony_ci    return OH_AudioDecoder_PushInputData(codec, index, info);
170da853ecaSopenharmony_ci}
171da853ecaSopenharmony_ci
172da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::FreeOutputData(OH_AVCodec* codec, uint32_t index)
173da853ecaSopenharmony_ci{
174da853ecaSopenharmony_ci    return OH_AudioDecoder_FreeOutputData(codec, index);
175da853ecaSopenharmony_ci}
176da853ecaSopenharmony_ci
177da853ecaSopenharmony_ciOH_AVErrCode ADecDemoAuto::IsValid(OH_AVCodec* codec, bool* isValid)
178da853ecaSopenharmony_ci{
179da853ecaSopenharmony_ci    return OH_AudioDecoder_IsValid(codec, isValid);
180da853ecaSopenharmony_ci}
181da853ecaSopenharmony_ci
182da853ecaSopenharmony_ciuint32_t ADecDemoAuto::GetInputIndex()
183da853ecaSopenharmony_ci{
184da853ecaSopenharmony_ci    int32_t sleepTime = 0;
185da853ecaSopenharmony_ci    uint32_t index;
186da853ecaSopenharmony_ci    int32_t condTime = 5;
187da853ecaSopenharmony_ci    while (signal_->inQueue_.empty() && sleepTime < condTime) {
188da853ecaSopenharmony_ci        sleep(1);
189da853ecaSopenharmony_ci        sleepTime++;
190da853ecaSopenharmony_ci    }
191da853ecaSopenharmony_ci    if (sleepTime >= condTime) {
192da853ecaSopenharmony_ci        return 0;
193da853ecaSopenharmony_ci    } else {
194da853ecaSopenharmony_ci        index = signal_->inQueue_.front();
195da853ecaSopenharmony_ci        signal_->inQueue_.pop();
196da853ecaSopenharmony_ci    }
197da853ecaSopenharmony_ci    return index;
198da853ecaSopenharmony_ci}
199da853ecaSopenharmony_ci
200da853ecaSopenharmony_ciuint32_t ADecDemoAuto::GetOutputIndex()
201da853ecaSopenharmony_ci{
202da853ecaSopenharmony_ci    int32_t sleepTime = 0;
203da853ecaSopenharmony_ci    uint32_t index;
204da853ecaSopenharmony_ci    int32_t condTime = 5;
205da853ecaSopenharmony_ci    while (signal_->outQueue_.empty() && sleepTime < condTime) {
206da853ecaSopenharmony_ci        sleep(1);
207da853ecaSopenharmony_ci        sleepTime++;
208da853ecaSopenharmony_ci    }
209da853ecaSopenharmony_ci    if (sleepTime >= condTime) {
210da853ecaSopenharmony_ci        return 0;
211da853ecaSopenharmony_ci    } else {
212da853ecaSopenharmony_ci        index = signal_->outQueue_.front();
213da853ecaSopenharmony_ci        signal_->outQueue_.pop();
214da853ecaSopenharmony_ci    }
215da853ecaSopenharmony_ci    return index;
216da853ecaSopenharmony_ci}
217da853ecaSopenharmony_ci
218da853ecaSopenharmony_civoid ADecDemoAuto::ClearQueue()
219da853ecaSopenharmony_ci{
220da853ecaSopenharmony_ci    while (!signal_->inQueue_.empty()) {
221da853ecaSopenharmony_ci        signal_->inQueue_.pop();
222da853ecaSopenharmony_ci    }
223da853ecaSopenharmony_ci    while (!signal_->outQueue_.empty()) {
224da853ecaSopenharmony_ci        signal_->outQueue_.pop();
225da853ecaSopenharmony_ci    }
226da853ecaSopenharmony_ci    while (!signal_->inBufferQueue_.empty()) {
227da853ecaSopenharmony_ci        signal_->inBufferQueue_.pop();
228da853ecaSopenharmony_ci    }
229da853ecaSopenharmony_ci    while (!signal_->outBufferQueue_.empty()) {
230da853ecaSopenharmony_ci        signal_->outBufferQueue_.pop();
231da853ecaSopenharmony_ci    }
232da853ecaSopenharmony_ci    while (!signal_->attrQueue_.empty()) {
233da853ecaSopenharmony_ci        signal_->attrQueue_.pop();
234da853ecaSopenharmony_ci    }
235da853ecaSopenharmony_ci}
236da853ecaSopenharmony_ci
237da853ecaSopenharmony_cibool ADecDemoAuto::InitFile(string inputFile)
238da853ecaSopenharmony_ci{
239da853ecaSopenharmony_ci    if (inputFile.find("aac") != std::string::npos) {
240da853ecaSopenharmony_ci        audioType_ = TYPE_AAC;
241da853ecaSopenharmony_ci    } else if (inputFile.find("flac") != std::string::npos) {
242da853ecaSopenharmony_ci        audioType_ = TYPE_FLAC;
243da853ecaSopenharmony_ci    } else if (inputFile.find("mp3") != std::string::npos) {
244da853ecaSopenharmony_ci        audioType_ = TYPE_MP3;
245da853ecaSopenharmony_ci    } else if (inputFile.find("vorbis") != std::string::npos) {
246da853ecaSopenharmony_ci        audioType_ = TYPE_VORBIS;
247da853ecaSopenharmony_ci    } else if (inputFile.find("amrnb") != std::string::npos) {
248da853ecaSopenharmony_ci        audioType_ = TYPE_AMRNB;
249da853ecaSopenharmony_ci    } else if (inputFile.find("amrwb") != std::string::npos) {
250da853ecaSopenharmony_ci        audioType_ = TYPE_AMRWB;
251da853ecaSopenharmony_ci    } else if (inputFile.find("opus") != std::string::npos) {
252da853ecaSopenharmony_ci        audioType_ = TYPE_OPUS;
253da853ecaSopenharmony_ci    } else if (inputFile.find("g711mu") != std::string::npos) {
254da853ecaSopenharmony_ci        audioType_ = TYPE_G711MU;
255da853ecaSopenharmony_ci    } else {
256da853ecaSopenharmony_ci        audioType_ = TYPE_AAC;
257da853ecaSopenharmony_ci    }
258da853ecaSopenharmony_ci    return true;
259da853ecaSopenharmony_ci}
260da853ecaSopenharmony_ci
261da853ecaSopenharmony_cibool ADecDemoAuto::InitFormat(OH_AVFormat *format)
262da853ecaSopenharmony_ci{
263da853ecaSopenharmony_ci    int32_t channelCount = CHANNEL_COUNT;
264da853ecaSopenharmony_ci    int32_t sampleRate = SAMPLE_RATE;
265da853ecaSopenharmony_ci    if (audioType_ == TYPE_AAC) {
266da853ecaSopenharmony_ci        OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AAC_IS_ADTS.data(),
267da853ecaSopenharmony_ci            DEFAULT_AAC_TYPE);
268da853ecaSopenharmony_ci        OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
269da853ecaSopenharmony_ci            OH_BitsPerSample::SAMPLE_S16LE);
270da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_AMRNB || audioType_ == TYPE_G711MU || audioType_ == TYPE_OPUS) {
271da853ecaSopenharmony_ci        channelCount = CHANNEL_COUNT1;
272da853ecaSopenharmony_ci        sampleRate = AMRNB_SAMPLE_RATE;
273da853ecaSopenharmony_ci        OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
274da853ecaSopenharmony_ci            OH_BitsPerSample::SAMPLE_S16LE);
275da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_AMRWB) {
276da853ecaSopenharmony_ci        channelCount = CHANNEL_COUNT1;
277da853ecaSopenharmony_ci        sampleRate = AMRWB_SAMPLE_RATE;
278da853ecaSopenharmony_ci        OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
279da853ecaSopenharmony_ci            OH_BitsPerSample::SAMPLE_S16LE);
280da853ecaSopenharmony_ci    }
281da853ecaSopenharmony_ci    OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
282da853ecaSopenharmony_ci        OH_BitsPerSample::SAMPLE_S16LE);
283da853ecaSopenharmony_ci    OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), channelCount);
284da853ecaSopenharmony_ci    OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), sampleRate);
285da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(Configure(format) == AVCS_ERR_OK, false,
286da853ecaSopenharmony_ci        "Fatal: Configure fail");
287da853ecaSopenharmony_ci    return true;
288da853ecaSopenharmony_ci}
289da853ecaSopenharmony_ci
290da853ecaSopenharmony_ciADecDemoAuto::ADecDemoAuto() : audioDec_(nullptr), signal_(nullptr), audioType_(TYPE_AAC)
291da853ecaSopenharmony_ci{
292da853ecaSopenharmony_ci    signal_ = new ADecSignal();
293da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_LOG(signal_ != nullptr, "Fatal: No memory");
294da853ecaSopenharmony_ci}
295da853ecaSopenharmony_ci
296da853ecaSopenharmony_ciADecDemoAuto::~ADecDemoAuto()
297da853ecaSopenharmony_ci{
298da853ecaSopenharmony_ci    if (signal_) {
299da853ecaSopenharmony_ci        delete signal_;
300da853ecaSopenharmony_ci        signal_ = nullptr;
301da853ecaSopenharmony_ci    }
302da853ecaSopenharmony_ci}
303da853ecaSopenharmony_ci
304da853ecaSopenharmony_ciint32_t ADecDemoAuto::CreateDec()
305da853ecaSopenharmony_ci{
306da853ecaSopenharmony_ci    if (audioType_ == TYPE_AAC) {
307da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByName((AVCodecCodecName::AUDIO_DECODER_AAC_NAME).data());
308da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_FLAC) {
309da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByName((AVCodecCodecName::AUDIO_DECODER_FLAC_NAME).data());
310da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_MP3) {
311da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByName((AVCodecCodecName::AUDIO_DECODER_MP3_NAME).data());
312da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_VORBIS) {
313da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByName((AVCodecCodecName::AUDIO_DECODER_VORBIS_NAME).data());
314da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_AMRNB) {
315da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByName((AVCodecCodecName::AUDIO_DECODER_AMRNB_NAME).data());
316da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_AMRWB) {
317da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByName((AVCodecCodecName::AUDIO_DECODER_AMRWB_NAME).data());
318da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_OPUS) {
319da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByName((AVCodecCodecName::AUDIO_DECODER_OPUS_NAME).data());
320da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_G711MU) {
321da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByName((AVCodecCodecName::AUDIO_DECODER_G711MU_NAME).data());
322da853ecaSopenharmony_ci    } else {
323da853ecaSopenharmony_ci        return AVCS_ERR_INVALID_VAL;
324da853ecaSopenharmony_ci    }
325da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(audioDec_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByName fail");
326da853ecaSopenharmony_ci
327da853ecaSopenharmony_ci    cb_ = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable };
328da853ecaSopenharmony_ci    int32_t ret = OH_AudioDecoder_SetCallback(audioDec_, cb_, signal_);
329da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_UNKNOWN, "Fatal: SetCallback fail");
330da853ecaSopenharmony_ci
331da853ecaSopenharmony_ci    return AVCS_ERR_OK;
332da853ecaSopenharmony_ci}
333da853ecaSopenharmony_ci
334da853ecaSopenharmony_ciint32_t ADecDemoAuto::CreateDecByMime()
335da853ecaSopenharmony_ci{
336da853ecaSopenharmony_ci    if (audioType_ == TYPE_AAC) {
337da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_AAC).data());
338da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_FLAC) {
339da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_FLAC).data());
340da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_MP3) {
341da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_MPEG).data());
342da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_VORBIS) {
343da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_VORBIS).data());
344da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_AMRNB) {
345da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_AMRNB).data());
346da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_AMRWB) {
347da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_AMRWB).data());
348da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_OPUS) {
349da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_OPUS).data());
350da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_G711MU) {
351da853ecaSopenharmony_ci        audioDec_ = OH_AudioDecoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_G711MU).data());
352da853ecaSopenharmony_ci    } else {
353da853ecaSopenharmony_ci        return AVCS_ERR_INVALID_VAL;
354da853ecaSopenharmony_ci    }
355da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(audioDec_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByName fail");
356da853ecaSopenharmony_ci    cb_ = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable };
357da853ecaSopenharmony_ci    int32_t ret = OH_AudioDecoder_SetCallback(audioDec_, cb_, signal_);
358da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_UNKNOWN, "Fatal: SetCallback fail");
359da853ecaSopenharmony_ci    return AVCS_ERR_OK;
360da853ecaSopenharmony_ci}
361da853ecaSopenharmony_ci
362da853ecaSopenharmony_ciint32_t ADecDemoAuto::Configure(OH_AVFormat* format)
363da853ecaSopenharmony_ci{
364da853ecaSopenharmony_ci    return OH_AudioDecoder_Configure(audioDec_, format);
365da853ecaSopenharmony_ci}
366da853ecaSopenharmony_ci
367da853ecaSopenharmony_ciint32_t ADecDemoAuto::Start()
368da853ecaSopenharmony_ci{
369da853ecaSopenharmony_ci    isRunning_.store(true);
370da853ecaSopenharmony_ci
371da853ecaSopenharmony_ci    inputLoop_ = make_unique<thread>(&ADecDemoAuto::InputFunc, this);
372da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(inputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
373da853ecaSopenharmony_ci
374da853ecaSopenharmony_ci    outputLoop_ = make_unique<thread>(&ADecDemoAuto::OutputFunc, this);
375da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(outputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
376da853ecaSopenharmony_ci
377da853ecaSopenharmony_ci    return OH_AudioDecoder_Start(audioDec_);
378da853ecaSopenharmony_ci}
379da853ecaSopenharmony_ci
380da853ecaSopenharmony_ciint32_t ADecDemoAuto::Stop()
381da853ecaSopenharmony_ci{
382da853ecaSopenharmony_ci    isRunning_.store(false);
383da853ecaSopenharmony_ci    if (inputLoop_ != nullptr && inputLoop_->joinable()) {
384da853ecaSopenharmony_ci        {
385da853ecaSopenharmony_ci            unique_lock<mutex> lock(signal_->inMutex_);
386da853ecaSopenharmony_ci            signal_->inCond_.notify_all();
387da853ecaSopenharmony_ci        }
388da853ecaSopenharmony_ci        inputLoop_->join();
389da853ecaSopenharmony_ci        inputLoop_ = nullptr;
390da853ecaSopenharmony_ci        while (!signal_->inQueue_.empty()) {
391da853ecaSopenharmony_ci            signal_->inQueue_.pop();
392da853ecaSopenharmony_ci        }
393da853ecaSopenharmony_ci        while (!signal_->inBufferQueue_.empty()) {
394da853ecaSopenharmony_ci            signal_->inBufferQueue_.pop();
395da853ecaSopenharmony_ci        }
396da853ecaSopenharmony_ci    }
397da853ecaSopenharmony_ci
398da853ecaSopenharmony_ci    if (outputLoop_ != nullptr && outputLoop_->joinable()) {
399da853ecaSopenharmony_ci        {
400da853ecaSopenharmony_ci            unique_lock<mutex> lock(signal_->outMutex_);
401da853ecaSopenharmony_ci            signal_->outCond_.notify_all();
402da853ecaSopenharmony_ci        }
403da853ecaSopenharmony_ci        outputLoop_->join();
404da853ecaSopenharmony_ci        outputLoop_ = nullptr;
405da853ecaSopenharmony_ci        while (!signal_->outQueue_.empty()) {
406da853ecaSopenharmony_ci            signal_->outQueue_.pop();
407da853ecaSopenharmony_ci        }
408da853ecaSopenharmony_ci        while (!signal_->attrQueue_.empty()) {
409da853ecaSopenharmony_ci            signal_->attrQueue_.pop();
410da853ecaSopenharmony_ci        }
411da853ecaSopenharmony_ci        while (!signal_->outBufferQueue_.empty()) {
412da853ecaSopenharmony_ci            signal_->outBufferQueue_.pop();
413da853ecaSopenharmony_ci        }
414da853ecaSopenharmony_ci    }
415da853ecaSopenharmony_ci    return OH_AudioDecoder_Stop(audioDec_);
416da853ecaSopenharmony_ci}
417da853ecaSopenharmony_ci
418da853ecaSopenharmony_ciint32_t ADecDemoAuto::Flush()
419da853ecaSopenharmony_ci{
420da853ecaSopenharmony_ci    isRunning_.store(false);
421da853ecaSopenharmony_ci    if (inputLoop_ != nullptr && inputLoop_->joinable()) {
422da853ecaSopenharmony_ci        {
423da853ecaSopenharmony_ci            unique_lock<mutex> lock(signal_->inMutex_);
424da853ecaSopenharmony_ci            signal_->inCond_.notify_all();
425da853ecaSopenharmony_ci        }
426da853ecaSopenharmony_ci        inputLoop_->join();
427da853ecaSopenharmony_ci        inputLoop_ = nullptr;
428da853ecaSopenharmony_ci        while (!signal_->inQueue_.empty()) {
429da853ecaSopenharmony_ci            signal_->inQueue_.pop();
430da853ecaSopenharmony_ci        }
431da853ecaSopenharmony_ci        while (!signal_->inBufferQueue_.empty()) {
432da853ecaSopenharmony_ci            signal_->inBufferQueue_.pop();
433da853ecaSopenharmony_ci        }
434da853ecaSopenharmony_ci        std::cout << "clear input buffer!\n";
435da853ecaSopenharmony_ci    }
436da853ecaSopenharmony_ci
437da853ecaSopenharmony_ci    if (outputLoop_ != nullptr && outputLoop_->joinable()) {
438da853ecaSopenharmony_ci        {
439da853ecaSopenharmony_ci            unique_lock<mutex> lock(signal_->outMutex_);
440da853ecaSopenharmony_ci            signal_->outCond_.notify_all();
441da853ecaSopenharmony_ci        }
442da853ecaSopenharmony_ci        outputLoop_->join();
443da853ecaSopenharmony_ci        outputLoop_ = nullptr;
444da853ecaSopenharmony_ci        while (!signal_->outQueue_.empty()) {
445da853ecaSopenharmony_ci            signal_->outQueue_.pop();
446da853ecaSopenharmony_ci        }
447da853ecaSopenharmony_ci        while (!signal_->attrQueue_.empty()) {
448da853ecaSopenharmony_ci            signal_->attrQueue_.pop();
449da853ecaSopenharmony_ci        }
450da853ecaSopenharmony_ci        while (!signal_->outBufferQueue_.empty()) {
451da853ecaSopenharmony_ci            signal_->outBufferQueue_.pop();
452da853ecaSopenharmony_ci        }
453da853ecaSopenharmony_ci        std::cout << "clear output buffer!\n";
454da853ecaSopenharmony_ci    }
455da853ecaSopenharmony_ci    return OH_AudioDecoder_Flush(audioDec_);
456da853ecaSopenharmony_ci}
457da853ecaSopenharmony_ci
458da853ecaSopenharmony_ciint32_t ADecDemoAuto::Reset()
459da853ecaSopenharmony_ci{
460da853ecaSopenharmony_ci    return OH_AudioDecoder_Reset(audioDec_);
461da853ecaSopenharmony_ci}
462da853ecaSopenharmony_ci
463da853ecaSopenharmony_ciint32_t ADecDemoAuto::Release()
464da853ecaSopenharmony_ci{
465da853ecaSopenharmony_ci    return OH_AudioDecoder_Destroy(audioDec_);
466da853ecaSopenharmony_ci}
467da853ecaSopenharmony_ci
468da853ecaSopenharmony_civoid ADecDemoAuto::HandleInputEOS(const uint32_t index)
469da853ecaSopenharmony_ci{
470da853ecaSopenharmony_ci    OH_AVCodecBufferAttr info;
471da853ecaSopenharmony_ci    info.size = 0;
472da853ecaSopenharmony_ci    info.offset = 0;
473da853ecaSopenharmony_ci    info.pts = 0;
474da853ecaSopenharmony_ci    info.flags = AVCODEC_BUFFER_FLAGS_EOS;
475da853ecaSopenharmony_ci    OH_AudioDecoder_PushInputData(audioDec_, index, info);
476da853ecaSopenharmony_ci    signal_->inBufferQueue_.pop();
477da853ecaSopenharmony_ci    signal_->inQueue_.pop();
478da853ecaSopenharmony_ci}
479da853ecaSopenharmony_ci
480da853ecaSopenharmony_ciint32_t ADecDemoAuto::HandleNormalInput(const uint32_t& index, const int64_t pts, const size_t size)
481da853ecaSopenharmony_ci{
482da853ecaSopenharmony_ci    OH_AVCodecBufferAttr info;
483da853ecaSopenharmony_ci    info.size = size;
484da853ecaSopenharmony_ci    info.offset = 0;
485da853ecaSopenharmony_ci    info.pts = pts;
486da853ecaSopenharmony_ci
487da853ecaSopenharmony_ci    int32_t ret = AVCS_ERR_OK;
488da853ecaSopenharmony_ci    if (isFirstFrame_) {
489da853ecaSopenharmony_ci        info.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
490da853ecaSopenharmony_ci        ret = OH_AudioDecoder_PushInputData(audioDec_, index, info);
491da853ecaSopenharmony_ci        isFirstFrame_ = false;
492da853ecaSopenharmony_ci    } else {
493da853ecaSopenharmony_ci        info.flags = AVCODEC_BUFFER_FLAGS_NONE;
494da853ecaSopenharmony_ci        ret = OH_AudioDecoder_PushInputData(audioDec_, index, info);
495da853ecaSopenharmony_ci    }
496da853ecaSopenharmony_ci    signal_->inQueue_.pop();
497da853ecaSopenharmony_ci    signal_->inBufferQueue_.pop();
498da853ecaSopenharmony_ci    frameCount_++;
499da853ecaSopenharmony_ci    return ret;
500da853ecaSopenharmony_ci}
501da853ecaSopenharmony_ci
502da853ecaSopenharmony_civoid ADecDemoAuto::InputFunc()
503da853ecaSopenharmony_ci{
504da853ecaSopenharmony_ci    size_t frameBytes = 1152;
505da853ecaSopenharmony_ci    if (audioType_ == TYPE_OPUS) {
506da853ecaSopenharmony_ci        size_t opussize = 320;
507da853ecaSopenharmony_ci        frameBytes = opussize;
508da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_G711MU) {
509da853ecaSopenharmony_ci        size_t gmusize = 320;
510da853ecaSopenharmony_ci        frameBytes = gmusize;
511da853ecaSopenharmony_ci    } else if (audioType_ == TYPE_AAC) {
512da853ecaSopenharmony_ci        size_t aacsize = 1024;
513da853ecaSopenharmony_ci        frameBytes = aacsize;
514da853ecaSopenharmony_ci    }
515da853ecaSopenharmony_ci    size_t currentSize = inputdatasize < frameBytes ? inputdatasize : frameBytes;
516da853ecaSopenharmony_ci    int64_t pts = 0;
517da853ecaSopenharmony_ci    while (isRunning_.load()) {
518da853ecaSopenharmony_ci        unique_lock<mutex> lock(signal_->inMutex_);
519da853ecaSopenharmony_ci        signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); });
520da853ecaSopenharmony_ci
521da853ecaSopenharmony_ci        if (!isRunning_.load()) {
522da853ecaSopenharmony_ci            break;
523da853ecaSopenharmony_ci        }
524da853ecaSopenharmony_ci
525da853ecaSopenharmony_ci        uint32_t index = signal_->inQueue_.front();
526da853ecaSopenharmony_ci        auto buffer = signal_->inBufferQueue_.front();
527da853ecaSopenharmony_ci        DEMO_CHECK_AND_BREAK_LOG(buffer != nullptr, "Fatal: GetInputBuffer fail");
528da853ecaSopenharmony_ci
529da853ecaSopenharmony_ci        if (isFirstFrame_ == false || currentSize <= 0) {
530da853ecaSopenharmony_ci            HandleInputEOS(index);
531da853ecaSopenharmony_ci            std::cout << "end buffer\n";
532da853ecaSopenharmony_ci            isRunning_.store(false);
533da853ecaSopenharmony_ci            break;
534da853ecaSopenharmony_ci        }
535da853ecaSopenharmony_ci
536da853ecaSopenharmony_ci        strncpy_s((char *)OH_AVMemory_GetAddr(buffer), currentSize, inputdata.c_str(), currentSize);
537da853ecaSopenharmony_ci        int32_t ret = HandleNormalInput(index, pts, currentSize);
538da853ecaSopenharmony_ci        if (ret != AVCS_ERR_OK) {
539da853ecaSopenharmony_ci            cout << "Fatal, exit" << endl;
540da853ecaSopenharmony_ci            isRunning_.store(false);
541da853ecaSopenharmony_ci            break;
542da853ecaSopenharmony_ci        }
543da853ecaSopenharmony_ci    }
544da853ecaSopenharmony_ci    signal_->startCond_.notify_all();
545da853ecaSopenharmony_ci}
546da853ecaSopenharmony_ci
547da853ecaSopenharmony_civoid ADecDemoAuto::OutputFunc()
548da853ecaSopenharmony_ci{
549da853ecaSopenharmony_ci    while (isRunning_.load()) {
550da853ecaSopenharmony_ci        unique_lock<mutex> lock(signal_->outMutex_);
551da853ecaSopenharmony_ci        signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); });
552da853ecaSopenharmony_ci        if (!isRunning_.load()) {
553da853ecaSopenharmony_ci            cout << "wait to stop, exit" << endl;
554da853ecaSopenharmony_ci            break;
555da853ecaSopenharmony_ci        }
556da853ecaSopenharmony_ci        uint32_t index = signal_->outQueue_.front();
557da853ecaSopenharmony_ci        OH_AVCodecBufferAttr attr = signal_->attrQueue_.front();
558da853ecaSopenharmony_ci        if (attr.flags == AVCODEC_BUFFER_FLAGS_EOS) {
559da853ecaSopenharmony_ci            cout << "decode eos" << endl;
560da853ecaSopenharmony_ci            isRunning_.store(false);
561da853ecaSopenharmony_ci            signal_->startCond_.notify_all();
562da853ecaSopenharmony_ci        }
563da853ecaSopenharmony_ci        signal_->outBufferQueue_.pop();
564da853ecaSopenharmony_ci        signal_->attrQueue_.pop();
565da853ecaSopenharmony_ci        signal_->outQueue_.pop();
566da853ecaSopenharmony_ci        if (OH_AudioDecoder_FreeOutputData(audioDec_, index) != AV_ERR_OK) {
567da853ecaSopenharmony_ci            cout << "Fatal: FreeOutputData fail" << endl;
568da853ecaSopenharmony_ci            break;
569da853ecaSopenharmony_ci        }
570da853ecaSopenharmony_ci    }
571da853ecaSopenharmony_ci    signal_->startCond_.notify_all();
572da853ecaSopenharmony_ci}
573da853ecaSopenharmony_ci
574da853ecaSopenharmony_cibool ADecDemoAuto::RunCaseFlush(const uint8_t *data, size_t size)
575da853ecaSopenharmony_ci{
576da853ecaSopenharmony_ci    std::string codecdata(reinterpret_cast<const char*>(data), size);
577da853ecaSopenharmony_ci    inputdata = codecdata;
578da853ecaSopenharmony_ci    inputdatasize = size;
579da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(CreateDec() == AVCS_ERR_OK, false, "Fatal: CreateDec fail");
580da853ecaSopenharmony_ci    OH_AVFormat* format = OH_AVFormat_Create();
581da853ecaSopenharmony_ci    auto res = InitFormat(format);
582da853ecaSopenharmony_ci    if (res == false) {
583da853ecaSopenharmony_ci        return false;
584da853ecaSopenharmony_ci    }
585da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(Start() == AVCS_ERR_OK, false, "Fatal: Start fail");
586da853ecaSopenharmony_ci    auto start = chrono::steady_clock::now();
587da853ecaSopenharmony_ci
588da853ecaSopenharmony_ci    unique_lock<mutex> lock(signal_->startMutex_);
589da853ecaSopenharmony_ci    signal_->startCond_.wait(lock, [this]() { return (!(isRunning_.load())); });
590da853ecaSopenharmony_ci
591da853ecaSopenharmony_ci    auto end = chrono::steady_clock::now();
592da853ecaSopenharmony_ci    std::cout << "Encode finished, time = " << std::chrono::duration_cast<chrono::milliseconds>(end - start).count()
593da853ecaSopenharmony_ci        << " ms" << std::endl;
594da853ecaSopenharmony_ci    //Flush
595da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(Flush() == AVCS_ERR_OK, false, "Fatal: Flush fail");
596da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(Stop() == AVCS_ERR_OK, false, "Fatal: Stop fail");
597da853ecaSopenharmony_ci    DEMO_CHECK_AND_RETURN_RET_LOG(Release() == AVCS_ERR_OK, false, "Fatal: Release fail");
598da853ecaSopenharmony_ci    if (format != nullptr) {
599da853ecaSopenharmony_ci        OH_AVFormat_Destroy(format);
600da853ecaSopenharmony_ci        format = nullptr;
601da853ecaSopenharmony_ci    }
602da853ecaSopenharmony_ci    sleep(1);
603da853ecaSopenharmony_ci    return true;
604da853ecaSopenharmony_ci}