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

Commit 2b8c219f authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add support create_broadcast with preferred quality for offload" into main am: 8eef88c9

parents 15d391c5 8eef88c9
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -421,9 +421,15 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
          LeAudioContextType::MEDIA | LeAudioContextType::CONVERSATIONAL;
    }

    /* Subgroups with different audio qualities is not being supported now,
     * if any subgroup preferred to use standard audio config, choose
     * the standard audio config instead
     */
    uint8_t BIG_audio_quality = bluetooth::le_audio::QUALITY_HIGH;
    for (const uint8_t quality : subgroup_quality) {
      if (quality == bluetooth::le_audio::QUALITY_STANDARD) {
        public_features |= bluetooth::le_audio::kLeAudioQualityStandard;
        BIG_audio_quality = bluetooth::le_audio::QUALITY_STANDARD;
      } else if (quality == bluetooth::le_audio::QUALITY_HIGH) {
        public_features |= bluetooth::le_audio::kLeAudioQualityHigh;
      }
@@ -481,13 +487,15 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      subgroup_ltvs.push_back(ltv);
    }

    auto codec_qos_pair = [](AudioContexts context_type)
    auto codec_qos_pair = [](AudioContexts context_type,
                             uint8_t BIG_audio_quality)
        -> std::optional<
            std::pair<const BroadcastCodecWrapper, const BroadcastQosConfig>> {
      if (CodecManager::GetInstance()->GetCodecLocation() ==
          CodecLocation::ADSP) {
        auto offload_config =
            CodecManager::GetInstance()->GetBroadcastOffloadConfig();
            CodecManager::GetInstance()->GetBroadcastOffloadConfig(
                BIG_audio_quality);
        if (offload_config == nullptr) {
          return std::nullopt;
        }
@@ -509,13 +517,24 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      } else {
        return le_audio::broadcaster::getStreamConfigForContext(context_type);
      }
    }(context_type);
    }(context_type, BIG_audio_quality);

    if (!codec_qos_pair) {
      LOG_ERROR("No valid broadcast offload config");
      callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid,
                                     false);
      return;
    }

    if (BIG_audio_quality == bluetooth::le_audio::QUALITY_HIGH &&
        codec_qos_pair->first.GetSampleRate() != 48000) {
      LOG_WARN(
          "Preferred quality isn't supported. Fallback to standard audio "
          "quality");
      public_features &= (0xFFFF & ~bluetooth::le_audio::kLeAudioQualityHigh);
      public_features |= bluetooth::le_audio::kLeAudioQualityStandard;
    }

    BroadcastStateMachineConfig msg = {
        .is_public = is_public,
        .broadcast_id = broadcast_id,
+75 −12
Original line number Diff line number Diff line
@@ -235,32 +235,93 @@ struct codec_manager_impl {
    }
  }

  const broadcast_offload_config* GetBroadcastOffloadConfig() {
  const broadcast_offload_config* GetBroadcastOffloadConfig(
      uint8_t preferred_quality) {
    if (supported_broadcast_config.empty()) {
      LOG_ERROR("There is no valid broadcast offload config");
      return nullptr;
    }
    /* Broadcast audio config selection based on source broadcast capability
     *
     * If the preferred_quality is HIGH, the configs ranking is
     * 48_4 > 48_2 > 24_2(sink mandatory) > 16_2(source & sink mandatory)
     *
     * If the preferred_quality is STANDARD, the configs ranking is
     * 24_2(sink mandatory) > 16_2(source & sink mandatory)
     */
    broadcast_target_config = -1;
    for (int i = 0; i < (int)supported_broadcast_config.size(); i++) {
      if (supported_broadcast_config[i].sampling_rate == 48000u) {
        if (preferred_quality == bluetooth::le_audio::QUALITY_STANDARD)
          continue;

        if (supported_broadcast_config[i].octets_per_frame == 120) {  // 48_4
          broadcast_target_config = i;
          break;
        } else if (supported_broadcast_config[i].octets_per_frame ==
                   100) {  // 48_2
          broadcast_target_config = i;
        }
      } else if (supported_broadcast_config[i].sampling_rate == 24000u &&
                 supported_broadcast_config[i].octets_per_frame ==
                     60) {  // 24_2
        if (preferred_quality == bluetooth::le_audio::QUALITY_STANDARD) {
          broadcast_target_config = i;
          break;
        } else if (broadcast_target_config ==
                   -1) {  // preferred_quality is QUALITY_HIGH, and
                          // haven't get the 48_4 or 48_2
          broadcast_target_config = i;
        }
      } else if (supported_broadcast_config[i].sampling_rate == 16000u &&
                 supported_broadcast_config[i].octets_per_frame ==
                     40) {  // 16_2
        if (preferred_quality == bluetooth::le_audio::QUALITY_STANDARD) {
          broadcast_target_config = i;
        } else if (broadcast_target_config == -1 ||
                   supported_broadcast_config[broadcast_target_config]
                           .sampling_rate !=
                       24000u) {  // preferred_quality is QUALITY_HIGH, and
                                  // haven't get the 48_4 or 48_2 or 24_2
          broadcast_target_config = i;
        }
      }
    }

    if (broadcast_target_config == -1) {
      LOG_ERROR(
          "There is no valid broadcast offload config with preferred_quality");
      return nullptr;
    }

    LOG_INFO(
        "stream_map.size(): %zu, sampling_rate: %d, frame_duration(us): %d, "
        "octets_per_frame: %d, blocks_per_sdu %d, "
        "retransmission_number: %d, max_transport_latency: %d",
        supported_broadcast_config[0].stream_map.size(),
        supported_broadcast_config[0].sampling_rate,
        supported_broadcast_config[0].frame_duration,
        supported_broadcast_config[0].octets_per_frame,
        (int)supported_broadcast_config[0].blocks_per_sdu,
        (int)supported_broadcast_config[0].retransmission_number,
        supported_broadcast_config[0].max_transport_latency);
        supported_broadcast_config[broadcast_target_config].stream_map.size(),
        supported_broadcast_config[broadcast_target_config].sampling_rate,
        supported_broadcast_config[broadcast_target_config].frame_duration,
        supported_broadcast_config[broadcast_target_config].octets_per_frame,
        (int)supported_broadcast_config[broadcast_target_config].blocks_per_sdu,
        (int)supported_broadcast_config[broadcast_target_config]
            .retransmission_number,
        supported_broadcast_config[broadcast_target_config]
            .max_transport_latency);

    return &supported_broadcast_config[0];
    return &supported_broadcast_config[broadcast_target_config];
  }

  void UpdateBroadcastConnHandle(
      const std::vector<uint16_t>& conn_handle,
      std::function<void(const ::le_audio::broadcast_offload_config& config)>
          update_receiver) {
    auto broadcast_config = supported_broadcast_config[0];
    if (broadcast_target_config == -1 ||
        broadcast_target_config >= (int)supported_broadcast_config.size()) {
      LOG_ERROR("There is no valid broadcast offload config");
      return;
    }

    auto broadcast_config = supported_broadcast_config[broadcast_target_config];
    LOG_ASSERT(conn_handle.size() == broadcast_config.stream_map.size());

    if (broadcast_config.stream_map.size() ==
@@ -639,6 +700,7 @@ struct codec_manager_impl {

  std::vector<btle_audio_codec_config_t> codec_input_capa = {};
  std::vector<btle_audio_codec_config_t> codec_output_capa = {};
  int broadcast_target_config = -1;
};  // namespace le_audio

struct CodecManager::impl {
@@ -728,9 +790,10 @@ const AudioSetConfigurations* CodecManager::GetOffloadCodecConfig(
}

const ::le_audio::broadcast_offload_config*
CodecManager::GetBroadcastOffloadConfig() {
CodecManager::GetBroadcastOffloadConfig(uint8_t preferred_quality) {
  if (pimpl_->IsRunning()) {
    return pimpl_->codec_manager_impl_->GetBroadcastOffloadConfig();
    return pimpl_->codec_manager_impl_->GetBroadcastOffloadConfig(
        preferred_quality);
  }

  return nullptr;
+2 −2
Original line number Diff line number Diff line
@@ -78,8 +78,8 @@ class CodecManager {
          update_receiver);
  virtual const ::le_audio::set_configurations::AudioSetConfigurations*
  GetOffloadCodecConfig(::le_audio::types::LeAudioContextType ctx_type);
  virtual const ::le_audio::broadcast_offload_config*
  GetBroadcastOffloadConfig();
  virtual const ::le_audio::broadcast_offload_config* GetBroadcastOffloadConfig(
      uint8_t preferred_quality);
  virtual void UpdateBroadcastConnHandle(
      const std::vector<uint16_t>& conn_handle,
      std::function<void(const ::le_audio::broadcast_offload_config& config)>
+2 −2
Original line number Diff line number Diff line
@@ -63,9 +63,9 @@ CodecManager::GetOffloadCodecConfig(types::LeAudioContextType ctx_type) {
}

const ::le_audio::broadcast_offload_config*
CodecManager::GetBroadcastOffloadConfig() {
CodecManager::GetBroadcastOffloadConfig(uint8_t preferred_quality) {
  if (!pimpl_) return nullptr;
  return pimpl_->GetBroadcastOffloadConfig();
  return pimpl_->GetBroadcastOffloadConfig(preferred_quality);
}

std::vector<bluetooth::le_audio::btle_audio_codec_config_t>
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ class MockCodecManager {
              GetOffloadCodecConfig,
              (le_audio::types::LeAudioContextType ctx_type), (const));
  MOCK_METHOD((le_audio::broadcast_offload_config*), GetBroadcastOffloadConfig,
              (), (const));
              (uint8_t preferred_quality), (const));
  MOCK_METHOD((std::vector<bluetooth::le_audio::btle_audio_codec_config_t>),
              GetLocalAudioOutputCodecCapa, ());
  MOCK_METHOD((std::vector<bluetooth::le_audio::btle_audio_codec_config_t>),