Merge "Parse broadcast offload capabilities"
This commit is contained in:
commit
47c304ee1e
7 changed files with 101 additions and 14 deletions
|
@ -1566,6 +1566,7 @@ TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
|
|||
};
|
||||
|
||||
for (auto& lc3_config : lc3_codec_configs) {
|
||||
le_audio_broadcast_config.streamMap.resize(1);
|
||||
le_audio_broadcast_config.streamMap[0]
|
||||
.leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
|
||||
lc3_config);
|
||||
|
|
|
@ -200,13 +200,21 @@ BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities(
|
|||
GetUnicastCapability(scenario.getEncode());
|
||||
UnicastCapability unicast_decode_capability =
|
||||
GetUnicastCapability(scenario.getDecode());
|
||||
// encode and decode cannot be unknown at the same time
|
||||
if (unicast_encode_capability.codecType == CodecType::UNKNOWN &&
|
||||
unicast_decode_capability.codecType == CodecType::UNKNOWN) {
|
||||
continue;
|
||||
}
|
||||
BroadcastCapability broadcast_capability = {.codecType =
|
||||
CodecType::UNKNOWN};
|
||||
|
||||
if (scenario.hasBroadcast()) {
|
||||
broadcast_capability = GetBroadcastCapability(scenario.getBroadcast());
|
||||
}
|
||||
|
||||
// At least one capability should be valid
|
||||
if (unicast_encode_capability.codecType == CodecType::UNKNOWN &&
|
||||
unicast_decode_capability.codecType == CodecType::UNKNOWN &&
|
||||
broadcast_capability.codecType == CodecType::UNKNOWN) {
|
||||
LOG(ERROR) << __func__ << ": None of the capability is valid.";
|
||||
continue;
|
||||
}
|
||||
|
||||
le_audio_codec_capabilities.push_back(
|
||||
{.unicastEncodeCapability = unicast_encode_capability,
|
||||
.unicastDecodeCapability = unicast_decode_capability,
|
||||
|
@ -252,6 +260,54 @@ UnicastCapability BluetoothLeAudioCodecsProvider::GetUnicastCapability(
|
|||
return {.codecType = CodecType::UNKNOWN};
|
||||
}
|
||||
|
||||
BroadcastCapability BluetoothLeAudioCodecsProvider::GetBroadcastCapability(
|
||||
const std::string& coding_direction) {
|
||||
if (coding_direction == "invalid") {
|
||||
return {.codecType = CodecType::UNKNOWN};
|
||||
}
|
||||
|
||||
auto configuration_iter = configuration_map_.find(coding_direction);
|
||||
if (configuration_iter == configuration_map_.end()) {
|
||||
return {.codecType = CodecType::UNKNOWN};
|
||||
}
|
||||
|
||||
auto codec_configuration_iter = codec_configuration_map_.find(
|
||||
configuration_iter->second.getCodecConfiguration());
|
||||
if (codec_configuration_iter == codec_configuration_map_.end()) {
|
||||
return {.codecType = CodecType::UNKNOWN};
|
||||
}
|
||||
|
||||
auto strategy_configuration_iter = strategy_configuration_map_.find(
|
||||
configuration_iter->second.getStrategyConfiguration());
|
||||
if (strategy_configuration_iter == strategy_configuration_map_.end()) {
|
||||
return {.codecType = CodecType::UNKNOWN};
|
||||
}
|
||||
|
||||
CodecType codec_type =
|
||||
GetCodecType(codec_configuration_iter->second.getCodec());
|
||||
std::vector<std::optional<Lc3Capabilities>> bcastLc3Cap(
|
||||
1, std::optional(ComposeLc3Capability(codec_configuration_iter->second)));
|
||||
|
||||
if (codec_type == CodecType::LC3) {
|
||||
return ComposeBroadcastCapability(
|
||||
codec_type,
|
||||
GetAudioLocation(
|
||||
strategy_configuration_iter->second.getAudioLocation()),
|
||||
strategy_configuration_iter->second.getChannelCount(), bcastLc3Cap);
|
||||
}
|
||||
return {.codecType = CodecType::UNKNOWN};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
BroadcastCapability BluetoothLeAudioCodecsProvider::ComposeBroadcastCapability(
|
||||
const CodecType& codec_type, const AudioLocation& audio_location,
|
||||
const uint8_t& channel_count, const std::vector<T>& capability) {
|
||||
return {.codecType = codec_type,
|
||||
.supportedChannel = audio_location,
|
||||
.channelCountPerStream = channel_count,
|
||||
.leAudioCodecCapabilities = std::optional(capability)};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
UnicastCapability BluetoothLeAudioCodecsProvider::ComposeUnicastCapability(
|
||||
const CodecType& codec_type, const AudioLocation& audio_location,
|
||||
|
@ -322,6 +378,10 @@ bool BluetoothLeAudioCodecsProvider::IsValidStrategyConfiguration(
|
|||
// 1. two connected device, one for L one for R
|
||||
// 2. one connected device for both L and R
|
||||
return true;
|
||||
} else if (strategy_configuration.getConnectedDevice() == 0 &&
|
||||
strategy_configuration.getChannelCount() == 2) {
|
||||
// Broadcast
|
||||
return true;
|
||||
}
|
||||
} else if (strategy_configuration.getAudioLocation() ==
|
||||
setting::AudioLocation::MONO) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <android-base/logging.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "aidl_android_hardware_bluetooth_audio_setting.h"
|
||||
|
||||
|
@ -66,12 +67,20 @@ class BluetoothLeAudioCodecsProvider {
|
|||
|
||||
static UnicastCapability GetUnicastCapability(
|
||||
const std::string& coding_direction);
|
||||
static BroadcastCapability GetBroadcastCapability(
|
||||
const std::string& coding_direction);
|
||||
|
||||
template <class T>
|
||||
static inline UnicastCapability ComposeUnicastCapability(
|
||||
const CodecType& codec_type, const AudioLocation& audio_location,
|
||||
const uint8_t& device_cnt, const uint8_t& channel_count,
|
||||
const T& capability);
|
||||
|
||||
template <class T>
|
||||
static inline BroadcastCapability ComposeBroadcastCapability(
|
||||
const CodecType& codec_type, const AudioLocation& audio_location,
|
||||
const uint8_t& channel_count, const std::vector<T>& capability);
|
||||
|
||||
static inline Lc3Capabilities ComposeLc3Capability(
|
||||
const setting::CodecConfiguration& codec_configuration);
|
||||
|
||||
|
|
|
@ -46,7 +46,11 @@ typedef std::tuple<std::vector<ScenarioList>, std::vector<ConfigurationList>,
|
|||
// Define valid components for each list
|
||||
// Scenario
|
||||
static const Scenario kValidScenario(std::make_optional("OneChanStereo_16_1"),
|
||||
std::make_optional("OneChanStereo_16_1"));
|
||||
std::make_optional("OneChanStereo_16_1"),
|
||||
std::nullopt);
|
||||
static const Scenario kValidBroadcastScenario(
|
||||
std::nullopt, std::nullopt, std::make_optional("BcastStereo_16_2"));
|
||||
|
||||
// Configuration
|
||||
static const Configuration kValidConfigOneChanStereo_16_1(
|
||||
std::make_optional("OneChanStereo_16_1"), std::make_optional("LC3_16k_1"),
|
||||
|
@ -69,11 +73,15 @@ static const StrategyConfiguration kValidStrategyMonoOneCis(
|
|||
std::make_optional("MONO_ONE_CIS_PER_DEVICE"),
|
||||
std::make_optional(AudioLocation::MONO), std::make_optional(1),
|
||||
std::make_optional(1));
|
||||
static const StrategyConfiguration kValidStrategyBroadcastStereo(
|
||||
std::make_optional("BROADCAST_STEREO"),
|
||||
std::make_optional(AudioLocation::STEREO), std::make_optional(0),
|
||||
std::make_optional(2));
|
||||
|
||||
// Define valid test list built from above valid components
|
||||
// Scenario, Configuration, CodecConfiguration, StrategyConfiguration
|
||||
static const std::vector<ScenarioList> kValidScenarioList = {
|
||||
ScenarioList(std::vector<Scenario>{kValidScenario})};
|
||||
static const std::vector<ScenarioList> kValidScenarioList = {ScenarioList(
|
||||
std::vector<Scenario>{kValidScenario, kValidBroadcastScenario})};
|
||||
static const std::vector<ConfigurationList> kValidConfigurationList = {
|
||||
ConfigurationList(
|
||||
std::vector<Configuration>{kValidConfigOneChanStereo_16_1})};
|
||||
|
@ -84,7 +92,7 @@ static const std::vector<StrategyConfigurationList>
|
|||
kValidStrategyConfigurationList = {
|
||||
StrategyConfigurationList(std::vector<StrategyConfiguration>{
|
||||
kValidStrategyStereoOneCis, kValidStrategyStereoTwoCis,
|
||||
kValidStrategyMonoOneCis})};
|
||||
kValidStrategyMonoOneCis, kValidStrategyBroadcastStereo})};
|
||||
|
||||
class BluetoothLeAudioCodecsProviderTest
|
||||
: public ::testing::TestWithParam<OffloadSetting> {
|
||||
|
@ -151,13 +159,15 @@ class GetScenariosTest : public BluetoothLeAudioCodecsProviderTest {
|
|||
static std::vector<ScenarioList> CreateInvalidScenarios() {
|
||||
std::vector<ScenarioList> invalid_scenario_test_cases;
|
||||
invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
|
||||
Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"))}));
|
||||
|
||||
invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
|
||||
Scenario(std::make_optional("OneChanStereo_16_1"), std::nullopt)}));
|
||||
Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"),
|
||||
std::nullopt)}));
|
||||
|
||||
invalid_scenario_test_cases.push_back(ScenarioList(
|
||||
std::vector<Scenario>{Scenario(std::nullopt, std::nullopt)}));
|
||||
std::vector<Scenario>{Scenario(std::make_optional("OneChanStereo_16_1"),
|
||||
std::nullopt, std::nullopt)}));
|
||||
|
||||
invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
|
||||
Scenario(std::nullopt, std::nullopt, std::nullopt)}));
|
||||
|
||||
invalid_scenario_test_cases.push_back(
|
||||
ScenarioList(std::vector<Scenario>{}));
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
<scenario encode="OneChanStereo_16_2" decode="OneChanMono_16_2"/>
|
||||
<scenario encode="TwoChanStereo_16_2" decode="OneChanMono_16_2"/>
|
||||
<scenario encode="OneChanMono_16_2" decode="OneChanMono_16_2"/>
|
||||
<!-- broadcast -->
|
||||
<scenario encode="invalid" decode="invalid" broadcast="BcastStereo_16_2"/>
|
||||
</scenarioList>
|
||||
<configurationList>
|
||||
<configuration name="OneChanMono_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
|
||||
|
@ -48,6 +50,7 @@
|
|||
<configuration name="OneChanMono_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="TwoChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
|
||||
<configuration name="OneChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="BcastStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="BROADCAST_STEREO"/>
|
||||
</configurationList>
|
||||
<codecConfigurationList>
|
||||
<codecConfiguration name="LC3_16k_1" codec="LC3" samplingFrequency="16000" frameDurationUs="7500" octetsPerCodecFrame="30"/>
|
||||
|
@ -57,5 +60,6 @@
|
|||
<strategyConfiguration name="STEREO_ONE_CIS_PER_DEVICE" audioLocation="STEREO" connectedDevice="2" channelCount="1"/>
|
||||
<strategyConfiguration name="STEREO_TWO_CISES_PER_DEVICE" audioLocation="STEREO" connectedDevice="1" channelCount="2"/>
|
||||
<strategyConfiguration name="MONO_ONE_CIS_PER_DEVICE" audioLocation="MONO" connectedDevice="1" channelCount="1"/>
|
||||
<strategyConfiguration name="BROADCAST_STEREO" audioLocation="STEREO" connectedDevice="0" channelCount="2"/>
|
||||
</strategyConfigurationList>
|
||||
</leAudioOffloadSetting>
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<xs:complexType>
|
||||
<xs:attribute name="encode" type="xs:string"/>
|
||||
<xs:attribute name="decode" type="xs:string"/>
|
||||
<xs:attribute name="broadcast" type="xs:string"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="configuration">
|
||||
|
|
|
@ -64,8 +64,10 @@ package aidl.android.hardware.bluetooth.audio.setting {
|
|||
|
||||
public class Scenario {
|
||||
ctor public Scenario();
|
||||
method public String getBroadcast();
|
||||
method public String getDecode();
|
||||
method public String getEncode();
|
||||
method public void setBroadcast(String);
|
||||
method public void setDecode(String);
|
||||
method public void setEncode(String);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue