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::RunCaseReset(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 581da853ecaSopenharmony_ci OH_AVFormat* format = OH_AVFormat_Create(); 582da853ecaSopenharmony_ci auto res = InitFormat(format); 583da853ecaSopenharmony_ci if (res == false) { 584da853ecaSopenharmony_ci return false; 585da853ecaSopenharmony_ci } 586da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(Start() == AVCS_ERR_OK, false, "Fatal: Start fail"); 587da853ecaSopenharmony_ci auto start = chrono::steady_clock::now(); 588da853ecaSopenharmony_ci 589da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->startMutex_); 590da853ecaSopenharmony_ci signal_->startCond_.wait(lock, [this]() { return (!(isRunning_.load())); }); 591da853ecaSopenharmony_ci 592da853ecaSopenharmony_ci auto end = chrono::steady_clock::now(); 593da853ecaSopenharmony_ci std::cout << "Encode finished, time = " << std::chrono::duration_cast<chrono::milliseconds>(end - start).count() 594da853ecaSopenharmony_ci << " ms" << std::endl; 595da853ecaSopenharmony_ci 596da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(Stop() == AVCS_ERR_OK, false, "Fatal: Stop fail"); 597da853ecaSopenharmony_ci //Reset 598da853ecaSopenharmony_ci if (AV_ERR_OK != Reset(audioDec_)) { 599da853ecaSopenharmony_ci return false; 600da853ecaSopenharmony_ci } 601da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(Release() == AVCS_ERR_OK, false, "Fatal: Release fail"); 602da853ecaSopenharmony_ci if (format != nullptr) { 603da853ecaSopenharmony_ci OH_AVFormat_Destroy(format); 604da853ecaSopenharmony_ci format = nullptr; 605da853ecaSopenharmony_ci } 606da853ecaSopenharmony_ci sleep(1); 607da853ecaSopenharmony_ci return true; 608da853ecaSopenharmony_ci}