diff --git a/interfaces/inner_api/native/avcodec_info.h b/interfaces/inner_api/native/avcodec_info.h index 9c56e929329692effd5cffb8a721591a00d227db..2424239ca42bc14be2e8d110ebb88fc4b77b4560 100644 --- a/interfaces/inner_api/native/avcodec_info.h +++ b/interfaces/inner_api/native/avcodec_info.h @@ -169,6 +169,7 @@ struct CapabilityData { std::map measuredFrameRate; bool supportSwapWidthHeight = false; std::map featuresMap; + int32_t rank = 0; }; struct LevelParams { diff --git a/services/engine/codeclist/audio_codeclist_info.cpp b/services/engine/codeclist/audio_codeclist_info.cpp index 3b0ee68dbd8207cce3950e4f277d04e8ba68f5eb..6462c03c1a541e96840174a19ac1371c6e8cc2cc 100644 --- a/services/engine/codeclist/audio_codeclist_info.cpp +++ b/services/engine/codeclist/audio_codeclist_info.cpp @@ -312,6 +312,7 @@ CapabilityData AudioCodeclistInfo::GetVendorAacEncoderCapability() audioAacCapability.sampleRate = AUDIO_SAMPLE_RATE; audioAacCapability.maxInstance = MAX_SUPPORT_AUDIO_INSTANCE; audioAacCapability.profiles = { AAC_PROFILE_LC, AAC_PROFILE_HE, AAC_PROFILE_HE_V2 }; + audioAacCapability.rank = 1; // larger than default rank 0 return audioAacCapability; } #endif diff --git a/services/engine/codeclist/codec_ability_singleton.cpp b/services/engine/codeclist/codec_ability_singleton.cpp index b5d702fba390fa377a86b3da9811d9d5b14ca70e..b414ea1a0d89ca46ae25e6397e4559ea6a6f5dc9 100644 --- a/services/engine/codeclist/codec_ability_singleton.cpp +++ b/services/engine/codeclist/codec_ability_singleton.cpp @@ -64,6 +64,21 @@ CodecAbilitySingleton::CodecAbilitySingleton() RegisterCapabilityArray(capaArray, codecType); } } + std::lock_guard lock(mutex_); + std::sort(capabilityDataArray_.begin(), capabilityDataArray_.end(), + [](CapabilityData a, CapabilityData b) { + return a.rank > b.rank; + }); + size_t idx = 0; + for (auto iter = capabilityDataArray_.begin(); iter != capabilityDataArray_.end(); iter++) { + std::string mimeType = (*iter).mimeType; + if (mimeCapIdxMap_.find(mimeType) == mimeCapIdxMap_.end()) { + std::vector idxVec; + mimeCapIdxMap_.insert(std::make_pair(mimeType, idxVec)); + } + mimeCapIdxMap_.at(mimeType).emplace_back(idx); + idx++; + } AVCODEC_LOGI("Succeed"); } @@ -75,13 +90,7 @@ CodecAbilitySingleton::~CodecAbilitySingleton() void CodecAbilitySingleton::RegisterCapabilityArray(std::vector &capaArray, CodecType codecType) { std::lock_guard lock(mutex_); - size_t beginIdx = capabilityDataArray_.size(); for (auto iter = capaArray.begin(); iter != capaArray.end(); iter++) { - std::string mimeType = (*iter).mimeType; - std::vector idxVec; - if (mimeCapIdxMap_.find(mimeType) == mimeCapIdxMap_.end()) { - mimeCapIdxMap_.insert(std::make_pair(mimeType, idxVec)); - } if ((*iter).profileLevelsMap.size() > MAX_MAP_SIZE) { while ((*iter).profileLevelsMap.size() > MAX_MAP_SIZE) { auto rIter = (*iter).profileLevelsMap.end(); @@ -100,9 +109,7 @@ void CodecAbilitySingleton::RegisterCapabilityArray(std::vector (*iter).measuredFrameRate.erase(--rIter); } capabilityDataArray_.emplace_back(*iter); - mimeCapIdxMap_.at(mimeType).emplace_back(beginIdx); nameCodecTypeMap_.insert(std::make_pair((*iter).codecName, codecType)); - beginIdx++; } AVCODEC_LOGD("Register capability successful"); } diff --git a/services/engine/codeclist/codeclist_core.cpp b/services/engine/codeclist/codeclist_core.cpp index dd663148c8f3cf5c384eb5146fa76aaf88a44a42..0ef72b421fe4dde07abf14b8c4662a2da6e83f68 100644 --- a/services/engine/codeclist/codeclist_core.cpp +++ b/services/engine/codeclist/codeclist_core.cpp @@ -284,11 +284,7 @@ std::vector CodecListCore::FindCodecNameArray(const std::string &mi for (auto index : iter->second) { if (capabilityArray[index].codecType == codecType) { - if (capabilityArray[index].codecName == std::string("OH.Media.Codec.Encoder.Audio.Vendor.AAC")) { - nameArray.insert(nameArray.begin(), capabilityArray[index].codecName); - } else { - nameArray.push_back(capabilityArray[index].codecName); - } + nameArray.push_back(capabilityArray[index].codecName); } } return nameArray; diff --git a/services/media_engine/plugins/ffmpeg_adapter/audio_encoder/aac/ffmpeg_aac_encoder_plugin.cpp b/services/media_engine/plugins/ffmpeg_adapter/audio_encoder/aac/ffmpeg_aac_encoder_plugin.cpp index 5383a4024cc3ac2343524820df64fbde0971e434..2641681ba5e70e66c37d481ea6d1a4dba600e52c 100644 --- a/services/media_engine/plugins/ffmpeg_adapter/audio_encoder/aac/ffmpeg_aac_encoder_plugin.cpp +++ b/services/media_engine/plugins/ffmpeg_adapter/audio_encoder/aac/ffmpeg_aac_encoder_plugin.cpp @@ -554,7 +554,15 @@ bool FFmpegAACEncoderPlugin::CheckResample() const Status FFmpegAACEncoderPlugin::GetMetaData(const std::shared_ptr &meta) { int32_t type; + int32_t aacProfile; MEDIA_LOG_I("GetMetaData enter"); + if (meta->Get(aacProfile)) { + if (aacProfile != AAC_PROFILE_LC) { + MEDIA_LOG_E("this plugin only support LC-AAC, input profile:%{public}d", aacProfile); + return Status::ERROR_INVALID_PARAMETER; + } + } + if (meta->Get(type)) { aacName_ = (type == 1 ? "aac" : "aac_latm"); } diff --git a/services/services/sa_avcodec/ipc/codeclist_parcel.cpp b/services/services/sa_avcodec/ipc/codeclist_parcel.cpp index 1f0261359ac843500588d9f923f8280fb7b1c736..7bae2680685a29e53cb9dc5dd11a191b5e5d940a 100644 --- a/services/services/sa_avcodec/ipc/codeclist_parcel.cpp +++ b/services/services/sa_avcodec/ipc/codeclist_parcel.cpp @@ -62,6 +62,7 @@ bool CodecListParcel::Marshalling(MessageParcel &parcel, CapabilityData &capabil (void)Marshalling(parcel, capabilityData.profileLevelsMap); (void)parcel.WriteBool(capabilityData.supportSwapWidthHeight); (void)Marshalling(parcel, capabilityData.featuresMap); + (void)parcel.WriteInt32(capabilityData.rank); AVCODEC_LOGD("success to Marshalling capabilityDataArray"); return true; @@ -141,6 +142,7 @@ bool CodecListParcel::Unmarshalling(MessageParcel &parcel, CapabilityData &capab capabilityData.supportSwapWidthHeight = parcel.ReadBool(); CHECK_AND_RETURN_RET_LOG(Unmarshalling(parcel, capabilityData.featuresMap), false, "failed to Unmarshalling features map"); + capabilityData.rank = parcel.ReadInt32(); AVCODEC_LOGD("success to Unmarshalling capabilityDataArray"); return true; } diff --git a/test/unittest/audio_test/audio_encoder_capi_unit_test.cpp b/test/unittest/audio_test/audio_encoder_capi_unit_test.cpp index 4383952716cfbdc797d69be09ff1ce6456cc3dd5..46a49ac7407d805c7ae77d02a50a5f5134c40c3d 100644 --- a/test/unittest/audio_test/audio_encoder_capi_unit_test.cpp +++ b/test/unittest/audio_test/audio_encoder_capi_unit_test.cpp @@ -30,6 +30,9 @@ #include "native_avformat.h" #include "avcodec_errors.h" #include "native_avcodec_audioencoder.h" +#include "native_avcodec_audiocodec.h" +#include "native_avcodec_base.h" +#include "native_avcapability.h" #include "securec.h" #include "ffmpeg_converter.h" @@ -100,6 +103,20 @@ public: std::queue attrQueue_; }; +class AEncSignalAv { +public: + std::mutex inMutex_; + std::mutex outMutex_; + std::mutex startMutex_; + std::condition_variable inCond_; + std::condition_variable outCond_; + std::condition_variable startCond_; + std::queue inQueue_; + std::queue outQueue_; + std::queue inBufferQueue_; + std::queue outBufferQueue_; +}; + static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData) { (void)codec; @@ -142,6 +159,30 @@ static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVMemo signal->outCond_.notify_all(); } +static void OnInputBufferAvailableAv(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) +{ + (void)codec; + AEncSignalAv *signal = static_cast(userData); + unique_lock lock(signal->inMutex_); + signal->inQueue_.push(index); + signal->inBufferQueue_.push(data); + signal->inCond_.notify_all(); +} + +static void OnOutputBufferAvailableAv(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) +{ + (void)codec; + AEncSignalAv *signal = static_cast(userData); + unique_lock lock(signal->outMutex_); + signal->outQueue_.push(index); + signal->outBufferQueue_.push(data); + if (data) { + } else { + cout << "OnOutputBufferAvailable error, attr is nullptr!" << endl; + } + signal->outCond_.notify_all(); +} + class AudioCodeCapiEncoderUnitTest : public testing::Test { public: static void SetUpTestCase(void); @@ -149,9 +190,13 @@ public: void SetUp(); void TearDown(); int32_t ProceFunc(const std::string codecName = CODEC_FLAC_NAME); + int32_t ProceByMimeFunc(const std::string mime, bool isEncoder); + int32_t ProceByCapabilityFunc(const std::string mime, bool isEncoder); int32_t CheckSoFunc(); void InputFunc(); void OutputFunc(); + void InputFuncAv(); + void OutputFuncAv(); protected: std::atomic isRunning_ = false; @@ -165,7 +210,9 @@ protected: std::string outputFilePath_ = FLAC_OUTPUT_FILE_PATH.data(); struct OH_AVCodecAsyncCallback cb_; - AEncSignal *signal_; + struct OH_AVCodecCallback avcb_; + AEncSignal *signal_ = nullptr; + AEncSignalAv *signalAv_ = nullptr; OH_AVCodec *audioEnc_; OH_AVFormat *format; bool isFirstFrame_ = true; @@ -189,6 +236,14 @@ void AudioCodeCapiEncoderUnitTest::SetUp(void) void AudioCodeCapiEncoderUnitTest::TearDown(void) { + if (signal_ != nullptr) { + delete signal_; + signal_ = nullptr; + } + if (signalAv_ != nullptr) { + delete signalAv_; + signalAv_ = nullptr; + } cout << "[TearDown]: over!!!" << endl; } @@ -294,6 +349,125 @@ int32_t AudioCodeCapiEncoderUnitTest::ProceFunc(const std::string codecName) return AVCS_ERR_OK; } +int32_t AudioCodeCapiEncoderUnitTest::ProceByMimeFunc(const std::string mime, bool isEncoder) +{ + audioEnc_ = OH_AudioCodec_CreateByMime(mime.c_str(), isEncoder); + EXPECT_NE((OH_AVCodec *)nullptr, audioEnc_); + + signalAv_ = new AEncSignalAv(); + EXPECT_NE(nullptr, signal); + + avcb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailableAv, &OnOutputBufferAvailableAv}; + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_RegisterCallback(audioEnc_, avcb_, signalAv_)); + + format = OH_AVFormat_Create(); + return AVCS_ERR_OK; +} + +int32_t AudioCodeCapiEncoderUnitTest::ProceByCapabilityFunc(const std::string mime, bool isEncoder) +{ + OH_AVCapability *cap = OH_AVCodec_GetCapability(mime.c_str(), isEncoder); + const char *name = OH_AVCapability_GetName(cap); + audioEnc_ = OH_AudioCodec_CreateByName(name); + EXPECT_NE((OH_AVCodec *)nullptr, audioEnc_); + + signalAv_ = new AEncSignalAv(); + EXPECT_NE(nullptr, signal); + + avcb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailableAv, &OnOutputBufferAvailableAv}; + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_RegisterCallback(audioEnc_, avcb_, signalAv_)); + + format = OH_AVFormat_Create(); + return AVCS_ERR_OK; +} + +void AudioCodeCapiEncoderUnitTest::InputFuncAv() +{ + OH_AVCodecBufferAttr info = {}; + bool isEos = false; + inputFile_ = std::make_unique(inputFilePath_, std::ios::binary); + if (!inputFile_->is_open()) { + std::cout << "open file failed, path: " << inputFilePath_ << std::endl; + return; + } + while (isRunning_.load()) { + unique_lock lock(signalAv_->inMutex_); + signalAv_->inCond_.wait(lock, [this]() { return (signalAv_->inQueue_.size() > 0 || !isRunning_.load()); }); + if (!isRunning_.load()) { + break; + } + uint32_t index = signalAv_->inQueue_.front(); + auto buffer = signalAv_->inBufferQueue_.front(); + isEos = !inputFile_->eof(); + if (!isEos) { + inputFile_->read((char *)OH_AVBuffer_GetAddr(buffer), frameBytes_); + } + info.size = frameBytes_; + info.flags = AVCODEC_BUFFER_FLAGS_NONE; + if (isEos) { + info.size = 0; + info.flags = AVCODEC_BUFFER_FLAGS_EOS; + } else if (isFirstFrame_) { + info.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA; + isFirstFrame_ = false; + } + info.offset = 0; + OH_AVBuffer_SetBufferAttr(buffer, &info); + int32_t ret = OH_AudioCodec_PushInputBuffer(audioEnc_, index); + signalAv_->inQueue_.pop(); + signalAv_->inBufferQueue_.pop(); + if (ret != AVCS_ERR_OK) { + isRunning_ = false; + break; + } + if (isEos) { + break; + } + timeStamp_ += FRAME_DURATION_US; + } + inputFile_->close(); +} + +void AudioCodeCapiEncoderUnitTest::OutputFuncAv() +{ + std::ofstream outputFile; + outputFile.open(outputFilePath_, std::ios::out | std::ios::binary); + if (!outputFile.is_open()) { + std::cout << "open file failed, path: " << outputFilePath_ << std::endl; + return; + } + + while (isRunning_.load()) { + unique_lock lock(signalAv_->outMutex_); + signalAv_->outCond_.wait(lock, [this]() { return (signalAv_->outQueue_.size() > 0 || !isRunning_.load()); }); + + if (!isRunning_.load()) { + cout << "wait to stop, exit" << endl; + break; + } + + uint32_t index = signalAv_->outQueue_.front(); + auto *data = signalAv_->outBufferQueue_.front(); + OH_AVCodecBufferAttr attr; + OH_AVBuffer_GetBufferAttr(data, &attr); + if (data != nullptr) { + outputFile.write(reinterpret_cast(OH_AVBuffer_GetAddr(data)), attr.size); + } + if (data != nullptr && (attr.flags == AVCODEC_BUFFER_FLAGS_EOS || attr.size == 0)) { + cout << "encode eos" << endl; + isRunning_.store(false); + signalAv_->startCond_.notify_all(); + } + signalAv_->outBufferQueue_.pop(); + signalAv_->outQueue_.pop(); + if (OH_AudioCodec_FreeOutputBuffer(audioEnc_, index) != AV_ERR_OK) { + cout << "Fatal: FreeOutputData fail" << endl; + break; + } + } + outputFile.close(); +} + int32_t AudioCodeCapiEncoderUnitTest::CheckSoFunc() { soFile_ = std::make_unique(OPUS_SO_FILE_PATH, std::ios::binary); @@ -1441,5 +1615,211 @@ HWTEST_F(AudioCodeCapiEncoderUnitTest, g711muNormal, TestSize.Level1) EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioEncoder_Flush(audioEnc_)); EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioEncoder_Destroy(audioEnc_)); } + +HWTEST_F(AudioCodeCapiEncoderUnitTest, EncoderConfigureLCAAC, TestSize.Level1) +{ + inputFilePath_ = AAC_INPUT_FILE_PATH; + outputFilePath_ = AAC_OUTPUT_FILE_PATH; + frameBytes_ = AAC_DEFAULT_FRAME_BYTES; + ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, AudioSampleFormat::SAMPLE_S16LE); + OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE); + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format)); + isRunning_.store(true); + + inputLoop_ = make_unique(&AudioCodeCapiEncoderUnitTest::InputFuncAv, this); + EXPECT_NE(nullptr, inputLoop_); + outputLoop_ = make_unique(&AudioCodeCapiEncoderUnitTest::OutputFuncAv, this); + EXPECT_NE(nullptr, outputLoop_); + + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Start(audioEnc_)); + while (isRunning_.load()) { + sleep(1); // sleep 1s + } + + isRunning_.store(false); + if (inputLoop_ != nullptr && inputLoop_->joinable()) { + { + unique_lock lock(signalAv_->inMutex_); + signalAv_->inCond_.notify_all(); + } + inputLoop_->join(); + } + + if (outputLoop_ != nullptr && outputLoop_->joinable()) { + { + unique_lock lock(signalAv_->outMutex_); + signalAv_->outCond_.notify_all(); + } + outputLoop_->join(); + } + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Flush(audioEnc_)); + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_)); +} + +HWTEST_F(AudioCodeCapiEncoderUnitTest, EncoderConfigureHEAAC, TestSize.Level1) +{ + inputFilePath_ = AAC_INPUT_FILE_PATH; + outputFilePath_ = AAC_OUTPUT_FILE_PATH; + frameBytes_ = AAC_DEFAULT_FRAME_BYTES; + OH_AVCodec *tmpCodec = OH_AudioCodec_CreateByName("OH.Media.Codec.Encoder.Audio.Vendor.AAC"); + bool vendorExist = (tmpCodec != nullptr); + if (vendorExist) { + OH_AudioCodec_Destroy(tmpCodec); + tmpCodec = nullptr; + } + + ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, AudioSampleFormat::SAMPLE_S16LE); + OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, AAC_PROFILE_HE); + if (vendorExist) { + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format)); + } else { + EXPECT_NE(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format)); + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_)); + return; + } + + isRunning_.store(true); + + inputLoop_ = make_unique(&AudioCodeCapiEncoderUnitTest::InputFuncAv, this); + EXPECT_NE(nullptr, inputLoop_); + outputLoop_ = make_unique(&AudioCodeCapiEncoderUnitTest::OutputFuncAv, this); + EXPECT_NE(nullptr, outputLoop_); + + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Start(audioEnc_)); + while (isRunning_.load()) { + sleep(1); // sleep 1s + } + + isRunning_.store(false); + if (inputLoop_ != nullptr && inputLoop_->joinable()) { + { + unique_lock lock(signalAv_->inMutex_); + signalAv_->inCond_.notify_all(); + } + inputLoop_->join(); + } + + if (outputLoop_ != nullptr && outputLoop_->joinable()) { + { + unique_lock lock(signalAv_->outMutex_); + signalAv_->outCond_.notify_all(); + } + outputLoop_->join(); + } + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Flush(audioEnc_)); + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_)); +} + +HWTEST_F(AudioCodeCapiEncoderUnitTest, EncoderConfigureHEAACv2, TestSize.Level1) +{ + inputFilePath_ = AAC_INPUT_FILE_PATH; + outputFilePath_ = AAC_OUTPUT_FILE_PATH; + frameBytes_ = AAC_DEFAULT_FRAME_BYTES; + OH_AVCodec *tmpCodec = OH_AudioCodec_CreateByName("OH.Media.Codec.Encoder.Audio.Vendor.AAC"); + bool vendorExist = (tmpCodec != nullptr); + if (vendorExist) { + OH_AudioCodec_Destroy(tmpCodec); + tmpCodec = nullptr; + } + ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, AudioSampleFormat::SAMPLE_S16LE); + OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, AAC_PROFILE_HE_V2); + if (vendorExist) { + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format)); + } else { + EXPECT_NE(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format)); + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_)); + return; + } + isRunning_.store(true); + + inputLoop_ = make_unique(&AudioCodeCapiEncoderUnitTest::InputFuncAv, this); + EXPECT_NE(nullptr, inputLoop_); + outputLoop_ = make_unique(&AudioCodeCapiEncoderUnitTest::OutputFuncAv, this); + EXPECT_NE(nullptr, outputLoop_); + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Start(audioEnc_)); + while (isRunning_.load()) { + sleep(1); // sleep 1s + } + + isRunning_.store(false); + if (inputLoop_ != nullptr && inputLoop_->joinable()) { + { + unique_lock lock(signalAv_->inMutex_); + signalAv_->inCond_.notify_all(); + } + inputLoop_->join(); + } + + if (outputLoop_ != nullptr && outputLoop_->joinable()) { + { + unique_lock lock(signalAv_->outMutex_); + signalAv_->outCond_.notify_all(); + } + outputLoop_->join(); + } + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Flush(audioEnc_)); + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_)); +} + +HWTEST_F(AudioCodeCapiEncoderUnitTest, EncoderConfigureByCap, TestSize.Level1) +{ + inputFilePath_ = AAC_INPUT_FILE_PATH; + outputFilePath_ = AAC_OUTPUT_FILE_PATH; + frameBytes_ = AAC_DEFAULT_FRAME_BYTES; + OH_AVCodec *tmpCodec = OH_AudioCodec_CreateByName("OH.Media.Codec.Encoder.Audio.Vendor.AAC"); + bool vendorExist = (tmpCodec != nullptr); + ProceByCapabilityFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, AudioSampleFormat::SAMPLE_S16LE); + OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE); + OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE); + if (vendorExist) { + OH_AudioCodec_Destroy(tmpCodec); + tmpCodec = nullptr; + OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, AAC_PROFILE_HE); + } + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format)); + isRunning_.store(true); + + inputLoop_ = make_unique(&AudioCodeCapiEncoderUnitTest::InputFuncAv, this); + EXPECT_NE(nullptr, inputLoop_); + outputLoop_ = make_unique(&AudioCodeCapiEncoderUnitTest::OutputFuncAv, this); + EXPECT_NE(nullptr, outputLoop_); + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Start(audioEnc_)); + while (isRunning_.load()) { + sleep(1); // sleep 1s + } + + isRunning_.store(false); + if (inputLoop_ != nullptr && inputLoop_->joinable()) { + { + unique_lock lock(signalAv_->inMutex_); + signalAv_->inCond_.notify_all(); + } + inputLoop_->join(); + } + + if (outputLoop_ != nullptr && outputLoop_->joinable()) { + { + unique_lock lock(signalAv_->outMutex_); + signalAv_->outCond_.notify_all(); + } + outputLoop_->join(); + } + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Flush(audioEnc_)); + EXPECT_EQ(OH_AVErrCode::AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_)); +} + } // namespace MediaAVCodec -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/test/unittest/audio_test/audio_media_codec_unit_test.cpp b/test/unittest/audio_test/audio_media_codec_unit_test.cpp index b40124954a2523423459deb9dabe17a237e977bd..7373137d5d4b4ab5eb4c0fde549abb55ec2e10b2 100644 --- a/test/unittest/audio_test/audio_media_codec_unit_test.cpp +++ b/test/unittest/audio_test/audio_media_codec_unit_test.cpp @@ -875,5 +875,41 @@ HWTEST_F(AudioMediaCodecUnitTest, FFmpegBaseDecoderPlugin_03, TestSize.Level1) EXPECT_EQ(Status::OK, plugin->SetParameter(meta)); } +HWTEST_F(AudioMediaCodecUnitTest, EncoderConfigureLCAAC, TestSize.Level1) +{ + auto mediaCodec = std::make_shared(); + EXPECT_EQ(0, mediaCodec->Init(AAC_MIME_TYPE, true)); + auto meta = std::make_shared(); + meta->Set(1); + meta->Set(Plugins::AudioSampleFormat::SAMPLE_F32LE); + meta->Set(SAMPLE_RATE_48k); + meta->Set(64000); // 64000: valid param + EXPECT_EQ(0, mediaCodec->Configure(meta)); + EXPECT_EQ(0, mediaCodec->Release()); +} + +HWTEST_F(AudioMediaCodecUnitTest, EncoderConfigureHEAAC, TestSize.Level1) +{ + auto detect = std::make_shared(); + bool vendorExist = (detect->Init("OH.Media.Codec.Encoder.Audio.Vendor.AAC") == 0); + auto mediaCodec = std::make_shared(); + EXPECT_EQ(0, mediaCodec->Init(AAC_MIME_TYPE, true)); + auto meta = std::make_shared(); + meta->Set(CHANNEL_COUNT_STEREO); + meta->Set(Plugins::AudioSampleFormat::SAMPLE_F32LE); + meta->Set(SAMPLE_RATE_48k); + meta->Set(64000); // 64000: valid param + meta->Set(Media::Plugins::AAC_PROFILE_HE); + if (vendorExist) { + EXPECT_EQ(0, mediaCodec->Configure(meta)); + mediaCodec->Reset(); + meta->Set(Media::Plugins::AAC_PROFILE_HE_V2); + EXPECT_EQ(0, mediaCodec->Configure(meta)); + } else { + EXPECT_NE(0, mediaCodec->Configure(meta)); + } + EXPECT_EQ(0, mediaCodec->Release()); +} + } // namespace MediaAVCodec } // namespace OHOS \ No newline at end of file diff --git a/test/unittest/codeclist_test/codeclist_unit_test.cpp b/test/unittest/codeclist_test/codeclist_unit_test.cpp index 332389b1546f5a14c6e46493b06db67743319d3a..31e49c1f866167d4d5a4fba0b14ff8ff5b9c6bf7 100644 --- a/test/unittest/codeclist_test/codeclist_unit_test.cpp +++ b/test/unittest/codeclist_test/codeclist_unit_test.cpp @@ -165,7 +165,13 @@ HWTEST_F(CodecListUnitTest, CodecList_GetName_001, TestSize.Level1) capability_ = CodecListMockFactory::GetCapabilityByCategory(mime, true, category); ASSERT_NE(nullptr, capability_) << mime << " can not found!" << std::endl; std::string codecName = capability_->GetName(); - EXPECT_EQ(nameOfMime, codecName) << mime << " get error name: " << codecName << std::endl; + if (mime == std::string(CodecMimeType::AUDIO_AAC)) { + bool check = (codecName == nameOfMime || + codecName == std::string(AVCodecCodecName::AUDIO_ENCODER_AAC_NAME)); + EXPECT_EQ(true, check) << mime << " get error name: " << codecName << std::endl; + } else { + EXPECT_EQ(nameOfMime, codecName) << mime << " get error name: " << codecName << std::endl; + } } if (isHardIncluded_) { for (auto it = CAPABILITY_DECODER_HARD_NAME.begin(); it != CAPABILITY_DECODER_HARD_NAME.end(); ++it) {