Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2016 The Android Open Source Project
      4  *  Copyright (C) 2009-2012 Broadcom Corporation
      5  *
      6  *  Licensed under the Apache License, Version 2.0 (the "License");
      7  *  you may not use this file except in compliance with the License.
      8  *  You may obtain a copy of the License at:
      9  *
     10  *  http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  *  Unless required by applicable law or agreed to in writing, software
     13  *  distributed under the License is distributed on an "AS IS" BASIS,
     14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  *
     18  ******************************************************************************/
     19 
     20 #define LOG_TAG "bt_btif_a2dp_sink"
     21 
     22 #include <string.h>
     23 
     24 #include "bt_common.h"
     25 #include "btif_a2dp.h"
     26 #include "btif_a2dp_sink.h"
     27 #include "btif_av.h"
     28 #include "btif_av_co.h"
     29 #include "btif_avrcp_audio_track.h"
     30 #include "btif_util.h"
     31 #include "osi/include/fixed_queue.h"
     32 #include "osi/include/log.h"
     33 #include "osi/include/osi.h"
     34 #include "osi/include/thread.h"
     35 
     36 #include "oi_codec_sbc.h"
     37 #include "oi_status.h"
     38 
     39 /**
     40  * The receiving queue buffer size.
     41  */
     42 #define MAX_INPUT_A2DP_FRAME_QUEUE_SZ (MAX_PCM_FRAME_NUM_PER_TICK * 2)
     43 
     44 #define BTIF_SINK_MEDIA_TIME_TICK_MS 20
     45 
     46 /* In case of A2DP Sink, we will delay start by 5 AVDTP Packets */
     47 #define MAX_A2DP_DELAYED_START_FRAME_COUNT 5
     48 
     49 enum {
     50   BTIF_A2DP_SINK_STATE_OFF,
     51   BTIF_A2DP_SINK_STATE_STARTING_UP,
     52   BTIF_A2DP_SINK_STATE_RUNNING,
     53   BTIF_A2DP_SINK_STATE_SHUTTING_DOWN
     54 };
     55 
     56 /* BTIF Media Sink command event definition */
     57 enum {
     58   BTIF_MEDIA_SINK_DECODER_UPDATE = 1,
     59   BTIF_MEDIA_SINK_CLEAR_TRACK,
     60   BTIF_MEDIA_SINK_SET_FOCUS_STATE,
     61   BTIF_MEDIA_SINK_AUDIO_RX_FLUSH
     62 };
     63 
     64 typedef struct {
     65   BT_HDR hdr;
     66   uint8_t codec_info[AVDT_CODEC_SIZE];
     67 } tBTIF_MEDIA_SINK_DECODER_UPDATE;
     68 
     69 typedef struct {
     70   BT_HDR hdr;
     71   btif_a2dp_sink_focus_state_t focus_state;
     72 } tBTIF_MEDIA_SINK_FOCUS_UPDATE;
     73 
     74 typedef struct {
     75   uint16_t num_frames_to_be_processed;
     76   uint16_t len;
     77   uint16_t offset;
     78   uint16_t layer_specific;
     79 } tBT_SBC_HDR;
     80 
     81 /* BTIF A2DP Sink control block */
     82 typedef struct {
     83   thread_t* worker_thread;
     84   fixed_queue_t* cmd_msg_queue;
     85   fixed_queue_t* rx_audio_queue;
     86   bool rx_flush; /* discards any incoming data when true */
     87   alarm_t* decode_alarm;
     88   uint8_t frames_to_process;
     89   tA2DP_SAMPLE_RATE sample_rate;
     90   tA2DP_CHANNEL_COUNT channel_count;
     91   btif_a2dp_sink_focus_state_t rx_focus_state; /* audio focus state */
     92   void* audio_track;
     93 } tBTIF_A2DP_SINK_CB;
     94 
     95 static tBTIF_A2DP_SINK_CB btif_a2dp_sink_cb;
     96 
     97 static int btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_OFF;
     98 
     99 static OI_CODEC_SBC_DECODER_CONTEXT btif_a2dp_sink_context;
    100 static uint32_t btif_a2dp_sink_context_data[CODEC_DATA_WORDS(
    101     2, SBC_CODEC_FAST_FILTER_BUFFERS)];
    102 static int16_t
    103     btif_a2dp_sink_pcm_data[15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS];
    104 
    105 static void btif_a2dp_sink_startup_delayed(void* context);
    106 static void btif_a2dp_sink_shutdown_delayed(void* context);
    107 static void btif_a2dp_sink_command_ready(fixed_queue_t* queue, void* context);
    108 static void btif_a2dp_sink_audio_handle_stop_decoding(void);
    109 static void btif_decode_alarm_cb(void* context);
    110 static void btif_a2dp_sink_audio_handle_start_decoding(void);
    111 static void btif_a2dp_sink_avk_handle_timer(UNUSED_ATTR void* context);
    112 static void btif_a2dp_sink_audio_rx_flush_req(void);
    113 /* Handle incoming media packets A2DP SINK streaming */
    114 static void btif_a2dp_sink_handle_inc_media(tBT_SBC_HDR* p_msg);
    115 static void btif_a2dp_sink_decoder_update_event(
    116     tBTIF_MEDIA_SINK_DECODER_UPDATE* p_buf);
    117 static void btif_a2dp_sink_clear_track_event(void);
    118 static void btif_a2dp_sink_set_focus_state_event(
    119     btif_a2dp_sink_focus_state_t state);
    120 static void btif_a2dp_sink_audio_rx_flush_event(void);
    121 static void btif_a2dp_sink_clear_track_event_req(void);
    122 
    123 UNUSED_ATTR static const char* dump_media_event(uint16_t event) {
    124   switch (event) {
    125     CASE_RETURN_STR(BTIF_MEDIA_SINK_DECODER_UPDATE)
    126     CASE_RETURN_STR(BTIF_MEDIA_SINK_CLEAR_TRACK)
    127     CASE_RETURN_STR(BTIF_MEDIA_SINK_SET_FOCUS_STATE)
    128     CASE_RETURN_STR(BTIF_MEDIA_SINK_AUDIO_RX_FLUSH)
    129     default:
    130       break;
    131   }
    132   return "UNKNOWN A2DP SINK EVENT";
    133 }
    134 
    135 bool btif_a2dp_sink_startup(void) {
    136   if (btif_a2dp_sink_state != BTIF_A2DP_SINK_STATE_OFF) {
    137     APPL_TRACE_ERROR("%s: A2DP Sink media task already running", __func__);
    138     return false;
    139   }
    140 
    141   memset(&btif_a2dp_sink_cb, 0, sizeof(btif_a2dp_sink_cb));
    142   btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_STARTING_UP;
    143 
    144   APPL_TRACE_EVENT("## A2DP SINK START MEDIA THREAD ##");
    145 
    146   /* Start A2DP Sink media task */
    147   btif_a2dp_sink_cb.worker_thread = thread_new("btif_a2dp_sink_worker_thread");
    148   if (btif_a2dp_sink_cb.worker_thread == NULL) {
    149     APPL_TRACE_ERROR("%s: unable to start up media thread", __func__);
    150     btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_OFF;
    151     return false;
    152   }
    153 
    154   btif_a2dp_sink_cb.rx_focus_state = BTIF_A2DP_SINK_FOCUS_NOT_GRANTED;
    155   btif_a2dp_sink_cb.audio_track = NULL;
    156   btif_a2dp_sink_cb.rx_audio_queue = fixed_queue_new(SIZE_MAX);
    157 
    158   btif_a2dp_sink_cb.cmd_msg_queue = fixed_queue_new(SIZE_MAX);
    159   fixed_queue_register_dequeue(
    160       btif_a2dp_sink_cb.cmd_msg_queue,
    161       thread_get_reactor(btif_a2dp_sink_cb.worker_thread),
    162       btif_a2dp_sink_command_ready, NULL);
    163 
    164   APPL_TRACE_EVENT("## A2DP SINK MEDIA THREAD STARTED ##");
    165 
    166   /* Schedule the rest of the startup operations */
    167   thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_startup_delayed,
    168               NULL);
    169 
    170   return true;
    171 }
    172 
    173 static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) {
    174   raise_priority_a2dp(TASK_HIGH_MEDIA);
    175   btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_RUNNING;
    176 }
    177 
    178 void btif_a2dp_sink_shutdown(void) {
    179   if ((btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) ||
    180       (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_SHUTTING_DOWN)) {
    181     return;
    182   }
    183 
    184   /* Make sure no channels are restarted while shutting down */
    185   btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_SHUTTING_DOWN;
    186 
    187   APPL_TRACE_EVENT("## A2DP SINK STOP MEDIA THREAD ##");
    188 
    189   // Stop the timer
    190   alarm_free(btif_a2dp_sink_cb.decode_alarm);
    191   btif_a2dp_sink_cb.decode_alarm = NULL;
    192 
    193   // Exit the thread
    194   fixed_queue_free(btif_a2dp_sink_cb.cmd_msg_queue, NULL);
    195   btif_a2dp_sink_cb.cmd_msg_queue = NULL;
    196   thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_shutdown_delayed,
    197               NULL);
    198   thread_free(btif_a2dp_sink_cb.worker_thread);
    199   btif_a2dp_sink_cb.worker_thread = NULL;
    200 }
    201 
    202 static void btif_a2dp_sink_shutdown_delayed(UNUSED_ATTR void* context) {
    203   fixed_queue_free(btif_a2dp_sink_cb.rx_audio_queue, NULL);
    204   btif_a2dp_sink_cb.rx_audio_queue = NULL;
    205 
    206   btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_OFF;
    207 }
    208 
    209 tA2DP_SAMPLE_RATE btif_a2dp_sink_get_sample_rate(void) {
    210   return btif_a2dp_sink_cb.sample_rate;
    211 }
    212 
    213 tA2DP_CHANNEL_COUNT btif_a2dp_sink_get_channel_count(void) {
    214   return btif_a2dp_sink_cb.channel_count;
    215 }
    216 
    217 static void btif_a2dp_sink_command_ready(fixed_queue_t* queue,
    218                                          UNUSED_ATTR void* context) {
    219   BT_HDR* p_msg = (BT_HDR*)fixed_queue_dequeue(queue);
    220 
    221   LOG_VERBOSE(LOG_TAG, "%s: event %d %s", __func__, p_msg->event,
    222               dump_media_event(p_msg->event));
    223 
    224   switch (p_msg->event) {
    225     case BTIF_MEDIA_SINK_DECODER_UPDATE:
    226       btif_a2dp_sink_decoder_update_event(
    227           (tBTIF_MEDIA_SINK_DECODER_UPDATE*)p_msg);
    228       break;
    229     case BTIF_MEDIA_SINK_CLEAR_TRACK:
    230       btif_a2dp_sink_clear_track_event();
    231       break;
    232     case BTIF_MEDIA_SINK_SET_FOCUS_STATE: {
    233       btif_a2dp_sink_focus_state_t state =
    234           ((tBTIF_MEDIA_SINK_FOCUS_UPDATE*)p_msg)->focus_state;
    235       btif_a2dp_sink_set_focus_state_event(state);
    236       break;
    237     }
    238     case BTIF_MEDIA_SINK_AUDIO_RX_FLUSH:
    239       btif_a2dp_sink_audio_rx_flush_event();
    240       break;
    241     default:
    242       APPL_TRACE_ERROR("ERROR in %s unknown event %d", __func__, p_msg->event);
    243       break;
    244   }
    245 
    246   osi_free(p_msg);
    247   LOG_VERBOSE(LOG_TAG, "%s: %s DONE", __func__, dump_media_event(p_msg->event));
    248 }
    249 
    250 void btif_a2dp_sink_update_decoder(const uint8_t* p_codec_info) {
    251   tBTIF_MEDIA_SINK_DECODER_UPDATE* p_buf =
    252       reinterpret_cast<tBTIF_MEDIA_SINK_DECODER_UPDATE*>(
    253           osi_malloc(sizeof(tBTIF_MEDIA_SINK_DECODER_UPDATE)));
    254 
    255   APPL_TRACE_EVENT("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__,
    256                    p_codec_info[1], p_codec_info[2], p_codec_info[3],
    257                    p_codec_info[4], p_codec_info[5], p_codec_info[6]);
    258 
    259   memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
    260   p_buf->hdr.event = BTIF_MEDIA_SINK_DECODER_UPDATE;
    261 
    262   fixed_queue_enqueue(btif_a2dp_sink_cb.cmd_msg_queue, p_buf);
    263 }
    264 
    265 void btif_a2dp_sink_on_idle(void) {
    266   if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return;
    267 
    268   btif_a2dp_sink_audio_handle_stop_decoding();
    269   btif_a2dp_sink_clear_track_event_req();
    270   APPL_TRACE_DEBUG("Stopped BT track");
    271 }
    272 
    273 void btif_a2dp_sink_on_stopped(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) {
    274   if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return;
    275 
    276   btif_a2dp_sink_audio_handle_stop_decoding();
    277 }
    278 
    279 void btif_a2dp_sink_on_suspended(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) {
    280   if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return;
    281 
    282   btif_a2dp_sink_audio_handle_stop_decoding();
    283 }
    284 
    285 static void btif_a2dp_sink_audio_handle_stop_decoding(void) {
    286   btif_a2dp_sink_cb.rx_flush = true;
    287   btif_a2dp_sink_audio_rx_flush_req();
    288 
    289   alarm_free(btif_a2dp_sink_cb.decode_alarm);
    290   btif_a2dp_sink_cb.decode_alarm = NULL;
    291 #ifndef OS_GENERIC
    292   BtifAvrcpAudioTrackPause(btif_a2dp_sink_cb.audio_track);
    293 #endif
    294 }
    295 
    296 static void btif_decode_alarm_cb(UNUSED_ATTR void* context) {
    297   if (btif_a2dp_sink_cb.worker_thread != NULL) {
    298     thread_post(btif_a2dp_sink_cb.worker_thread,
    299                 btif_a2dp_sink_avk_handle_timer, NULL);
    300   }
    301 }
    302 
    303 static void btif_a2dp_sink_clear_track_event(void) {
    304   APPL_TRACE_DEBUG("%s", __func__);
    305 
    306 #ifndef OS_GENERIC
    307   BtifAvrcpAudioTrackStop(btif_a2dp_sink_cb.audio_track);
    308   BtifAvrcpAudioTrackDelete(btif_a2dp_sink_cb.audio_track);
    309 #endif
    310   btif_a2dp_sink_cb.audio_track = NULL;
    311 }
    312 
    313 static void btif_a2dp_sink_audio_handle_start_decoding(void) {
    314   if (btif_a2dp_sink_cb.decode_alarm != NULL)
    315     return;  // Already started decoding
    316 
    317 #ifndef OS_GENERIC
    318   BtifAvrcpAudioTrackStart(btif_a2dp_sink_cb.audio_track);
    319 #endif
    320 
    321   btif_a2dp_sink_cb.decode_alarm = alarm_new_periodic("btif.a2dp_sink_decode");
    322   if (btif_a2dp_sink_cb.decode_alarm == NULL) {
    323     LOG_ERROR(LOG_TAG, "%s: unable to allocate decode alarm", __func__);
    324     return;
    325   }
    326   alarm_set(btif_a2dp_sink_cb.decode_alarm, BTIF_SINK_MEDIA_TIME_TICK_MS,
    327             btif_decode_alarm_cb, NULL);
    328 }
    329 
    330 static void btif_a2dp_sink_handle_inc_media(tBT_SBC_HDR* p_msg) {
    331   uint8_t* sbc_start_frame = ((uint8_t*)(p_msg + 1) + p_msg->offset + 1);
    332   int count;
    333   uint32_t pcmBytes, availPcmBytes;
    334   int16_t* pcmDataPointer =
    335       btif_a2dp_sink_pcm_data; /* Will be overwritten on next packet receipt */
    336   OI_STATUS status;
    337   int num_sbc_frames = p_msg->num_frames_to_be_processed;
    338   uint32_t sbc_frame_len = p_msg->len - 1;
    339   availPcmBytes = sizeof(btif_a2dp_sink_pcm_data);
    340 
    341   if ((btif_av_get_peer_sep() == AVDT_TSEP_SNK) ||
    342       (btif_a2dp_sink_cb.rx_flush)) {
    343     APPL_TRACE_DEBUG("State Changed happened in this tick");
    344     return;
    345   }
    346 
    347   APPL_TRACE_DEBUG("%s Number of SBC frames %d, frame_len %d", __func__,
    348                    num_sbc_frames, sbc_frame_len);
    349 
    350   for (count = 0; count < num_sbc_frames && sbc_frame_len != 0; count++) {
    351     pcmBytes = availPcmBytes;
    352     status = OI_CODEC_SBC_DecodeFrame(
    353         &btif_a2dp_sink_context, (const OI_BYTE**)&sbc_start_frame,
    354         (uint32_t*)&sbc_frame_len, (int16_t*)pcmDataPointer,
    355         (uint32_t*)&pcmBytes);
    356     if (!OI_SUCCESS(status)) {
    357       APPL_TRACE_ERROR("%s: Decoding failure: %d", __func__, status);
    358       break;
    359     }
    360     availPcmBytes -= pcmBytes;
    361     pcmDataPointer += pcmBytes / 2;
    362     p_msg->offset += (p_msg->len - 1) - sbc_frame_len;
    363     p_msg->len = sbc_frame_len + 1;
    364   }
    365 
    366 #ifndef OS_GENERIC
    367   BtifAvrcpAudioTrackWriteData(
    368       btif_a2dp_sink_cb.audio_track, (void*)btif_a2dp_sink_pcm_data,
    369       (sizeof(btif_a2dp_sink_pcm_data) - availPcmBytes));
    370 #endif
    371 }
    372 
    373 static void btif_a2dp_sink_avk_handle_timer(UNUSED_ATTR void* context) {
    374   tBT_SBC_HDR* p_msg;
    375   int num_sbc_frames;
    376   int num_frames_to_process;
    377 
    378   if (fixed_queue_is_empty(btif_a2dp_sink_cb.rx_audio_queue)) {
    379     APPL_TRACE_DEBUG("%s: empty queue", __func__);
    380     return;
    381   }
    382 
    383   /* Don't do anything in case of focus not granted */
    384   if (btif_a2dp_sink_cb.rx_focus_state == BTIF_A2DP_SINK_FOCUS_NOT_GRANTED) {
    385     APPL_TRACE_DEBUG("%s: skipping frames since focus is not present",
    386                      __func__);
    387     return;
    388   }
    389   /* Play only in BTIF_A2DP_SINK_FOCUS_GRANTED case */
    390   if (btif_a2dp_sink_cb.rx_flush) {
    391     fixed_queue_flush(btif_a2dp_sink_cb.rx_audio_queue, osi_free);
    392     return;
    393   }
    394 
    395   num_frames_to_process = btif_a2dp_sink_cb.frames_to_process;
    396   APPL_TRACE_DEBUG(" Process Frames + ");
    397 
    398   do {
    399     p_msg = (tBT_SBC_HDR*)fixed_queue_try_peek_first(
    400         btif_a2dp_sink_cb.rx_audio_queue);
    401     if (p_msg == NULL) return;
    402     /* Number of frames in queue packets */
    403     num_sbc_frames = p_msg->num_frames_to_be_processed;
    404     APPL_TRACE_DEBUG("Frames left in topmost packet %d", num_sbc_frames);
    405     APPL_TRACE_DEBUG("Remaining frames to process in tick %d",
    406                      num_frames_to_process);
    407     APPL_TRACE_DEBUG("Number of packets in queue %d",
    408                      fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue));
    409 
    410     if (num_sbc_frames > num_frames_to_process) {
    411       /* Queue packet has more frames */
    412       p_msg->num_frames_to_be_processed = num_frames_to_process;
    413       btif_a2dp_sink_handle_inc_media(p_msg);
    414       p_msg->num_frames_to_be_processed =
    415           num_sbc_frames - num_frames_to_process;
    416       num_frames_to_process = 0;
    417       break;
    418     }
    419     /* Queue packet has less frames */
    420     btif_a2dp_sink_handle_inc_media(p_msg);
    421     p_msg =
    422         (tBT_SBC_HDR*)fixed_queue_try_dequeue(btif_a2dp_sink_cb.rx_audio_queue);
    423     if (p_msg == NULL) {
    424       APPL_TRACE_ERROR("Insufficient data in queue");
    425       break;
    426     }
    427     num_frames_to_process =
    428         num_frames_to_process - p_msg->num_frames_to_be_processed;
    429     osi_free(p_msg);
    430   } while (num_frames_to_process > 0);
    431 
    432   APPL_TRACE_DEBUG("Process Frames - ");
    433 }
    434 
    435 /* when true media task discards any rx frames */
    436 void btif_a2dp_sink_set_rx_flush(bool enable) {
    437   APPL_TRACE_EVENT("## DROP RX %d ##", enable);
    438   btif_a2dp_sink_cb.rx_flush = enable;
    439 }
    440 
    441 static void btif_a2dp_sink_audio_rx_flush_event(void) {
    442   /* Flush all received SBC buffers (encoded) */
    443   APPL_TRACE_DEBUG("%s", __func__);
    444 
    445   fixed_queue_flush(btif_a2dp_sink_cb.rx_audio_queue, osi_free);
    446 }
    447 
    448 static void btif_a2dp_sink_decoder_update_event(
    449     tBTIF_MEDIA_SINK_DECODER_UPDATE* p_buf) {
    450   OI_STATUS status;
    451 
    452   APPL_TRACE_DEBUG("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__,
    453                    p_buf->codec_info[1], p_buf->codec_info[2],
    454                    p_buf->codec_info[3], p_buf->codec_info[4],
    455                    p_buf->codec_info[5], p_buf->codec_info[6]);
    456 
    457   int sample_rate = A2DP_GetTrackSampleRate(p_buf->codec_info);
    458   if (sample_rate == -1) {
    459     APPL_TRACE_ERROR("%s: cannot get the track frequency", __func__);
    460     return;
    461   }
    462   int channel_count = A2DP_GetTrackChannelCount(p_buf->codec_info);
    463   if (channel_count == -1) {
    464     APPL_TRACE_ERROR("%s: cannot get the channel count", __func__);
    465     return;
    466   }
    467   int channel_type = A2DP_GetSinkTrackChannelType(p_buf->codec_info);
    468   if (channel_type == -1) {
    469     APPL_TRACE_ERROR("%s: cannot get the Sink channel type", __func__);
    470     return;
    471   }
    472   btif_a2dp_sink_cb.sample_rate = sample_rate;
    473   btif_a2dp_sink_cb.channel_count = channel_count;
    474 
    475   btif_a2dp_sink_cb.rx_flush = false;
    476   APPL_TRACE_DEBUG("%s: Reset to Sink role", __func__);
    477   status = OI_CODEC_SBC_DecoderReset(
    478       &btif_a2dp_sink_context, btif_a2dp_sink_context_data,
    479       sizeof(btif_a2dp_sink_context_data), 2, 2, false);
    480   if (!OI_SUCCESS(status)) {
    481     APPL_TRACE_ERROR("%s: OI_CODEC_SBC_DecoderReset failed with error code %d",
    482                      __func__, status);
    483   }
    484 
    485   APPL_TRACE_DEBUG("%s: A2dpSink: SBC create track", __func__);
    486   btif_a2dp_sink_cb.audio_track =
    487 #ifndef OS_GENERIC
    488       BtifAvrcpAudioTrackCreate(sample_rate, channel_type);
    489 #else
    490       NULL;
    491 #endif
    492   if (btif_a2dp_sink_cb.audio_track == NULL) {
    493     APPL_TRACE_ERROR("%s: A2dpSink: Track creation failed", __func__);
    494     return;
    495   }
    496 
    497   btif_a2dp_sink_cb.frames_to_process = A2DP_GetSinkFramesCountToProcess(
    498       BTIF_SINK_MEDIA_TIME_TICK_MS, p_buf->codec_info);
    499   APPL_TRACE_DEBUG("%s: Frames to be processed in 20 ms %d", __func__,
    500                    btif_a2dp_sink_cb.frames_to_process);
    501   if (btif_a2dp_sink_cb.frames_to_process == 0) {
    502     APPL_TRACE_ERROR("%s: Cannot compute the number of frames to process",
    503                      __func__);
    504   }
    505 }
    506 
    507 uint8_t btif_a2dp_sink_enqueue_buf(BT_HDR* p_pkt) {
    508   if (btif_a2dp_sink_cb.rx_flush) /* Flush enabled, do not enqueue */
    509     return fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue);
    510 
    511   if (fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue) ==
    512       MAX_INPUT_A2DP_FRAME_QUEUE_SZ) {
    513     uint8_t ret = fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue);
    514     osi_free(fixed_queue_try_dequeue(btif_a2dp_sink_cb.rx_audio_queue));
    515     return ret;
    516   }
    517 
    518   BTIF_TRACE_VERBOSE("%s +", __func__);
    519   /* Allocate and queue this buffer */
    520   tBT_SBC_HDR* p_msg = reinterpret_cast<tBT_SBC_HDR*>(
    521       osi_malloc(sizeof(tBT_SBC_HDR) + p_pkt->offset + p_pkt->len));
    522   memcpy((uint8_t*)(p_msg + 1), (uint8_t*)(p_pkt + 1) + p_pkt->offset,
    523          p_pkt->len);
    524   p_msg->num_frames_to_be_processed =
    525       (*((uint8_t*)(p_pkt + 1) + p_pkt->offset)) & 0x0f;
    526   p_msg->len = p_pkt->len;
    527   p_msg->offset = 0;
    528   p_msg->layer_specific = p_pkt->layer_specific;
    529   BTIF_TRACE_VERBOSE("%s: frames to process %d, len %d", __func__,
    530                      p_msg->num_frames_to_be_processed, p_msg->len);
    531   fixed_queue_enqueue(btif_a2dp_sink_cb.rx_audio_queue, p_msg);
    532   if (fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue) ==
    533       MAX_A2DP_DELAYED_START_FRAME_COUNT) {
    534     BTIF_TRACE_DEBUG("%s: Initiate decoding", __func__);
    535     btif_a2dp_sink_audio_handle_start_decoding();
    536   }
    537 
    538   return fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue);
    539 }
    540 
    541 void btif_a2dp_sink_audio_rx_flush_req(void) {
    542   if (fixed_queue_is_empty(btif_a2dp_sink_cb.rx_audio_queue)) {
    543     /* Queue is already empty */
    544     return;
    545   }
    546 
    547   BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR)));
    548   p_buf->event = BTIF_MEDIA_SINK_AUDIO_RX_FLUSH;
    549   fixed_queue_enqueue(btif_a2dp_sink_cb.cmd_msg_queue, p_buf);
    550 }
    551 
    552 void btif_a2dp_sink_debug_dump(UNUSED_ATTR int fd) {
    553   // Nothing to do
    554 }
    555 
    556 void btif_a2dp_sink_set_focus_state_req(btif_a2dp_sink_focus_state_t state) {
    557   tBTIF_MEDIA_SINK_FOCUS_UPDATE* p_buf =
    558       reinterpret_cast<tBTIF_MEDIA_SINK_FOCUS_UPDATE*>(
    559           osi_malloc(sizeof(tBTIF_MEDIA_SINK_FOCUS_UPDATE)));
    560 
    561   APPL_TRACE_EVENT("%s", __func__);
    562 
    563   p_buf->focus_state = state;
    564   p_buf->hdr.event = BTIF_MEDIA_SINK_SET_FOCUS_STATE;
    565   fixed_queue_enqueue(btif_a2dp_sink_cb.cmd_msg_queue, p_buf);
    566 }
    567 
    568 static void btif_a2dp_sink_set_focus_state_event(
    569     btif_a2dp_sink_focus_state_t state) {
    570   if (!btif_av_is_connected()) return;
    571   APPL_TRACE_DEBUG("%s: setting focus state to %d", __func__, state);
    572   btif_a2dp_sink_cb.rx_focus_state = state;
    573   if (btif_a2dp_sink_cb.rx_focus_state == BTIF_A2DP_SINK_FOCUS_NOT_GRANTED) {
    574     fixed_queue_flush(btif_a2dp_sink_cb.rx_audio_queue, osi_free);
    575     btif_a2dp_sink_cb.rx_flush = true;
    576   } else if (btif_a2dp_sink_cb.rx_focus_state == BTIF_A2DP_SINK_FOCUS_GRANTED) {
    577     btif_a2dp_sink_cb.rx_flush = false;
    578   }
    579 }
    580 
    581 void btif_a2dp_sink_set_audio_track_gain(float gain) {
    582   APPL_TRACE_DEBUG("%s set gain to %f", __func__, gain);
    583 #ifndef OS_GENERIC
    584   BtifAvrcpSetAudioTrackGain(btif_a2dp_sink_cb.audio_track, gain);
    585 #endif
    586 }
    587 
    588 static void btif_a2dp_sink_clear_track_event_req(void) {
    589   BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR)));
    590 
    591   p_buf->event = BTIF_MEDIA_SINK_CLEAR_TRACK;
    592   fixed_queue_enqueue(btif_a2dp_sink_cb.cmd_msg_queue, p_buf);
    593 }
    594