123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743 |
- /*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "a2dp_encoding.h"
- #include "client_interface.h"
- #include "a2dp_aac_constants.h"
- #include "a2dp_sbc_constants.h"
- #include "a2dp_vendor_ldac_constants.h"
- #include "bta/av/bta_av_int.h"
- #include "btif_a2dp_source.h"
- #include "btif_av.h"
- #include "btif_av_co.h"
- #include "btif_hf.h"
- #include "osi/include/properties.h"
- namespace {
- using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
- using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
- using ::android::hardware::bluetooth::audio::V2_0::CodecType;
- using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
- using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
- using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
- using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
- using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
- using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
- using ::bluetooth::audio::AudioConfiguration;
- using ::bluetooth::audio::BitsPerSample;
- using ::bluetooth::audio::BluetoothAudioCtrlAck;
- using ::bluetooth::audio::ChannelMode;
- using ::bluetooth::audio::CodecConfiguration;
- using ::bluetooth::audio::PcmParameters;
- using ::bluetooth::audio::SampleRate;
- using ::bluetooth::audio::SessionType;
- const CodecConfiguration kInvalidCodecConfiguration = {
- .codecType = CodecType::UNKNOWN,
- .encodedAudioBitrate = 0x00000000,
- .peerMtu = 0xffff,
- .isScmstEnabled = false,
- .config = {}};
- BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack);
- // Provide call-in APIs for the Bluetooth Audio HAL
- class A2dpTransport : public ::bluetooth::audio::IBluetoothTransportInstance {
- public:
- A2dpTransport(SessionType sessionType)
- : IBluetoothTransportInstance(sessionType, {}),
- a2dp_pending_cmd_(A2DP_CTRL_CMD_NONE),
- remote_delay_report_(0),
- total_bytes_read_(0),
- data_position_({}){};
- BluetoothAudioCtrlAck StartRequest() override {
- // Check if a previous request is not finished
- if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_START in progress";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
- } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
- LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
- // Don't send START request to stack while we are in a call
- if (!bluetooth::headset::IsCallIdle()) {
- LOG(ERROR) << __func__ << ": call state is busy";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_INCALL_FAILURE);
- }
- if (btif_a2dp_source_is_streaming()) {
- LOG(ERROR) << __func__ << ": source is busy streaming";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
- if (btif_av_stream_ready()) {
- /*
- * Post start event and wait for audio path to open.
- * If we are the source, the ACK will be sent after the start
- * procedure is completed, othewise send it now.
- */
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
- btif_av_stream_start();
- if (btif_av_get_peer_sep() != AVDT_TSEP_SRC) {
- LOG(INFO) << __func__ << ": accepted";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
- }
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
- if (btif_av_stream_started_ready()) {
- // Already started, ACK back immediately.
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
- LOG(ERROR) << __func__ << ": AV stream is not ready to start";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
- BluetoothAudioCtrlAck SuspendRequest() override {
- // Previous request is not finished
- if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_SUSPEND) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_SUSPEND in progress";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
- } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
- LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
- // Local suspend
- if (btif_av_stream_started_ready()) {
- LOG(INFO) << __func__ << ": accepted";
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_SUSPEND;
- btif_av_stream_suspend();
- return BluetoothAudioCtrlAck::PENDING;
- }
- /* If we are not in started state, just ack back ok and let
- * audioflinger close the channel. This can happen if we are
- * remotely suspended, clear REMOTE SUSPEND flag.
- */
- btif_av_clear_remote_suspend_flag();
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
- void StopRequest() override {
- if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
- !btif_a2dp_source_is_streaming()) {
- return;
- }
- LOG(INFO) << __func__ << ": handling";
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
- btif_av_stream_stop(RawAddress::kEmpty);
- }
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_read,
- timespec* data_position) override {
- *remote_delay_report_ns = remote_delay_report_ * 100000u;
- *total_bytes_read = total_bytes_read_;
- *data_position = data_position_;
- VLOG(2) << __func__ << ": delay=" << remote_delay_report_
- << "/10ms, data=" << total_bytes_read_
- << " byte(s), timestamp=" << data_position_.tv_sec << "."
- << data_position_.tv_nsec << "s";
- return true;
- }
- void MetadataChanged(const source_metadata_t& source_metadata) override {
- auto track_count = source_metadata.track_count;
- auto tracks = source_metadata.tracks;
- VLOG(1) << __func__ << ": " << track_count << " track(s) received";
- while (track_count) {
- VLOG(2) << __func__ << ": usage=" << tracks->usage
- << ", content_type=" << tracks->content_type
- << ", gain=" << tracks->gain;
- --track_count;
- ++tracks;
- }
- }
- tA2DP_CTRL_CMD GetPendingCmd() const { return a2dp_pending_cmd_; }
- void ResetPendingCmd() { a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; }
- void ResetPresentationPosition() override {
- remote_delay_report_ = 0;
- total_bytes_read_ = 0;
- data_position_ = {};
- }
- void LogBytesRead(size_t bytes_read) override {
- if (bytes_read != 0) {
- total_bytes_read_ += bytes_read;
- clock_gettime(CLOCK_MONOTONIC, &data_position_);
- }
- }
- // delay reports from AVDTP is based on 1/10 ms (100us)
- void SetRemoteDelay(uint16_t delay_report) {
- remote_delay_report_ = delay_report;
- }
- private:
- tA2DP_CTRL_CMD a2dp_pending_cmd_;
- uint16_t remote_delay_report_;
- uint64_t total_bytes_read_;
- timespec data_position_;
- };
- A2dpTransport* a2dp_sink = nullptr;
- // Common interface to call-out into Bluetooth Audio HAL
- bluetooth::audio::BluetoothAudioClientInterface* a2dp_hal_clientif = nullptr;
- auto session_type = SessionType::UNKNOWN;
- // Save the value if the remote reports its delay before a2dp_sink is
- // initialized
- uint16_t remote_delay = 0;
- bool btaudio_a2dp_disabled = false;
- bool is_configured = false;
- BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack) {
- switch (ack) {
- case A2DP_CTRL_ACK_SUCCESS:
- return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- case A2DP_CTRL_ACK_PENDING:
- return BluetoothAudioCtrlAck::PENDING;
- case A2DP_CTRL_ACK_INCALL_FAILURE:
- return BluetoothAudioCtrlAck::FAILURE_BUSY;
- case A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS:
- return BluetoothAudioCtrlAck::FAILURE_DISCONNECTING;
- case A2DP_CTRL_ACK_UNSUPPORTED: /* Offloading but resource failure */
- return BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED;
- case A2DP_CTRL_ACK_FAILURE:
- return BluetoothAudioCtrlAck::FAILURE;
- default:
- return BluetoothAudioCtrlAck::FAILURE;
- }
- }
- SampleRate a2dp_codec_to_hal_sample_rate(
- const btav_a2dp_codec_config_t& a2dp_codec_config) {
- switch (a2dp_codec_config.sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- return SampleRate::RATE_44100;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- return SampleRate::RATE_48000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- return SampleRate::RATE_88200;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- return SampleRate::RATE_96000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- return SampleRate::RATE_176400;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- return SampleRate::RATE_192000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- return SampleRate::RATE_16000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- return SampleRate::RATE_24000;
- default:
- return SampleRate::RATE_UNKNOWN;
- }
- }
- BitsPerSample a2dp_codec_to_hal_bits_per_sample(
- const btav_a2dp_codec_config_t& a2dp_codec_config) {
- switch (a2dp_codec_config.bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- return BitsPerSample::BITS_16;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- return BitsPerSample::BITS_24;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- return BitsPerSample::BITS_32;
- default:
- return BitsPerSample::BITS_UNKNOWN;
- }
- }
- ChannelMode a2dp_codec_to_hal_channel_mode(
- const btav_a2dp_codec_config_t& a2dp_codec_config) {
- switch (a2dp_codec_config.channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- return ChannelMode::MONO;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- return ChannelMode::STEREO;
- default:
- return ChannelMode::UNKNOWN;
- }
- }
- bool a2dp_get_selected_hal_codec_config(CodecConfiguration* codec_config) {
- A2dpCodecConfig* a2dp_codec_configs = bta_av_get_a2dp_current_codec();
- if (a2dp_codec_configs == nullptr) {
- LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
- *codec_config = kInvalidCodecConfiguration;
- return false;
- }
- btav_a2dp_codec_config_t current_codec = a2dp_codec_configs->getCodecConfig();
- tBT_A2DP_OFFLOAD a2dp_offload;
- a2dp_codec_configs->getCodecSpecificConfig(&a2dp_offload);
- switch (current_codec.codec_type) {
- case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_SBC: {
- codec_config->codecType = CodecType::SBC;
- codec_config->config.sbcConfig({});
- auto sbc_config = codec_config->config.sbcConfig();
- sbc_config.sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
- if (sbc_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown SBC sample_rate=" << current_codec.sample_rate;
- return false;
- }
- uint8_t channel_mode = a2dp_offload.codec_info[3] & A2DP_SBC_IE_CH_MD_MSK;
- switch (channel_mode) {
- case A2DP_SBC_IE_CH_MD_JOINT:
- sbc_config.channelMode = SbcChannelMode::JOINT_STEREO;
- break;
- case A2DP_SBC_IE_CH_MD_STEREO:
- sbc_config.channelMode = SbcChannelMode::STEREO;
- break;
- case A2DP_SBC_IE_CH_MD_DUAL:
- sbc_config.channelMode = SbcChannelMode::DUAL;
- break;
- case A2DP_SBC_IE_CH_MD_MONO:
- sbc_config.channelMode = SbcChannelMode::MONO;
- break;
- default:
- LOG(ERROR) << __func__
- << ": Unknown SBC channel_mode=" << channel_mode;
- sbc_config.channelMode = SbcChannelMode::UNKNOWN;
- return false;
- }
- uint8_t block_length =
- a2dp_offload.codec_info[0] & A2DP_SBC_IE_BLOCKS_MSK;
- switch (block_length) {
- case A2DP_SBC_IE_BLOCKS_4:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_4;
- break;
- case A2DP_SBC_IE_BLOCKS_8:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_8;
- break;
- case A2DP_SBC_IE_BLOCKS_12:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_12;
- break;
- case A2DP_SBC_IE_BLOCKS_16:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_16;
- break;
- default:
- LOG(ERROR) << __func__
- << ": Unknown SBC block_length=" << block_length;
- return false;
- }
- uint8_t sub_bands = a2dp_offload.codec_info[0] & A2DP_SBC_IE_SUBBAND_MSK;
- switch (sub_bands) {
- case A2DP_SBC_IE_SUBBAND_4:
- sbc_config.numSubbands = SbcNumSubbands::SUBBAND_4;
- break;
- case A2DP_SBC_IE_SUBBAND_8:
- sbc_config.numSubbands = SbcNumSubbands::SUBBAND_8;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown SBC Subbands=" << sub_bands;
- return false;
- }
- uint8_t alloc_method =
- a2dp_offload.codec_info[0] & A2DP_SBC_IE_ALLOC_MD_MSK;
- switch (alloc_method) {
- case A2DP_SBC_IE_ALLOC_MD_S:
- sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_S;
- break;
- case A2DP_SBC_IE_ALLOC_MD_L:
- sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_L;
- break;
- default:
- LOG(ERROR) << __func__
- << ": Unknown SBC alloc_method=" << alloc_method;
- return false;
- }
- sbc_config.minBitpool = a2dp_offload.codec_info[1];
- sbc_config.maxBitpool = a2dp_offload.codec_info[2];
- sbc_config.bitsPerSample =
- a2dp_codec_to_hal_bits_per_sample(current_codec);
- if (sbc_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown SBC bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.sbcConfig(sbc_config);
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_AAC: {
- codec_config->codecType = CodecType::AAC;
- codec_config->config.aacConfig({});
- auto aac_config = codec_config->config.aacConfig();
- uint8_t object_type = a2dp_offload.codec_info[0];
- switch (object_type) {
- case A2DP_AAC_OBJECT_TYPE_MPEG2_LC:
- aac_config.objectType = AacObjectType::MPEG2_LC;
- break;
- case A2DP_AAC_OBJECT_TYPE_MPEG4_LC:
- aac_config.objectType = AacObjectType::MPEG4_LC;
- break;
- case A2DP_AAC_OBJECT_TYPE_MPEG4_LTP:
- aac_config.objectType = AacObjectType::MPEG4_LTP;
- break;
- case A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE:
- aac_config.objectType = AacObjectType::MPEG4_SCALABLE;
- break;
- default:
- LOG(ERROR) << __func__
- << ": Unknown AAC object_type=" << +object_type;
- return false;
- }
- aac_config.sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
- if (aac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown AAC sample_rate=" << current_codec.sample_rate;
- return false;
- }
- aac_config.channelMode = a2dp_codec_to_hal_channel_mode(current_codec);
- if (aac_config.channelMode == ChannelMode::UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown AAC channel_mode="
- << current_codec.channel_mode;
- return false;
- }
- uint8_t vbr_enabled =
- a2dp_offload.codec_info[1] & A2DP_AAC_VARIABLE_BIT_RATE_MASK;
- switch (vbr_enabled) {
- case A2DP_AAC_VARIABLE_BIT_RATE_ENABLED:
- aac_config.variableBitRateEnabled = AacVariableBitRate::ENABLED;
- break;
- case A2DP_AAC_VARIABLE_BIT_RATE_DISABLED:
- aac_config.variableBitRateEnabled = AacVariableBitRate::DISABLED;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown AAC VBR=" << +vbr_enabled;
- return false;
- }
- aac_config.bitsPerSample =
- a2dp_codec_to_hal_bits_per_sample(current_codec);
- if (aac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown AAC bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.aacConfig(aac_config);
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD: {
- if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) {
- codec_config->codecType = CodecType::APTX;
- } else {
- codec_config->codecType = CodecType::APTX_HD;
- }
- codec_config->config.aptxConfig({});
- auto aptx_config = codec_config->config.aptxConfig();
- aptx_config.sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
- if (aptx_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown aptX sample_rate="
- << current_codec.sample_rate;
- return false;
- }
- aptx_config.channelMode = a2dp_codec_to_hal_channel_mode(current_codec);
- if (aptx_config.channelMode == ChannelMode::UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown aptX channel_mode="
- << current_codec.channel_mode;
- return false;
- }
- aptx_config.bitsPerSample =
- a2dp_codec_to_hal_bits_per_sample(current_codec);
- if (aptx_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown aptX bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.aptxConfig(aptx_config);
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC: {
- codec_config->codecType = CodecType::LDAC;
- codec_config->config.ldacConfig({});
- auto ldac_config = codec_config->config.ldacConfig();
- ldac_config.sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
- if (ldac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown LDAC sample_rate="
- << current_codec.sample_rate;
- return false;
- }
- switch (a2dp_offload.codec_info[7]) {
- case A2DP_LDAC_CHANNEL_MODE_STEREO:
- ldac_config.channelMode = LdacChannelMode::STEREO;
- break;
- case A2DP_LDAC_CHANNEL_MODE_DUAL:
- ldac_config.channelMode = LdacChannelMode::DUAL;
- break;
- case A2DP_LDAC_CHANNEL_MODE_MONO:
- ldac_config.channelMode = LdacChannelMode::MONO;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown LDAC channel_mode="
- << a2dp_offload.codec_info[7];
- ldac_config.channelMode = LdacChannelMode::UNKNOWN;
- return false;
- }
- switch (a2dp_offload.codec_info[6]) {
- case A2DP_LDAC_QUALITY_HIGH:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_HIGH;
- break;
- case A2DP_LDAC_QUALITY_MID:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_MID;
- break;
- case A2DP_LDAC_QUALITY_LOW:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_LOW;
- break;
- case A2DP_LDAC_QUALITY_ABR_OFFLOAD:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_ABR;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown LDAC QualityIndex="
- << a2dp_offload.codec_info[6];
- return false;
- }
- ldac_config.bitsPerSample =
- a2dp_codec_to_hal_bits_per_sample(current_codec);
- if (ldac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown LDAC bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.ldacConfig(ldac_config);
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_MAX:
- [[fallthrough]];
- default:
- LOG(ERROR) << __func__
- << ": Unknown codec_type=" << current_codec.codec_type;
- codec_config->codecType = CodecType::UNKNOWN;
- codec_config->config = {};
- return false;
- }
- codec_config->encodedAudioBitrate = a2dp_codec_configs->getTrackBitRate();
- // Obtain the MTU
- RawAddress peer_addr = btif_av_source_active_peer();
- tA2DP_ENCODER_INIT_PEER_PARAMS peer_param;
- bta_av_co_get_peer_params(peer_addr, &peer_param);
- int effectiveMtu = a2dp_codec_configs->getEffectiveMtu();
- if (effectiveMtu > 0 && effectiveMtu < peer_param.peer_mtu) {
- codec_config->peerMtu = effectiveMtu;
- } else {
- codec_config->peerMtu = peer_param.peer_mtu;
- }
- LOG(INFO) << __func__ << ": CodecConfiguration=" << toString(*codec_config);
- return true;
- }
- bool a2dp_get_selected_hal_pcm_config(PcmParameters* pcm_config) {
- if (pcm_config == nullptr) return false;
- A2dpCodecConfig* a2dp_codec_configs = bta_av_get_a2dp_current_codec();
- if (a2dp_codec_configs == nullptr) {
- LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
- *pcm_config = ::bluetooth::audio::BluetoothAudioClientInterface::
- kInvalidPcmConfiguration;
- return false;
- }
- btav_a2dp_codec_config_t current_codec = a2dp_codec_configs->getCodecConfig();
- pcm_config->sampleRate = a2dp_codec_to_hal_sample_rate(current_codec);
- pcm_config->bitsPerSample = a2dp_codec_to_hal_bits_per_sample(current_codec);
- pcm_config->channelMode = a2dp_codec_to_hal_channel_mode(current_codec);
- return (pcm_config->sampleRate != SampleRate::RATE_UNKNOWN &&
- pcm_config->bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
- pcm_config->channelMode != ChannelMode::UNKNOWN);
- }
- // Checking if new bluetooth_audio is supported
- bool is_hal_2_0_force_disabled() {
- if (!is_configured) {
- btaudio_a2dp_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
- is_configured = true;
- }
- return btaudio_a2dp_disabled;
- }
- } // namespace
- namespace bluetooth {
- namespace audio {
- namespace a2dp {
- // Checking if new bluetooth_audio is enabled
- bool is_hal_2_0_enabled() { return a2dp_hal_clientif != nullptr; }
- // Initialize BluetoothAudio HAL: openProvider
- bool init(bluetooth::common::MessageLoopThread* message_loop) {
- LOG(INFO) << __func__;
- if (is_hal_2_0_force_disabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
- return false;
- }
- if (btif_av_is_a2dp_offload_enabled()) {
- session_type = SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
- } else {
- session_type = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
- }
- a2dp_sink = new A2dpTransport(session_type);
- a2dp_hal_clientif = new bluetooth::audio::BluetoothAudioClientInterface(
- a2dp_sink, message_loop);
- if (!a2dp_hal_clientif->IsValid()) {
- LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP session=" << toString(session_type) << " is invalid?!";
- delete a2dp_hal_clientif;
- a2dp_hal_clientif = nullptr;
- delete a2dp_sink;
- a2dp_sink = nullptr;
- return false;
- }
- if (remote_delay != 0) {
- LOG(INFO) << __func__ << ": restore DELAY "
- << static_cast<float>(remote_delay / 10.0) << " ms";
- a2dp_sink->SetRemoteDelay(remote_delay);
- remote_delay = 0;
- }
- return true;
- }
- // Clean up BluetoothAudio HAL
- void cleanup() {
- if (!is_hal_2_0_enabled()) return;
- end_session();
- delete a2dp_hal_clientif;
- a2dp_hal_clientif = nullptr;
- delete a2dp_sink;
- a2dp_sink = nullptr;
- session_type = SessionType::UNKNOWN;
- remote_delay = 0;
- }
- // Set up the codec into BluetoothAudio HAL
- bool setup_codec() {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return false;
- }
- AudioConfiguration audio_config{};
- if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- CodecConfiguration codec_config{};
- if (!a2dp_get_selected_hal_codec_config(&codec_config)) {
- LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration";
- return false;
- }
- audio_config.codecConfig(codec_config);
- } else if (session_type == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH) {
- PcmParameters pcm_config{};
- if (!a2dp_get_selected_hal_pcm_config(&pcm_config)) {
- LOG(ERROR) << __func__ << ": Failed to get PcmConfiguration";
- return false;
- }
- audio_config.pcmConfig(pcm_config);
- }
- return a2dp_hal_clientif->UpdateAudioConfig(audio_config);
- }
- void start_session() {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return;
- }
- a2dp_hal_clientif->StartSession();
- }
- void end_session() {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return;
- }
- a2dp_hal_clientif->EndSession();
- }
- void ack_stream_started(const tA2DP_CTRL_ACK& ack) {
- auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
- LOG(INFO) << __func__ << ": result=" << ctrl_ack;
- auto pending_cmd = a2dp_sink->GetPendingCmd();
- if (pending_cmd == A2DP_CTRL_CMD_START) {
- a2dp_hal_clientif->StreamStarted(ctrl_ack);
- } else {
- LOG(WARNING) << __func__ << ": pending=" << pending_cmd
- << " ignore result=" << ctrl_ack;
- return;
- }
- if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
- a2dp_sink->ResetPendingCmd();
- }
- }
- void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) {
- auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
- LOG(INFO) << __func__ << ": result=" << ctrl_ack;
- auto pending_cmd = a2dp_sink->GetPendingCmd();
- if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) {
- a2dp_hal_clientif->StreamSuspended(ctrl_ack);
- } else if (pending_cmd == A2DP_CTRL_CMD_STOP) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_STOP result=" << ctrl_ack;
- } else {
- LOG(WARNING) << __func__ << ": pending=" << pending_cmd
- << " ignore result=" << ctrl_ack;
- return;
- }
- if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
- a2dp_sink->ResetPendingCmd();
- }
- }
- // Read from the FMQ of BluetoothAudio HAL
- size_t read(uint8_t* p_buf, uint32_t len) {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return 0;
- } else if (session_type != SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH) {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type)
- << " is not A2DP_SOFTWARE_ENCODING_DATAPATH";
- return 0;
- }
- return a2dp_hal_clientif->ReadAudioData(p_buf, len);
- }
- // Update A2DP delay report to BluetoothAudio HAL
- void set_remote_delay(uint16_t delay_report) {
- if (!is_hal_2_0_enabled()) {
- LOG(INFO) << __func__ << ": not ready for DelayReport "
- << static_cast<float>(delay_report / 10.0) << " ms";
- remote_delay = delay_report;
- return;
- }
- LOG(INFO) << __func__ << ": DELAY " << static_cast<float>(delay_report / 10.0)
- << " ms";
- a2dp_sink->SetRemoteDelay(delay_report);
- }
- } // namespace a2dp
- } // namespace audio
- } // namespace bluetooth
|