From 6fa68b2c4a39334d0bad5599a4cb05d0613b7532 Mon Sep 17 00:00:00 2001 From: zhuzhihui Date: Wed, 19 Mar 2025 17:00:07 +0800 Subject: [PATCH] support OPUS. Signed-off-by: zhuzhihui --- .../avtransstubonremoterequest_fuzzer.cpp | 2 -- .../av_trans_audio_decoder_filter.cpp | 28 +++++++++++++++---- .../av_trans_audio_decoder_filter.h | 4 ++- .../av_trans_audio_encoder_filter.cpp | 23 ++++++++++++--- .../av_trans_audio_encoder_filter.h | 4 ++- .../av_trans_audio_decoder_filter_test.cpp | 3 ++ .../av_trans_audio_encoder_filter_test.cpp | 23 +++++++++++++++ av_transport/common/include/pipeline_event.h | 3 +- 8 files changed, 75 insertions(+), 15 deletions(-) diff --git a/av_transport/av_trans_control_center/test/fuzztest/avtransstubonremoterequest_fuzzer/avtransstubonremoterequest_fuzzer.cpp b/av_transport/av_trans_control_center/test/fuzztest/avtransstubonremoterequest_fuzzer/avtransstubonremoterequest_fuzzer.cpp index 5b95196a..984fa7a6 100644 --- a/av_transport/av_trans_control_center/test/fuzztest/avtransstubonremoterequest_fuzzer/avtransstubonremoterequest_fuzzer.cpp +++ b/av_transport/av_trans_control_center/test/fuzztest/avtransstubonremoterequest_fuzzer/avtransstubonremoterequest_fuzzer.cpp @@ -54,10 +54,8 @@ void AVTransStubOnRemoteRequestFuzzTest(const uint8_t *data, size_t size) pdata.WriteString(value); } else if (code == (uint32_t)IAVTransControlCenterCallback::Message::SET_SHARED_MEMORY) { FuzzedDataProvider fdp(data, size); - int32_t fd = fdp.ConsumeIntegral(); int32_t len = fdp.ConsumeIntegral(); std::string name(reinterpret_cast(data), size); - pdata.WriteFileDescriptor(fd); pdata.WriteInt32(len); pdata.WriteString(name); } else if (code == (uint32_t)IAVTransControlCenterCallback::Message::NOTIFY_AV_EVENT) { diff --git a/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_decoder_filter.cpp b/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_decoder_filter.cpp index d04f2efe..d747dd5f 100644 --- a/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_decoder_filter.cpp +++ b/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_decoder_filter.cpp @@ -303,6 +303,13 @@ Status AudioDecoderFilter::OnLinked(StreamType inType, const std::shared_ptrGetData(Media::Tag::AUDIO_CHANNEL_COUNT, initDecParams_.channel); meta->GetData(Media::Tag::AUDIO_SAMPLE_RATE, initDecParams_.sampleRate); meta->GetData(Media::Tag::AUDIO_SAMPLE_FORMAT, initDecParams_.sampleDepth); + meta->GetData(Media::Tag::MEDIA_BITRATE, initDecParams_.bitRate); + int32_t mimeType = 0; + meta->GetData(Media::Tag::MIME_TYPE, mimeType); + initDecParams_.codecType = static_cast(mimeType); + if (initDecParams_.codecType == AudioCodecType::AUDIO_CODEC_OPUS) { + initDecParams_.bitRate = BITRATE_OPUS; + } meta_ = meta; return Status::OK; } @@ -341,8 +348,13 @@ void AudioDecoderFilter::OnUpdatedResult(std::shared_ptr& meta) Status AudioDecoderFilter::CreateAudioCodec() { - AVTRANS_LOGI("enter"); - audioDecoder_ = OH_AudioCodec_CreateByName((MediaAVCodec::AVCodecCodecName::AUDIO_DECODER_AAC_NAME).data()); + if (initDecParams_.codecType == AudioCodecType::AUDIO_CODEC_OPUS) { + AVTRANS_LOGI("decoderType::opus"); + audioDecoder_ = OH_AudioCodec_CreateByName((MediaAVCodec::AVCodecCodecName::AUDIO_DECODER_OPUS_NAME).data()); + } else { + AVTRANS_LOGI("decoderType::aac"); + audioDecoder_ = OH_AudioCodec_CreateByName((MediaAVCodec::AVCodecCodecName::AUDIO_DECODER_AAC_NAME).data()); + } TRUE_RETURN_V_MSG_E(audioDecoder_ == nullptr, Status::ERROR_NULL_POINTER, "Create AudioCodec failed"); OH_AVCodecCallback cb = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable}; int32_t ret = OH_AudioCodec_RegisterCallback(audioDecoder_, cb, this); @@ -395,14 +407,18 @@ Status AudioDecoderFilter::SetDecoderFormat(const ADecInitParams& initDecParams) OH_AVFormat *format = OH_AVFormat_Create(); TRUE_RETURN_V_MSG_E(format == nullptr, Status::ERROR_NULL_POINTER, "Create AV format failed."); OH_AVFormat_SetIntValue(format, MediaAVCodec::MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), - initDecParams.channel); + initDecParams.channel); OH_AVFormat_SetIntValue(format, MediaAVCodec::MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), - initDecParams.sampleRate); + initDecParams.sampleRate); OH_AVFormat_SetIntValue(format, MediaAVCodec::MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(), - initDecParams.sampleDepth); + initDecParams.sampleDepth); + if (initDecParams.codecType == AudioCodecType::AUDIO_CODEC_OPUS) { + OH_AVFormat_SetLongValue(format, MediaAVCodec::MediaDescriptionKey::MD_KEY_BITRATE.data(), + initDecParams.bitRate); + } int32_t res = OH_AudioCodec_Configure(audioDecoder_, format); if (res != AV_ERR_OK) { - AVTRANS_LOGE("configure decoder failed: %{public}d", ret); + AVTRANS_LOGE("configure decoder failed: %{public}d", res); OH_AVFormat_Destroy(format); return Status::ERROR_INVALID_OPERATION; } diff --git a/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_decoder_filter.h b/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_decoder_filter.h index a937b651..9fc7be5a 100644 --- a/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_decoder_filter.h +++ b/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_decoder_filter.h @@ -41,9 +41,10 @@ namespace OHOS { namespace DistributedHardware { namespace Pipeline { typedef struct { - int32_t codecType; + AudioCodecType codecType; int32_t channel; int32_t sampleRate; + int32_t bitRate; MediaAVCodec::AudioSampleFormat sampleDepth; } ADecInitParams; @@ -110,6 +111,7 @@ private: constexpr static int32_t CHANNEL_MASK_MAX = 2; constexpr static int32_t SAMPLE_RATE_MIN = 8000; constexpr static int32_t SAMPLE_RATE_MAX = 96000; + constexpr static int32_t BITRATE_OPUS = 32000; std::shared_ptr nextFilter_ {nullptr}; std::shared_ptr eventReceiver_ {nullptr}; diff --git a/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_encoder_filter.cpp b/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_encoder_filter.cpp index 503bd1df..37624f16 100644 --- a/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_encoder_filter.cpp +++ b/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_encoder_filter.cpp @@ -302,6 +302,13 @@ Status AudioEncoderFilter::OnLinked(StreamType inType, const std::shared_ptrGetData(Media::Tag::AUDIO_CHANNEL_COUNT, initEncParams_.channel); meta->GetData(Media::Tag::AUDIO_SAMPLE_RATE, initEncParams_.sampleRate); meta->GetData(Media::Tag::AUDIO_SAMPLE_FORMAT, initEncParams_.sampleDepth); + meta->GetData(Media::Tag::MEDIA_BITRATE, initEncParams_.bitRate); + int32_t mimeType = 0; + meta->GetData(Media::Tag::MIME_TYPE, mimeType); + initEncParams_.codecType = static_cast(mimeType); + if (initEncParams_.codecType == AudioCodecType::AUDIO_CODEC_OPUS) { + initEncParams_.bitRate = BITRATE_OPUS; + } meta_ = meta; return Status::OK; } @@ -340,8 +347,13 @@ void AudioEncoderFilter::OnUpdatedResult(std::shared_ptr& meta) Status AudioEncoderFilter::CreateAudioCodec() { - AVTRANS_LOGI("enter"); - audioEncoder_ = OH_AudioCodec_CreateByName((MediaAVCodec::AVCodecCodecName::AUDIO_ENCODER_AAC_NAME).data()); + if (initEncParams_.codecType == AudioCodecType::AUDIO_CODEC_OPUS) { + AVTRANS_LOGI("encoderType::opus"); + audioEncoder_ = OH_AudioCodec_CreateByName((MediaAVCodec::AVCodecCodecName::AUDIO_ENCODER_OPUS_NAME).data()); + } else { + AVTRANS_LOGI("encoderType::aac"); + audioEncoder_ = OH_AudioCodec_CreateByName((MediaAVCodec::AVCodecCodecName::AUDIO_ENCODER_AAC_NAME).data()); + } TRUE_RETURN_V_MSG_E(audioEncoder_ == nullptr, Status::ERROR_NULL_POINTER, "Create AudioCodec failed"); OH_AVCodecCallback cb = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable}; int32_t ret = OH_AudioCodec_RegisterCallback(audioEncoder_, cb, this); @@ -397,10 +409,13 @@ Status AudioEncoderFilter::SetEncoderFormat(const AEncInitParams &initEncParams) initEncParams.sampleRate); OH_AVFormat_SetIntValue(format, MediaAVCodec::MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(), initEncParams.sampleDepth); - + if (initEncParams.codecType == AudioCodecType::AUDIO_CODEC_OPUS) { + OH_AVFormat_SetLongValue(format, MediaAVCodec::MediaDescriptionKey::MD_KEY_BITRATE.data(), + initEncParams.bitRate); + } int32_t res = OH_AudioCodec_Configure(audioEncoder_, format); if (res != AV_ERR_OK) { - AVTRANS_LOGE("configure encoder failed: %{public}d", ret); + AVTRANS_LOGE("configure encoder failed: %{public}d", res); OH_AVFormat_Destroy(format); return Status::ERROR_INVALID_OPERATION; } diff --git a/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_encoder_filter.h b/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_encoder_filter.h index 5a2312f5..775019f9 100644 --- a/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_encoder_filter.h +++ b/av_transport/av_trans_engine/filters/av_trans_coder/av_trans_audio_encoder_filter.h @@ -41,9 +41,10 @@ namespace OHOS { namespace DistributedHardware { namespace Pipeline { typedef struct { - int32_t codecType; + AudioCodecType codecType; int32_t channel; int32_t sampleRate; + int32_t bitRate; MediaAVCodec::AudioSampleFormat sampleDepth; } AEncInitParams; @@ -109,6 +110,7 @@ private: constexpr static int32_t CHANNEL_MASK_MAX = 2; constexpr static int32_t SAMPLE_RATE_MIN = 8000; constexpr static int32_t SAMPLE_RATE_MAX = 96000; + constexpr static int32_t BITRATE_OPUS = 32000; std::shared_ptr nextFilter_ {nullptr}; std::shared_ptr eventReceiver_ {nullptr}; diff --git a/av_transport/av_trans_engine/filters/test/av_trans_coder_filter_test/av_trans_audio_decoder_filter_test.cpp b/av_transport/av_trans_engine/filters/test/av_trans_coder_filter_test/av_trans_audio_decoder_filter_test.cpp index 0381cec6..5f002dfe 100644 --- a/av_transport/av_trans_engine/filters/test/av_trans_coder_filter_test/av_trans_audio_decoder_filter_test.cpp +++ b/av_transport/av_trans_engine/filters/test/av_trans_coder_filter_test/av_trans_audio_decoder_filter_test.cpp @@ -409,6 +409,9 @@ HWTEST_F(AvTransportAudioDecoderFilterTest, OnLinked_002, testing::ext::TestSize EXPECT_EQ(status, Status::ERROR_NULL_POINTER); status = avAudioDecoderTest_->OnLinked(inType, nullptr, callback); EXPECT_EQ(status, Status::ERROR_NULL_POINTER); + avAudioDecoderTest_->initDecParams_.codecType = Pipeline::AudioCodecType::AUDIO_CODEC_OPUS; + status = avAudioDecoderTest_->OnLinked(inType, meta, callback); + EXPECT_EQ(status, Status::OK); } HWTEST_F(AvTransportAudioDecoderFilterTest, OnUpdated_001, testing::ext::TestSize.Level1) diff --git a/av_transport/av_trans_engine/filters/test/av_trans_coder_filter_test/av_trans_audio_encoder_filter_test.cpp b/av_transport/av_trans_engine/filters/test/av_trans_coder_filter_test/av_trans_audio_encoder_filter_test.cpp index e2307758..45b940f4 100644 --- a/av_transport/av_trans_engine/filters/test/av_trans_coder_filter_test/av_trans_audio_encoder_filter_test.cpp +++ b/av_transport/av_trans_engine/filters/test/av_trans_coder_filter_test/av_trans_audio_encoder_filter_test.cpp @@ -103,6 +103,7 @@ HWTEST_F(AvTransportAudioEncoderFilterTest, StartAudioCodec_001, testing::ext::T EXPECT_EQ(Status::ERROR_NULL_POINTER, ret); // Create Audio Codec + avAudioEncoderTest_->initEncParams_.codecType = Pipeline::AudioCodecType::AUDIO_CODEC_AAC; ret = avAudioEncoderTest_->CreateAudioCodec(); EXPECT_EQ(Status::OK, ret); } @@ -144,6 +145,7 @@ HWTEST_F(AvTransportAudioEncoderFilterTest, CreateAudioCodec_001, testing::ext:: std::make_shared("builtin.recorder.audioencoderfilter", Pipeline::FilterType::FILTERTYPE_AENC); ASSERT_TRUE(avAudioEncoderTest_ != nullptr); + avAudioEncoderTest_->initEncParams_.codecType = Pipeline::AudioCodecType::AUDIO_CODEC_AAC; Status ret = avAudioEncoderTest_->CreateAudioCodec(); EXPECT_EQ(Status::OK, ret); } @@ -409,6 +411,9 @@ HWTEST_F(AvTransportAudioEncoderFilterTest, OnLinked_002, testing::ext::TestSize EXPECT_EQ(status, Status::ERROR_NULL_POINTER); status = avAudioEncoderTest_->OnLinked(inType, nullptr, callback); EXPECT_EQ(status, Status::ERROR_NULL_POINTER); + meta->SetData(Media::Tag::MIME_TYPE, Pipeline::AudioCodecType::AUDIO_CODEC_OPUS); + status = avAudioEncoderTest_->OnLinked(inType, meta, callback); + EXPECT_EQ(status, Status::OK); } HWTEST_F(AvTransportAudioEncoderFilterTest, OnUpdated_001, testing::ext::TestSize.Level1) @@ -492,6 +497,24 @@ HWTEST_F(AvTransportAudioEncoderFilterTest, SetEncoderFormat_002, testing::ext:: EXPECT_EQ(status, Status::ERROR_NULL_POINTER); } +HWTEST_F(AvTransportAudioEncoderFilterTest, SetEncoderFormat_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr avAudioEncoderTest_ = + std::make_shared("builtin.recorder.audioencoderfilter", + Pipeline::FilterType::FILTERTYPE_AENC); + ASSERT_TRUE(avAudioEncoderTest_ != nullptr); + Pipeline::AEncInitParams encInitParams; + encInitParams.channel = 2; + encInitParams.sampleRate = 44100; + encInitParams.sampleDepth = MediaAVCodec::AudioSampleFormat::SAMPLE_U8; + encInitParams.codecType = Pipeline::AudioCodecType::AUDIO_CODEC_OPUS; + OH_AVCodec audioEncoder(AVMagic::AVCODEC_MAGIC_AUDIO_ENCODER); + avAudioEncoderTest_->audioEncoder_ = &audioEncoder; + Status status = avAudioEncoderTest_->SetEncoderFormat(encInitParams); + avAudioEncoderTest_->audioEncoder_ = nullptr; + EXPECT_EQ(status, Status::ERROR_INVALID_OPERATION); +} + HWTEST_F(AvTransportAudioEncoderFilterTest, CheckEncoderFormat_002, testing::ext::TestSize.Level1) { std::shared_ptr avAudioEncoderTest_ = diff --git a/av_transport/common/include/pipeline_event.h b/av_transport/common/include/pipeline_event.h index 7411326a..a824a194 100644 --- a/av_transport/common/include/pipeline_event.h +++ b/av_transport/common/include/pipeline_event.h @@ -66,7 +66,8 @@ struct Event { typedef enum { AUDIO_CODEC_AAC = 0, AUDIO_CODEC_FLAC = 1, - AUDIO_CODEC_AAC_EN = 2 + AUDIO_CODEC_AAC_EN = 2, + AUDIO_CODEC_OPUS = 3 } AudioCodecType; const char* GetEventName(EventType type); -- Gitee