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 20da853ecaSopenharmony_ci#include "securec.h" 21da853ecaSopenharmony_ci#include "demo_log.h" 22da853ecaSopenharmony_ci#include "avcodec_common.h" 23da853ecaSopenharmony_ci#include "avcodec_errors.h" 24da853ecaSopenharmony_ci#include "native_averrors.h" 25da853ecaSopenharmony_ci#include "native_avformat.h" 26da853ecaSopenharmony_ci#include "audioencoderdemo.h" 27da853ecaSopenharmony_ci#include "media_description.h" 28da853ecaSopenharmony_ci#include "avcodec_mime_type.h" 29da853ecaSopenharmony_ci#include "avcodec_codec_name.h" 30da853ecaSopenharmony_ci#include "native_avcodec_base.h" 31da853ecaSopenharmony_ci#include "avcodec_audio_channel_layout.h" 32da853ecaSopenharmony_ci 33da853ecaSopenharmony_ciusing namespace OHOS; 34da853ecaSopenharmony_ciusing namespace OHOS::MediaAVCodec; 35da853ecaSopenharmony_ciusing namespace OHOS::MediaAVCodec::AudioEncDemoAuto; 36da853ecaSopenharmony_ciusing namespace std; 37da853ecaSopenharmony_ci 38da853ecaSopenharmony_cinamespace OHOS { 39da853ecaSopenharmony_cinamespace MediaAVCodec { 40da853ecaSopenharmony_cinamespace AudioEncDemoAuto { 41da853ecaSopenharmony_ci constexpr uint32_t CHANNEL_COUNT = 2; 42da853ecaSopenharmony_ci constexpr uint32_t SAMPLE_RATE = 48000; 43da853ecaSopenharmony_ci constexpr uint32_t SAMPLE_RATE_8000 = 8000; 44da853ecaSopenharmony_ci constexpr uint32_t BIT_RATE_64000 = 64000; 45da853ecaSopenharmony_ci constexpr int32_t CHANNEL_COUNT_1 = 1; 46da853ecaSopenharmony_ci constexpr uint32_t DEFAULT_AAC_TYPE = 1; 47da853ecaSopenharmony_ci constexpr int32_t BIT_PER_CODE_COUNT = 16; 48da853ecaSopenharmony_ci constexpr int32_t COMPLEXITY_COUNT = 10; 49da853ecaSopenharmony_ci constexpr int32_t CHANNEL_1 = 1; 50da853ecaSopenharmony_ci constexpr int32_t CHANNEL_2 = 2; 51da853ecaSopenharmony_ci constexpr int32_t CHANNEL_3 = 3; 52da853ecaSopenharmony_ci constexpr int32_t CHANNEL_4 = 4; 53da853ecaSopenharmony_ci constexpr int32_t CHANNEL_5 = 5; 54da853ecaSopenharmony_ci constexpr int32_t CHANNEL_6 = 6; 55da853ecaSopenharmony_ci constexpr int32_t CHANNEL_7 = 7; 56da853ecaSopenharmony_ci constexpr int32_t CHANNEL_8 = 8; 57da853ecaSopenharmony_ci 58da853ecaSopenharmony_ci void OnError(OH_AVCodec* codec, int32_t errorCode, void* userData) 59da853ecaSopenharmony_ci { 60da853ecaSopenharmony_ci (void)codec; 61da853ecaSopenharmony_ci (void)errorCode; 62da853ecaSopenharmony_ci (void)userData; 63da853ecaSopenharmony_ci } 64da853ecaSopenharmony_ci 65da853ecaSopenharmony_ci void OnOutputFormatChanged(OH_AVCodec* codec, OH_AVFormat* format, void* userData) 66da853ecaSopenharmony_ci { 67da853ecaSopenharmony_ci (void)codec; 68da853ecaSopenharmony_ci (void)format; 69da853ecaSopenharmony_ci (void)userData; 70da853ecaSopenharmony_ci cout << "OnOutputFormatChanged received" << endl; 71da853ecaSopenharmony_ci } 72da853ecaSopenharmony_ci 73da853ecaSopenharmony_ci void OnInputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data, void* userData) 74da853ecaSopenharmony_ci { 75da853ecaSopenharmony_ci (void)codec; 76da853ecaSopenharmony_ci AEncSignal* signal = static_cast<AEncSignal*>(userData); 77da853ecaSopenharmony_ci unique_lock<mutex> lock(signal->inMutex_); 78da853ecaSopenharmony_ci signal->inQueue_.push(index); 79da853ecaSopenharmony_ci signal->inBufferQueue_.push(data); 80da853ecaSopenharmony_ci signal->inCond_.notify_all(); 81da853ecaSopenharmony_ci } 82da853ecaSopenharmony_ci 83da853ecaSopenharmony_ci void OnOutputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data, OH_AVCodecBufferAttr* attr, 84da853ecaSopenharmony_ci void* userData) 85da853ecaSopenharmony_ci { 86da853ecaSopenharmony_ci (void)codec; 87da853ecaSopenharmony_ci AEncSignal* signal = static_cast<AEncSignal*>(userData); 88da853ecaSopenharmony_ci unique_lock<mutex> lock(signal->outMutex_); 89da853ecaSopenharmony_ci signal->outQueue_.push(index); 90da853ecaSopenharmony_ci signal->outBufferQueue_.push(data); 91da853ecaSopenharmony_ci if (attr) { 92da853ecaSopenharmony_ci signal->attrQueue_.push(*attr); 93da853ecaSopenharmony_ci } else { 94da853ecaSopenharmony_ci cout << "OnOutputBufferAvailable, attr is nullptr!" << endl; 95da853ecaSopenharmony_ci } 96da853ecaSopenharmony_ci signal->outCond_.notify_all(); 97da853ecaSopenharmony_ci } 98da853ecaSopenharmony_ci} 99da853ecaSopenharmony_ci} 100da853ecaSopenharmony_ci} 101da853ecaSopenharmony_ci 102da853ecaSopenharmony_cistatic uint64_t GetChannelLayout(int32_t channel) 103da853ecaSopenharmony_ci{ 104da853ecaSopenharmony_ci switch (channel) { 105da853ecaSopenharmony_ci case CHANNEL_1: 106da853ecaSopenharmony_ci return MONO; 107da853ecaSopenharmony_ci case CHANNEL_2: 108da853ecaSopenharmony_ci return STEREO; 109da853ecaSopenharmony_ci case CHANNEL_3: 110da853ecaSopenharmony_ci return CH_2POINT1; 111da853ecaSopenharmony_ci case CHANNEL_4: 112da853ecaSopenharmony_ci return CH_3POINT1; 113da853ecaSopenharmony_ci case CHANNEL_5: 114da853ecaSopenharmony_ci return CH_4POINT1; 115da853ecaSopenharmony_ci case CHANNEL_6: 116da853ecaSopenharmony_ci return CH_5POINT1; 117da853ecaSopenharmony_ci case CHANNEL_7: 118da853ecaSopenharmony_ci return CH_6POINT1; 119da853ecaSopenharmony_ci case CHANNEL_8: 120da853ecaSopenharmony_ci return CH_7POINT1; 121da853ecaSopenharmony_ci default: 122da853ecaSopenharmony_ci return UNKNOWN_CHANNEL_LAYOUT; 123da853ecaSopenharmony_ci } 124da853ecaSopenharmony_ci} 125da853ecaSopenharmony_ci 126da853ecaSopenharmony_civoid AEncDemoAuto::HandleEOS(const uint32_t& index) 127da853ecaSopenharmony_ci{ 128da853ecaSopenharmony_ci OH_AVCodecBufferAttr info; 129da853ecaSopenharmony_ci info.size = 0; 130da853ecaSopenharmony_ci info.offset = 0; 131da853ecaSopenharmony_ci info.pts = 0; 132da853ecaSopenharmony_ci info.flags = AVCODEC_BUFFER_FLAGS_EOS; 133da853ecaSopenharmony_ci OH_AudioEncoder_PushInputData(audioEnc_, index, info); 134da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 135da853ecaSopenharmony_ci signal_->inQueue_.pop(); 136da853ecaSopenharmony_ci} 137da853ecaSopenharmony_ci 138da853ecaSopenharmony_ciOH_AVCodec* AEncDemoAuto::CreateByMime(const char* mime) 139da853ecaSopenharmony_ci{ 140da853ecaSopenharmony_ci return OH_AudioEncoder_CreateByMime(mime); 141da853ecaSopenharmony_ci} 142da853ecaSopenharmony_ci 143da853ecaSopenharmony_ciOH_AVCodec* AEncDemoAuto::CreateByName(const char* name) 144da853ecaSopenharmony_ci{ 145da853ecaSopenharmony_ci return OH_AudioEncoder_CreateByName(name); 146da853ecaSopenharmony_ci} 147da853ecaSopenharmony_ci 148da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::Destroy(OH_AVCodec* codec) 149da853ecaSopenharmony_ci{ 150da853ecaSopenharmony_ci if (format_ != nullptr) { 151da853ecaSopenharmony_ci OH_AVFormat_Destroy(format_); 152da853ecaSopenharmony_ci format_ = nullptr; 153da853ecaSopenharmony_ci } 154da853ecaSopenharmony_ci OH_AVErrCode ret = OH_AudioEncoder_Destroy(codec); 155da853ecaSopenharmony_ci ClearQueue(); 156da853ecaSopenharmony_ci return ret; 157da853ecaSopenharmony_ci} 158da853ecaSopenharmony_ci 159da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::SetCallback(OH_AVCodec* codec) 160da853ecaSopenharmony_ci{ 161da853ecaSopenharmony_ci cb_ = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable }; 162da853ecaSopenharmony_ci return OH_AudioEncoder_SetCallback(codec, cb_, signal_); 163da853ecaSopenharmony_ci} 164da853ecaSopenharmony_ci 165da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::Prepare(OH_AVCodec* codec) 166da853ecaSopenharmony_ci{ 167da853ecaSopenharmony_ci return OH_AudioEncoder_Prepare(codec); 168da853ecaSopenharmony_ci} 169da853ecaSopenharmony_ci 170da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::Start(OH_AVCodec* codec) 171da853ecaSopenharmony_ci{ 172da853ecaSopenharmony_ci return OH_AudioEncoder_Start(codec); 173da853ecaSopenharmony_ci} 174da853ecaSopenharmony_ci 175da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::Stop(OH_AVCodec* codec) 176da853ecaSopenharmony_ci{ 177da853ecaSopenharmony_ci OH_AVErrCode ret = OH_AudioEncoder_Stop(codec); 178da853ecaSopenharmony_ci ClearQueue(); 179da853ecaSopenharmony_ci return ret; 180da853ecaSopenharmony_ci} 181da853ecaSopenharmony_ci 182da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::Flush(OH_AVCodec* codec) 183da853ecaSopenharmony_ci{ 184da853ecaSopenharmony_ci OH_AVErrCode ret = OH_AudioEncoder_Flush(codec); 185da853ecaSopenharmony_ci std::cout << "Flush ret:"<< ret <<endl; 186da853ecaSopenharmony_ci ClearQueue(); 187da853ecaSopenharmony_ci return ret; 188da853ecaSopenharmony_ci} 189da853ecaSopenharmony_ci 190da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::Reset(OH_AVCodec* codec) 191da853ecaSopenharmony_ci{ 192da853ecaSopenharmony_ci return OH_AudioEncoder_Reset(codec); 193da853ecaSopenharmony_ci} 194da853ecaSopenharmony_ci 195da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::PushInputData(OH_AVCodec* codec, uint32_t index, int32_t size, int32_t offset) 196da853ecaSopenharmony_ci{ 197da853ecaSopenharmony_ci OH_AVCodecBufferAttr info; 198da853ecaSopenharmony_ci info.size = size; 199da853ecaSopenharmony_ci info.offset = offset; 200da853ecaSopenharmony_ci info.pts = 0; 201da853ecaSopenharmony_ci info.flags = AVCODEC_BUFFER_FLAGS_NONE; 202da853ecaSopenharmony_ci return OH_AudioEncoder_PushInputData(codec, index, info); 203da853ecaSopenharmony_ci} 204da853ecaSopenharmony_ci 205da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::PushInputDataEOS(OH_AVCodec* codec, uint32_t index) 206da853ecaSopenharmony_ci{ 207da853ecaSopenharmony_ci OH_AVCodecBufferAttr info; 208da853ecaSopenharmony_ci info.size = 0; 209da853ecaSopenharmony_ci info.offset = 0; 210da853ecaSopenharmony_ci info.pts = 0; 211da853ecaSopenharmony_ci info.flags = AVCODEC_BUFFER_FLAGS_EOS; 212da853ecaSopenharmony_ci 213da853ecaSopenharmony_ci return OH_AudioEncoder_PushInputData(codec, index, info); 214da853ecaSopenharmony_ci} 215da853ecaSopenharmony_ci 216da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::FreeOutputData(OH_AVCodec* codec, uint32_t index) 217da853ecaSopenharmony_ci{ 218da853ecaSopenharmony_ci return OH_AudioEncoder_FreeOutputData(codec, index); 219da853ecaSopenharmony_ci} 220da853ecaSopenharmony_ci 221da853ecaSopenharmony_ciOH_AVErrCode AEncDemoAuto::IsValid(OH_AVCodec* codec, bool* isValid) 222da853ecaSopenharmony_ci{ 223da853ecaSopenharmony_ci return OH_AudioEncoder_IsValid(codec, isValid); 224da853ecaSopenharmony_ci} 225da853ecaSopenharmony_ci 226da853ecaSopenharmony_ciuint32_t AEncDemoAuto::GetInputIndex() 227da853ecaSopenharmony_ci{ 228da853ecaSopenharmony_ci int32_t sleepTime = 0; 229da853ecaSopenharmony_ci uint32_t index; 230da853ecaSopenharmony_ci int32_t condTime = 5; 231da853ecaSopenharmony_ci while (signal_->inQueue_.empty() && sleepTime < condTime) { 232da853ecaSopenharmony_ci sleep(1); 233da853ecaSopenharmony_ci sleepTime++; 234da853ecaSopenharmony_ci } 235da853ecaSopenharmony_ci if (sleepTime >= condTime) { 236da853ecaSopenharmony_ci return 0; 237da853ecaSopenharmony_ci } else { 238da853ecaSopenharmony_ci index = signal_->inQueue_.front(); 239da853ecaSopenharmony_ci signal_->inQueue_.pop(); 240da853ecaSopenharmony_ci } 241da853ecaSopenharmony_ci return index; 242da853ecaSopenharmony_ci} 243da853ecaSopenharmony_ci 244da853ecaSopenharmony_ciuint32_t AEncDemoAuto::GetOutputIndex() 245da853ecaSopenharmony_ci{ 246da853ecaSopenharmony_ci int32_t sleepTime = 0; 247da853ecaSopenharmony_ci uint32_t index; 248da853ecaSopenharmony_ci int32_t condTime = 5; 249da853ecaSopenharmony_ci while (signal_->outQueue_.empty() && sleepTime < condTime) { 250da853ecaSopenharmony_ci sleep(1); 251da853ecaSopenharmony_ci sleepTime++; 252da853ecaSopenharmony_ci } 253da853ecaSopenharmony_ci if (sleepTime >= condTime) { 254da853ecaSopenharmony_ci return 0; 255da853ecaSopenharmony_ci } else { 256da853ecaSopenharmony_ci index = signal_->outQueue_.front(); 257da853ecaSopenharmony_ci signal_->outQueue_.pop(); 258da853ecaSopenharmony_ci } 259da853ecaSopenharmony_ci return index; 260da853ecaSopenharmony_ci} 261da853ecaSopenharmony_ci 262da853ecaSopenharmony_civoid AEncDemoAuto::ClearQueue() 263da853ecaSopenharmony_ci{ 264da853ecaSopenharmony_ci while (!signal_->inQueue_.empty()) { 265da853ecaSopenharmony_ci signal_->inQueue_.pop(); 266da853ecaSopenharmony_ci } 267da853ecaSopenharmony_ci while (!signal_->outQueue_.empty()) { 268da853ecaSopenharmony_ci signal_->outQueue_.pop(); 269da853ecaSopenharmony_ci } 270da853ecaSopenharmony_ci while (!signal_->inBufferQueue_.empty()) { 271da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 272da853ecaSopenharmony_ci } 273da853ecaSopenharmony_ci while (!signal_->outBufferQueue_.empty()) { 274da853ecaSopenharmony_ci signal_->outBufferQueue_.pop(); 275da853ecaSopenharmony_ci } 276da853ecaSopenharmony_ci while (!signal_->attrQueue_.empty()) { 277da853ecaSopenharmony_ci signal_->attrQueue_.pop(); 278da853ecaSopenharmony_ci } 279da853ecaSopenharmony_ci} 280da853ecaSopenharmony_ci 281da853ecaSopenharmony_cibool AEncDemoAuto::InitFile(string inputFile) 282da853ecaSopenharmony_ci{ 283da853ecaSopenharmony_ci if (inputFile.find("opus") != std::string::npos) { 284da853ecaSopenharmony_ci audioType_ = TYPE_OPUS; 285da853ecaSopenharmony_ci } else if (inputFile.find("g711") != std::string::npos) { 286da853ecaSopenharmony_ci audioType_ = TYPE_G711MU; 287da853ecaSopenharmony_ci } else if (inputFile.find("flac") != std::string::npos) { 288da853ecaSopenharmony_ci audioType_ = TYPE_FLAC; 289da853ecaSopenharmony_ci } else { 290da853ecaSopenharmony_ci audioType_ = TYPE_AAC; 291da853ecaSopenharmony_ci } 292da853ecaSopenharmony_ci return true; 293da853ecaSopenharmony_ci} 294da853ecaSopenharmony_ci 295da853ecaSopenharmony_ciAEncDemoAuto::AEncDemoAuto() 296da853ecaSopenharmony_ci{ 297da853ecaSopenharmony_ci audioEnc_ = nullptr; 298da853ecaSopenharmony_ci signal_ = new AEncSignal(); 299da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_LOG(signal_ != nullptr, "Fatal: No memory"); 300da853ecaSopenharmony_ci format_ = nullptr; 301da853ecaSopenharmony_ci audioType_ = TYPE_OPUS; 302da853ecaSopenharmony_ci} 303da853ecaSopenharmony_ci 304da853ecaSopenharmony_ci 305da853ecaSopenharmony_ciAEncDemoAuto::~AEncDemoAuto() 306da853ecaSopenharmony_ci{ 307da853ecaSopenharmony_ci isRunning_.store(false); 308da853ecaSopenharmony_ci if (signal_) { 309da853ecaSopenharmony_ci delete signal_; 310da853ecaSopenharmony_ci signal_ = nullptr; 311da853ecaSopenharmony_ci } 312da853ecaSopenharmony_ci} 313da853ecaSopenharmony_ci 314da853ecaSopenharmony_ciint32_t AEncDemoAuto::CreateEnd() 315da853ecaSopenharmony_ci{ 316da853ecaSopenharmony_ci if (audioType_ == TYPE_AAC) { 317da853ecaSopenharmony_ci audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecCodecName::AUDIO_ENCODER_AAC_NAME).data()); 318da853ecaSopenharmony_ci } else if (audioType_ == TYPE_FLAC) { 319da853ecaSopenharmony_ci audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecCodecName::AUDIO_ENCODER_FLAC_NAME).data()); 320da853ecaSopenharmony_ci } else if (audioType_ == TYPE_OPUS) { 321da853ecaSopenharmony_ci audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecCodecName::AUDIO_ENCODER_OPUS_NAME).data()); 322da853ecaSopenharmony_ci } else if (audioType_ == TYPE_G711MU) { 323da853ecaSopenharmony_ci audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecCodecName::AUDIO_ENCODER_G711MU_NAME).data()); 324da853ecaSopenharmony_ci } else { 325da853ecaSopenharmony_ci return AVCS_ERR_INVALID_VAL; 326da853ecaSopenharmony_ci } 327da853ecaSopenharmony_ci 328da853ecaSopenharmony_ci if (signal_ == nullptr) { 329da853ecaSopenharmony_ci signal_ = new AEncSignal(); 330da853ecaSopenharmony_ci } 331da853ecaSopenharmony_ci if (signal_ == nullptr) { 332da853ecaSopenharmony_ci return AVCS_ERR_UNKNOWN; 333da853ecaSopenharmony_ci } 334da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(audioEnc_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByName fail"); 335da853ecaSopenharmony_ci 336da853ecaSopenharmony_ci cb_ = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable }; 337da853ecaSopenharmony_ci int32_t ret = OH_AudioEncoder_SetCallback(audioEnc_, cb_, signal_); 338da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_UNKNOWN, "Fatal: SetCallback fail"); 339da853ecaSopenharmony_ci 340da853ecaSopenharmony_ci return AVCS_ERR_OK; 341da853ecaSopenharmony_ci} 342da853ecaSopenharmony_ci 343da853ecaSopenharmony_ciint32_t AEncDemoAuto::CreateEndByMime() 344da853ecaSopenharmony_ci{ 345da853ecaSopenharmony_ci if (audioType_ == TYPE_AAC) { 346da853ecaSopenharmony_ci audioEnc_ = OH_AudioEncoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_AAC).data()); 347da853ecaSopenharmony_ci } else if (audioType_ == TYPE_FLAC) { 348da853ecaSopenharmony_ci audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_FLAC).data()); 349da853ecaSopenharmony_ci } else if (audioType_ == TYPE_OPUS) { 350da853ecaSopenharmony_ci audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_OPUS).data()); 351da853ecaSopenharmony_ci } else if (audioType_ == TYPE_G711MU) { 352da853ecaSopenharmony_ci audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_G711MU).data()); 353da853ecaSopenharmony_ci } else { 354da853ecaSopenharmony_ci return AVCS_ERR_INVALID_VAL; 355da853ecaSopenharmony_ci } 356da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(audioEnc_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByMime fail"); 357da853ecaSopenharmony_ci return AVCS_ERR_OK; 358da853ecaSopenharmony_ci} 359da853ecaSopenharmony_ci 360da853ecaSopenharmony_civoid AEncDemoAuto::SetFormat(OH_AVFormat *format) 361da853ecaSopenharmony_ci{ 362da853ecaSopenharmony_ci int32_t channelCount = CHANNEL_COUNT; 363da853ecaSopenharmony_ci int32_t sampleRate = SAMPLE_RATE; 364da853ecaSopenharmony_ci if (audioType_ == TYPE_OPUS) { 365da853ecaSopenharmony_ci channelCount = CHANNEL_COUNT_1; 366da853ecaSopenharmony_ci sampleRate = SAMPLE_RATE_8000; 367da853ecaSopenharmony_ci OH_AVFormat_SetLongValue(format, MediaDescriptionKey::MD_KEY_BITRATE.data(), BIT_RATE_64000); 368da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_BITS_PER_CODED_SAMPLE.data(), BIT_PER_CODE_COUNT); 369da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_COMPLIANCE_LEVEL.data(), COMPLEXITY_COUNT); 370da853ecaSopenharmony_ci } else if (audioType_ == TYPE_G711MU) { 371da853ecaSopenharmony_ci channelCount = CHANNEL_COUNT_1; 372da853ecaSopenharmony_ci sampleRate = SAMPLE_RATE_8000; 373da853ecaSopenharmony_ci OH_AVFormat_SetLongValue(format, MediaDescriptionKey::MD_KEY_BITRATE.data(), BIT_RATE_64000); 374da853ecaSopenharmony_ci } else if (audioType_ == TYPE_FLAC) { 375da853ecaSopenharmony_ci uint64_t channelLayout = GetChannelLayout(CHANNEL_COUNT); 376da853ecaSopenharmony_ci OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, channelLayout); 377da853ecaSopenharmony_ci OH_AVFormat_SetLongValue(format, MediaDescriptionKey::MD_KEY_BITRATE.data(), BIT_RATE_64000); 378da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, OH_BitsPerSample::SAMPLE_S16LE); 379da853ecaSopenharmony_ci } else if (audioType_ == TYPE_AAC) { 380da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, DEFAULT_AAC_TYPE); 381da853ecaSopenharmony_ci } 382da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), channelCount); 383da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), sampleRate); 384da853ecaSopenharmony_ci OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(), 385da853ecaSopenharmony_ci AudioSampleFormat::SAMPLE_S16LE); 386da853ecaSopenharmony_ci} 387da853ecaSopenharmony_ci 388da853ecaSopenharmony_ciint32_t AEncDemoAuto::Configure(OH_AVFormat* format) 389da853ecaSopenharmony_ci{ 390da853ecaSopenharmony_ci return OH_AudioEncoder_Configure(audioEnc_, format); 391da853ecaSopenharmony_ci} 392da853ecaSopenharmony_ci 393da853ecaSopenharmony_ciint32_t AEncDemoAuto::Start() 394da853ecaSopenharmony_ci{ 395da853ecaSopenharmony_ci isRunning_.store(false); 396da853ecaSopenharmony_ci signal_->inCond_.notify_all(); 397da853ecaSopenharmony_ci signal_->outCond_.notify_all(); 398da853ecaSopenharmony_ci if (inputLoop_ != nullptr && inputLoop_->joinable()) { 399da853ecaSopenharmony_ci inputLoop_->join(); 400da853ecaSopenharmony_ci inputLoop_.reset(); 401da853ecaSopenharmony_ci inputLoop_ = nullptr; 402da853ecaSopenharmony_ci } 403da853ecaSopenharmony_ci 404da853ecaSopenharmony_ci if (outputLoop_ != nullptr && outputLoop_->joinable()) { 405da853ecaSopenharmony_ci outputLoop_->join(); 406da853ecaSopenharmony_ci outputLoop_.reset(); 407da853ecaSopenharmony_ci outputLoop_ = nullptr; 408da853ecaSopenharmony_ci } 409da853ecaSopenharmony_ci sleep(1); 410da853ecaSopenharmony_ci { 411da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 412da853ecaSopenharmony_ci while (!signal_->inQueue_.empty()) { 413da853ecaSopenharmony_ci signal_->inQueue_.pop(); 414da853ecaSopenharmony_ci } 415da853ecaSopenharmony_ci while (!signal_->inBufferQueue_.empty()) { 416da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 417da853ecaSopenharmony_ci } 418da853ecaSopenharmony_ci } 419da853ecaSopenharmony_ci { 420da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->outMutex_); 421da853ecaSopenharmony_ci while (!signal_->outQueue_.empty()) { 422da853ecaSopenharmony_ci signal_->outQueue_.pop(); 423da853ecaSopenharmony_ci } 424da853ecaSopenharmony_ci while (!signal_->attrQueue_.empty()) { 425da853ecaSopenharmony_ci signal_->attrQueue_.pop(); 426da853ecaSopenharmony_ci } 427da853ecaSopenharmony_ci while (!signal_->outBufferQueue_.empty()) { 428da853ecaSopenharmony_ci signal_->outBufferQueue_.pop(); 429da853ecaSopenharmony_ci } 430da853ecaSopenharmony_ci } 431da853ecaSopenharmony_ci isRunning_.store(true); 432da853ecaSopenharmony_ci inputLoop_ = make_unique<thread>(&AEncDemoAuto::InputFunc, this); 433da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(inputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory"); 434da853ecaSopenharmony_ci 435da853ecaSopenharmony_ci outputLoop_ = make_unique<thread>(&AEncDemoAuto::OutputFunc, this); 436da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(outputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory"); 437da853ecaSopenharmony_ci if (audioEnc_ == nullptr) { 438da853ecaSopenharmony_ci std::cout << "audioEnc_ is nullptr " << std::endl; 439da853ecaSopenharmony_ci } 440da853ecaSopenharmony_ci int32_t ret = OH_AudioEncoder_Start(audioEnc_); 441da853ecaSopenharmony_ci return ret; 442da853ecaSopenharmony_ci} 443da853ecaSopenharmony_ci 444da853ecaSopenharmony_ciint32_t AEncDemoAuto::Stop() 445da853ecaSopenharmony_ci{ 446da853ecaSopenharmony_ci return OH_AudioEncoder_Stop(audioEnc_); 447da853ecaSopenharmony_ci} 448da853ecaSopenharmony_ci 449da853ecaSopenharmony_ciint32_t AEncDemoAuto::Flush() 450da853ecaSopenharmony_ci{ 451da853ecaSopenharmony_ci OH_AVErrCode ret = OH_AudioEncoder_Flush(audioEnc_); 452da853ecaSopenharmony_ci return ret; 453da853ecaSopenharmony_ci} 454da853ecaSopenharmony_ci 455da853ecaSopenharmony_ciint32_t AEncDemoAuto::Release() 456da853ecaSopenharmony_ci{ 457da853ecaSopenharmony_ci isRunning_.store(false); 458da853ecaSopenharmony_ci signal_->startCond_.notify_all(); 459da853ecaSopenharmony_ci if (inputLoop_ != nullptr && inputLoop_->joinable()) { 460da853ecaSopenharmony_ci { 461da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 462da853ecaSopenharmony_ci signal_->inCond_.notify_all(); 463da853ecaSopenharmony_ci } 464da853ecaSopenharmony_ci inputLoop_->join(); 465da853ecaSopenharmony_ci inputLoop_.reset(); 466da853ecaSopenharmony_ci inputLoop_ = nullptr; 467da853ecaSopenharmony_ci while (!signal_->inQueue_.empty()) { 468da853ecaSopenharmony_ci signal_->inQueue_.pop(); 469da853ecaSopenharmony_ci } 470da853ecaSopenharmony_ci while (!signal_->inBufferQueue_.empty()) { 471da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 472da853ecaSopenharmony_ci } 473da853ecaSopenharmony_ci std::cout << "clear input buffer!\n"; 474da853ecaSopenharmony_ci } 475da853ecaSopenharmony_ci 476da853ecaSopenharmony_ci if (outputLoop_ != nullptr && outputLoop_->joinable()) { 477da853ecaSopenharmony_ci { 478da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->outMutex_); 479da853ecaSopenharmony_ci signal_->outCond_.notify_all(); 480da853ecaSopenharmony_ci } 481da853ecaSopenharmony_ci outputLoop_->join(); 482da853ecaSopenharmony_ci outputLoop_.reset(); 483da853ecaSopenharmony_ci outputLoop_ = nullptr; 484da853ecaSopenharmony_ci while (!signal_->outQueue_.empty()) { 485da853ecaSopenharmony_ci signal_->outQueue_.pop(); 486da853ecaSopenharmony_ci } 487da853ecaSopenharmony_ci while (!signal_->attrQueue_.empty()) { 488da853ecaSopenharmony_ci signal_->attrQueue_.pop(); 489da853ecaSopenharmony_ci } 490da853ecaSopenharmony_ci while (!signal_->outBufferQueue_.empty()) { 491da853ecaSopenharmony_ci signal_->outBufferQueue_.pop(); 492da853ecaSopenharmony_ci } 493da853ecaSopenharmony_ci std::cout << "clear output buffer!\n"; 494da853ecaSopenharmony_ci } 495da853ecaSopenharmony_ci if (signal_) { 496da853ecaSopenharmony_ci ClearQueue(); 497da853ecaSopenharmony_ci delete signal_; 498da853ecaSopenharmony_ci signal_ = nullptr; 499da853ecaSopenharmony_ci std::cout << "signal_Release" <<endl; 500da853ecaSopenharmony_ci } 501da853ecaSopenharmony_ci int32_t ret = OH_AudioEncoder_Destroy(audioEnc_); 502da853ecaSopenharmony_ci audioEnc_ = nullptr; 503da853ecaSopenharmony_ci return ret; 504da853ecaSopenharmony_ci} 505da853ecaSopenharmony_ci 506da853ecaSopenharmony_ciint32_t AEncDemoAuto::Reset() 507da853ecaSopenharmony_ci{ 508da853ecaSopenharmony_ci return OH_AudioEncoder_Reset(audioEnc_); 509da853ecaSopenharmony_ci} 510da853ecaSopenharmony_ci 511da853ecaSopenharmony_ciOH_AVFormat* AEncDemoAuto::GetOutputDescription(OH_AVCodec* codec) 512da853ecaSopenharmony_ci{ 513da853ecaSopenharmony_ci return OH_AudioEncoder_GetOutputDescription(codec); 514da853ecaSopenharmony_ci} 515da853ecaSopenharmony_ci 516da853ecaSopenharmony_civoid AEncDemoAuto::HandleInputEOS(const uint32_t index) 517da853ecaSopenharmony_ci{ 518da853ecaSopenharmony_ci OH_AVCodecBufferAttr info; 519da853ecaSopenharmony_ci info.size = 0; 520da853ecaSopenharmony_ci info.offset = 0; 521da853ecaSopenharmony_ci info.pts = 0; 522da853ecaSopenharmony_ci info.flags = AVCODEC_BUFFER_FLAGS_EOS; 523da853ecaSopenharmony_ci OH_AVErrCode ret = OH_AudioEncoder_PushInputData(audioEnc_, index, info); 524da853ecaSopenharmony_ci std::cout << "HandleInputEOS->ret:"<< ret <<endl; 525da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 526da853ecaSopenharmony_ci signal_->inQueue_.pop(); 527da853ecaSopenharmony_ci} 528da853ecaSopenharmony_ci 529da853ecaSopenharmony_ciint32_t AEncDemoAuto::HandleNormalInput(const uint32_t& index, const int64_t pts, const size_t size) 530da853ecaSopenharmony_ci{ 531da853ecaSopenharmony_ci OH_AVCodecBufferAttr info; 532da853ecaSopenharmony_ci info.size = size; 533da853ecaSopenharmony_ci info.offset = 0; 534da853ecaSopenharmony_ci info.pts = pts; 535da853ecaSopenharmony_ci 536da853ecaSopenharmony_ci int32_t ret = AVCS_ERR_OK; 537da853ecaSopenharmony_ci if (isFirstFrame_) { 538da853ecaSopenharmony_ci info.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA; 539da853ecaSopenharmony_ci ret = OH_AudioEncoder_PushInputData(audioEnc_, index, info); 540da853ecaSopenharmony_ci isFirstFrame_ = false; 541da853ecaSopenharmony_ci } else { 542da853ecaSopenharmony_ci info.flags = AVCODEC_BUFFER_FLAGS_NONE; 543da853ecaSopenharmony_ci ret = OH_AudioEncoder_PushInputData(audioEnc_, index, info); 544da853ecaSopenharmony_ci } 545da853ecaSopenharmony_ci signal_->inQueue_.pop(); 546da853ecaSopenharmony_ci signal_->inBufferQueue_.pop(); 547da853ecaSopenharmony_ci return ret; 548da853ecaSopenharmony_ci} 549da853ecaSopenharmony_ci 550da853ecaSopenharmony_ci 551da853ecaSopenharmony_civoid AEncDemoAuto::InputFunc() 552da853ecaSopenharmony_ci{ 553da853ecaSopenharmony_ci int64_t pts = 0; 554da853ecaSopenharmony_ci size_t frameBytes = 1152; 555da853ecaSopenharmony_ci if (audioType_ == TYPE_OPUS) { 556da853ecaSopenharmony_ci size_t opussize = 960; 557da853ecaSopenharmony_ci frameBytes = opussize; 558da853ecaSopenharmony_ci } else if (audioType_ == TYPE_G711MU) { 559da853ecaSopenharmony_ci size_t gmusize = 320; 560da853ecaSopenharmony_ci frameBytes = gmusize; 561da853ecaSopenharmony_ci } else if (audioType_ == TYPE_AAC) { 562da853ecaSopenharmony_ci size_t aacsize = 1024; 563da853ecaSopenharmony_ci frameBytes = aacsize; 564da853ecaSopenharmony_ci } 565da853ecaSopenharmony_ci size_t currentSize = inputdatasize < frameBytes ? inputdatasize : frameBytes; 566da853ecaSopenharmony_ci while (isRunning_.load()) { 567da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->inMutex_); 568da853ecaSopenharmony_ci signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); }); 569da853ecaSopenharmony_ci if (!isRunning_.load()) { 570da853ecaSopenharmony_ci break; 571da853ecaSopenharmony_ci } 572da853ecaSopenharmony_ci uint32_t index = signal_->inQueue_.front(); 573da853ecaSopenharmony_ci auto buffer = signal_->inBufferQueue_.front(); 574da853ecaSopenharmony_ci DEMO_CHECK_AND_BREAK_LOG(buffer != nullptr, "Fatal: GetInputBuffer fail"); 575da853ecaSopenharmony_ci strncpy_s((char *)OH_AVMemory_GetAddr(buffer), currentSize, inputdata.c_str(), currentSize); 576da853ecaSopenharmony_ci if (isFirstFrame_ == false || currentSize <= 0) { 577da853ecaSopenharmony_ci HandleInputEOS(index); 578da853ecaSopenharmony_ci std::cout << "end buffer\n"; 579da853ecaSopenharmony_ci isRunning_.store(false); 580da853ecaSopenharmony_ci break; 581da853ecaSopenharmony_ci } 582da853ecaSopenharmony_ci int32_t ret = HandleNormalInput(index, pts, frameBytes); 583da853ecaSopenharmony_ci if (ret != AVCS_ERR_OK) { 584da853ecaSopenharmony_ci cout << "Fatal, exit:" <<ret << endl; 585da853ecaSopenharmony_ci isRunning_.store(false); 586da853ecaSopenharmony_ci break; 587da853ecaSopenharmony_ci } 588da853ecaSopenharmony_ci } 589da853ecaSopenharmony_ci signal_->startCond_.notify_all(); 590da853ecaSopenharmony_ci} 591da853ecaSopenharmony_ci 592da853ecaSopenharmony_civoid AEncDemoAuto::OutputFunc() 593da853ecaSopenharmony_ci{ 594da853ecaSopenharmony_ci while (isRunning_.load()) { 595da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->outMutex_); 596da853ecaSopenharmony_ci signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); }); 597da853ecaSopenharmony_ci 598da853ecaSopenharmony_ci if (!isRunning_.load()) { 599da853ecaSopenharmony_ci cout << "wait to stop, exit" << endl; 600da853ecaSopenharmony_ci break; 601da853ecaSopenharmony_ci } 602da853ecaSopenharmony_ci uint32_t index = signal_->outQueue_.front(); 603da853ecaSopenharmony_ci OH_AVCodecBufferAttr attr = signal_->attrQueue_.front(); 604da853ecaSopenharmony_ci 605da853ecaSopenharmony_ci signal_->outBufferQueue_.pop(); 606da853ecaSopenharmony_ci signal_->attrQueue_.pop(); 607da853ecaSopenharmony_ci signal_->outQueue_.pop(); 608da853ecaSopenharmony_ci if (OH_AudioEncoder_FreeOutputData(audioEnc_, index) != AV_ERR_OK) { 609da853ecaSopenharmony_ci cout << "Fatal: FreeOutputData fail" << endl; 610da853ecaSopenharmony_ci break; 611da853ecaSopenharmony_ci } 612da853ecaSopenharmony_ci if (attr.flags == AVCODEC_BUFFER_FLAGS_EOS) { 613da853ecaSopenharmony_ci cout << "encode eos" << endl; 614da853ecaSopenharmony_ci break; 615da853ecaSopenharmony_ci } 616da853ecaSopenharmony_ci } 617da853ecaSopenharmony_ci isRunning_.store(false); 618da853ecaSopenharmony_ci signal_->startCond_.notify_all(); 619da853ecaSopenharmony_ci} 620da853ecaSopenharmony_ci 621da853ecaSopenharmony_cibool AEncDemoAuto::RunCaseFlush(const uint8_t *data, size_t size) 622da853ecaSopenharmony_ci{ 623da853ecaSopenharmony_ci std::string codecdata(reinterpret_cast<const char*>(data), size); 624da853ecaSopenharmony_ci inputdata = codecdata; 625da853ecaSopenharmony_ci inputdatasize = size; 626da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(CreateEnd() == AVCS_ERR_OK, false, "Fatal: CreateEnd fail"); 627da853ecaSopenharmony_ci OH_AVFormat* format = OH_AVFormat_Create(); 628da853ecaSopenharmony_ci SetFormat(format); 629da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(Configure(format) == AVCS_ERR_OK, false, "Fatal: Configure fail"); 630da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(Start() == AVCS_ERR_OK, false, "Fatal: Start fail"); 631da853ecaSopenharmony_ci sleep(1); 632da853ecaSopenharmony_ci auto start = chrono::steady_clock::now(); 633da853ecaSopenharmony_ci 634da853ecaSopenharmony_ci unique_lock<mutex> lock(signal_->startMutex_); 635da853ecaSopenharmony_ci signal_->startCond_.wait(lock, [this]() { return (!(isRunning_.load())); }); 636da853ecaSopenharmony_ci 637da853ecaSopenharmony_ci auto end = chrono::steady_clock::now(); 638da853ecaSopenharmony_ci std::cout << "Encode finished, time = " << std::chrono::duration_cast<chrono::milliseconds>(end - start).count() 639da853ecaSopenharmony_ci << " ms" << std::endl; 640da853ecaSopenharmony_ci //Flush 641da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(Flush() == AVCS_ERR_OK, false, "Fatal: Flush fail"); 642da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(Stop() == AVCS_ERR_OK, false, "Fatal: Stop fail"); 643da853ecaSopenharmony_ci DEMO_CHECK_AND_RETURN_RET_LOG(Release() == AVCS_ERR_OK, false, "Fatal: Release fail"); 644da853ecaSopenharmony_ci if (format != nullptr) { 645da853ecaSopenharmony_ci OH_AVFormat_Destroy(format); 646da853ecaSopenharmony_ci format = nullptr; 647da853ecaSopenharmony_ci } 648da853ecaSopenharmony_ci sleep(1); 649da853ecaSopenharmony_ci return true; 650da853ecaSopenharmony_ci}