Merge "Get default provider codec from HAL" am: d563e5bc9e am: e3a2c2c421

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1906371

Change-Id: I5586f0d85c788b4a27389af92da3f0169df1be5c
This commit is contained in:
Treehugger Robot 2021-12-28 06:12:24 +00:00 committed by Automerger Merge Worker
commit 7e9292b531
6 changed files with 218 additions and 0 deletions

View file

@ -48,4 +48,26 @@ interface IBluetoothAudioProvidersFactory extends @2.1::IBluetoothAudioProviders
*/
openProvider_2_2(SessionType sessionType)
generates (Status status, IBluetoothAudioProvider provider);
/**
* Gets a list of audio capabilities for a session type.
*
* For software encoding, the PCM capabilities are returned.
* For hardware encoding, the supported codecs and their capabilities are
* returned.
*
* @param sessionType The session type (e.g.
* A2DP_SOFTWARE_ENCODING_DATAPATH).
* @return audioCapabilities A list containing all the capabilities
* supported by the sesson type. The capabilities is a list of
* available options when configuring the codec for the session.
* For software encoding it is the PCM data rate.
* For hardware encoding it is the list of supported codecs and their
* capabilities.
* If a provider isn't supported, an empty list should be returned.
* Note: Only one entry should exist per codec when using hardware
* encoding.
*/
getProviderCapabilities_2_2(SessionType sessionType)
generates (vec<AudioCapabilities> audioCapabilities);
};

View file

@ -221,6 +221,47 @@ Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities_2_1(
return Void();
}
Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities_2_2(
const V2_1::SessionType sessionType,
getProviderCapabilities_2_2_cb _hidl_cb) {
hidl_vec<V2_2::AudioCapabilities> audio_capabilities =
hidl_vec<V2_2::AudioCapabilities>(0);
if (sessionType == V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
std::vector<CodecCapabilities> db_codec_capabilities =
android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
if (db_codec_capabilities.size()) {
audio_capabilities.resize(db_codec_capabilities.size());
for (int i = 0; i < db_codec_capabilities.size(); ++i) {
audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
}
}
} else if (sessionType == V2_1::SessionType::
LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
sessionType == V2_1::SessionType::
LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
std::vector<LeAudioCodecCapabilitiesPair> db_codec_capabilities =
android::bluetooth::audio::GetLeAudioOffloadCodecCapabilities(
sessionType);
if (db_codec_capabilities.size()) {
audio_capabilities.resize(db_codec_capabilities.size());
for (int i = 0; i < db_codec_capabilities.size(); ++i) {
audio_capabilities[i].leAudioCapabilities(db_codec_capabilities[i]);
}
}
} else if (sessionType != V2_1::SessionType::UNKNOWN) {
std::vector<V2_1::PcmParameters> db_pcm_capabilities =
android::bluetooth::audio::GetSoftwarePcmCapabilities_2_1();
if (db_pcm_capabilities.size() == 1) {
audio_capabilities.resize(1);
audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
}
}
LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
<< " supports " << audio_capabilities.size() << " codecs";
_hidl_cb(audio_capabilities);
return Void();
}
IBluetoothAudioProvidersFactory* HIDL_FETCH_IBluetoothAudioProvidersFactory(
const char* /* name */) {
return new BluetoothAudioProvidersFactory();

View file

@ -53,6 +53,10 @@ class BluetoothAudioProvidersFactory : public IBluetoothAudioProvidersFactory {
const V2_1::SessionType sessionType,
getProviderCapabilities_2_1_cb _hidl_cb) override;
Return<void> getProviderCapabilities_2_2(
const V2_1::SessionType sessionType,
getProviderCapabilities_2_2_cb _hidl_cb) override;
private:
static A2dpSoftwareAudioProvider a2dp_software_provider_instance_;
static A2dpOffloadAudioProvider a2dp_offload_provider_instance_;

View file

@ -19,6 +19,8 @@ package android.hardware.bluetooth.audio@2.2;
import @2.1::Lc3Parameters;
import @2.1::PcmParameters;
import @2.0::CodecConfiguration;
import @2.0::CodecCapabilities;
import @2.1::CodecType;
enum LeAudioMode : uint8_t {
UNKNOWN = 0x00,
@ -26,6 +28,12 @@ enum LeAudioMode : uint8_t {
BROADCAST = 0x02,
};
enum AudioLocation : uint8_t {
UNKNOWN = 0,
FRONT_LEFT = 1,
FRONT_RIGHT = 2,
};
struct UnicastStreamMap {
/* The connection handle used for a unicast or a broadcast group. */
uint16_t streamHandle;
@ -70,3 +78,37 @@ safe_union AudioConfiguration {
CodecConfiguration codecConfig;
LeAudioConfiguration leAudioConfig;
};
/** Used to specify the capabilities of the different session types */
safe_union AudioCapabilities {
PcmParameters pcmCapabilities;
CodecCapabilities codecCapabilities;
LeAudioCodecCapabilitiesPair leAudioCapabilities;
};
/**
* Used to specify th le audio capabilities pair of the Hardware offload encode and decode.
*/
struct LeAudioCodecCapabilitiesPair{
LeAudioMode mode;
LeAudioCodecCapability encodeCapability;
LeAudioCodecCapability decodeCapability;
};
/**
* Used to specify the le audio capabilities of the codecs supported by Hardware offload
* for encode or decode.
*/
struct LeAudioCodecCapability {
CodecType codecType;
AudioLocation supportedChannel;
// The number of connected device
uint8_t deviceCount;
// Supported channel count for each device
uint8_t channelCountPerDevice;
// Should use safe union when there is more than one codec
Lc3Parameters capabilities;
};

View file

@ -24,9 +24,59 @@ namespace android {
namespace bluetooth {
namespace audio {
using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
using ::android::hardware::bluetooth::audio::V2_1::CodecType;
using ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration;
using ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
using ::android::hardware::bluetooth::audio::V2_2::AudioLocation;
using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesPair;
using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapability;
using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
using SessionType_2_1 =
::android::hardware::bluetooth::audio::V2_1::SessionType;
// Stores the list of offload supported capability
std::vector<LeAudioCodecCapabilitiesPair> kDefaultOffloadLeAudioCapabilities;
static const LeAudioCodecCapability kInvalidLc3Capability = {
.codecType = CodecType::UNKNOWN};
// Default Supported Codecs
// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30
static const Lc3Parameters kLc3Capability_16_1 = {
.samplingFrequency = SampleRate::RATE_16000,
.frameDuration = Lc3FrameDuration::DURATION_7500US,
.octetsPerFrame = 30};
// Default Supported Codecs
// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40
static const Lc3Parameters kLc3Capability_16_2 = {
.samplingFrequency = SampleRate::RATE_16000,
.frameDuration = Lc3FrameDuration::DURATION_10000US,
.octetsPerFrame = 40};
// Default Supported Codecs
// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
static const Lc3Parameters kLc3Capability_48_4 = {
.samplingFrequency = SampleRate::RATE_48000,
.frameDuration = Lc3FrameDuration::DURATION_10000US,
.octetsPerFrame = 120};
static const std::vector<Lc3Parameters> supportedLc3CapabilityList = {
kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1};
static AudioLocation stereoAudio = static_cast<AudioLocation>(
AudioLocation::FRONT_LEFT | AudioLocation::FRONT_RIGHT);
static AudioLocation monoAudio = AudioLocation::UNKNOWN;
// Stores the supported setting of audio location, connected device, and the
// channel count for each device
std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
supportedDeviceSetting = {std::make_tuple(stereoAudio, 2, 1),
std::make_tuple(monoAudio, 1, 2),
std::make_tuple(monoAudio, 1, 1)};
bool IsOffloadLeAudioConfigurationValid(
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
session_type,
@ -44,6 +94,60 @@ bool IsOffloadLeAudioConfigurationValid(
return true;
}
LeAudioCodecCapability composeLc3Capability(AudioLocation audioLocation,
uint8_t deviceCnt,
uint8_t channelCount,
Lc3Parameters capability) {
return LeAudioCodecCapability{.codecType = CodecType::LC3,
.supportedChannel = audioLocation,
.deviceCount = deviceCnt,
.channelCountPerDevice = channelCount,
.capabilities = capability};
}
std::vector<LeAudioCodecCapabilitiesPair> GetLeAudioOffloadCodecCapabilities(
const SessionType_2_1& session_type) {
if (session_type !=
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
session_type !=
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
return std::vector<LeAudioCodecCapabilitiesPair>(0);
}
if (kDefaultOffloadLeAudioCapabilities.empty()) {
for (auto [audioLocation, deviceCnt, channelCount] :
supportedDeviceSetting) {
for (auto capability : supportedLc3CapabilityList) {
LeAudioCodecCapability lc3Capability = composeLc3Capability(
audioLocation, deviceCnt, channelCount, capability);
LeAudioCodecCapability lc3MonoCapability =
composeLc3Capability(monoAudio, 1, 1, capability);
// Adds the capability for encode only
kDefaultOffloadLeAudioCapabilities.push_back(
{.mode = LeAudioMode::UNICAST,
.encodeCapability = lc3Capability,
.decodeCapability = kInvalidLc3Capability});
// Adds the capability for decode only
kDefaultOffloadLeAudioCapabilities.push_back(
{.mode = LeAudioMode::UNICAST,
.encodeCapability = kInvalidLc3Capability,
.decodeCapability = lc3Capability});
// Adds the capability for the case that encode and decode exist at the
// same time
kDefaultOffloadLeAudioCapabilities.push_back(
{.mode = LeAudioMode::UNICAST,
.encodeCapability = lc3Capability,
.decodeCapability = lc3MonoCapability});
}
}
}
return kDefaultOffloadLeAudioCapabilities;
}
} // namespace audio
} // namespace bluetooth
} // namespace android

View file

@ -30,6 +30,11 @@ bool IsOffloadLeAudioConfigurationValid(
session_type,
const ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration&
le_audio_codec_config);
std::vector<hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesPair>
GetLeAudioOffloadCodecCapabilities(
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
session_type);
} // namespace audio
} // namespace bluetooth
} // namespace android