Skip to content
Snippets Groups Projects
Commit 74324cbd authored by Jack He's avatar Jack He
Browse files

A2DP-SINK: Use MessageLoopThread for decoding

* Instead of OSI thread, use MessageLoopThread for decoding
* Similar to A2DP source
* Change tBTIF_A2DP_SINK_CB into a proper class BtifA2dpSinkControlBlock
* Initialize variables in BtifA2dpSinkControlBlock's constructor
* Free un-freed variables in BtifA2dpSinkControlBlock::Reset() method

Bug: 110303473
Test: mm -j40, unit test, stream music
Change-Id: I21f5b0c9f88d2cadada6fc854070d31ac378244f
parent a96e9b3c
No related branches found
No related tags found
No related merge requests found
...@@ -133,6 +133,7 @@ cc_test { ...@@ -133,6 +133,7 @@ cc_test {
"libbtcore", "libbtcore",
"libbt-common", "libbt-common",
"libbt-stack", "libbt-stack",
"libbt-sbc-decoder",
"libbt-sbc-encoder", "libbt-sbc-encoder",
"libbt-utils", "libbt-utils",
"libFraunhoferAAC", "libFraunhoferAAC",
......
...@@ -20,8 +20,12 @@ ...@@ -20,8 +20,12 @@
#define LOG_TAG "bt_btif_a2dp_sink" #define LOG_TAG "bt_btif_a2dp_sink"
#include <atomic> #include <atomic>
#include <cstdio>
#include <cstring> #include <cstring>
#include <mutex> #include <mutex>
#include <string>
#include <base/bind.h>
#include "bt_common.h" #include "bt_common.h"
#include "btif_a2dp.h" #include "btif_a2dp.h"
...@@ -30,11 +34,12 @@ ...@@ -30,11 +34,12 @@
#include "btif_av_co.h" #include "btif_av_co.h"
#include "btif_avrcp_audio_track.h" #include "btif_avrcp_audio_track.h"
#include "btif_util.h" #include "btif_util.h"
#include "common/message_loop_thread.h"
#include "osi/include/fixed_queue.h" #include "osi/include/fixed_queue.h"
#include "osi/include/log.h" #include "osi/include/log.h"
#include "osi/include/osi.h" #include "osi/include/osi.h"
#include "osi/include/thread.h"
using bluetooth::common::MessageLoopThread;
using LockGuard = std::lock_guard<std::mutex>; using LockGuard = std::lock_guard<std::mutex>;
/** /**
...@@ -73,9 +78,37 @@ typedef struct { ...@@ -73,9 +78,37 @@ typedef struct {
} tBTIF_MEDIA_SINK_FOCUS_UPDATE; } tBTIF_MEDIA_SINK_FOCUS_UPDATE;
/* BTIF A2DP Sink control block */ /* BTIF A2DP Sink control block */
typedef struct { class BtifA2dpSinkControlBlock {
thread_t* worker_thread; public:
fixed_queue_t* cmd_msg_queue; explicit BtifA2dpSinkControlBlock(const std::string& thread_name)
: worker_thread(thread_name),
rx_audio_queue(nullptr),
rx_flush(false),
decode_alarm(nullptr),
sample_rate(0),
channel_count(0),
rx_focus_state(BTIF_A2DP_SINK_FOCUS_NOT_GRANTED),
audio_track(nullptr),
decoder_interface(nullptr) {}
void Reset() {
if (audio_track != nullptr) {
BtifAvrcpAudioTrackStop(audio_track);
BtifAvrcpAudioTrackDelete(audio_track);
}
audio_track = nullptr;
fixed_queue_free(rx_audio_queue, nullptr);
rx_audio_queue = nullptr;
alarm_free(decode_alarm);
decode_alarm = nullptr;
rx_flush = false;
rx_focus_state = BTIF_A2DP_SINK_FOCUS_NOT_GRANTED;
sample_rate = 0;
channel_count = 0;
decoder_interface = nullptr;
}
MessageLoopThread worker_thread;
fixed_queue_t* rx_audio_queue; fixed_queue_t* rx_audio_queue;
bool rx_flush; /* discards any incoming data when true */ bool rx_flush; /* discards any incoming data when true */
alarm_t* decode_alarm; alarm_t* decode_alarm;
...@@ -84,36 +117,37 @@ typedef struct { ...@@ -84,36 +117,37 @@ typedef struct {
btif_a2dp_sink_focus_state_t rx_focus_state; /* audio focus state */ btif_a2dp_sink_focus_state_t rx_focus_state; /* audio focus state */
void* audio_track; void* audio_track;
const tA2DP_DECODER_INTERFACE* decoder_interface; const tA2DP_DECODER_INTERFACE* decoder_interface;
} tBTIF_A2DP_SINK_CB; };
// Mutex for below data structures. // Mutex for below data structures.
static std::mutex g_mutex; static std::mutex g_mutex;
static tBTIF_A2DP_SINK_CB btif_a2dp_sink_cb; static BtifA2dpSinkControlBlock btif_a2dp_sink_cb(
"btif_a2dp_sink_worker_thread");
static std::atomic<int> btif_a2dp_sink_state{BTIF_A2DP_SINK_STATE_OFF}; static std::atomic<int> btif_a2dp_sink_state{BTIF_A2DP_SINK_STATE_OFF};
static void btif_a2dp_sink_init_delayed(void* context); static void btif_a2dp_sink_init_delayed();
static void btif_a2dp_sink_startup_delayed(void* context); static void btif_a2dp_sink_startup_delayed();
static void btif_a2dp_sink_start_session_delayed(void* context); static void btif_a2dp_sink_start_session_delayed();
static void btif_a2dp_sink_end_session_delayed(void* context); static void btif_a2dp_sink_end_session_delayed();
static void btif_a2dp_sink_shutdown_delayed(void* context); static void btif_a2dp_sink_shutdown_delayed();
static void btif_a2dp_sink_cleanup_delayed(void* context); static void btif_a2dp_sink_cleanup_delayed();
static void btif_a2dp_sink_command_ready(fixed_queue_t* queue, void* context); static void btif_a2dp_sink_command_ready(BT_HDR* p_msg);
static void btif_a2dp_sink_audio_handle_stop_decoding(void); static void btif_a2dp_sink_audio_handle_stop_decoding();
static void btif_decode_alarm_cb(void* context); static void btif_decode_alarm_cb(void* context);
static void btif_a2dp_sink_audio_handle_start_decoding(void); static void btif_a2dp_sink_audio_handle_start_decoding();
static void btif_a2dp_sink_avk_handle_timer(UNUSED_ATTR void* context); static void btif_a2dp_sink_avk_handle_timer();
static void btif_a2dp_sink_audio_rx_flush_req(void); static void btif_a2dp_sink_audio_rx_flush_req();
/* Handle incoming media packets A2DP SINK streaming */ /* Handle incoming media packets A2DP SINK streaming */
static void btif_a2dp_sink_handle_inc_media(BT_HDR* p_msg); static void btif_a2dp_sink_handle_inc_media(BT_HDR* p_msg);
static void btif_a2dp_sink_decoder_update_event( static void btif_a2dp_sink_decoder_update_event(
tBTIF_MEDIA_SINK_DECODER_UPDATE* p_buf); tBTIF_MEDIA_SINK_DECODER_UPDATE* p_buf);
static void btif_a2dp_sink_clear_track_event(void); static void btif_a2dp_sink_clear_track_event();
static void btif_a2dp_sink_set_focus_state_event( static void btif_a2dp_sink_set_focus_state_event(
btif_a2dp_sink_focus_state_t state); btif_a2dp_sink_focus_state_t state);
static void btif_a2dp_sink_audio_rx_flush_event(void); static void btif_a2dp_sink_audio_rx_flush_event();
static void btif_a2dp_sink_clear_track_event_req(void); static void btif_a2dp_sink_clear_track_event_req();
UNUSED_ATTR static const char* dump_media_event(uint16_t event) { UNUSED_ATTR static const char* dump_media_event(uint16_t event) {
switch (event) { switch (event) {
...@@ -127,7 +161,7 @@ UNUSED_ATTR static const char* dump_media_event(uint16_t event) { ...@@ -127,7 +161,7 @@ UNUSED_ATTR static const char* dump_media_event(uint16_t event) {
return "UNKNOWN A2DP SINK EVENT"; return "UNKNOWN A2DP SINK EVENT";
} }
bool btif_a2dp_sink_init(void) { bool btif_a2dp_sink_init() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
...@@ -136,48 +170,42 @@ bool btif_a2dp_sink_init(void) { ...@@ -136,48 +170,42 @@ bool btif_a2dp_sink_init(void) {
return false; return false;
} }
memset(&btif_a2dp_sink_cb, 0, sizeof(btif_a2dp_sink_cb)); btif_a2dp_sink_cb.Reset();
btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_STARTING_UP; btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_STARTING_UP;
/* Start A2DP Sink media task */ /* Start A2DP Sink media task */
btif_a2dp_sink_cb.worker_thread = thread_new("btif_a2dp_sink_worker_thread"); btif_a2dp_sink_cb.worker_thread.StartUp();
if (btif_a2dp_sink_cb.worker_thread == NULL) { if (!btif_a2dp_sink_cb.worker_thread.IsRunning()) {
LOG_ERROR(LOG_TAG, "%s: unable to start up media thread", __func__); LOG_ERROR(LOG_TAG, "%s: unable to start up media thread", __func__);
btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_OFF; btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_OFF;
return false; return false;
} }
btif_a2dp_sink_cb.rx_focus_state = BTIF_A2DP_SINK_FOCUS_NOT_GRANTED;
btif_a2dp_sink_cb.audio_track = NULL;
btif_a2dp_sink_cb.rx_audio_queue = fixed_queue_new(SIZE_MAX); btif_a2dp_sink_cb.rx_audio_queue = fixed_queue_new(SIZE_MAX);
btif_a2dp_sink_cb.cmd_msg_queue = fixed_queue_new(SIZE_MAX);
fixed_queue_register_dequeue(
btif_a2dp_sink_cb.cmd_msg_queue,
thread_get_reactor(btif_a2dp_sink_cb.worker_thread),
btif_a2dp_sink_command_ready, NULL);
/* Schedule the rest of the operations */ /* Schedule the rest of the operations */
thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_init_delayed, if (!btif_a2dp_sink_cb.worker_thread.EnableRealTimeScheduling()) {
NULL); LOG(FATAL) << __func__
<< ": Failed to increase A2DP decoder thread priority";
}
btif_a2dp_sink_cb.worker_thread.DoInThread(
FROM_HERE, base::BindOnce(btif_a2dp_sink_init_delayed));
return true; return true;
} }
static void btif_a2dp_sink_init_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_init_delayed() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
raise_priority_a2dp(TASK_HIGH_MEDIA);
btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_RUNNING; btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_RUNNING;
} }
bool btif_a2dp_sink_startup(void) { bool btif_a2dp_sink_startup() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_startup_delayed, btif_a2dp_sink_cb.worker_thread.DoInThread(
NULL); FROM_HERE, base::BindOnce(btif_a2dp_sink_startup_delayed));
return true; return true;
} }
static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_startup_delayed() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
// Nothing to do // Nothing to do
...@@ -186,12 +214,12 @@ static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) { ...@@ -186,12 +214,12 @@ static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) {
bool btif_a2dp_sink_start_session(const RawAddress& peer_address) { bool btif_a2dp_sink_start_session(const RawAddress& peer_address) {
LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__, LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
peer_address.ToString().c_str()); peer_address.ToString().c_str());
thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_cb.worker_thread.DoInThread(
btif_a2dp_sink_start_session_delayed, NULL); FROM_HERE, base::BindOnce(btif_a2dp_sink_start_session_delayed));
return true; return true;
} }
static void btif_a2dp_sink_start_session_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_start_session_delayed() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
// Nothing to do // Nothing to do
...@@ -226,35 +254,33 @@ bool btif_a2dp_sink_restart_session(const RawAddress& old_peer_address, ...@@ -226,35 +254,33 @@ bool btif_a2dp_sink_restart_session(const RawAddress& old_peer_address,
bool btif_a2dp_sink_end_session(const RawAddress& peer_address) { bool btif_a2dp_sink_end_session(const RawAddress& peer_address) {
LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__, LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
peer_address.ToString().c_str()); peer_address.ToString().c_str());
thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_cb.worker_thread.DoInThread(
btif_a2dp_sink_end_session_delayed, NULL); FROM_HERE, base::BindOnce(btif_a2dp_sink_end_session_delayed));
return true; return true;
} }
static void btif_a2dp_sink_end_session_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_end_session_delayed() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
// Nothing to do // Nothing to do
} }
void btif_a2dp_sink_shutdown(void) { void btif_a2dp_sink_shutdown() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_shutdown_delayed, btif_a2dp_sink_cb.worker_thread.DoInThread(
NULL); FROM_HERE, base::BindOnce(btif_a2dp_sink_shutdown_delayed));
} }
static void btif_a2dp_sink_shutdown_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_shutdown_delayed() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
// Nothing to do // Nothing to do
} }
void btif_a2dp_sink_cleanup(void) { void btif_a2dp_sink_cleanup() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
alarm_t* decode_alarm; alarm_t* decode_alarm;
fixed_queue_t* cmd_msg_queue;
thread_t* worker_thread;
// Make sure the sink is shutdown // Make sure the sink is shutdown
btif_a2dp_sink_shutdown(); btif_a2dp_sink_shutdown();
...@@ -269,47 +295,38 @@ void btif_a2dp_sink_cleanup(void) { ...@@ -269,47 +295,38 @@ void btif_a2dp_sink_cleanup(void) {
btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_SHUTTING_DOWN; btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_SHUTTING_DOWN;
decode_alarm = btif_a2dp_sink_cb.decode_alarm; decode_alarm = btif_a2dp_sink_cb.decode_alarm;
btif_a2dp_sink_cb.decode_alarm = NULL; btif_a2dp_sink_cb.decode_alarm = nullptr;
cmd_msg_queue = btif_a2dp_sink_cb.cmd_msg_queue;
btif_a2dp_sink_cb.cmd_msg_queue = NULL;
worker_thread = btif_a2dp_sink_cb.worker_thread;
btif_a2dp_sink_cb.worker_thread = NULL;
} }
// Stop the timer // Stop the timer
alarm_free(decode_alarm); alarm_free(decode_alarm);
// Exit the thread // Exit the thread
fixed_queue_free(cmd_msg_queue, NULL); btif_a2dp_sink_cb.worker_thread.DoInThread(
thread_post(worker_thread, btif_a2dp_sink_cleanup_delayed, NULL); FROM_HERE, base::BindOnce(btif_a2dp_sink_cleanup_delayed));
thread_free(worker_thread); btif_a2dp_sink_cb.worker_thread.ShutDown();
} }
static void btif_a2dp_sink_cleanup_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_cleanup_delayed() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
fixed_queue_free(btif_a2dp_sink_cb.rx_audio_queue, NULL); fixed_queue_free(btif_a2dp_sink_cb.rx_audio_queue, nullptr);
btif_a2dp_sink_cb.rx_audio_queue = NULL; btif_a2dp_sink_cb.rx_audio_queue = nullptr;
btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_OFF; btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_OFF;
} }
tA2DP_SAMPLE_RATE btif_a2dp_sink_get_sample_rate(void) { tA2DP_SAMPLE_RATE btif_a2dp_sink_get_sample_rate() {
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
return btif_a2dp_sink_cb.sample_rate; return btif_a2dp_sink_cb.sample_rate;
} }
tA2DP_CHANNEL_COUNT btif_a2dp_sink_get_channel_count(void) { tA2DP_CHANNEL_COUNT btif_a2dp_sink_get_channel_count() {
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
return btif_a2dp_sink_cb.channel_count; return btif_a2dp_sink_cb.channel_count;
} }
static void btif_a2dp_sink_command_ready(fixed_queue_t* queue, static void btif_a2dp_sink_command_ready(BT_HDR* p_msg) {
UNUSED_ATTR void* context) {
BT_HDR* p_msg = (BT_HDR*)fixed_queue_dequeue(queue);
LOG_VERBOSE(LOG_TAG, "%s: event %d %s", __func__, p_msg->event, LOG_VERBOSE(LOG_TAG, "%s: event %d %s", __func__, p_msg->event,
dump_media_event(p_msg->event)); dump_media_event(p_msg->event));
...@@ -352,10 +369,11 @@ void btif_a2dp_sink_update_decoder(const uint8_t* p_codec_info) { ...@@ -352,10 +369,11 @@ void btif_a2dp_sink_update_decoder(const uint8_t* p_codec_info) {
memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE); memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
p_buf->hdr.event = BTIF_MEDIA_SINK_DECODER_UPDATE; p_buf->hdr.event = BTIF_MEDIA_SINK_DECODER_UPDATE;
fixed_queue_enqueue(btif_a2dp_sink_cb.cmd_msg_queue, p_buf); btif_a2dp_sink_cb.worker_thread.DoInThread(
FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, (BT_HDR*)p_buf));
} }
void btif_a2dp_sink_on_idle(void) { void btif_a2dp_sink_on_idle() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return;
btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_audio_handle_stop_decoding();
...@@ -374,7 +392,7 @@ void btif_a2dp_sink_on_suspended(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { ...@@ -374,7 +392,7 @@ void btif_a2dp_sink_on_suspended(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) {
btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_audio_handle_stop_decoding();
} }
static void btif_a2dp_sink_audio_handle_stop_decoding(void) { static void btif_a2dp_sink_audio_handle_stop_decoding() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
alarm_t* old_alarm; alarm_t* old_alarm;
{ {
...@@ -382,7 +400,7 @@ static void btif_a2dp_sink_audio_handle_stop_decoding(void) { ...@@ -382,7 +400,7 @@ static void btif_a2dp_sink_audio_handle_stop_decoding(void) {
btif_a2dp_sink_cb.rx_flush = true; btif_a2dp_sink_cb.rx_flush = true;
btif_a2dp_sink_audio_rx_flush_req(); btif_a2dp_sink_audio_rx_flush_req();
old_alarm = btif_a2dp_sink_cb.decode_alarm; old_alarm = btif_a2dp_sink_cb.decode_alarm;
btif_a2dp_sink_cb.decode_alarm = NULL; btif_a2dp_sink_cb.decode_alarm = nullptr;
} }
// Drop the lock here, btif_decode_alarm_cb may in the process of being called // Drop the lock here, btif_decode_alarm_cb may in the process of being called
...@@ -401,13 +419,11 @@ static void btif_a2dp_sink_audio_handle_stop_decoding(void) { ...@@ -401,13 +419,11 @@ static void btif_a2dp_sink_audio_handle_stop_decoding(void) {
static void btif_decode_alarm_cb(UNUSED_ATTR void* context) { static void btif_decode_alarm_cb(UNUSED_ATTR void* context) {
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
if (btif_a2dp_sink_cb.worker_thread != NULL) { btif_a2dp_sink_cb.worker_thread.DoInThread(
thread_post(btif_a2dp_sink_cb.worker_thread, FROM_HERE, base::BindOnce(btif_a2dp_sink_avk_handle_timer));
btif_a2dp_sink_avk_handle_timer, NULL);
}
} }
static void btif_a2dp_sink_clear_track_event(void) { static void btif_a2dp_sink_clear_track_event() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
...@@ -415,13 +431,13 @@ static void btif_a2dp_sink_clear_track_event(void) { ...@@ -415,13 +431,13 @@ static void btif_a2dp_sink_clear_track_event(void) {
BtifAvrcpAudioTrackStop(btif_a2dp_sink_cb.audio_track); BtifAvrcpAudioTrackStop(btif_a2dp_sink_cb.audio_track);
BtifAvrcpAudioTrackDelete(btif_a2dp_sink_cb.audio_track); BtifAvrcpAudioTrackDelete(btif_a2dp_sink_cb.audio_track);
#endif #endif
btif_a2dp_sink_cb.audio_track = NULL; btif_a2dp_sink_cb.audio_track = nullptr;
} }
// Must be called while locked. // Must be called while locked.
static void btif_a2dp_sink_audio_handle_start_decoding(void) { static void btif_a2dp_sink_audio_handle_start_decoding() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
if (btif_a2dp_sink_cb.decode_alarm != NULL) if (btif_a2dp_sink_cb.decode_alarm != nullptr)
return; // Already started decoding return; // Already started decoding
#ifndef OS_GENERIC #ifndef OS_GENERIC
...@@ -429,12 +445,12 @@ static void btif_a2dp_sink_audio_handle_start_decoding(void) { ...@@ -429,12 +445,12 @@ static void btif_a2dp_sink_audio_handle_start_decoding(void) {
#endif #endif
btif_a2dp_sink_cb.decode_alarm = alarm_new_periodic("btif.a2dp_sink_decode"); btif_a2dp_sink_cb.decode_alarm = alarm_new_periodic("btif.a2dp_sink_decode");
if (btif_a2dp_sink_cb.decode_alarm == NULL) { if (btif_a2dp_sink_cb.decode_alarm == nullptr) {
LOG_ERROR(LOG_TAG, "%s: unable to allocate decode alarm", __func__); LOG_ERROR(LOG_TAG, "%s: unable to allocate decode alarm", __func__);
return; return;
} }
alarm_set(btif_a2dp_sink_cb.decode_alarm, BTIF_SINK_MEDIA_TIME_TICK_MS, alarm_set(btif_a2dp_sink_cb.decode_alarm, BTIF_SINK_MEDIA_TIME_TICK_MS,
btif_decode_alarm_cb, NULL); btif_decode_alarm_cb, nullptr);
} }
static void btif_a2dp_sink_on_decode_complete(uint8_t* data, uint32_t len) { static void btif_a2dp_sink_on_decode_complete(uint8_t* data, uint32_t len) {
...@@ -452,13 +468,13 @@ static void btif_a2dp_sink_handle_inc_media(BT_HDR* p_msg) { ...@@ -452,13 +468,13 @@ static void btif_a2dp_sink_handle_inc_media(BT_HDR* p_msg) {
return; return;
} }
CHECK(btif_a2dp_sink_cb.decoder_interface); CHECK(btif_a2dp_sink_cb.decoder_interface != nullptr);
if (!btif_a2dp_sink_cb.decoder_interface->decode_packet(p_msg)) { if (!btif_a2dp_sink_cb.decoder_interface->decode_packet(p_msg)) {
LOG_ERROR(LOG_TAG, "%s: decoding failed", __func__); LOG_ERROR(LOG_TAG, "%s: decoding failed", __func__);
} }
} }
static void btif_a2dp_sink_avk_handle_timer(UNUSED_ATTR void* context) { static void btif_a2dp_sink_avk_handle_timer() {
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
BT_HDR* p_msg; BT_HDR* p_msg;
...@@ -503,7 +519,7 @@ void btif_a2dp_sink_set_rx_flush(bool enable) { ...@@ -503,7 +519,7 @@ void btif_a2dp_sink_set_rx_flush(bool enable) {
btif_a2dp_sink_cb.rx_flush = enable; btif_a2dp_sink_cb.rx_flush = enable;
} }
static void btif_a2dp_sink_audio_rx_flush_event(void) { static void btif_a2dp_sink_audio_rx_flush_event() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
LockGuard lock(g_mutex); LockGuard lock(g_mutex);
// Flush all received encoded audio buffers // Flush all received encoded audio buffers
...@@ -541,7 +557,7 @@ static void btif_a2dp_sink_decoder_update_event( ...@@ -541,7 +557,7 @@ static void btif_a2dp_sink_decoder_update_event(
APPL_TRACE_DEBUG("%s: reset to Sink role", __func__); APPL_TRACE_DEBUG("%s: reset to Sink role", __func__);
btif_a2dp_sink_cb.decoder_interface = bta_av_co_get_decoder_interface(); btif_a2dp_sink_cb.decoder_interface = bta_av_co_get_decoder_interface();
if (btif_a2dp_sink_cb.decoder_interface == NULL) { if (btif_a2dp_sink_cb.decoder_interface == nullptr) {
LOG_ERROR(LOG_TAG, "%s: cannot stream audio: no source decoder interface", LOG_ERROR(LOG_TAG, "%s: cannot stream audio: no source decoder interface",
__func__); __func__);
return; return;
...@@ -560,7 +576,7 @@ static void btif_a2dp_sink_decoder_update_event( ...@@ -560,7 +576,7 @@ static void btif_a2dp_sink_decoder_update_event(
#else #else
NULL; NULL;
#endif #endif
if (btif_a2dp_sink_cb.audio_track == NULL) { if (btif_a2dp_sink_cb.audio_track == nullptr) {
LOG_ERROR(LOG_TAG, "%s: track creation failed", __func__); LOG_ERROR(LOG_TAG, "%s: track creation failed", __func__);
return; return;
} }
...@@ -595,7 +611,7 @@ uint8_t btif_a2dp_sink_enqueue_buf(BT_HDR* p_pkt) { ...@@ -595,7 +611,7 @@ uint8_t btif_a2dp_sink_enqueue_buf(BT_HDR* p_pkt) {
return fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue); return fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue);
} }
void btif_a2dp_sink_audio_rx_flush_req(void) { void btif_a2dp_sink_audio_rx_flush_req() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
if (fixed_queue_is_empty(btif_a2dp_sink_cb.rx_audio_queue)) { if (fixed_queue_is_empty(btif_a2dp_sink_cb.rx_audio_queue)) {
/* Queue is already empty */ /* Queue is already empty */
...@@ -604,7 +620,8 @@ void btif_a2dp_sink_audio_rx_flush_req(void) { ...@@ -604,7 +620,8 @@ void btif_a2dp_sink_audio_rx_flush_req(void) {
BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR)));
p_buf->event = BTIF_MEDIA_SINK_AUDIO_RX_FLUSH; p_buf->event = BTIF_MEDIA_SINK_AUDIO_RX_FLUSH;
fixed_queue_enqueue(btif_a2dp_sink_cb.cmd_msg_queue, p_buf); btif_a2dp_sink_cb.worker_thread.DoInThread(
FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf));
} }
void btif_a2dp_sink_debug_dump(UNUSED_ATTR int fd) { void btif_a2dp_sink_debug_dump(UNUSED_ATTR int fd) {
...@@ -618,7 +635,8 @@ void btif_a2dp_sink_set_focus_state_req(btif_a2dp_sink_focus_state_t state) { ...@@ -618,7 +635,8 @@ void btif_a2dp_sink_set_focus_state_req(btif_a2dp_sink_focus_state_t state) {
osi_malloc(sizeof(tBTIF_MEDIA_SINK_FOCUS_UPDATE))); osi_malloc(sizeof(tBTIF_MEDIA_SINK_FOCUS_UPDATE)));
p_buf->focus_state = state; p_buf->focus_state = state;
p_buf->hdr.event = BTIF_MEDIA_SINK_SET_FOCUS_STATE; p_buf->hdr.event = BTIF_MEDIA_SINK_SET_FOCUS_STATE;
fixed_queue_enqueue(btif_a2dp_sink_cb.cmd_msg_queue, p_buf); btif_a2dp_sink_cb.worker_thread.DoInThread(
FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, (BT_HDR*)p_buf));
} }
static void btif_a2dp_sink_set_focus_state_event( static void btif_a2dp_sink_set_focus_state_event(
...@@ -646,10 +664,11 @@ void btif_a2dp_sink_set_audio_track_gain(float gain) { ...@@ -646,10 +664,11 @@ void btif_a2dp_sink_set_audio_track_gain(float gain) {
#endif #endif
} }
static void btif_a2dp_sink_clear_track_event_req(void) { static void btif_a2dp_sink_clear_track_event_req() {
LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__);
BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR)));
p_buf->event = BTIF_MEDIA_SINK_CLEAR_TRACK; p_buf->event = BTIF_MEDIA_SINK_CLEAR_TRACK;
fixed_queue_enqueue(btif_a2dp_sink_cb.cmd_msg_queue, p_buf); btif_a2dp_sink_cb.worker_thread.DoInThread(
FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf));
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment