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

Commit 06651a5c authored by Alice Kuo's avatar Alice Kuo
Browse files

LE audio hardware offload: audio configuration update

The patch including:
1. Gathering all the information needed by hardware offload
2. Update the audio configuration as the remote device ready to stream
3. The offloader could get the callback as config changed and then get
the audio config before processing the audio data without session
restarted

Bug: 197296692
Bug: 150670922
Test: Verify LE audio hardware offload with HAL 2.2 for media
Change-Id: I490cb2c6db6aebc182c2556513eb5e11551604c9
parent e1e1f141
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -732,6 +732,20 @@ bool BluetoothAudioClientInterface::UpdateAudioConfig_2_2(
  }

  transport_->UpdateAudioConfiguration_2_2(audio_config_2_2);

  if (provider_2_2_ == nullptr) {
    LOG(INFO) << __func__
              << ": BluetoothAudioHal nullptr, update it as session started";
    return true;
  }

  ::android::hardware::Return<void> hidl_retval;
  hidl_retval = provider_2_2_->updateAudioConfiguration(audio_config_2_2);

  if (!hidl_retval.isOk()) {
    LOG(ERROR) << __func__
               << ": BluetoothAudioHal failure: " << hidl_retval.description();
  }
  return true;
}

+60 −3
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@ 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 ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration;
using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
using ::android::hardware::bluetooth::audio::V2_2::UnicastConfig;
using ::android::hardware::bluetooth::audio::V2_2::UnicastStreamMap;
using ::bluetooth::audio::AudioConfiguration_2_2;
using ::bluetooth::audio::BluetoothAudioCtrlAck;
using ::bluetooth::audio::SampleRate_2_1;
@@ -529,7 +532,8 @@ static SampleRate_2_1 le_audio_sample_rate2audio_hal(uint32_t sample_rate_2_1) {
  return SampleRate_2_1::RATE_UNKNOWN;
}

static BitsPerSample le_audio_bit_rate2audio_hal(uint8_t bits_per_sample) {
static BitsPerSample le_audio_bits_per_sample2audio_hal(
    uint8_t bits_per_sample) {
  switch (bits_per_sample) {
    case 16:
      return BitsPerSample::BITS_16;
@@ -551,6 +555,18 @@ static ChannelMode le_audio_channel_mode2audio_hal(uint8_t channels_count) {
  return ChannelMode::UNKNOWN;
}

static Lc3FrameDuration le_audio_frame_duration2audio_hal(
    uint8_t frame_duration) {
  switch (frame_duration) {
    case 10000:
      return Lc3FrameDuration::DURATION_10000US;
    case 7500:
      return Lc3FrameDuration::DURATION_7500US;
  }
  // TODO: handle error in the aidl version
  return Lc3FrameDuration::DURATION_10000US;
}

void LeAudioClientInterface::Sink::Cleanup() {
  LOG(INFO) << __func__ << " sink";
  StopSession();
@@ -564,7 +580,7 @@ void LeAudioClientInterface::Sink::SetPcmParameters(
    const PcmParameters& params) {
  le_audio_sink->LeAudioSetSelectedHalPcmConfig(
      le_audio_sample_rate2audio_hal(params.sample_rate),
      le_audio_bit_rate2audio_hal(params.bits_per_sample),
      le_audio_bits_per_sample2audio_hal(params.bits_per_sample),
      le_audio_channel_mode2audio_hal(params.channels_count),
      params.data_interval_us);
}
@@ -635,6 +651,41 @@ void LeAudioClientInterface::Sink::StopSession() {
  le_audio_sink_hal_clientinterface->EndSession();
}

void LeAudioClientInterface::Sink::UpdateAudioConfigToHal(
    const ::le_audio::offload_config& offload_config) {
  if (le_audio_sink_hal_clientinterface->GetTransportInstance()
          ->GetSessionType_2_1() !=
      SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
    return;
  }

  AudioConfiguration_2_2 audio_config;
  std::vector<UnicastStreamMap> unicast_map;
  for (auto& [handle, location] : offload_config.stream_map) {
    UnicastStreamMap stream = {.streamHandle = handle,
                               .audioChannelAllocation = location};
    unicast_map.emplace_back(stream);
  }
  hidl_vec<UnicastStreamMap> hal_map;
  hal_map.setToExternal(unicast_map.data(), unicast_map.size());
  LeAudioConfiguration le_audio_config;
  le_audio_config.mode = LeAudioMode::UNICAST;
  le_audio_config.config.unicastConfig() = {
      .streamMap = std::move(hal_map),
      .peerDelay = offload_config.peer_delay,
      .lc3Config = {.pcmBitDepth = le_audio_bits_per_sample2audio_hal(
                        offload_config.bits_per_sample),
                    .samplingFrequency = le_audio_sample_rate2audio_hal(
                        offload_config.sampling_rate),
                    .frameDuration = le_audio_frame_duration2audio_hal(
                        offload_config.frame_duration),
                    .octetsPerFrame = offload_config.octets_per_frame,
                    .blocksPerSdu = offload_config.blocks_per_sdu}};
  audio_config.leAudioConfig(le_audio_config);

  le_audio_sink_hal_clientinterface->UpdateAudioConfig_2_2(audio_config);
}

size_t LeAudioClientInterface::Sink::Read(uint8_t* p_buf, uint32_t len) {
  return le_audio_sink_hal_clientinterface->ReadAudioData(p_buf, len);
}
@@ -652,7 +703,7 @@ void LeAudioClientInterface::Source::SetPcmParameters(
    const PcmParameters& params) {
  le_audio_source->LeAudioSetSelectedHalPcmConfig(
      le_audio_sample_rate2audio_hal(params.sample_rate),
      le_audio_bit_rate2audio_hal(params.bits_per_sample),
      le_audio_bits_per_sample2audio_hal(params.bits_per_sample),
      le_audio_channel_mode2audio_hal(params.channels_count),
      params.data_interval_us);
}
@@ -719,6 +770,12 @@ void LeAudioClientInterface::Source::StopSession() {
  le_audio_source_hal_clientinterface->EndSession();
}

void LeAudioClientInterface::Source::UpdateAudioConfigToHal(
    const ::le_audio::offload_config& config) {
  LOG(INFO) << __func__ << " source: not handle now";
  return;
}

size_t LeAudioClientInterface::Source::Write(const uint8_t* p_buf,
                                             uint32_t len) {
  return le_audio_source_hal_clientinterface->WriteAudioData(p_buf, len);
+7 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include <functional>

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

@@ -71,6 +72,8 @@ class LeAudioClientInterface {
    virtual void StopSession() = 0;
    virtual void ConfirmStreamingRequest() = 0;
    virtual void CancelStreamingRequest() = 0;
    virtual void UpdateAudioConfigToHal(
        const ::le_audio::offload_config& config) = 0;
  };

 public:
@@ -85,7 +88,8 @@ class LeAudioClientInterface {
    void StopSession() override;
    void ConfirmStreamingRequest() override;
    void CancelStreamingRequest() override;

    void UpdateAudioConfigToHal(
        const ::le_audio::offload_config& config) override;
    // Read the stream of bytes sinked to us by the upper layers
    size_t Read(uint8_t* p_buf, uint32_t len);
  };
@@ -100,7 +104,8 @@ class LeAudioClientInterface {
    void StopSession() override;
    void ConfirmStreamingRequest() override;
    void CancelStreamingRequest() override;

    void UpdateAudioConfigToHal(
        const ::le_audio::offload_config& config) override;
    // Source the given stream of bytes to be sinked into the upper layers
    size_t Write(const uint8_t* p_buf, uint32_t len);
  };
+25 −18
Original line number Diff line number Diff line
@@ -2109,6 +2109,10 @@ class LeAudioClientImpl : public LeAudioClient {
      return false;
    }

    uint16_t remote_delay_ms =
        group->GetRemoteDelay(le_audio::types::kLeAudioDirectionSink);
    if (CodecManager::GetInstance()->GetCodecLocation() ==
        le_audio::types::CodecLocation::HOST) {
      if (lc3_encoder_left_mem) {
        LOG(WARNING)
            << " The encoder instance should have been already released.";
@@ -2125,10 +2129,13 @@ class LeAudioClientImpl : public LeAudioClient {
      lc3_encoder_right_mem = malloc(enc_size);

      lc3_encoder_left = lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_left_mem);
    lc3_encoder_right = lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_right_mem);

    uint16_t remote_delay_ms =
        group->GetRemoteDelay(le_audio::types::kLeAudioDirectionSink);
      lc3_encoder_right =
          lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_right_mem);
    } else if (CodecManager::GetInstance()->GetCodecLocation() ==
               le_audio::types::CodecLocation::ADSP) {
      CodecManager::GetInstance()->UpdateActiveAudioConfig(*stream_conf,
                                                           remote_delay_ms);
    }

    LeAudioClientAudioSource::UpdateRemoteDelay(remote_delay_ms);
    LeAudioClientAudioSource::ConfirmStreamingRequest();
+24 −0
Original line number Diff line number Diff line
@@ -436,6 +436,18 @@ void LeAudioClientAudioSource::DebugDump(int fd) {
  dprintf(fd, "%s", stream.str().c_str());
}

void LeAudioClientAudioSource::UpdateAudioConfigToHal(
    const ::le_audio::offload_config& config) {
  LOG(INFO) << __func__;
  if ((sinkClientInterface == nullptr) ||
      (le_audio_sink_hal_state != HAL_STARTED)) {
    LOG(ERROR) << "LE audio device HAL was not started!";
    return;
  }

  sinkClientInterface->UpdateAudioConfigToHal(config);
}

bool LeAudioClientAudioSink::Start(
    const LeAudioCodecConfiguration& codec_configuration,
    LeAudioClientAudioSourceReceiver* audioReceiver) {
@@ -599,3 +611,15 @@ void LeAudioClientAudioSink::UpdateRemoteDelay(uint16_t remote_delay_ms) {
void LeAudioClientAudioSink::DebugDump(int fd) {
  /* TODO: Add some statistic for source client interface */
}

void LeAudioClientAudioSink::UpdateAudioConfigToHal(
    const ::le_audio::offload_config& config) {
  LOG(INFO) << __func__;
  if ((sourceClientInterface == nullptr) ||
      (le_audio_source_hal_state != HAL_STARTED)) {
    LOG(ERROR) << "LE audio device HAL was not started!";
    return;
  }

  sourceClientInterface->UpdateAudioConfigToHal(config);
}
Loading