diff --git a/frameworks/native/audiostream/include/i_audio_stream.h b/frameworks/native/audiostream/include/i_audio_stream.h index 0f7ea1136617e1aa518872742d840f0b1e57d290..5c0f6ef1f6843ae5ec4e3d1c8a5f31989c4bb501 100644 --- a/frameworks/native/audiostream/include/i_audio_stream.h +++ b/frameworks/native/audiostream/include/i_audio_stream.h @@ -136,7 +136,9 @@ public: static bool IsCustomSampleRateValid(uint32_t customSampleRate); static bool IsRendererChannelLayoutValid(uint64_t channelLayout); static bool IsCapturerChannelLayoutValid(uint64_t channelLayout); - static bool IsPlaybackChannelRelatedInfoValid(uint8_t channels, uint64_t channelLayout); + static bool IsChannelLayoutMatchedWithChannel(uint8_t channel, uint64_t channelLayout, + uint8_t encodingType = ENCODING_PCM); + static bool IsPlaybackChannelRelatedInfoValid(uint8_t encodingType, uint8_t channels, uint64_t channelLayout); static bool IsRecordChannelRelatedInfoValid(uint8_t channels, uint64_t channelLayout); static inline bool IsFastStreamClass(StreamClass streamClass) { diff --git a/services/audio_service/client/src/i_audio_stream.cpp b/services/audio_service/client/src/i_audio_stream.cpp index ac94f965bde834e90c9292964f7808cfa76ff275..be5a07e5bda70223f4d7e7f853e4dcff5f91296b 100644 --- a/services/audio_service/client/src/i_audio_stream.cpp +++ b/services/audio_service/client/src/i_audio_stream.cpp @@ -120,7 +120,8 @@ int32_t IAudioStream::CheckRendererAudioStreamInfo(const AudioStreamParams info) AUDIO_ERR_LOG("Unsupported audio renderer parameter"); return ERR_NOT_SUPPORTED; } - CHECK_AND_RETURN_RET(IsPlaybackChannelRelatedInfoValid(info.channels, info.channelLayout), ERR_NOT_SUPPORTED); + CHECK_AND_RETURN_RET(IsPlaybackChannelRelatedInfoValid(info.encoding, info.channels, info.channelLayout), + ERR_NOT_SUPPORTED); return SUCCESS; } @@ -328,7 +329,24 @@ bool IAudioStream::IsCapturerChannelLayoutValid(uint64_t channelLayout) return isValidCapturerChannelLayout; } -bool IAudioStream::IsPlaybackChannelRelatedInfoValid(uint8_t channels, uint64_t channelLayout) +bool IAudioStream::IsChannelLayoutMatchedWithChannel(uint8_t channel, uint64_t channelLayout, uint8_t encodingType) +{ + // for audio vivid, no need to match channel count with channel layout + CHECK_AND_RETURN_RET(encodingType != ENCODING_AUDIOVIVID, true); + // unknown channel layout is matched with any channel count + CHECK_AND_RETURN_RET(channelLayout != CH_LAYOUT_UNKNOWN, true); + + if (((channelLayout & CH_MODE_MASK) >> CH_MODE_OFFSET) == 0) { + int32_t channelCount = __builtin_popcountll(channelLayout); + return channelCount == static_cast(channel); + } + + uint64_t order = (channelLayout & CH_HOA_ORDNUM_MASK) >> CH_HOA_ORDNUM_OFFSET; + uint64_t channelCountHoa = (order + 1) * (order + 1); + return channelCountHoa == static_cast(channel); +} + +bool IAudioStream::IsPlaybackChannelRelatedInfoValid(uint8_t encodingType, uint8_t channels, uint64_t channelLayout) { if (!IsRendererChannelValid(channels)) { AUDIO_ERR_LOG("AudioStream: Invalid sink channel %{public}d", channels); @@ -338,6 +356,10 @@ bool IAudioStream::IsPlaybackChannelRelatedInfoValid(uint8_t channels, uint64_t AUDIO_ERR_LOG("AudioStream: Invalid sink channel layout"); return false; } + if (!IsChannelLayoutMatchedWithChannel(channels, channelLayout, encodingType)) { + AUDIO_ERR_LOG("AudioStream: not matched sink channel and channel layout"); + return false; + } return true; } @@ -351,6 +373,10 @@ bool IAudioStream::IsRecordChannelRelatedInfoValid(uint8_t channels, uint64_t ch AUDIO_ERR_LOG("AudioStream: Invalid source channel layout"); return false; } + if (!IsChannelLayoutMatchedWithChannel(channels, channelLayout)) { + AUDIO_ERR_LOG("AudioStream: not matched source channel and channel layout"); + return false; + } return true; } } // namespace AudioStandard diff --git a/services/audio_service/test/unittest/client/i_audio_stream_unit_test.cpp b/services/audio_service/test/unittest/client/i_audio_stream_unit_test.cpp index 7fb2852203c733f11ce55b28d13e7a86f2bc75e5..51fb84f078c4aa91fefe1a8e47416fe9639ef426 100644 --- a/services/audio_service/test/unittest/client/i_audio_stream_unit_test.cpp +++ b/services/audio_service/test/unittest/client/i_audio_stream_unit_test.cpp @@ -153,11 +153,19 @@ HWTEST(IAudioStreamUnitTest, IsPlaybackChannelRelatedInfoValid_001, TestSize.Lev std::make_shared(AudioStreamType::STREAM_MUSIC, 0); std::uint8_t audioChannel = 100; std::uint64_t channelLayout = 100; - EXPECT_FALSE(IAudioStream::IsPlaybackChannelRelatedInfoValid(audioChannel, channelLayout)); + EXPECT_FALSE(IAudioStream::IsPlaybackChannelRelatedInfoValid(ENCODING_PCM, audioChannel, channelLayout)); audioChannel = 2; channelLayout = 100; - EXPECT_FALSE(IAudioStream::IsPlaybackChannelRelatedInfoValid(audioChannel, channelLayout)); + EXPECT_FALSE(IAudioStream::IsPlaybackChannelRelatedInfoValid(ENCODING_PCM, audioChannel, channelLayout)); + + audioChannel = 2; + channelLayout = 4; + EXPECT_FALSE(IAudioStream::IsPlaybackChannelRelatedInfoValid(ENCODING_PCM, audioChannel, channelLayout)); + + audioChannel = 2; + channelLayout = 3; + EXPECT_TRUE(IAudioStream::IsPlaybackChannelRelatedInfoValid(ENCODING_PCM, audioChannel, channelLayout)); } /** @@ -170,9 +178,21 @@ HWTEST(IAudioStreamUnitTest, IsRecordChannelRelatedInfoValid_001, TestSize.Level { std::shared_ptr capturerInClientInner_ = std::make_shared(AudioStreamType::STREAM_MUSIC, 0); - std::uint8_t audioChannel = 2; + std::uint8_t audioChannel = 100; std::uint64_t channelLayout = 100; EXPECT_FALSE(IAudioStream::IsRecordChannelRelatedInfoValid(audioChannel, channelLayout)); + + audioChannel = 2; + channelLayout = 100; + EXPECT_FALSE(IAudioStream::IsRecordChannelRelatedInfoValid(audioChannel, channelLayout)); + + audioChannel = 2; + channelLayout = 4; + EXPECT_FALSE(IAudioStream::IsRecordChannelRelatedInfoValid(audioChannel, channelLayout)); + + audioChannel = 2; + channelLayout = 3; + EXPECT_TRUE(IAudioStream::IsRecordChannelRelatedInfoValid(audioChannel, channelLayout)); } /**