Loading system/audio_hal_interface/a2dp_encoding.cc +102 −44 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ using ::bluetooth::audio::PcmParameters; using ::bluetooth::audio::SampleRate; using ::bluetooth::audio::SampleRate; using ::bluetooth::audio::SessionType; using ::bluetooth::audio::SessionType; using ::bluetooth::audio::BluetoothAudioClientInterface; using ::bluetooth::audio::codec::A2dpAacToHalConfig; using ::bluetooth::audio::codec::A2dpAacToHalConfig; using ::bluetooth::audio::codec::A2dpAptxToHalConfig; using ::bluetooth::audio::codec::A2dpAptxToHalConfig; using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample; using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample; Loading @@ -51,8 +52,6 @@ class A2dpTransport : public ::bluetooth::audio::IBluetoothTransportInstance { public: public: A2dpTransport(SessionType sessionType) A2dpTransport(SessionType sessionType) : IBluetoothTransportInstance(sessionType, {}), : IBluetoothTransportInstance(sessionType, {}), a2dp_pending_cmd_(A2DP_CTRL_CMD_NONE), remote_delay_report_(0), total_bytes_read_(0), total_bytes_read_(0), data_position_({}){}; data_position_({}){}; Loading Loading @@ -178,19 +177,21 @@ class A2dpTransport : public ::bluetooth::audio::IBluetoothTransportInstance { } } private: private: tA2DP_CTRL_CMD a2dp_pending_cmd_; static tA2DP_CTRL_CMD a2dp_pending_cmd_; uint16_t remote_delay_report_; static uint16_t remote_delay_report_; uint64_t total_bytes_read_; uint64_t total_bytes_read_; timespec data_position_; timespec data_position_; }; }; A2dpTransport* a2dp_sink = nullptr; tA2DP_CTRL_CMD A2dpTransport::a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; uint16_t A2dpTransport::remote_delay_report_ = 0; // Common interface to call-out into Bluetooth Audio HAL // Common interface to call-out into Bluetooth Audio HAL bluetooth::audio::BluetoothAudioClientInterface* a2dp_hal_clientif = nullptr; BluetoothAudioClientInterface* software_hal_interface = nullptr; auto session_type = SessionType::UNKNOWN; BluetoothAudioClientInterface* offloading_hal_interface = nullptr; BluetoothAudioClientInterface* active_hal_interface = nullptr; // Save the value if the remote reports its delay before a2dp_sink is // Save the value if the remote reports its delay before this interface is // initialized // initialized uint16_t remote_delay = 0; uint16_t remote_delay = 0; Loading Loading @@ -318,7 +319,16 @@ bool update_codec_offloading_capabilities( } } // Checking if new bluetooth_audio is enabled // Checking if new bluetooth_audio is enabled bool is_hal_2_0_enabled() { return a2dp_hal_clientif != nullptr; } bool is_hal_2_0_enabled() { return active_hal_interface != nullptr; } // Check if new bluetooth_audio is running with offloading encoders bool is_hal_2_0_offloading() { if (!is_hal_2_0_enabled()) { return false; } return active_hal_interface->GetTransportInstance()->GetSessionType() == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH; } // Initialize BluetoothAudio HAL: openProvider // Initialize BluetoothAudio HAL: openProvider bool init(bluetooth::common::MessageLoopThread* message_loop) { bool init(bluetooth::common::MessageLoopThread* message_loop) { Loading @@ -329,27 +339,47 @@ bool init(bluetooth::common::MessageLoopThread* message_loop) { return false; return false; } } if (btif_av_is_a2dp_offload_enabled()) { auto a2dp_sink = session_type = SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH; new A2dpTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH); } else { software_hal_interface = new bluetooth::audio::BluetoothAudioClientInterface( session_type = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH; } a2dp_sink = new A2dpTransport(session_type); a2dp_hal_clientif = new bluetooth::audio::BluetoothAudioClientInterface( a2dp_sink, message_loop); a2dp_sink, message_loop); if (!a2dp_hal_clientif->IsValid()) { if (!software_hal_interface->IsValid()) { LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP session=" << toString(session_type) << " is invalid?!"; LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP is invalid?!"; delete a2dp_hal_clientif; delete software_hal_interface; a2dp_hal_clientif = nullptr; software_hal_interface = nullptr; delete a2dp_sink; delete a2dp_sink; a2dp_sink = nullptr; return false; return false; } } if (btif_av_is_a2dp_offload_enabled()) { a2dp_sink = new A2dpTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH); offloading_hal_interface = new bluetooth::audio::BluetoothAudioClientInterface(a2dp_sink, message_loop); if (!offloading_hal_interface->IsValid()) { LOG(FATAL) << __func__ << ": BluetoothAudio HAL for A2DP offloading is invalid?!"; delete offloading_hal_interface; offloading_hal_interface = nullptr; delete a2dp_sink; a2dp_sink = static_cast<A2dpTransport*>( software_hal_interface->GetTransportInstance()); delete software_hal_interface; software_hal_interface = nullptr; delete a2dp_sink; return false; } } active_hal_interface = (offloading_hal_interface != nullptr ? offloading_hal_interface : software_hal_interface); if (remote_delay != 0) { if (remote_delay != 0) { LOG(INFO) << __func__ << ": restore DELAY " LOG(INFO) << __func__ << ": restore DELAY " << static_cast<float>(remote_delay / 10.0) << " ms"; << static_cast<float>(remote_delay / 10.0) << " ms"; a2dp_sink->SetRemoteDelay(remote_delay); static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance()) ->SetRemoteDelay(remote_delay); remote_delay = 0; remote_delay = 0; } } return true; return true; Loading @@ -359,11 +389,19 @@ bool init(bluetooth::common::MessageLoopThread* message_loop) { void cleanup() { void cleanup() { if (!is_hal_2_0_enabled()) return; if (!is_hal_2_0_enabled()) return; end_session(); end_session(); delete a2dp_hal_clientif; a2dp_hal_clientif = nullptr; active_hal_interface = nullptr; auto a2dp_sink = software_hal_interface->GetTransportInstance(); delete software_hal_interface; software_hal_interface = nullptr; delete a2dp_sink; if (offloading_hal_interface != nullptr) { a2dp_sink = offloading_hal_interface->GetTransportInstance(); delete offloading_hal_interface; offloading_hal_interface = nullptr; delete a2dp_sink; delete a2dp_sink; a2dp_sink = nullptr; } session_type = SessionType::UNKNOWN; remote_delay = 0; remote_delay = 0; } } Loading @@ -373,15 +411,28 @@ bool setup_codec() { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; return false; return false; } } AudioConfiguration audio_config{}; if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) { CodecConfiguration codec_config{}; CodecConfiguration codec_config{}; if (!a2dp_get_selected_hal_codec_config(&codec_config)) { if (!a2dp_get_selected_hal_codec_config(&codec_config)) { LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration"; LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration"; return false; return false; } } bool should_codec_offloading = bluetooth::audio::codec::IsCodecOffloadingEnabled(codec_config); if (should_codec_offloading && !is_hal_2_0_offloading()) { LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Hardware"; end_session(); active_hal_interface = offloading_hal_interface; } else if (!should_codec_offloading && is_hal_2_0_offloading()) { LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Software"; end_session(); active_hal_interface = software_hal_interface; } AudioConfiguration audio_config{}; if (active_hal_interface->GetTransportInstance()->GetSessionType() == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) { audio_config.codecConfig(codec_config); audio_config.codecConfig(codec_config); } else if (session_type == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH) { } else { PcmParameters pcm_config{}; PcmParameters pcm_config{}; if (!a2dp_get_selected_hal_pcm_config(&pcm_config)) { if (!a2dp_get_selected_hal_pcm_config(&pcm_config)) { LOG(ERROR) << __func__ << ": Failed to get PcmConfiguration"; LOG(ERROR) << __func__ << ": Failed to get PcmConfiguration"; Loading @@ -389,7 +440,7 @@ bool setup_codec() { } } audio_config.pcmConfig(pcm_config); audio_config.pcmConfig(pcm_config); } } return a2dp_hal_clientif->UpdateAudioConfig(audio_config); return active_hal_interface->UpdateAudioConfig(audio_config); } } void start_session() { void start_session() { Loading @@ -397,7 +448,7 @@ void start_session() { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; return; return; } } a2dp_hal_clientif->StartSession(); active_hal_interface->StartSession(); } } void end_session() { void end_session() { Loading @@ -405,15 +456,17 @@ void end_session() { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; return; return; } } a2dp_hal_clientif->EndSession(); active_hal_interface->EndSession(); } } void ack_stream_started(const tA2DP_CTRL_ACK& ack) { void ack_stream_started(const tA2DP_CTRL_ACK& ack) { auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack); auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack); LOG(INFO) << __func__ << ": result=" << ctrl_ack; LOG(INFO) << __func__ << ": result=" << ctrl_ack; auto a2dp_sink = static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance()); auto pending_cmd = a2dp_sink->GetPendingCmd(); auto pending_cmd = a2dp_sink->GetPendingCmd(); if (pending_cmd == A2DP_CTRL_CMD_START) { if (pending_cmd == A2DP_CTRL_CMD_START) { a2dp_hal_clientif->StreamStarted(ctrl_ack); active_hal_interface->StreamStarted(ctrl_ack); } else { } else { LOG(WARNING) << __func__ << ": pending=" << pending_cmd LOG(WARNING) << __func__ << ": pending=" << pending_cmd << " ignore result=" << ctrl_ack; << " ignore result=" << ctrl_ack; Loading @@ -427,9 +480,11 @@ void ack_stream_started(const tA2DP_CTRL_ACK& ack) { void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) { void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) { auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack); auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack); LOG(INFO) << __func__ << ": result=" << ctrl_ack; LOG(INFO) << __func__ << ": result=" << ctrl_ack; auto a2dp_sink = static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance()); auto pending_cmd = a2dp_sink->GetPendingCmd(); auto pending_cmd = a2dp_sink->GetPendingCmd(); if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) { if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) { a2dp_hal_clientif->StreamSuspended(ctrl_ack); active_hal_interface->StreamSuspended(ctrl_ack); } else if (pending_cmd == A2DP_CTRL_CMD_STOP) { } else if (pending_cmd == A2DP_CTRL_CMD_STOP) { LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_STOP result=" << ctrl_ack; LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_STOP result=" << ctrl_ack; } else { } else { Loading @@ -447,12 +502,14 @@ size_t read(uint8_t* p_buf, uint32_t len) { if (!is_hal_2_0_enabled()) { if (!is_hal_2_0_enabled()) { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; return 0; return 0; } else if (session_type != SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH) { } else if (is_hal_2_0_offloading()) { LOG(ERROR) << __func__ << ": session_type=" << toString(session_type) LOG(ERROR) << __func__ << ": session_type=" << toString(active_hal_interface->GetTransportInstance() ->GetSessionType()) << " is not A2DP_SOFTWARE_ENCODING_DATAPATH"; << " is not A2DP_SOFTWARE_ENCODING_DATAPATH"; return 0; return 0; } } return a2dp_hal_clientif->ReadAudioData(p_buf, len); return active_hal_interface->ReadAudioData(p_buf, len); } } // Update A2DP delay report to BluetoothAudio HAL // Update A2DP delay report to BluetoothAudio HAL Loading @@ -463,9 +520,10 @@ void set_remote_delay(uint16_t delay_report) { remote_delay = delay_report; remote_delay = delay_report; return; return; } } LOG(INFO) << __func__ << ": DELAY " << static_cast<float>(delay_report / 10.0) VLOG(1) << __func__ << ": DELAY " << static_cast<float>(delay_report / 10.0) << " ms"; << " ms"; a2dp_sink->SetRemoteDelay(delay_report); static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance()) ->SetRemoteDelay(delay_report); } } } // namespace a2dp } // namespace a2dp Loading system/audio_hal_interface/a2dp_encoding.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,9 @@ bool update_codec_offloading_capabilities( // Check if new bluetooth_audio is enabled // Check if new bluetooth_audio is enabled bool is_hal_2_0_enabled(); bool is_hal_2_0_enabled(); // Check if new bluetooth_audio is running with offloading encoders bool is_hal_2_0_offloading(); // Initialize BluetoothAudio HAL: openProvider // Initialize BluetoothAudio HAL: openProvider bool init(bluetooth::common::MessageLoopThread* message_loop); bool init(bluetooth::common::MessageLoopThread* message_loop); Loading system/audio_hal_interface/client_interface.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -134,6 +134,8 @@ class BluetoothAudioClientInterface { return provider_ != nullptr; return provider_ != nullptr; } } IBluetoothTransportInstance* GetTransportInstance() const { return sink_; } std::vector<AudioCapabilities> GetAudioCapabilities() const; std::vector<AudioCapabilities> GetAudioCapabilities() const; static std::vector<AudioCapabilities> GetAudioCapabilities( static std::vector<AudioCapabilities> GetAudioCapabilities( SessionType session_type); SessionType session_type); Loading system/btif/include/btif_av.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -187,6 +187,12 @@ void btif_av_src_disconnect_sink(const RawAddress& peer_address); */ */ bool btif_av_is_a2dp_offload_enabled(void); bool btif_av_is_a2dp_offload_enabled(void); /** * check A2DP offload enabled and running * @param none */ bool btif_av_is_a2dp_offload_running(void); /** /** * Check whether peer device is silenced * Check whether peer device is silenced * * Loading system/btif/src/btif_a2dp.cc +9 −4 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,7 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { bluetooth::audio::a2dp::ack_stream_started(status); bluetooth::audio::a2dp::ack_stream_started(status); } else if (btif_av_is_a2dp_offload_enabled()) { } else if (btif_av_is_a2dp_offload_enabled()) { // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_started(status); btif_a2dp_audio_on_started(status); } else { } else { btif_a2dp_command_ack(status); btif_a2dp_command_ack(status); Loading @@ -75,7 +76,7 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start LOG(WARNING) << __func__ << ": peer " << peer_addr << " A2DP is suspending and ignores the started event"; LOG(WARNING) << __func__ << ": peer " << peer_addr << " A2DP is suspending and ignores the started event"; return false; return false; } } if (btif_av_is_a2dp_offload_enabled()) { if (btif_av_is_a2dp_offload_running()) { btif_av_stream_start_offload(); btif_av_stream_start_offload(); } else if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { } else if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) { if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) { Loading @@ -98,6 +99,7 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE); bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE); } else if (btif_av_is_a2dp_offload_enabled()) { } else if (btif_av_is_a2dp_offload_enabled()) { // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_started(p_av_start->status); btif_a2dp_audio_on_started(p_av_start->status); } else { } else { btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); Loading @@ -116,9 +118,10 @@ void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) { return; return; } } if (bluetooth::audio::a2dp::is_hal_2_0_enabled() || if (bluetooth::audio::a2dp::is_hal_2_0_enabled() || !btif_av_is_a2dp_offload_enabled()) { !btif_av_is_a2dp_offload_running()) { btif_a2dp_source_on_stopped(p_av_suspend); btif_a2dp_source_on_stopped(p_av_suspend); } else if (p_av_suspend != NULL) { } else if (p_av_suspend != NULL) { // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_stopped(p_av_suspend->status); btif_a2dp_audio_on_stopped(p_av_suspend->status); } } } } Loading @@ -131,9 +134,10 @@ void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) { return; return; } } if (bluetooth::audio::a2dp::is_hal_2_0_enabled() || if (bluetooth::audio::a2dp::is_hal_2_0_enabled() || !btif_av_is_a2dp_offload_enabled()) { !btif_av_is_a2dp_offload_running()) { btif_a2dp_source_on_suspended(p_av_suspend); btif_a2dp_source_on_suspended(p_av_suspend); } else if (p_av_suspend != NULL) { } else if (p_av_suspend != NULL) { // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_suspended(p_av_suspend->status); btif_a2dp_audio_on_suspended(p_av_suspend->status); } } } } Loading @@ -159,7 +163,7 @@ void btif_a2dp_on_offload_started(const RawAddress& peer_addr, ack = A2DP_CTRL_ACK_FAILURE; ack = A2DP_CTRL_ACK_FAILURE; break; break; } } if (btif_av_is_a2dp_offload_enabled()) { if (btif_av_is_a2dp_offload_running()) { if (ack != BTA_AV_SUCCESS && btif_av_stream_started_ready()) { if (ack != BTA_AV_SUCCESS && btif_av_stream_started_ready()) { // Offload request will return with failure from btif_av sm if // Offload request will return with failure from btif_av sm if // suspend is triggered for remote start. Disconnect only if SoC // suspend is triggered for remote start. Disconnect only if SoC Loading @@ -173,6 +177,7 @@ void btif_a2dp_on_offload_started(const RawAddress& peer_addr, bluetooth::audio::a2dp::ack_stream_started(ack); bluetooth::audio::a2dp::ack_stream_started(ack); } else { } else { btif_a2dp_command_ack(ack); btif_a2dp_command_ack(ack); // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_started(status); btif_a2dp_audio_on_started(status); } } } } Loading Loading
system/audio_hal_interface/a2dp_encoding.cc +102 −44 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ using ::bluetooth::audio::PcmParameters; using ::bluetooth::audio::SampleRate; using ::bluetooth::audio::SampleRate; using ::bluetooth::audio::SessionType; using ::bluetooth::audio::SessionType; using ::bluetooth::audio::BluetoothAudioClientInterface; using ::bluetooth::audio::codec::A2dpAacToHalConfig; using ::bluetooth::audio::codec::A2dpAacToHalConfig; using ::bluetooth::audio::codec::A2dpAptxToHalConfig; using ::bluetooth::audio::codec::A2dpAptxToHalConfig; using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample; using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample; Loading @@ -51,8 +52,6 @@ class A2dpTransport : public ::bluetooth::audio::IBluetoothTransportInstance { public: public: A2dpTransport(SessionType sessionType) A2dpTransport(SessionType sessionType) : IBluetoothTransportInstance(sessionType, {}), : IBluetoothTransportInstance(sessionType, {}), a2dp_pending_cmd_(A2DP_CTRL_CMD_NONE), remote_delay_report_(0), total_bytes_read_(0), total_bytes_read_(0), data_position_({}){}; data_position_({}){}; Loading Loading @@ -178,19 +177,21 @@ class A2dpTransport : public ::bluetooth::audio::IBluetoothTransportInstance { } } private: private: tA2DP_CTRL_CMD a2dp_pending_cmd_; static tA2DP_CTRL_CMD a2dp_pending_cmd_; uint16_t remote_delay_report_; static uint16_t remote_delay_report_; uint64_t total_bytes_read_; uint64_t total_bytes_read_; timespec data_position_; timespec data_position_; }; }; A2dpTransport* a2dp_sink = nullptr; tA2DP_CTRL_CMD A2dpTransport::a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; uint16_t A2dpTransport::remote_delay_report_ = 0; // Common interface to call-out into Bluetooth Audio HAL // Common interface to call-out into Bluetooth Audio HAL bluetooth::audio::BluetoothAudioClientInterface* a2dp_hal_clientif = nullptr; BluetoothAudioClientInterface* software_hal_interface = nullptr; auto session_type = SessionType::UNKNOWN; BluetoothAudioClientInterface* offloading_hal_interface = nullptr; BluetoothAudioClientInterface* active_hal_interface = nullptr; // Save the value if the remote reports its delay before a2dp_sink is // Save the value if the remote reports its delay before this interface is // initialized // initialized uint16_t remote_delay = 0; uint16_t remote_delay = 0; Loading Loading @@ -318,7 +319,16 @@ bool update_codec_offloading_capabilities( } } // Checking if new bluetooth_audio is enabled // Checking if new bluetooth_audio is enabled bool is_hal_2_0_enabled() { return a2dp_hal_clientif != nullptr; } bool is_hal_2_0_enabled() { return active_hal_interface != nullptr; } // Check if new bluetooth_audio is running with offloading encoders bool is_hal_2_0_offloading() { if (!is_hal_2_0_enabled()) { return false; } return active_hal_interface->GetTransportInstance()->GetSessionType() == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH; } // Initialize BluetoothAudio HAL: openProvider // Initialize BluetoothAudio HAL: openProvider bool init(bluetooth::common::MessageLoopThread* message_loop) { bool init(bluetooth::common::MessageLoopThread* message_loop) { Loading @@ -329,27 +339,47 @@ bool init(bluetooth::common::MessageLoopThread* message_loop) { return false; return false; } } if (btif_av_is_a2dp_offload_enabled()) { auto a2dp_sink = session_type = SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH; new A2dpTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH); } else { software_hal_interface = new bluetooth::audio::BluetoothAudioClientInterface( session_type = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH; } a2dp_sink = new A2dpTransport(session_type); a2dp_hal_clientif = new bluetooth::audio::BluetoothAudioClientInterface( a2dp_sink, message_loop); a2dp_sink, message_loop); if (!a2dp_hal_clientif->IsValid()) { if (!software_hal_interface->IsValid()) { LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP session=" << toString(session_type) << " is invalid?!"; LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP is invalid?!"; delete a2dp_hal_clientif; delete software_hal_interface; a2dp_hal_clientif = nullptr; software_hal_interface = nullptr; delete a2dp_sink; delete a2dp_sink; a2dp_sink = nullptr; return false; return false; } } if (btif_av_is_a2dp_offload_enabled()) { a2dp_sink = new A2dpTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH); offloading_hal_interface = new bluetooth::audio::BluetoothAudioClientInterface(a2dp_sink, message_loop); if (!offloading_hal_interface->IsValid()) { LOG(FATAL) << __func__ << ": BluetoothAudio HAL for A2DP offloading is invalid?!"; delete offloading_hal_interface; offloading_hal_interface = nullptr; delete a2dp_sink; a2dp_sink = static_cast<A2dpTransport*>( software_hal_interface->GetTransportInstance()); delete software_hal_interface; software_hal_interface = nullptr; delete a2dp_sink; return false; } } active_hal_interface = (offloading_hal_interface != nullptr ? offloading_hal_interface : software_hal_interface); if (remote_delay != 0) { if (remote_delay != 0) { LOG(INFO) << __func__ << ": restore DELAY " LOG(INFO) << __func__ << ": restore DELAY " << static_cast<float>(remote_delay / 10.0) << " ms"; << static_cast<float>(remote_delay / 10.0) << " ms"; a2dp_sink->SetRemoteDelay(remote_delay); static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance()) ->SetRemoteDelay(remote_delay); remote_delay = 0; remote_delay = 0; } } return true; return true; Loading @@ -359,11 +389,19 @@ bool init(bluetooth::common::MessageLoopThread* message_loop) { void cleanup() { void cleanup() { if (!is_hal_2_0_enabled()) return; if (!is_hal_2_0_enabled()) return; end_session(); end_session(); delete a2dp_hal_clientif; a2dp_hal_clientif = nullptr; active_hal_interface = nullptr; auto a2dp_sink = software_hal_interface->GetTransportInstance(); delete software_hal_interface; software_hal_interface = nullptr; delete a2dp_sink; if (offloading_hal_interface != nullptr) { a2dp_sink = offloading_hal_interface->GetTransportInstance(); delete offloading_hal_interface; offloading_hal_interface = nullptr; delete a2dp_sink; delete a2dp_sink; a2dp_sink = nullptr; } session_type = SessionType::UNKNOWN; remote_delay = 0; remote_delay = 0; } } Loading @@ -373,15 +411,28 @@ bool setup_codec() { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; return false; return false; } } AudioConfiguration audio_config{}; if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) { CodecConfiguration codec_config{}; CodecConfiguration codec_config{}; if (!a2dp_get_selected_hal_codec_config(&codec_config)) { if (!a2dp_get_selected_hal_codec_config(&codec_config)) { LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration"; LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration"; return false; return false; } } bool should_codec_offloading = bluetooth::audio::codec::IsCodecOffloadingEnabled(codec_config); if (should_codec_offloading && !is_hal_2_0_offloading()) { LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Hardware"; end_session(); active_hal_interface = offloading_hal_interface; } else if (!should_codec_offloading && is_hal_2_0_offloading()) { LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Software"; end_session(); active_hal_interface = software_hal_interface; } AudioConfiguration audio_config{}; if (active_hal_interface->GetTransportInstance()->GetSessionType() == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) { audio_config.codecConfig(codec_config); audio_config.codecConfig(codec_config); } else if (session_type == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH) { } else { PcmParameters pcm_config{}; PcmParameters pcm_config{}; if (!a2dp_get_selected_hal_pcm_config(&pcm_config)) { if (!a2dp_get_selected_hal_pcm_config(&pcm_config)) { LOG(ERROR) << __func__ << ": Failed to get PcmConfiguration"; LOG(ERROR) << __func__ << ": Failed to get PcmConfiguration"; Loading @@ -389,7 +440,7 @@ bool setup_codec() { } } audio_config.pcmConfig(pcm_config); audio_config.pcmConfig(pcm_config); } } return a2dp_hal_clientif->UpdateAudioConfig(audio_config); return active_hal_interface->UpdateAudioConfig(audio_config); } } void start_session() { void start_session() { Loading @@ -397,7 +448,7 @@ void start_session() { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; return; return; } } a2dp_hal_clientif->StartSession(); active_hal_interface->StartSession(); } } void end_session() { void end_session() { Loading @@ -405,15 +456,17 @@ void end_session() { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; return; return; } } a2dp_hal_clientif->EndSession(); active_hal_interface->EndSession(); } } void ack_stream_started(const tA2DP_CTRL_ACK& ack) { void ack_stream_started(const tA2DP_CTRL_ACK& ack) { auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack); auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack); LOG(INFO) << __func__ << ": result=" << ctrl_ack; LOG(INFO) << __func__ << ": result=" << ctrl_ack; auto a2dp_sink = static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance()); auto pending_cmd = a2dp_sink->GetPendingCmd(); auto pending_cmd = a2dp_sink->GetPendingCmd(); if (pending_cmd == A2DP_CTRL_CMD_START) { if (pending_cmd == A2DP_CTRL_CMD_START) { a2dp_hal_clientif->StreamStarted(ctrl_ack); active_hal_interface->StreamStarted(ctrl_ack); } else { } else { LOG(WARNING) << __func__ << ": pending=" << pending_cmd LOG(WARNING) << __func__ << ": pending=" << pending_cmd << " ignore result=" << ctrl_ack; << " ignore result=" << ctrl_ack; Loading @@ -427,9 +480,11 @@ void ack_stream_started(const tA2DP_CTRL_ACK& ack) { void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) { void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) { auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack); auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack); LOG(INFO) << __func__ << ": result=" << ctrl_ack; LOG(INFO) << __func__ << ": result=" << ctrl_ack; auto a2dp_sink = static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance()); auto pending_cmd = a2dp_sink->GetPendingCmd(); auto pending_cmd = a2dp_sink->GetPendingCmd(); if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) { if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) { a2dp_hal_clientif->StreamSuspended(ctrl_ack); active_hal_interface->StreamSuspended(ctrl_ack); } else if (pending_cmd == A2DP_CTRL_CMD_STOP) { } else if (pending_cmd == A2DP_CTRL_CMD_STOP) { LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_STOP result=" << ctrl_ack; LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_STOP result=" << ctrl_ack; } else { } else { Loading @@ -447,12 +502,14 @@ size_t read(uint8_t* p_buf, uint32_t len) { if (!is_hal_2_0_enabled()) { if (!is_hal_2_0_enabled()) { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; return 0; return 0; } else if (session_type != SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH) { } else if (is_hal_2_0_offloading()) { LOG(ERROR) << __func__ << ": session_type=" << toString(session_type) LOG(ERROR) << __func__ << ": session_type=" << toString(active_hal_interface->GetTransportInstance() ->GetSessionType()) << " is not A2DP_SOFTWARE_ENCODING_DATAPATH"; << " is not A2DP_SOFTWARE_ENCODING_DATAPATH"; return 0; return 0; } } return a2dp_hal_clientif->ReadAudioData(p_buf, len); return active_hal_interface->ReadAudioData(p_buf, len); } } // Update A2DP delay report to BluetoothAudio HAL // Update A2DP delay report to BluetoothAudio HAL Loading @@ -463,9 +520,10 @@ void set_remote_delay(uint16_t delay_report) { remote_delay = delay_report; remote_delay = delay_report; return; return; } } LOG(INFO) << __func__ << ": DELAY " << static_cast<float>(delay_report / 10.0) VLOG(1) << __func__ << ": DELAY " << static_cast<float>(delay_report / 10.0) << " ms"; << " ms"; a2dp_sink->SetRemoteDelay(delay_report); static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance()) ->SetRemoteDelay(delay_report); } } } // namespace a2dp } // namespace a2dp Loading
system/audio_hal_interface/a2dp_encoding.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,9 @@ bool update_codec_offloading_capabilities( // Check if new bluetooth_audio is enabled // Check if new bluetooth_audio is enabled bool is_hal_2_0_enabled(); bool is_hal_2_0_enabled(); // Check if new bluetooth_audio is running with offloading encoders bool is_hal_2_0_offloading(); // Initialize BluetoothAudio HAL: openProvider // Initialize BluetoothAudio HAL: openProvider bool init(bluetooth::common::MessageLoopThread* message_loop); bool init(bluetooth::common::MessageLoopThread* message_loop); Loading
system/audio_hal_interface/client_interface.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -134,6 +134,8 @@ class BluetoothAudioClientInterface { return provider_ != nullptr; return provider_ != nullptr; } } IBluetoothTransportInstance* GetTransportInstance() const { return sink_; } std::vector<AudioCapabilities> GetAudioCapabilities() const; std::vector<AudioCapabilities> GetAudioCapabilities() const; static std::vector<AudioCapabilities> GetAudioCapabilities( static std::vector<AudioCapabilities> GetAudioCapabilities( SessionType session_type); SessionType session_type); Loading
system/btif/include/btif_av.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -187,6 +187,12 @@ void btif_av_src_disconnect_sink(const RawAddress& peer_address); */ */ bool btif_av_is_a2dp_offload_enabled(void); bool btif_av_is_a2dp_offload_enabled(void); /** * check A2DP offload enabled and running * @param none */ bool btif_av_is_a2dp_offload_running(void); /** /** * Check whether peer device is silenced * Check whether peer device is silenced * * Loading
system/btif/src/btif_a2dp.cc +9 −4 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,7 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { bluetooth::audio::a2dp::ack_stream_started(status); bluetooth::audio::a2dp::ack_stream_started(status); } else if (btif_av_is_a2dp_offload_enabled()) { } else if (btif_av_is_a2dp_offload_enabled()) { // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_started(status); btif_a2dp_audio_on_started(status); } else { } else { btif_a2dp_command_ack(status); btif_a2dp_command_ack(status); Loading @@ -75,7 +76,7 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start LOG(WARNING) << __func__ << ": peer " << peer_addr << " A2DP is suspending and ignores the started event"; LOG(WARNING) << __func__ << ": peer " << peer_addr << " A2DP is suspending and ignores the started event"; return false; return false; } } if (btif_av_is_a2dp_offload_enabled()) { if (btif_av_is_a2dp_offload_running()) { btif_av_stream_start_offload(); btif_av_stream_start_offload(); } else if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { } else if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) { if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) { Loading @@ -98,6 +99,7 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) { bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE); bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE); } else if (btif_av_is_a2dp_offload_enabled()) { } else if (btif_av_is_a2dp_offload_enabled()) { // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_started(p_av_start->status); btif_a2dp_audio_on_started(p_av_start->status); } else { } else { btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); Loading @@ -116,9 +118,10 @@ void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) { return; return; } } if (bluetooth::audio::a2dp::is_hal_2_0_enabled() || if (bluetooth::audio::a2dp::is_hal_2_0_enabled() || !btif_av_is_a2dp_offload_enabled()) { !btif_av_is_a2dp_offload_running()) { btif_a2dp_source_on_stopped(p_av_suspend); btif_a2dp_source_on_stopped(p_av_suspend); } else if (p_av_suspend != NULL) { } else if (p_av_suspend != NULL) { // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_stopped(p_av_suspend->status); btif_a2dp_audio_on_stopped(p_av_suspend->status); } } } } Loading @@ -131,9 +134,10 @@ void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) { return; return; } } if (bluetooth::audio::a2dp::is_hal_2_0_enabled() || if (bluetooth::audio::a2dp::is_hal_2_0_enabled() || !btif_av_is_a2dp_offload_enabled()) { !btif_av_is_a2dp_offload_running()) { btif_a2dp_source_on_suspended(p_av_suspend); btif_a2dp_source_on_suspended(p_av_suspend); } else if (p_av_suspend != NULL) { } else if (p_av_suspend != NULL) { // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_suspended(p_av_suspend->status); btif_a2dp_audio_on_suspended(p_av_suspend->status); } } } } Loading @@ -159,7 +163,7 @@ void btif_a2dp_on_offload_started(const RawAddress& peer_addr, ack = A2DP_CTRL_ACK_FAILURE; ack = A2DP_CTRL_ACK_FAILURE; break; break; } } if (btif_av_is_a2dp_offload_enabled()) { if (btif_av_is_a2dp_offload_running()) { if (ack != BTA_AV_SUCCESS && btif_av_stream_started_ready()) { if (ack != BTA_AV_SUCCESS && btif_av_stream_started_ready()) { // Offload request will return with failure from btif_av sm if // Offload request will return with failure from btif_av sm if // suspend is triggered for remote start. Disconnect only if SoC // suspend is triggered for remote start. Disconnect only if SoC Loading @@ -173,6 +177,7 @@ void btif_a2dp_on_offload_started(const RawAddress& peer_addr, bluetooth::audio::a2dp::ack_stream_started(ack); bluetooth::audio::a2dp::ack_stream_started(ack); } else { } else { btif_a2dp_command_ack(ack); btif_a2dp_command_ack(ack); // TODO: BluetoothA2dp@1.0 is deprecated btif_a2dp_audio_on_started(status); btif_a2dp_audio_on_started(status); } } } } Loading