Loading system/bta/le_audio/broadcaster/broadcaster.cc +3 −7 Original line number Diff line number Diff line Loading @@ -570,16 +570,12 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { // Prepare the configuration requirements for each subgroup. // Note: For now, each subgroup contains exactly the same content, but // differs in codec configuration. std::vector< std::pair<bluetooth::le_audio::types::LeAudioContextType, uint8_t>> subgroup_requirements; CodecManager::BroadcastConfigurationRequirements requirements; for (auto& idx : subgroup_quality) { subgroup_requirements.push_back( requirements.subgroup_quality.push_back( {ChooseConfigurationContextType(context_type), idx}); } auto config = CodecManager::GetInstance()->GetBroadcastConfig( subgroup_requirements, std::nullopt); auto config = CodecManager::GetInstance()->GetBroadcastConfig(requirements); if (!config) { log::error("No valid broadcast offload config"); Loading system/bta/le_audio/broadcaster/broadcaster_test.cc +5 −7 Original line number Diff line number Diff line Loading @@ -930,10 +930,8 @@ TEST_F(BroadcasterTest, VendorCodecConfig) { ConfigCodecManagerMock(types::CodecLocation::HOST); ON_CALL(*mock_codec_manager_, GetBroadcastConfig) .WillByDefault(Invoke( [](const std::vector<std::pair<types::LeAudioContextType, uint8_t>>& subgroup_quality, std::optional<const types::PublishedAudioCapabilities*> pacs) { .WillByDefault(Invoke([](const bluetooth::le_audio::CodecManager:: BroadcastConfigurationRequirements&) { return std::make_unique<broadcaster::BroadcastConfiguration>( vendor_stereo_16_2_1); })); Loading system/bta/le_audio/codec_manager.cc +25 −31 Original line number Diff line number Diff line Loading @@ -204,35 +204,37 @@ struct codec_manager_impl { } const AudioSetConfigurations* GetSupportedCodecConfigurations( types::LeAudioContextType ctx_type) { const CodecManager::UnicastConfigurationRequirements& requirements) const { if (GetCodecLocation() == le_audio::types::CodecLocation::ADSP) { log::verbose("Get offload config for the context type: {}", (int)ctx_type); (int)requirements.audio_context_type); // TODO: Need to have a mechanism to switch to software session if offload // doesn't support. return context_type_offload_config_map_.count(ctx_type) ? &context_type_offload_config_map_[ctx_type] return context_type_offload_config_map_.count( requirements.audio_context_type) ? &context_type_offload_config_map_.at( requirements.audio_context_type) : nullptr; } log::verbose("Get software config for the context type: {}", (int)ctx_type); return AudioSetConfigurationProvider::Get()->GetConfigurations(ctx_type); log::verbose("Get software config for the context type: {}", (int)requirements.audio_context_type); return AudioSetConfigurationProvider::Get()->GetConfigurations( requirements.audio_context_type); } std::unique_ptr<AudioSetConfiguration> GetCodecConfig( types::LeAudioContextType ctx_type, std::function<const set_configurations::AudioSetConfiguration*( types::LeAudioContextType context_type, const set_configurations::AudioSetConfigurations* confs)> non_vendor_config_matcher) { const CodecManager::UnicastConfigurationRequirements& requirements, CodecManager::UnicastConfigurationVerifier verifier) { auto configs = GetSupportedCodecConfigurations(requirements); // Note: For the only supported right now legacy software configuration // provider, we use the device group logic to match the proper // configuration with group capabilities. Note that this path only // supports the LC3 codec format. For the multicodec support we should // rely on the configuration matcher behind the AIDL interface. auto conf = non_vendor_config_matcher( ctx_type, GetSupportedCodecConfigurations(ctx_type)); auto conf = verifier(requirements, configs); return conf ? std::make_unique<AudioSetConfiguration>(*conf) : nullptr; } Loading Loading @@ -366,14 +368,12 @@ struct codec_manager_impl { } std::unique_ptr<broadcaster::BroadcastConfiguration> GetBroadcastConfig( const std::vector<std::pair<types::LeAudioContextType, uint8_t>>& subgroup_quality, std::optional<const types::PublishedAudioCapabilities*> pacs) { const CodecManager::BroadcastConfigurationRequirements& requirements) { if (GetCodecLocation() != types::CodecLocation::ADSP) { // Get the software supported broadcast configuration return std::make_unique<broadcaster::BroadcastConfiguration>( ::bluetooth::le_audio::broadcaster::GetBroadcastConfig( subgroup_quality)); requirements.subgroup_quality)); } /* Subgroups with different audio qualities is not being supported now, Loading @@ -381,7 +381,7 @@ struct codec_manager_impl { * the standard audio config instead */ uint8_t BIG_audio_quality = bluetooth::le_audio::QUALITY_HIGH; for (const auto& [_, quality] : subgroup_quality) { for (const auto& [_, quality] : requirements.subgroup_quality) { if (quality == bluetooth::le_audio::QUALITY_STANDARD) { BIG_audio_quality = bluetooth::le_audio::QUALITY_STANDARD; } Loading Loading @@ -438,7 +438,7 @@ struct codec_manager_impl { if (max_sdu_octets < sdu_octets) max_sdu_octets = sdu_octets; } if (subgroup_quality.size() > 1) { if (requirements.subgroup_quality.size() > 1) { log::error("More than one subgroup is not supported!"); } Loading Loading @@ -983,14 +983,10 @@ void CodecManager::UpdateActiveAudioConfig( } std::unique_ptr<AudioSetConfiguration> CodecManager::GetCodecConfig( types::LeAudioContextType ctx_type, std::function<const set_configurations::AudioSetConfiguration*( types::LeAudioContextType context_type, const set_configurations::AudioSetConfigurations* confs)> non_vendor_config_matcher) { const CodecManager::UnicastConfigurationRequirements& requirements, CodecManager::UnicastConfigurationVerifier verifier) { if (pimpl_->IsRunning()) { return pimpl_->codec_manager_impl_->GetCodecConfig( ctx_type, non_vendor_config_matcher); return pimpl_->codec_manager_impl_->GetCodecConfig(requirements, verifier); } return nullptr; Loading @@ -1007,12 +1003,10 @@ bool CodecManager::CheckCodecConfigIsBiDirSwb( std::unique_ptr<broadcaster::BroadcastConfiguration> CodecManager::GetBroadcastConfig( const std::vector<std::pair<types::LeAudioContextType, uint8_t>>& subgroup_quality, std::optional<const types::PublishedAudioCapabilities*> pacs) const { const CodecManager::BroadcastConfigurationRequirements& requirements) const { if (pimpl_->IsRunning()) { return pimpl_->codec_manager_impl_->GetBroadcastConfig(subgroup_quality, pacs); return pimpl_->codec_manager_impl_->GetBroadcastConfig(requirements); } return nullptr; Loading system/bta/le_audio/codec_manager.h +18 −9 Original line number Diff line number Diff line Loading @@ -58,6 +58,21 @@ struct broadcast_offload_config { class CodecManager { public: struct UnicastConfigurationRequirements { ::bluetooth::le_audio::types::LeAudioContextType audio_context_type; }; typedef std::function<const set_configurations::AudioSetConfiguration*( const UnicastConfigurationRequirements& requirements, const set_configurations::AudioSetConfigurations* confs)> UnicastConfigurationVerifier; struct BroadcastConfigurationRequirements { std::vector< std::pair<bluetooth::le_audio::types::LeAudioContextType, uint8_t>> subgroup_quality; }; virtual ~CodecManager() = default; static CodecManager* GetInstance(void) { static CodecManager* instance = new CodecManager(); Loading @@ -79,21 +94,15 @@ class CodecManager { update_receiver); virtual std::unique_ptr< ::bluetooth::le_audio::set_configurations::AudioSetConfiguration> GetCodecConfig(::bluetooth::le_audio::types::LeAudioContextType ctx_type, std::function<const set_configurations::AudioSetConfiguration*( types::LeAudioContextType context_type, const set_configurations::AudioSetConfigurations* confs)> non_vendor_config_matcher); GetCodecConfig(const UnicastConfigurationRequirements& requirements, UnicastConfigurationVerifier verifier); virtual bool CheckCodecConfigIsBiDirSwb( const ::bluetooth::le_audio::set_configurations::AudioSetConfiguration& config) const; virtual std::unique_ptr<broadcaster::BroadcastConfiguration> GetBroadcastConfig( const std::vector< std::pair<bluetooth::le_audio::types::LeAudioContextType, uint8_t>>& subgroup_quality, std::optional<const types::PublishedAudioCapabilities*> pacs) const; const BroadcastConfigurationRequirements& requirements) const; virtual void UpdateBroadcastConnHandle( const std::vector<uint16_t>& conn_handle, Loading system/bta/le_audio/codec_manager_test.cc +16 −8 Original line number Diff line number Diff line Loading @@ -390,7 +390,7 @@ TEST_F(CodecManagerTestAdsp, test_capabilities_none) { codec_manager->Start(offloading_preference); auto match_first_config = [](types::LeAudioContextType context_type, [](const CodecManager::UnicastConfigurationRequirements& requirements, const set_configurations::AudioSetConfigurations* confs) -> const set_configurations::AudioSetConfiguration* { if (confs && confs->size()) { Loading @@ -404,8 +404,11 @@ TEST_F(CodecManagerTestAdsp, test_capabilities_none) { // Verify every context for (::bluetooth::le_audio::types::LeAudioContextType ctx_type : ::bluetooth::le_audio::types::kLeAudioContextAllTypesArray) { CodecManager::UnicastConfigurationRequirements requirements = { .audio_context_type = ctx_type, }; ASSERT_EQ(nullptr, codec_manager->GetCodecConfig(ctx_type, match_first_config)); codec_manager->GetCodecConfig(requirements, match_first_config)); } } Loading Loading @@ -435,7 +438,7 @@ TEST_F(CodecManagerTestAdsp, test_capabilities) { size_t available_configs_size = 0; auto match_first_config = [&available_configs_size]( types::LeAudioContextType context_type, const CodecManager::UnicastConfigurationRequirements& requirements, const set_configurations::AudioSetConfigurations* confs) -> const set_configurations::AudioSetConfiguration* { if (confs && confs->size()) { Loading @@ -447,7 +450,10 @@ TEST_F(CodecManagerTestAdsp, test_capabilities) { return nullptr; }; auto cfg = codec_manager->GetCodecConfig(test_context, match_first_config); CodecManager::UnicastConfigurationRequirements requirements = { .audio_context_type = test_context, }; auto cfg = codec_manager->GetCodecConfig(requirements, match_first_config); ASSERT_NE(nullptr, cfg); ASSERT_EQ(offload_capabilities.size(), available_configs_size); Loading @@ -469,8 +475,9 @@ TEST_F(CodecManagerTestAdsp, test_broadcast_config) { {.codec_type = bluetooth::le_audio::LE_AUDIO_CODEC_INDEX_SOURCE_LC3}}; codec_manager->Start(offloading_preference); auto cfg = codec_manager->GetBroadcastConfig( {{types::LeAudioContextType::MEDIA, 1}}, std::nullopt); CodecManager::BroadcastConfigurationRequirements requirements = { .subgroup_quality = {{types::LeAudioContextType::MEDIA, 1}}}; auto cfg = codec_manager->GetBroadcastConfig(requirements); ASSERT_EQ(2, cfg->GetNumBisTotal()); ASSERT_EQ(2, cfg->GetNumChannelsMax()); ASSERT_EQ(48000u, cfg->GetSamplingFrequencyHzMax()); Loading @@ -493,8 +500,9 @@ TEST_F(CodecManagerTestAdsp, test_update_broadcast_offloader) { {.codec_type = bluetooth::le_audio::LE_AUDIO_CODEC_INDEX_SOURCE_LC3}}; codec_manager->Start(offloading_preference); codec_manager->GetBroadcastConfig({{types::LeAudioContextType::MEDIA, 1}}, std::nullopt); CodecManager::BroadcastConfigurationRequirements requirements = { .subgroup_quality = {{types::LeAudioContextType::MEDIA, 1}}}; codec_manager->GetBroadcastConfig(requirements); bool was_called = false; bluetooth::le_audio::broadcast_offload_config bcast_config; Loading Loading
system/bta/le_audio/broadcaster/broadcaster.cc +3 −7 Original line number Diff line number Diff line Loading @@ -570,16 +570,12 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { // Prepare the configuration requirements for each subgroup. // Note: For now, each subgroup contains exactly the same content, but // differs in codec configuration. std::vector< std::pair<bluetooth::le_audio::types::LeAudioContextType, uint8_t>> subgroup_requirements; CodecManager::BroadcastConfigurationRequirements requirements; for (auto& idx : subgroup_quality) { subgroup_requirements.push_back( requirements.subgroup_quality.push_back( {ChooseConfigurationContextType(context_type), idx}); } auto config = CodecManager::GetInstance()->GetBroadcastConfig( subgroup_requirements, std::nullopt); auto config = CodecManager::GetInstance()->GetBroadcastConfig(requirements); if (!config) { log::error("No valid broadcast offload config"); Loading
system/bta/le_audio/broadcaster/broadcaster_test.cc +5 −7 Original line number Diff line number Diff line Loading @@ -930,10 +930,8 @@ TEST_F(BroadcasterTest, VendorCodecConfig) { ConfigCodecManagerMock(types::CodecLocation::HOST); ON_CALL(*mock_codec_manager_, GetBroadcastConfig) .WillByDefault(Invoke( [](const std::vector<std::pair<types::LeAudioContextType, uint8_t>>& subgroup_quality, std::optional<const types::PublishedAudioCapabilities*> pacs) { .WillByDefault(Invoke([](const bluetooth::le_audio::CodecManager:: BroadcastConfigurationRequirements&) { return std::make_unique<broadcaster::BroadcastConfiguration>( vendor_stereo_16_2_1); })); Loading
system/bta/le_audio/codec_manager.cc +25 −31 Original line number Diff line number Diff line Loading @@ -204,35 +204,37 @@ struct codec_manager_impl { } const AudioSetConfigurations* GetSupportedCodecConfigurations( types::LeAudioContextType ctx_type) { const CodecManager::UnicastConfigurationRequirements& requirements) const { if (GetCodecLocation() == le_audio::types::CodecLocation::ADSP) { log::verbose("Get offload config for the context type: {}", (int)ctx_type); (int)requirements.audio_context_type); // TODO: Need to have a mechanism to switch to software session if offload // doesn't support. return context_type_offload_config_map_.count(ctx_type) ? &context_type_offload_config_map_[ctx_type] return context_type_offload_config_map_.count( requirements.audio_context_type) ? &context_type_offload_config_map_.at( requirements.audio_context_type) : nullptr; } log::verbose("Get software config for the context type: {}", (int)ctx_type); return AudioSetConfigurationProvider::Get()->GetConfigurations(ctx_type); log::verbose("Get software config for the context type: {}", (int)requirements.audio_context_type); return AudioSetConfigurationProvider::Get()->GetConfigurations( requirements.audio_context_type); } std::unique_ptr<AudioSetConfiguration> GetCodecConfig( types::LeAudioContextType ctx_type, std::function<const set_configurations::AudioSetConfiguration*( types::LeAudioContextType context_type, const set_configurations::AudioSetConfigurations* confs)> non_vendor_config_matcher) { const CodecManager::UnicastConfigurationRequirements& requirements, CodecManager::UnicastConfigurationVerifier verifier) { auto configs = GetSupportedCodecConfigurations(requirements); // Note: For the only supported right now legacy software configuration // provider, we use the device group logic to match the proper // configuration with group capabilities. Note that this path only // supports the LC3 codec format. For the multicodec support we should // rely on the configuration matcher behind the AIDL interface. auto conf = non_vendor_config_matcher( ctx_type, GetSupportedCodecConfigurations(ctx_type)); auto conf = verifier(requirements, configs); return conf ? std::make_unique<AudioSetConfiguration>(*conf) : nullptr; } Loading Loading @@ -366,14 +368,12 @@ struct codec_manager_impl { } std::unique_ptr<broadcaster::BroadcastConfiguration> GetBroadcastConfig( const std::vector<std::pair<types::LeAudioContextType, uint8_t>>& subgroup_quality, std::optional<const types::PublishedAudioCapabilities*> pacs) { const CodecManager::BroadcastConfigurationRequirements& requirements) { if (GetCodecLocation() != types::CodecLocation::ADSP) { // Get the software supported broadcast configuration return std::make_unique<broadcaster::BroadcastConfiguration>( ::bluetooth::le_audio::broadcaster::GetBroadcastConfig( subgroup_quality)); requirements.subgroup_quality)); } /* Subgroups with different audio qualities is not being supported now, Loading @@ -381,7 +381,7 @@ struct codec_manager_impl { * the standard audio config instead */ uint8_t BIG_audio_quality = bluetooth::le_audio::QUALITY_HIGH; for (const auto& [_, quality] : subgroup_quality) { for (const auto& [_, quality] : requirements.subgroup_quality) { if (quality == bluetooth::le_audio::QUALITY_STANDARD) { BIG_audio_quality = bluetooth::le_audio::QUALITY_STANDARD; } Loading Loading @@ -438,7 +438,7 @@ struct codec_manager_impl { if (max_sdu_octets < sdu_octets) max_sdu_octets = sdu_octets; } if (subgroup_quality.size() > 1) { if (requirements.subgroup_quality.size() > 1) { log::error("More than one subgroup is not supported!"); } Loading Loading @@ -983,14 +983,10 @@ void CodecManager::UpdateActiveAudioConfig( } std::unique_ptr<AudioSetConfiguration> CodecManager::GetCodecConfig( types::LeAudioContextType ctx_type, std::function<const set_configurations::AudioSetConfiguration*( types::LeAudioContextType context_type, const set_configurations::AudioSetConfigurations* confs)> non_vendor_config_matcher) { const CodecManager::UnicastConfigurationRequirements& requirements, CodecManager::UnicastConfigurationVerifier verifier) { if (pimpl_->IsRunning()) { return pimpl_->codec_manager_impl_->GetCodecConfig( ctx_type, non_vendor_config_matcher); return pimpl_->codec_manager_impl_->GetCodecConfig(requirements, verifier); } return nullptr; Loading @@ -1007,12 +1003,10 @@ bool CodecManager::CheckCodecConfigIsBiDirSwb( std::unique_ptr<broadcaster::BroadcastConfiguration> CodecManager::GetBroadcastConfig( const std::vector<std::pair<types::LeAudioContextType, uint8_t>>& subgroup_quality, std::optional<const types::PublishedAudioCapabilities*> pacs) const { const CodecManager::BroadcastConfigurationRequirements& requirements) const { if (pimpl_->IsRunning()) { return pimpl_->codec_manager_impl_->GetBroadcastConfig(subgroup_quality, pacs); return pimpl_->codec_manager_impl_->GetBroadcastConfig(requirements); } return nullptr; Loading
system/bta/le_audio/codec_manager.h +18 −9 Original line number Diff line number Diff line Loading @@ -58,6 +58,21 @@ struct broadcast_offload_config { class CodecManager { public: struct UnicastConfigurationRequirements { ::bluetooth::le_audio::types::LeAudioContextType audio_context_type; }; typedef std::function<const set_configurations::AudioSetConfiguration*( const UnicastConfigurationRequirements& requirements, const set_configurations::AudioSetConfigurations* confs)> UnicastConfigurationVerifier; struct BroadcastConfigurationRequirements { std::vector< std::pair<bluetooth::le_audio::types::LeAudioContextType, uint8_t>> subgroup_quality; }; virtual ~CodecManager() = default; static CodecManager* GetInstance(void) { static CodecManager* instance = new CodecManager(); Loading @@ -79,21 +94,15 @@ class CodecManager { update_receiver); virtual std::unique_ptr< ::bluetooth::le_audio::set_configurations::AudioSetConfiguration> GetCodecConfig(::bluetooth::le_audio::types::LeAudioContextType ctx_type, std::function<const set_configurations::AudioSetConfiguration*( types::LeAudioContextType context_type, const set_configurations::AudioSetConfigurations* confs)> non_vendor_config_matcher); GetCodecConfig(const UnicastConfigurationRequirements& requirements, UnicastConfigurationVerifier verifier); virtual bool CheckCodecConfigIsBiDirSwb( const ::bluetooth::le_audio::set_configurations::AudioSetConfiguration& config) const; virtual std::unique_ptr<broadcaster::BroadcastConfiguration> GetBroadcastConfig( const std::vector< std::pair<bluetooth::le_audio::types::LeAudioContextType, uint8_t>>& subgroup_quality, std::optional<const types::PublishedAudioCapabilities*> pacs) const; const BroadcastConfigurationRequirements& requirements) const; virtual void UpdateBroadcastConnHandle( const std::vector<uint16_t>& conn_handle, Loading
system/bta/le_audio/codec_manager_test.cc +16 −8 Original line number Diff line number Diff line Loading @@ -390,7 +390,7 @@ TEST_F(CodecManagerTestAdsp, test_capabilities_none) { codec_manager->Start(offloading_preference); auto match_first_config = [](types::LeAudioContextType context_type, [](const CodecManager::UnicastConfigurationRequirements& requirements, const set_configurations::AudioSetConfigurations* confs) -> const set_configurations::AudioSetConfiguration* { if (confs && confs->size()) { Loading @@ -404,8 +404,11 @@ TEST_F(CodecManagerTestAdsp, test_capabilities_none) { // Verify every context for (::bluetooth::le_audio::types::LeAudioContextType ctx_type : ::bluetooth::le_audio::types::kLeAudioContextAllTypesArray) { CodecManager::UnicastConfigurationRequirements requirements = { .audio_context_type = ctx_type, }; ASSERT_EQ(nullptr, codec_manager->GetCodecConfig(ctx_type, match_first_config)); codec_manager->GetCodecConfig(requirements, match_first_config)); } } Loading Loading @@ -435,7 +438,7 @@ TEST_F(CodecManagerTestAdsp, test_capabilities) { size_t available_configs_size = 0; auto match_first_config = [&available_configs_size]( types::LeAudioContextType context_type, const CodecManager::UnicastConfigurationRequirements& requirements, const set_configurations::AudioSetConfigurations* confs) -> const set_configurations::AudioSetConfiguration* { if (confs && confs->size()) { Loading @@ -447,7 +450,10 @@ TEST_F(CodecManagerTestAdsp, test_capabilities) { return nullptr; }; auto cfg = codec_manager->GetCodecConfig(test_context, match_first_config); CodecManager::UnicastConfigurationRequirements requirements = { .audio_context_type = test_context, }; auto cfg = codec_manager->GetCodecConfig(requirements, match_first_config); ASSERT_NE(nullptr, cfg); ASSERT_EQ(offload_capabilities.size(), available_configs_size); Loading @@ -469,8 +475,9 @@ TEST_F(CodecManagerTestAdsp, test_broadcast_config) { {.codec_type = bluetooth::le_audio::LE_AUDIO_CODEC_INDEX_SOURCE_LC3}}; codec_manager->Start(offloading_preference); auto cfg = codec_manager->GetBroadcastConfig( {{types::LeAudioContextType::MEDIA, 1}}, std::nullopt); CodecManager::BroadcastConfigurationRequirements requirements = { .subgroup_quality = {{types::LeAudioContextType::MEDIA, 1}}}; auto cfg = codec_manager->GetBroadcastConfig(requirements); ASSERT_EQ(2, cfg->GetNumBisTotal()); ASSERT_EQ(2, cfg->GetNumChannelsMax()); ASSERT_EQ(48000u, cfg->GetSamplingFrequencyHzMax()); Loading @@ -493,8 +500,9 @@ TEST_F(CodecManagerTestAdsp, test_update_broadcast_offloader) { {.codec_type = bluetooth::le_audio::LE_AUDIO_CODEC_INDEX_SOURCE_LC3}}; codec_manager->Start(offloading_preference); codec_manager->GetBroadcastConfig({{types::LeAudioContextType::MEDIA, 1}}, std::nullopt); CodecManager::BroadcastConfigurationRequirements requirements = { .subgroup_quality = {{types::LeAudioContextType::MEDIA, 1}}}; codec_manager->GetBroadcastConfig(requirements); bool was_called = false; bluetooth::le_audio::broadcast_offload_config bcast_config; Loading