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

Commit f5c39150 authored by Alice Kuo's avatar Alice Kuo
Browse files

Seperate audio allocation and connection status configuraiton update

With the patch, we change flow and remove downmix property. As the stream started, the bluetooth stack will update the target allocation to the bluetooth audio HAL. If part of cises are not connected, the stack will update the audio configuration again with the streamMap that contains the current allocation.

Bug: 231084798
Test: check the audio configuration update sequence as downmix_fallback_
enable/disable
Test: atest bluetooth_le_audio_test

Change-Id: Ic5d4bb8b3f265499657f2d162b3616e1b377adbb
parent 0eca2b96
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -2520,6 +2520,12 @@ class LeAudioClientImpl : public LeAudioClient {
    leAudioClientAudioSource->UpdateRemoteDelay(remote_delay_ms);
    leAudioClientAudioSource->ConfirmStreamingRequest();
    audio_sender_state_ = AudioState::STARTED;
    /* We update the target audio allocation before streamStarted that the
     * offloder would know how to configure offloader encoder. We should check
     * if we need to update the current
     * allocation here as the target allocation and the current allocation is
     * different */
    updateOffloaderIfNeeded(group);

    return true;
  }
@@ -2578,6 +2584,12 @@ class LeAudioClientImpl : public LeAudioClient {
    leAudioClientAudioSink->UpdateRemoteDelay(remote_delay_ms);
    leAudioClientAudioSink->ConfirmStreamingRequest();
    audio_receiver_state_ = AudioState::STARTED;
    /* We update the target audio allocation before streamStarted that the
     * offloder would know how to configure offloader decoder. We should check
     * if we need to update the current
     * allocation here as the target allocation and the current allocation is
     * different */
    updateOffloaderIfNeeded(group);
  }

  void SuspendAudio(void) {
@@ -3504,7 +3516,7 @@ class LeAudioClientImpl : public LeAudioClient {

    const auto* stream_conf = &group->stream_conf;

    if (stream_conf->sink_offloader_changed) {
    if (stream_conf->sink_offloader_changed || stream_conf->sink_is_initial) {
      LOG_INFO("Update sink offloader streams");
      uint16_t remote_delay_ms =
          group->GetRemoteDelay(le_audio::types::kLeAudioDirectionSink);
@@ -3515,7 +3527,8 @@ class LeAudioClientImpl : public LeAudioClient {
      group->StreamOffloaderUpdated(le_audio::types::kLeAudioDirectionSink);
    }

    if (stream_conf->source_offloader_changed) {
    if (stream_conf->source_offloader_changed ||
        stream_conf->source_is_initial) {
      LOG_INFO("Update source offloader streams");
      uint16_t remote_delay_ms =
          group->GetRemoteDelay(le_audio::types::kLeAudioDirectionSource);
+14 −2
Original line number Diff line number Diff line
@@ -89,7 +89,13 @@ struct codec_manager_impl {
          update_receiver) {
    if (stream_conf.sink_streams.empty()) return;

    sink_config.stream_map = std::move(stream_conf.sink_offloader_streams);
    if (stream_conf.sink_is_initial) {
      sink_config.stream_map =
          stream_conf.sink_offloader_streams_target_allocation;
    } else {
      sink_config.stream_map =
          stream_conf.sink_offloader_streams_current_allocation;
    }
    // TODO: set the default value 16 for now, would change it if we support
    // mode bits_per_sample
    sink_config.bits_per_sample = 16;
@@ -107,7 +113,13 @@ struct codec_manager_impl {
          update_receiver) {
    if (stream_conf.source_streams.empty()) return;

    source_config.stream_map = std::move(stream_conf.source_offloader_streams);
    if (stream_conf.source_is_initial) {
      source_config.stream_map =
          stream_conf.source_offloader_streams_target_allocation;
    } else {
      source_config.stream_map =
          stream_conf.source_offloader_streams_current_allocation;
    }
    // TODO: set the default value 16 for now, would change it if we support
    // mode bits_per_sample
    source_config.bits_per_sample = 16;
+50 −29
Original line number Diff line number Diff line
@@ -109,7 +109,8 @@ int LeAudioDeviceGroup::NumOfConnected(types::LeAudioContextType context_type) {
void LeAudioDeviceGroup::ClearSinksFromConfiguration(void) {
  LOG_INFO("Group %p, group_id %d", this, group_id_);
  stream_conf.sink_streams.clear();
  stream_conf.sink_offloader_streams.clear();
  stream_conf.sink_offloader_streams_target_allocation.clear();
  stream_conf.sink_offloader_streams_current_allocation.clear();
  stream_conf.sink_audio_channel_allocation = 0;
  stream_conf.sink_num_of_channels = 0;
  stream_conf.sink_num_of_devices = 0;
@@ -122,7 +123,8 @@ void LeAudioDeviceGroup::ClearSinksFromConfiguration(void) {
void LeAudioDeviceGroup::ClearSourcesFromConfiguration(void) {
  LOG_INFO("Group %p, group_id %d", this, group_id_);
  stream_conf.source_streams.clear();
  stream_conf.source_offloader_streams.clear();
  stream_conf.source_offloader_streams_target_allocation.clear();
  stream_conf.source_offloader_streams_current_allocation.clear();
  stream_conf.source_audio_channel_allocation = 0;
  stream_conf.source_num_of_channels = 0;
  stream_conf.source_num_of_devices = 0;
@@ -1636,9 +1638,9 @@ bool LeAudioDeviceGroup::IsMetadataChanged(

void LeAudioDeviceGroup::StreamOffloaderUpdated(uint8_t direction) {
  if (direction == le_audio::types::kLeAudioDirectionSource) {
    stream_conf.source_offloader_changed = false;
    stream_conf.source_is_initial = false;
  } else {
    stream_conf.sink_offloader_changed = false;
    stream_conf.sink_is_initial = false;
  }
}

@@ -1650,23 +1652,35 @@ void LeAudioDeviceGroup::CreateStreamVectorForOffloader(uint8_t direction) {

  CisType cis_type;
  std::vector<std::pair<uint16_t, uint32_t>>* streams;
  std::vector<std::pair<uint16_t, uint32_t>>* offloader_streams;
  std::vector<std::pair<uint16_t, uint32_t>>*
      offloader_streams_target_allocation;
  std::vector<std::pair<uint16_t, uint32_t>>*
      offloader_streams_current_allocation;
  std::string tag;
  uint32_t available_allocations = 0;
  bool* changed_flag;
  bool* is_initial;
  if (direction == le_audio::types::kLeAudioDirectionSource) {
    changed_flag = &stream_conf.source_offloader_changed;
    is_initial = &stream_conf.source_is_initial;
    cis_type = CisType::CIS_TYPE_UNIDIRECTIONAL_SOURCE;
    streams = &stream_conf.source_streams;
    offloader_streams = &stream_conf.source_offloader_streams;
    offloader_streams_target_allocation =
        &stream_conf.source_offloader_streams_target_allocation;
    offloader_streams_current_allocation =
        &stream_conf.source_offloader_streams_current_allocation;
    tag = "Source";
    available_allocations = AdjustAllocationForOffloader(
        stream_conf.source_audio_channel_allocation);
  } else {
    changed_flag = &stream_conf.sink_offloader_changed;
    is_initial = &stream_conf.sink_is_initial;
    cis_type = CisType::CIS_TYPE_UNIDIRECTIONAL_SINK;
    streams = &stream_conf.sink_streams;
    offloader_streams = &stream_conf.sink_offloader_streams;
    offloader_streams_target_allocation =
        &stream_conf.sink_offloader_streams_target_allocation;
    offloader_streams_current_allocation =
        &stream_conf.sink_offloader_streams_current_allocation;
    tag = "Sink";
    available_allocations =
        AdjustAllocationForOffloader(stream_conf.sink_audio_channel_allocation);
@@ -1677,26 +1691,24 @@ void LeAudioDeviceGroup::CreateStreamVectorForOffloader(uint8_t direction) {
    return;
  }

  if (offloader_streams->size() > 0) {
    /* We are here because of the CIS modification during streaming.
     * this makes sense only when downmixing is enabled so we can notify
     * offloader about connected / disconnected CISes. If downmixing is disabled
     * then there is not need to notify offloader as it has all the informations
     * already */
    if (!downmix_fallback_) {
      LOG_INFO("Downmixing disabled - nothing to do");
      return;
    }
  if (offloader_streams_target_allocation->size() == 0) {
    *is_initial = true;
  }

  offloader_streams->clear();
  offloader_streams_current_allocation->clear();
  *changed_flag = true;

  bool not_all_cises_connected = false;
  if (available_allocations != codec_spec_conf::kLeAudioLocationStereo) {
    not_all_cises_connected = true;
  }

  /* If the all cises are connected as stream started, reset changed_flag that
   * the bt stack wouldn't send another audio configuration for the connection
   * status */
  if (*is_initial && !not_all_cises_connected) {
    *changed_flag = false;
  }

  /* Note: For the offloader case we simplify allocation to only Left and Right.
   * If we need 2 CISes and only one is connected, the connected one will have
   * allocation set to stereo (left | right) and other one will have allocation
@@ -1710,28 +1722,37 @@ void LeAudioDeviceGroup::CreateStreamVectorForOffloader(uint8_t direction) {
    if ((cis_entry.type == CisType::CIS_TYPE_BIDIRECTIONAL ||
         cis_entry.type == cis_type) &&
        cis_entry.conn_handle != 0) {
      uint32_t allocation = 0;
      uint32_t target_allocation = 0;
      uint32_t current_allocation = 0;
      for (const auto& s : *streams) {
        if (s.first == cis_entry.conn_handle) {
          allocation = AdjustAllocationForOffloader(s.second);
          if (not_all_cises_connected && downmix_fallback_) {
          target_allocation = AdjustAllocationForOffloader(s.second);
          current_allocation = target_allocation;
          if (not_all_cises_connected) {
            /* Tell offloader to mix on this CIS.*/
            allocation = codec_spec_conf::kLeAudioLocationStereo;
            current_allocation = codec_spec_conf::kLeAudioLocationStereo;
          }
          break;
        }
      }

      if (allocation == 0 && !downmix_fallback_) {
      if (target_allocation == 0) {
        /* Take missing allocation for that one .*/
        allocation =
        target_allocation =
            codec_spec_conf::kLeAudioLocationStereo & ~available_allocations;
      }

      LOG_INFO("%s: Cis handle 0x%04x, allocation  0x%08x", tag.c_str(),
               cis_entry.conn_handle, allocation);
      offloader_streams->emplace_back(
          std::make_pair(cis_entry.conn_handle, allocation));
      LOG_INFO(
          "%s: Cis handle 0x%04x, target allocation  0x%08x, current "
          "allocation 0x%08x",
          tag.c_str(), cis_entry.conn_handle, target_allocation,
          current_allocation);
      if (*is_initial) {
        offloader_streams_target_allocation->emplace_back(
            std::make_pair(cis_entry.conn_handle, target_allocation));
      }
      offloader_streams_current_allocation->emplace_back(
          std::make_pair(cis_entry.conn_handle, current_allocation));
    }
  }
}
+1 −6
Original line number Diff line number Diff line
@@ -214,9 +214,7 @@ class LeAudioDeviceGroup {
        pending_update_available_contexts_(std::nullopt),
        target_state_(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE),
        current_state_(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE),
        context_type_(types::LeAudioContextType::UNINITIALIZED) {
    downmix_fallback_ = osi_property_get_bool(kDownmixFallback, false);
  }
        context_type_(types::LeAudioContextType::UNINITIALIZED) {}
  ~LeAudioDeviceGroup(void);

  void AddNode(const std::shared_ptr<LeAudioDevice>& leAudioDevice);
@@ -349,9 +347,6 @@ class LeAudioDeviceGroup {
           const set_configurations::AudioSetConfiguration*>
      active_context_to_configuration_map;

  static constexpr char kDownmixFallback[] =
      "persist.bluetooth.leaudio.offloader.downmix_fallback";
  bool downmix_fallback_;
  types::AseState target_state_;
  types::AseState current_state_;
  types::LeAudioContextType context_type_;
+14 −2
Original line number Diff line number Diff line
@@ -703,8 +703,14 @@ struct stream_configuration {
  int sink_num_of_devices;
  /* cis_handle, audio location*/
  std::vector<std::pair<uint16_t, uint32_t>> sink_streams;
  std::vector<std::pair<uint16_t, uint32_t>> sink_offloader_streams;
  /* cis_handle, target allocation */
  std::vector<std::pair<uint16_t, uint32_t>>
      sink_offloader_streams_target_allocation;
  /* cis_handle, current allocation */
  std::vector<std::pair<uint16_t, uint32_t>>
      sink_offloader_streams_current_allocation;
  bool sink_offloader_changed;
  bool sink_is_initial;

  /* Source configuration */
  /* For now we have always same frequency for all the channels */
@@ -718,8 +724,14 @@ struct stream_configuration {
  int source_num_of_devices;
  /* cis_handle, audio location*/
  std::vector<std::pair<uint16_t, uint32_t>> source_streams;
  std::vector<std::pair<uint16_t, uint32_t>> source_offloader_streams;
  /* cis_handle, target allocation */
  std::vector<std::pair<uint16_t, uint32_t>>
      source_offloader_streams_target_allocation;
  /* cis_handle, current allocation */
  std::vector<std::pair<uint16_t, uint32_t>>
      source_offloader_streams_current_allocation;
  bool source_offloader_changed;
  bool source_is_initial;
};

void AppendMetadataLtvEntryForCcidList(std::vector<uint8_t>& metadata,
Loading