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