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
49enum {
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 */
57enum {
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
64typedef struct {
65  BT_HDR hdr;
66  uint8_t codec_info[AVDT_CODEC_SIZE];
67} tBTIF_MEDIA_SINK_DECODER_UPDATE;
68
69typedef struct {
70  BT_HDR hdr;
71  btif_a2dp_sink_focus_state_t focus_state;
72} tBTIF_MEDIA_SINK_FOCUS_UPDATE;
73
74typedef 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 */
82typedef 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
95static tBTIF_A2DP_SINK_CB btif_a2dp_sink_cb;
96
97static int btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_OFF;
98
99static OI_CODEC_SBC_DECODER_CONTEXT btif_a2dp_sink_context;
100static uint32_t btif_a2dp_sink_context_data[CODEC_DATA_WORDS(
101    2, SBC_CODEC_FAST_FILTER_BUFFERS)];
102static int16_t
103    btif_a2dp_sink_pcm_data[15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS];
104
105static void btif_a2dp_sink_startup_delayed(void* context);
106static void btif_a2dp_sink_shutdown_delayed(void* context);
107static void btif_a2dp_sink_command_ready(fixed_queue_t* queue, void* context);
108static void btif_a2dp_sink_audio_handle_stop_decoding(void);
109static void btif_decode_alarm_cb(void* context);
110static void btif_a2dp_sink_audio_handle_start_decoding(void);
111static void btif_a2dp_sink_avk_handle_timer(UNUSED_ATTR void* context);
112static void btif_a2dp_sink_audio_rx_flush_req(void);
113/* Handle incoming media packets A2DP SINK streaming */
114static void btif_a2dp_sink_handle_inc_media(tBT_SBC_HDR* p_msg);
115static void btif_a2dp_sink_decoder_update_event(
116    tBTIF_MEDIA_SINK_DECODER_UPDATE* p_buf);
117static void btif_a2dp_sink_clear_track_event(void);
118static void btif_a2dp_sink_set_focus_state_event(
119    btif_a2dp_sink_focus_state_t state);
120static void btif_a2dp_sink_audio_rx_flush_event(void);
121static void btif_a2dp_sink_clear_track_event_req(void);
122
123UNUSED_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
135bool 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
173static 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
178void 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
202static 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
209tA2DP_SAMPLE_RATE btif_a2dp_sink_get_sample_rate(void) {
210  return btif_a2dp_sink_cb.sample_rate;
211}
212
213tA2DP_CHANNEL_COUNT btif_a2dp_sink_get_channel_count(void) {
214  return btif_a2dp_sink_cb.channel_count;
215}
216
217static 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
250void 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
265void 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
273void 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
279void 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
285static 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
296static 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
303static 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
313static 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
330static 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
373static 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 */
436void 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
441static 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
448static 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
507uint8_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
541void 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
552void btif_a2dp_sink_debug_dump(UNUSED_ATTR int fd) {
553  // Nothing to do
554}
555
556void 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
568static 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
581void 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
588static 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