Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d563e5bc authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Get default provider codec from HAL"

parents 3a16f8fe 784e4433
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -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);
};
+41 −0
Original line number Diff line number Diff line
@@ -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();
+4 −0
Original line number Diff line number Diff line
@@ -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_;
+42 −0
Original line number Diff line number Diff line
@@ -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;
};
+104 −0
Original line number Diff line number Diff line
@@ -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
Loading