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

Commit 00391605 authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Extend the codec requirements

This extends the Codec Manager interface to allow passing the
requirements needed for the AIDL codec config provider.
Additionally unit tests are parametrized to run with the vendor
codec configurations.

Bug: 308428860
Bug: 295972694
Test: atest --host bluetooth_le_audio_test bluetooth_le_audio_client_test  bluetooth_test_broadcaster bluetooth_test_broadcaster_state_machine bluetooth_le_audio_codec_manager_test
Flags: EXEMPT; Vendor codec boilerplate - not in the execution path yet
Change-Id: Idaee57b9085503ebdea20dbe53e43ed0364dd95f
parent e0c0aef0
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -62,6 +62,17 @@ class CodecManager {
 public:
 public:
  struct UnicastConfigurationRequirements {
  struct UnicastConfigurationRequirements {
    ::bluetooth::le_audio::types::LeAudioContextType audio_context_type;
    ::bluetooth::le_audio::types::LeAudioContextType audio_context_type;
    std::optional<std::vector<types::acs_ac_record>> sink_pacs;
    std::optional<std::vector<types::acs_ac_record>> source_pacs;

    struct DeviceDirectionRequirements {
      uint8_t target_latency = types::kTargetLatencyUndefined;
      uint8_t target_Phy = types::kTargetPhyUndefined;
      types::LeAudioLtvMap params;
    };

    std::optional<std::vector<DeviceDirectionRequirements>> sink_requirements;
    std::optional<std::vector<DeviceDirectionRequirements>> source_requirements;
  };
  };


  /* The verifier function checks each possible configuration (from the set of
  /* The verifier function checks each possible configuration (from the set of
+86 −4
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@
#include "hci/controller_interface.h"
#include "hci/controller_interface.h"
#include "internal_include/bt_trace.h"
#include "internal_include/bt_trace.h"
#include "le_audio/codec_manager.h"
#include "le_audio/codec_manager.h"
#include "le_audio/devices.h"
#include "le_audio/le_audio_types.h"
#include "le_audio/le_audio_types.h"
#include "le_audio_set_configuration_provider.h"
#include "le_audio_set_configuration_provider.h"
#include "le_audio_utils.h"
#include "le_audio_utils.h"
@@ -783,11 +784,90 @@ bool LeAudioDeviceGroup::UpdateAudioContextAvailability(void) {
  return old_contexts != GetAvailableContexts();
  return old_contexts != GetAvailableContexts();
}
}


CodecManager::UnicastConfigurationRequirements
LeAudioDeviceGroup::GetAudioSetConfigurationRequirements(
    types::LeAudioContextType ctx_type) const {
  auto new_req = CodecManager::UnicastConfigurationRequirements{
      .audio_context_type = ctx_type,
  };

  // Define a requirement for each location. Knowing codec specific
  // capabilities (i.e. multiplexing capability) the config provider can
  // determine the number of ASEs to activate.
  for (auto const& weak_dev_ptr : leAudioDevices_) {
    auto device = weak_dev_ptr.lock();
    BidirectionalPair<bool> has_location = {false, false};

    for (auto direction :
         {types::kLeAudioDirectionSink, types::kLeAudioDirectionSource}) {
      if (device->GetAseCount(direction) == 0) {
        log::warn("Device {} has no ASEs for direction: {}", device->address_,
                  (int)direction);
        continue;
      }

      auto& dev_locations = (direction == types::kLeAudioDirectionSink)
                                ? device->snk_audio_locations_
                                : device->src_audio_locations_;
      if (dev_locations.none()) {
        log::warn("Device {} has no locations for direction: {}",
                  device->address_, (int)direction);
        continue;
      }

      has_location.get(direction) = true;
      auto& direction_req = (direction == types::kLeAudioDirectionSink)
                                ? new_req.sink_requirements
                                : new_req.source_requirements;
      if (!direction_req) {
        direction_req =
            std::vector<CodecManager::UnicastConfigurationRequirements::
                            DeviceDirectionRequirements>();
      }

      // Pass the audio channel allocation requirement
      auto locations = dev_locations.to_ulong();
      CodecManager::UnicastConfigurationRequirements::
          DeviceDirectionRequirements config_req;
      config_req.params.Add(
          codec_spec_conf::kLeAudioLtvTypeAudioChannelAllocation,
          (uint32_t)locations);
      log::warn("Device {} pushes requirement, location: {}, direction: {}",
                device->address_, (int)locations, (int)direction);
      direction_req->push_back(std::move(config_req));
    }

    // Push sink PACs if there are some sink requirements
    if (has_location.sink && !device->snk_pacs_.empty()) {
      if (!new_req.sink_pacs) {
        new_req.sink_pacs = std::vector<types::acs_ac_record>{};
      }
      for (auto const& [_, pac_char] : device->snk_pacs_) {
        for (auto const& pac_record : pac_char) {
          new_req.sink_pacs->push_back(pac_record);
        }
      }
    }

    // Push source PACs if there are some source requirements
    if (has_location.source && !device->src_pacs_.empty()) {
      if (!new_req.source_pacs) {
        new_req.source_pacs = std::vector<types::acs_ac_record>{};
      }
      for (auto& [_, pac_char] : device->src_pacs_) {
        for (auto const& pac_record : pac_char) {
          new_req.source_pacs->push_back(pac_record);
        }
      }
    }
  }

  return new_req;
}

bool LeAudioDeviceGroup::UpdateAudioSetConfigurationCache(
bool LeAudioDeviceGroup::UpdateAudioSetConfigurationCache(
    LeAudioContextType ctx_type) const {
    LeAudioContextType ctx_type) const {
  CodecManager::UnicastConfigurationRequirements requirements = {
  auto requirements = GetAudioSetConfigurationRequirements(ctx_type);
      .audio_context_type = ctx_type};

  auto new_conf = CodecManager::GetInstance()->GetCodecConfig(
  auto new_conf = CodecManager::GetInstance()->GetCodecConfig(
      requirements,
      requirements,
      std::bind(&LeAudioDeviceGroup::FindFirstSupportedConfiguration, this,
      std::bind(&LeAudioDeviceGroup::FindFirstSupportedConfiguration, this,
@@ -1375,10 +1455,12 @@ bool LeAudioDeviceGroup::IsAudioSetConfigurationSupported(
                   static_cast<int>(ase_cnt - active_ase_cnt));
                   static_cast<int>(ase_cnt - active_ase_cnt));


      for (auto const& ent : ase_confs) {
      for (auto const& ent : ase_confs) {
        // Verify PACS only if this is transparent LTV format
        auto const& pacs = (direction == types::kLeAudioDirectionSink)
        auto const& pacs = (direction == types::kLeAudioDirectionSink)
                               ? device->snk_pacs_
                               ? device->snk_pacs_
                               : device->src_pacs_;
                               : device->src_pacs_;
        if (!utils::GetConfigurationSupportedPac(pacs, ent.codec)) {
        if (utils::IsCodecUsingLtvFormat(ent.codec.id) &&
            !utils::GetConfigurationSupportedPac(pacs, ent.codec)) {
          log::debug(
          log::debug(
              "Insufficient PAC for {}",
              "Insufficient PAC for {}",
              direction == types::kLeAudioDirectionSink ? "sink" : "source");
              direction == types::kLeAudioDirectionSink ? "sink" : "source");
+3 −0
Original line number Original line Diff line number Diff line
@@ -211,6 +211,9 @@ class LeAudioDeviceGroup {
  bool UpdateAudioContextAvailability(void);
  bool UpdateAudioContextAvailability(void);
  bool UpdateAudioSetConfigurationCache(
  bool UpdateAudioSetConfigurationCache(
      types::LeAudioContextType ctx_type) const;
      types::LeAudioContextType ctx_type) const;
  CodecManager::UnicastConfigurationRequirements
  GetAudioSetConfigurationRequirements(
      types::LeAudioContextType ctx_type) const;
  bool ReloadAudioLocations(void);
  bool ReloadAudioLocations(void);
  bool ReloadAudioDirections(void);
  bool ReloadAudioDirections(void);
  std::shared_ptr<const set_configurations::AudioSetConfiguration>
  std::shared_ptr<const set_configurations::AudioSetConfiguration>
+9 −3
Original line number Original line Diff line number Diff line
@@ -257,6 +257,7 @@ bool LeAudioDevice::ConfigureAses(


  if (!ase) {
  if (!ase) {
    log::error("Unable to find an ASE to configure");
    log::error("Unable to find an ASE to configure");
    PrintDebugState();
    return false;
    return false;
  }
  }


@@ -265,7 +266,8 @@ bool LeAudioDevice::ConfigureAses(
      (direction == types::kLeAudioDirectionSink) ? snk_pacs_ : src_pacs_;
      (direction == types::kLeAudioDirectionSink) ? snk_pacs_ : src_pacs_;
  for (size_t i = 0; i < ase_configs.size() && ase; ++i) {
  for (size_t i = 0; i < ase_configs.size() && ase; ++i) {
    auto const& ase_cfg = ase_configs.at(i);
    auto const& ase_cfg = ase_configs.at(i);
    if (!utils::GetConfigurationSupportedPac(pacs, ase_cfg.codec)) {
    if (utils::IsCodecUsingLtvFormat(ase_cfg.codec.id) &&
        !utils::GetConfigurationSupportedPac(pacs, ase_cfg.codec)) {
      return false;
      return false;
    }
    }
  }
  }
@@ -283,13 +285,15 @@ bool LeAudioDevice::ConfigureAses(
                             : src_audio_locations_;
                             : src_audio_locations_;


  // Before we activate the ASEs, make sure we have the right configuration
  // Before we activate the ASEs, make sure we have the right configuration
  // Check for matching PACs only if we know that the LTV format is being used.
  uint8_t max_required_ase_per_dev = ase_configs.size() / num_of_devices +
  uint8_t max_required_ase_per_dev = ase_configs.size() / num_of_devices +
                                     (ase_configs.size() % num_of_devices);
                                     (ase_configs.size() % num_of_devices);
  int needed_ase = std::min((int)(max_required_ase_per_dev),
  int needed_ase = std::min((int)(max_required_ase_per_dev),
                            (int)(ase_configs.size() - active_ases));
                            (int)(ase_configs.size() - active_ases));
  for (int i = 0; i < needed_ase; ++i) {
  for (int i = 0; i < needed_ase; ++i) {
    auto const& ase_cfg = ase_configs.at(i);
    auto const& ase_cfg = ase_configs.at(i);
    if (!utils::GetConfigurationSupportedPac(pacs, ase_cfg.codec)) {
    if (utils::IsCodecUsingLtvFormat(ase_cfg.codec.id) &&
        !utils::GetConfigurationSupportedPac(pacs, ase_cfg.codec)) {
      log::error("No matching PAC found. Stop the activation.");
      log::error("No matching PAC found. Stop the activation.");
      return false;
      return false;
    }
    }
@@ -331,6 +335,7 @@ bool LeAudioDevice::ConfigureAses(
      ase->target_latency = ase_cfg.qos.target_latency;
      ase->target_latency = ase_cfg.qos.target_latency;
      ase->codec_id = ase_cfg.codec.id;
      ase->codec_id = ase_cfg.codec.id;
      ase->codec_config = ase_cfg.codec.params;
      ase->codec_config = ase_cfg.codec.params;
      ase->vendor_codec_config = ase_cfg.codec.vendor_params;
      ase->channel_count = ase_cfg.codec.channel_count_per_iso_stream;
      ase->channel_count = ase_cfg.codec.channel_count_per_iso_stream;


      /* Let's choose audio channel allocation if not set */
      /* Let's choose audio channel allocation if not set */
@@ -341,7 +346,8 @@ bool LeAudioDevice::ConfigureAses(


      /* Get default value if no requirement for specific frame blocks per sdu
      /* Get default value if no requirement for specific frame blocks per sdu
       */
       */
      if (!ase->codec_config.Find(
      if (utils::IsCodecUsingLtvFormat(ase->codec_id) &&
          !ase->codec_config.Find(
              codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu)) {
              codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu)) {
        ase->codec_config.Add(
        ase->codec_config.Add(
            codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu,
            codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu,
+391 −97

File changed.

Preview size limit exceeded, changes collapsed.

Loading