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

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

Merge "Get default LE audio offload codec capability from HAL"

parents 879520c4 b5859f2c
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -302,35 +302,35 @@ BluetoothAudioClientInterface::GetAudioCapabilities_2_1(
  return capabilities_2_1;
}

std::vector<AudioCapabilities_2_1>
std::vector<AudioCapabilities_2_2>
BluetoothAudioClientInterface::GetAudioCapabilities_2_2(
    SessionType_2_1 session_type_2_1) {
  if (HalVersionManager::GetHalVersion() ==
      BluetoothAudioHalVersion::VERSION_2_1) {
    return GetAudioCapabilities_2_1(session_type_2_1);
  std::vector<AudioCapabilities_2_2> capabilities_2_2(0);
  if (HalVersionManager::GetHalVersion() !=
      BluetoothAudioHalVersion::VERSION_2_2) {
    LOG(ERROR) << __func__ << ", can't get capability for HAL 2.2";
    return capabilities_2_2;
  }

  std::vector<AudioCapabilities_2_1> capabilities_2_1(0);
  android::sp<IBluetoothAudioProvidersFactory_2_2> providersFactory =
      HalVersionManager::GetProvidersFactory_2_2();
  CHECK(providersFactory != nullptr)
      << "IBluetoothAudioProvidersFactory::getService() failed";

  auto getProviderCapabilities_cb =
      [&capabilities_2_1](
          const hidl_vec<AudioCapabilities_2_1>& audioCapabilities_2_1) {
        for (auto capability_2_1 : audioCapabilities_2_1) {
          capabilities_2_1.push_back(capability_2_1);
      [&capabilities_2_2](
          const hidl_vec<AudioCapabilities_2_2>& audioCapabilities_2_2) {
        for (auto capability_2_2 : audioCapabilities_2_2) {
          capabilities_2_2.push_back(capability_2_2);
        }
      };
  auto hidl_retval = providersFactory->getProviderCapabilities_2_1(
  auto hidl_retval = providersFactory->getProviderCapabilities_2_2(
      session_type_2_1, getProviderCapabilities_cb);
  if (!hidl_retval.isOk()) {
    LOG(FATAL) << __func__
               << ": BluetoothAudioHal::getProviderCapabilities failure: "
               << hidl_retval.description();
  }
  return capabilities_2_1;
  return capabilities_2_2;
}

void BluetoothAudioClientInterface::FetchAudioProvider() {
+4 −1
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ using AudioCapabilities =
    ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
using AudioCapabilities_2_1 =
    ::android::hardware::bluetooth::audio::V2_1::AudioCapabilities;
using AudioCapabilities_2_2 =
    ::android::hardware::bluetooth::audio::V2_2::AudioCapabilities;
using AudioConfiguration =
    ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
using AudioConfiguration_2_1 =
@@ -229,7 +231,7 @@ class BluetoothAudioClientInterface {
      SessionType session_type);
  static std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1(
      SessionType_2_1 session_type_2_1);
  static std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_2(
  static std::vector<AudioCapabilities_2_2> GetAudioCapabilities_2_2(
      SessionType_2_1 session_type_2_1);

  void StreamStarted(const BluetoothAudioCtrlAck& ack);
@@ -278,6 +280,7 @@ class BluetoothAudioClientInterface {
  IBluetoothTransportInstance* transport_;
  std::vector<AudioCapabilities> capabilities_;
  std::vector<AudioCapabilities_2_1> capabilities_2_1_;
  std::vector<AudioCapabilities_2_2> capabilities_2_2_;
};

// The client interface connects an IBluetoothTransportInstance to
+149 −1
Original line number Diff line number Diff line
@@ -19,7 +19,11 @@

#include "le_audio_software.h"

#include <unordered_map>
#include <vector>

#include "client_interface.h"
#include "codec_status.h"
#include "hal_version_manager.h"
#include "osi/include/log.h"
#include "osi/include/properties.h"
@@ -28,8 +32,11 @@ namespace {

using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
using ::android::hardware::bluetooth::audio::V2_0::CodecType;
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::PcmParameters;
using ::android::hardware::bluetooth::audio::V2_2::AudioLocation;
using ::bluetooth::audio::AudioConfiguration_2_2;
using ::bluetooth::audio::BluetoothAudioCtrlAck;
using ::bluetooth::audio::SampleRate_2_1;
@@ -37,6 +44,14 @@ using ::bluetooth::audio::SessionType;
using ::bluetooth::audio::SessionType_2_1;
using ::bluetooth::audio::le_audio::LeAudioClientInterface;
using ::bluetooth::audio::le_audio::StreamCallbacks;
using AudioCapabilities_2_2 =
    ::android::hardware::bluetooth::audio::V2_2::AudioCapabilities;
using android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapability;

using ::le_audio::set_configurations::AudioSetConfiguration;
using ::le_audio::set_configurations::CodecCapabilitySetting;
using ::le_audio::set_configurations::SetConfiguration;
using ::le_audio::types::LeAudioLc3Config;

bluetooth::audio::BluetoothAudioSinkClientInterface*
    le_audio_sink_hal_clientinterface = nullptr;
@@ -339,6 +354,139 @@ namespace bluetooth {
namespace audio {
namespace le_audio {

std::unordered_map<SampleRate_2_1, uint8_t> sampling_freq_map{
    {SampleRate_2_1::RATE_8000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq8000Hz},
    {SampleRate_2_1::RATE_16000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq16000Hz},
    {SampleRate_2_1::RATE_24000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq24000Hz},
    {SampleRate_2_1::RATE_32000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq32000Hz},
    {SampleRate_2_1::RATE_44100,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq44100Hz},
    {SampleRate_2_1::RATE_48000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq48000Hz},
    {SampleRate_2_1::RATE_88200,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq88200Hz},
    {SampleRate_2_1::RATE_96000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq96000Hz},
    {SampleRate_2_1::RATE_176400,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq176400Hz},
    {SampleRate_2_1::RATE_192000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq192000Hz}};

std::unordered_map<Lc3FrameDuration, uint8_t> frame_duration_map{
    {Lc3FrameDuration::DURATION_7500US,
     ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameDur7500us},
    {Lc3FrameDuration::DURATION_10000US,
     ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameDur10000us}};

std::unordered_map<uint32_t, uint16_t> octets_per_frame_map{
    {30, ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameLen30},
    {40, ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameLen40},
    {120, ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameLen120}};

std::unordered_map<AudioLocation, uint32_t> audio_location_map{
    {AudioLocation::UNKNOWN,
     ::le_audio::codec_spec_conf::kLeAudioLocationMonoUnspecified},
    {AudioLocation::FRONT_LEFT,
     ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft},
    {AudioLocation::FRONT_RIGHT,
     ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight},
    {static_cast<AudioLocation>(AudioLocation::FRONT_LEFT |
                                AudioLocation::FRONT_RIGHT),
     ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft |
         ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight}};

bool halConfigToCodecCapabilitySetting(
    LeAudioCodecCapability halConfig, CodecCapabilitySetting& codecCapability) {
  if (halConfig.codecType != CodecType::LC3) {
    LOG(WARNING) << "Unsupported codecType: " << toString(halConfig.codecType);
    return false;
  }

  Lc3Parameters halLc3Config = halConfig.capabilities;
  AudioLocation supportedChannel = halConfig.supportedChannel;

  if (sampling_freq_map.find(halLc3Config.samplingFrequency) ==
          sampling_freq_map.end() ||
      frame_duration_map.find(halLc3Config.frameDuration) ==
          frame_duration_map.end() ||
      octets_per_frame_map.find(halLc3Config.octetsPerFrame) ==
          octets_per_frame_map.end() ||
      audio_location_map.find(supportedChannel) == audio_location_map.end()) {
    LOG(ERROR) << __func__ << ": Failed to convert HAL format to stack format"
               << "\nsample rate = " << (uint8_t)halLc3Config.samplingFrequency
               << "\nframe duration = " << (uint8_t)halLc3Config.frameDuration
               << "\noctets per frame= " << halLc3Config.octetsPerFrame
               << "\naudio location = " << (uint8_t)supportedChannel;

    return false;
  }

  codecCapability = {
      .id = ::le_audio::set_configurations::LeAudioCodecIdLc3,
      .config = LeAudioLc3Config(
          {.sampling_frequency =
               sampling_freq_map[halLc3Config.samplingFrequency],
           .frame_duration = frame_duration_map[halLc3Config.frameDuration],
           .octets_per_codec_frame =
               octets_per_frame_map[halLc3Config.octetsPerFrame],
           .audio_channel_allocation = audio_location_map[supportedChannel]})};

  return true;
}

std::vector<AudioSetConfiguration> get_offload_capabilities() {
  LOG(INFO) << __func__;
  std::vector<AudioSetConfiguration> offload_capabilities;
  std::vector<AudioCapabilities_2_2> le_audio_hal_capabilities =
      audio::BluetoothAudioSinkClientInterface::GetAudioCapabilities_2_2(
          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
  std::string strCapabilityLog;

  for (auto halCapability : le_audio_hal_capabilities) {
    CodecCapabilitySetting encodeCapability;
    CodecCapabilitySetting decodeCapability;
    LeAudioCodecCapability halEncodeConfig =
        halCapability.leAudioCapabilities().encodeCapability;
    LeAudioCodecCapability halDecodeConfig =
        halCapability.leAudioCapabilities().decodeCapability;
    AudioSetConfiguration audioSetConfig = {.name = "offload capability"};
    strCapabilityLog.clear();

    if (halConfigToCodecCapabilitySetting(halEncodeConfig, encodeCapability)) {
      audioSetConfig.confs.push_back(SetConfiguration(
          ::le_audio::types::kLeAudioDirectionSink, halEncodeConfig.deviceCount,
          halEncodeConfig.deviceCount * halEncodeConfig.channelCountPerDevice,
          encodeCapability));
      strCapabilityLog = " Encode Capability: " + toString(halEncodeConfig);
    }

    if (halConfigToCodecCapabilitySetting(halDecodeConfig, decodeCapability)) {
      audioSetConfig.confs.push_back(SetConfiguration(
          ::le_audio::types::kLeAudioDirectionSource,
          halDecodeConfig.deviceCount,
          halDecodeConfig.deviceCount * halDecodeConfig.channelCountPerDevice,
          decodeCapability));
      strCapabilityLog += " Decode Capability: " + toString(halDecodeConfig);
    }

    if (!audioSetConfig.confs.empty()) {
      offload_capabilities.push_back(audioSetConfig);
      LOG(INFO) << __func__
                << ": Supported codec capability =" << strCapabilityLog;

    } else {
      LOG(INFO) << __func__
                << ": Unknown codec capability =" << toString(halCapability);
    }
  }

  return offload_capabilities;
}

LeAudioClientInterface* LeAudioClientInterface::interface = nullptr;
LeAudioClientInterface* LeAudioClientInterface::Get() {
  if (osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false)) {
+4 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include <functional>

#include "bta/le_audio/le_audio_types.h"
#include "common/message_loop_thread.h"

namespace bluetooth {
@@ -47,6 +48,9 @@ struct StreamCallbacks {
  std::function<bool(const sink_metadata_t&)> on_sink_metadata_update_;
};

std::vector<::le_audio::set_configurations::AudioSetConfiguration>
get_offload_capabilities();

class LeAudioClientInterface {
 public:
  struct PcmParameters {
+5 −0
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@ namespace audio {

namespace le_audio {

std::vector<::le_audio::set_configurations::AudioSetConfiguration>
get_offload_capabilities() {
  return std::vector<::le_audio::set_configurations::AudioSetConfiguration>(0);
}

LeAudioClientInterface* LeAudioClientInterface::Get() { return nullptr; }

bool LeAudioClientInterface::IsSinkAcquired() { return false; }
Loading