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

Commit 66757bac authored by Jack He's avatar Jack He Committed by Gerrit Code Review
Browse files

Merge "LeAudio: Extend the codec requirements" into main

parents 53af0c27 00391605
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -62,6 +62,17 @@ class CodecManager {
 public:
  struct UnicastConfigurationRequirements {
    ::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
+86 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include "hci/controller_interface.h"
#include "internal_include/bt_trace.h"
#include "le_audio/codec_manager.h"
#include "le_audio/devices.h"
#include "le_audio/le_audio_types.h"
#include "le_audio_set_configuration_provider.h"
#include "le_audio_utils.h"
@@ -783,11 +784,90 @@ bool LeAudioDeviceGroup::UpdateAudioContextAvailability(void) {
  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(
    LeAudioContextType ctx_type) const {
  CodecManager::UnicastConfigurationRequirements requirements = {
      .audio_context_type = ctx_type};

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

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

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

@@ -265,7 +266,8 @@ bool LeAudioDevice::ConfigureAses(
      (direction == types::kLeAudioDirectionSink) ? snk_pacs_ : src_pacs_;
  for (size_t i = 0; i < ase_configs.size() && ase; ++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;
    }
  }
@@ -283,13 +285,15 @@ bool LeAudioDevice::ConfigureAses(
                             : src_audio_locations_;

  // 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 +
                                     (ase_configs.size() % num_of_devices);
  int needed_ase = std::min((int)(max_required_ase_per_dev),
                            (int)(ase_configs.size() - active_ases));
  for (int i = 0; i < needed_ase; ++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.");
      return false;
    }
@@ -331,6 +335,7 @@ bool LeAudioDevice::ConfigureAses(
      ase->target_latency = ase_cfg.qos.target_latency;
      ase->codec_id = ase_cfg.codec.id;
      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;

      /* 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
       */
      if (!ase->codec_config.Find(
      if (utils::IsCodecUsingLtvFormat(ase->codec_id) &&
          !ase->codec_config.Find(
              codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu)) {
        ase->codec_config.Add(
            codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu,
+391 −97

File changed.

Preview size limit exceeded, changes collapsed.

Loading