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

Commit 40916534 authored by Jakub Pawłowski's avatar Jakub Pawłowski Committed by Gerrit Code Review
Browse files

Merge changes Ia591e1d3,Iec29b128,I772e238c,I785a0f69,Iaa1876ff, ... into main

* changes:
  LeAudio: Enable essential audio context logs
  LeAudio: Remove Lc3 spec. code from client_parser
  LeAudio: Offloader related code encapsulation Part 2
  LeAudio: Offloader related code encapsulation Part 1
  LeAudio: Correct header inclusion chain for le_audio_types.h
  LeAudio: Improve BidirectionalPair type
  LeAudio: Improve data path setup
  LeAudio: Bind configuration provider life time with the Codec Manager
  LeAudio: Fix not releasing the codec resources
  LeAudio: Introduce codec wrapper interface
parents fc47a9ea c7a3b699
Loading
Loading
Loading
Loading
+76 −4
Original line number Diff line number Diff line
@@ -102,13 +102,13 @@ cc_library_static {
        "le_audio/broadcaster/state_machine.cc",
        "le_audio/client.cc",
        "le_audio/client_parser.cc",
        "le_audio/codec_interface.cc",
        "le_audio/codec_manager.cc",
        "le_audio/content_control_id_keeper.cc",
        "le_audio/devices.cc",
        "le_audio/hal_verifier.cc",
        "le_audio/le_audio_health_status.cc",
        "le_audio/le_audio_log_history.cc",
        "le_audio/le_audio_set_configuration_provider.cc",
        "le_audio/le_audio_set_configuration_provider_json.cc",
        "le_audio/le_audio_types.cc",
        "le_audio/le_audio_utils.cc",
@@ -648,6 +648,77 @@ prebuilt_etc {

// bta unit tests for LE Audio
// ========================================================
cc_test {
    name: "bluetooth_le_audio_codec_manager_test",
    test_suites: ["device-tests"],
    defaults: [
        "bluetooth_gtest_x86_asan_workaround",
        "fluoride_defaults",
        "mts_defaults",
    ],
    host_supported: true,
    target: {
        darwin: {
            enabled: false,
        },
        android: {
            sanitize: {
                misc_undefined: ["bounds"],
            },
            whole_static_libs: [
                "libPlatformProperties",
            ],
        },
    },
    include_dirs: [
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system/bta/include",
        "packages/modules/Bluetooth/system/bta/test/common",
        "packages/modules/Bluetooth/system/btif/include",
        "packages/modules/Bluetooth/system/gd",
        "packages/modules/Bluetooth/system/stack/include",
    ],
    srcs: [
        ":TestCommonMockFunctions",
        ":TestMockBtaLeAudioHalVerifier",
        ":TestStubOsi",
        "le_audio/codec_manager.cc",
        "le_audio/codec_manager_test.cc",
        "le_audio/le_audio_set_configuration_provider_json.cc",
        "le_audio/le_audio_types.cc",
        "test/common/btm_api_mock.cc",
        "test/common/mock_controller.cc",
    ],
    data: [
        ":audio_set_configurations_bfbs",
        ":audio_set_configurations_json",
        ":audio_set_scenarios_bfbs",
        ":audio_set_scenarios_json",
    ],
    generated_headers: [
        "LeAudioSetConfigSchemas_h",
    ],
    shared_libs: [
        "android.hardware.bluetooth.audio@2.0",
        "android.hardware.bluetooth.audio@2.1",
        "libcrypto",
        "libhidlbase",
        "liblog", // __android_log_print
    ],
    static_libs: [
        "libbluetooth_gd",
        "libbt-common",
        "libchrome",
        "libevent",
        "libflatbuffers-cpp",
        "libgmock",
        "libosi",
    ],
    sanitize: {
        cfi: false,
    },
}

cc_test {
    name: "bluetooth_le_audio_test",
    test_suites: ["device-tests"],
@@ -697,6 +768,7 @@ cc_test {
        "le_audio/le_audio_types.cc",
        "le_audio/le_audio_types_test.cc",
        "le_audio/metrics_collector_linux.cc",
        "le_audio/mock_codec_interface.cc",
        "le_audio/mock_codec_manager.cc",
        "le_audio/mock_iso_manager.cc",
        "le_audio/state_machine.cc",
@@ -775,6 +847,7 @@ cc_test {
        "le_audio/le_audio_utils.cc",
        "le_audio/metrics_collector.cc",
        "le_audio/metrics_collector_test.cc",
        "le_audio/mock_codec_interface.cc",
        "le_audio/mock_codec_manager.cc",
        "le_audio/mock_iso_manager.cc",
        "le_audio/mock_state_machine.cc",
@@ -805,7 +878,6 @@ cc_test {
        "libevent",
        "libflatbuffers-cpp",
        "libgmock",
        "liblc3",
        "libosi",
    ],
    data: [
@@ -907,6 +979,7 @@ cc_test {
        "le_audio/broadcaster/state_machine.cc",
        "le_audio/broadcaster/state_machine_test.cc",
        "le_audio/le_audio_types.cc",
        "le_audio/mock_codec_interface.cc",
        "le_audio/mock_codec_manager.cc",
        "le_audio/mock_iso_manager.cc",
    ],
@@ -919,7 +992,6 @@ cc_test {
        "libbt-common",
        "libchrome",
        "libgmock",
        "liblc3",
    ],
    sanitize: {
        cfi: true,
@@ -964,6 +1036,7 @@ cc_test {
        "le_audio/le_audio_types.cc",
        "le_audio/le_audio_utils.cc",
        "le_audio/metrics_collector_linux.cc",
        "le_audio/mock_codec_interface.cc",
        "le_audio/mock_codec_manager.cc",
        "le_audio/mock_iso_manager.cc",
        "test/common/mock_controller.cc",
@@ -983,7 +1056,6 @@ cc_test {
        "libchrome",
        "libevent",
        "libgmock",
        "liblc3",
        "libosi",
    ],
    sanitize: {
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@
#include "bta/include/utl.h"

#ifdef __ANDROID__
#include "bta/le_audio/devices.h"
#include "bta_le_audio_api.h"
#endif

#include "device/include/interop.h"
+1 −4
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ class LeAudioClient {
      base::Closure initCb, base::Callback<bool()> hal_2_1_verifier,
      const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
          offloading_preference);
  static void Cleanup(base::Callback<void()> cleanupCb);
  static void Cleanup(void);
  static LeAudioClient* Get(void);
  static void DebugDump(int fd);

@@ -90,7 +90,4 @@ class LeAudioClient {
  static bool GetAsesForStorage(const RawAddress& addr,
                                std::vector<uint8_t>& out);
  static bool IsLeAudioClientRunning();

  static void InitializeAudioSetConfigurationProvider(void);
  static void CleanupAudioSetConfigurationProvider(void);
};
+27 −52
Original line number Diff line number Diff line
@@ -22,12 +22,12 @@
#include "bta/include/bta_le_audio_api.h"
#include "bta/include/bta_le_audio_broadcaster_api.h"
#include "bta/le_audio/broadcaster/state_machine.h"
#include "bta/le_audio/codec_interface.h"
#include "bta/le_audio/content_control_id_keeper.h"
#include "bta/le_audio/le_audio_types.h"
#include "bta/le_audio/le_audio_utils.h"
#include "bta/le_audio/metrics_collector.h"
#include "device/include/controller.h"
#include "embdrv/lc3/include/lc3.h"
#include "gd/common/strings.h"
#include "internal_include/stack_config.h"
#include "osi/include/log.h"
@@ -956,31 +956,21 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {

    void CheckAndReconfigureEncoders() {
      auto const& codec_id = codec_wrapper_.GetLeAudioCodecId();
      if (codec_id.coding_format != kLeAudioCodingFormatLC3) {
        LOG_ERROR("Invalid codec ID: [%d:%d:%d]", codec_id.coding_format,
                  codec_id.vendor_company_id, codec_id.vendor_codec_id);
      /* TODO: We should act smart and reuse current configurations */
      sw_enc_.clear();
      while (sw_enc_.size() != codec_wrapper_.GetNumChannels()) {
        auto codec = le_audio::CodecInterface::CreateInstance(codec_id);

        auto codec_status =
            codec->InitEncoder(codec_wrapper_.GetLeAudioCodecConfiguration(),
                               codec_wrapper_.GetLeAudioCodecConfiguration());
        if (codec_status != le_audio::CodecInterface::Status::STATUS_OK) {
          LOG_ERROR("Channel %d codec setup failed with err: %d",
                    (uint32_t)sw_enc_.size(), codec_status);
          return;
        }

      if (enc_audio_buffers_.size() != codec_wrapper_.GetNumChannels()) {
        enc_audio_buffers_.resize(codec_wrapper_.GetNumChannels());
      }

      const int dt_us = codec_wrapper_.GetDataIntervalUs();
      const int sr_hz = codec_wrapper_.GetSampleRate();
      const auto encoder_bytes = lc3_encoder_size(dt_us, sr_hz);
      const auto channel_bytes = codec_wrapper_.GetMaxSduSizePerChannel();

      /* TODO: We should act smart and reuse current configurations */
      encoders_.clear();
      encoders_mem_.clear();
      while (encoders_.size() < codec_wrapper_.GetNumChannels()) {
        auto& encoder_buf = enc_audio_buffers_.at(encoders_.size());
        encoder_buf.resize(channel_bytes);

        encoders_mem_.emplace_back(malloc(encoder_bytes), &std::free);
        encoders_.emplace_back(
            lc3_setup_encoder(dt_us, sr_hz, 0, encoders_mem_.back().get()));
        sw_enc_.emplace_back(std::move(codec));
      }
    }

@@ -992,23 +982,9 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
      codec_wrapper_ = config;
    }

    void encodeLc3Channel(lc3_encoder_t encoder,
                          std::vector<uint8_t>& out_buffer,
                          const std::vector<uint8_t>& data,
                          int initial_channel_offset, int pitch_samples,
                          int num_channels) {
      auto encoder_status =
          lc3_encode(encoder, LC3_PCM_FORMAT_S16,
                     (int16_t*)(data.data() + initial_channel_offset),
                     pitch_samples, out_buffer.size(), out_buffer.data());
      if (encoder_status != 0) {
        LOG_ERROR("Encoding error=%d", encoder_status);
      }
    }

    static void sendBroadcastData(
        const std::unique_ptr<BroadcastStateMachine>& broadcast,
        std::vector<std::vector<uint8_t>>& encoded_channels) {
        std::vector<std::unique_ptr<le_audio::CodecInterface>>& encoders) {
      auto const& config = broadcast->GetBigConfig();
      if (config == std::nullopt) {
        LOG_ERROR(
@@ -1019,15 +995,16 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
        return;
      }

      if (config->connection_handles.size() < encoded_channels.size()) {
      if (config->connection_handles.size() < encoders.size()) {
        LOG_ERROR("Not enough BIS'es to broadcast all channels!");
        return;
      }

      for (uint8_t chan = 0; chan < encoded_channels.size(); ++chan) {
        IsoManager::GetInstance()->SendIsoData(config->connection_handles[chan],
                                               encoded_channels[chan].data(),
                                               encoded_channels[chan].size());
      for (uint8_t chan = 0; chan < encoders.size(); ++chan) {
        IsoManager::GetInstance()->SendIsoData(
            config->connection_handles[chan],
            (const uint8_t*)encoders[chan]->GetDecodedSamples().data(),
            encoders[chan]->GetDecodedSamples().size() * 2);
      }
    }

@@ -1042,9 +1019,9 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {

      /* Prepare encoded data for all channels */
      for (uint8_t chan = 0; chan < num_channels; ++chan) {
        /* TODO: Use encoder agnostic wrapper */
        encodeLc3Channel(encoders_[chan], enc_audio_buffers_[chan], data,
                         chan * bytes_per_sample, num_channels, num_channels);
        auto initial_channel_offset = chan * bytes_per_sample;
        sw_enc_[chan]->Encode(data.data() + initial_channel_offset,
                              num_channels, codec_wrapper_.GetFrameLen());
      }

      /* Currently there is no way to broadcast multiple distinct streams.
@@ -1056,7 +1033,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
        if ((broadcast->GetState() ==
             BroadcastStateMachine::State::STREAMING) &&
            !broadcast->IsMuted())
          sendBroadcastData(broadcast, enc_audio_buffers_);
          sendBroadcastData(broadcast, sw_enc_);
      }
      LOG_VERBOSE("All data sent.");
    }
@@ -1103,9 +1080,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {

   private:
    BroadcastCodecWrapper codec_wrapper_;
    std::vector<lc3_encoder_t> encoders_;
    std::vector<std::unique_ptr<void, decltype(&std::free)>> encoders_mem_;
    std::vector<std::vector<uint8_t>> enc_audio_buffers_;
    std::vector<std::unique_ptr<le_audio::CodecInterface>> sw_enc_;
  } audio_receiver_;

  static class QueuedBroadcast {
+1 −4
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
#include "bt_types.h"
#include "bta_le_audio_broadcaster_api.h"
#include "btm_ble_api_types.h"
#include "embdrv/lc3/include/lc3.h"
#include "internal_include/stack_config.h"
#include "osi/include/properties.h"

@@ -374,10 +373,8 @@ types::LeAudioLtvMap BroadcastCodecWrapper::GetSubgroupCodecSpecData() const {
  };

  if (codec_id.coding_format == kLeAudioCodecIdLc3.coding_format) {
    uint16_t bc =
        lc3_frame_bytes(source_codec_config.data_interval_us, codec_bitrate);
    codec_spec_ltvs[codec_spec_conf::kLeAudioCodecLC3TypeOctetPerFrame] =
        UINT16_TO_VEC_UINT8(bc);
        UINT16_TO_VEC_UINT8(codec_frame_len);
  }

  if (source_codec_config.num_channels == 1) {
Loading