]> granicus.if.org Git - esp-idf/blob - components/bt/bluedroid/btif/btif_media_task.c
component/bt: A2DP code original in example project moved to component/bt directory;
[esp-idf] / components / bt / bluedroid / btif / btif_media_task.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2009-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18
19 /******************************************************************************
20  **
21  **  Name:          btif_media_task.c
22  **
23  **  Description:   This is the multimedia module for the BTIF system.  It
24  **                 contains task implementations AV, HS and HF profiles
25  **                 audio & video processing
26  **
27  ******************************************************************************/
28
29 #define LOG_TAG "bt_btif_media"
30
31 #include "bt_trace.h"
32 #include <string.h>
33 #include <stdio.h>
34 #include <stdint.h>
35
36 #include "bt_target.h"
37 #include "fixed_queue.h"
38 #include "gki.h"
39 #include "bta_api.h"
40 #include "btu.h"
41 #include "bta_sys.h"
42 #include "bta_sys_int.h"
43
44 #include "bta_av_api.h"
45 #include "a2d_api.h"
46 #include "a2d_sbc.h"
47 #include "a2d_int.h"
48 #include "bta_av_sbc.h"
49 #include "bta_av_ci.h"
50 #include "l2c_api.h"
51
52 #include "btif_av_co.h"
53 #include "btif_media.h"
54
55 #include "alarm.h"
56 #include "bt_trace.h"
57 #include "thread.h"
58
59 #include "bt_defs.h"
60 #include "btif_av.h"
61 #include "btif_sm.h"
62 #include "btif_util.h"
63 #if (BTA_AV_SINK_INCLUDED == TRUE)
64 #include "oi_codec_sbc.h"
65 #include "oi_status.h"
66 #endif
67 #include "stdio.h"
68
69 #include "btif_media.h"
70 #include "allocator.h"
71 #include "bt_utils.h"
72 #include "esp_a2dp_api.h"
73
74 #if (BTA_AV_SINK_INCLUDED == TRUE)
75 OI_CODEC_SBC_DECODER_CONTEXT context;
76 OI_UINT32 contextData[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
77 OI_INT16 pcmData[15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS];
78 #endif
79
80
81 /*****************************************************************************
82  **  Constants
83  *****************************************************************************/
84
85 #ifndef AUDIO_CHANNEL_OUT_MONO
86 #define AUDIO_CHANNEL_OUT_MONO 0x01
87 #endif
88
89 #ifndef AUDIO_CHANNEL_OUT_STEREO
90 #define AUDIO_CHANNEL_OUT_STEREO 0x03
91 #endif
92
93 /* BTIF media cmd event definition : BTIF_MEDIA_TASK_CMD */
94 enum {
95     BTIF_MEDIA_START_AA_TX = 1,
96     BTIF_MEDIA_STOP_AA_TX,
97     BTIF_MEDIA_AA_RX_RDY,
98     BTIF_MEDIA_UIPC_RX_RDY,
99     BTIF_MEDIA_SBC_ENC_INIT,
100     BTIF_MEDIA_SBC_ENC_UPDATE,
101     BTIF_MEDIA_SBC_DEC_INIT,
102     BTIF_MEDIA_VIDEO_DEC_INIT,
103     BTIF_MEDIA_FLUSH_AA_TX,
104     BTIF_MEDIA_FLUSH_AA_RX,
105     BTIF_MEDIA_AUDIO_FEEDING_INIT,
106     BTIF_MEDIA_AUDIO_RECEIVING_INIT,
107     BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE,
108     BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK
109 };
110
111 enum {
112     MEDIA_TASK_STATE_OFF = 0,
113     MEDIA_TASK_STATE_ON = 1,
114     MEDIA_TASK_STATE_SHUTTING_DOWN = 2
115 };
116
117 enum {
118     SIG_MEDIA_TASK_INIT = 0xf0,
119     SIG_MEDIA_TASK_CLEAN_UP = 0xf1,
120     SIG_MEDIA_TASK_AVK_ALARM_TO = 0xf2,
121     SIG_MEDIA_TASK_AA_ALARM_TO = 0xf3,
122     SIG_MEDIA_TASK_CMD_READY = 0xf4
123 };
124
125 /* Macro to multiply the media task tick */
126 #ifndef BTIF_MEDIA_NUM_TICK
127 #define BTIF_MEDIA_NUM_TICK      1
128 #endif
129
130 /* Media task tick in milliseconds, must be set to multiple of
131    (1000/TICKS_PER_SEC) (10) */
132
133 #define BTIF_MEDIA_TIME_TICK                     (20 * BTIF_MEDIA_NUM_TICK)
134 #define A2DP_DATA_READ_POLL_MS    (BTIF_MEDIA_TIME_TICK / 2)
135 #define BTIF_SINK_MEDIA_TIME_TICK                (20 * BTIF_MEDIA_NUM_TICK)
136
137
138 /* buffer pool */
139 #define BTIF_MEDIA_AA_POOL_ID GKI_POOL_ID_3
140 #define BTIF_MEDIA_AA_BUF_SIZE GKI_BUF3_SIZE
141
142 /* offset */
143 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
144 #define BTIF_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE + 1)
145 #else
146 #define BTIF_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE)
147 #endif
148
149 /* Define the bitrate step when trying to match bitpool value */
150 #ifndef BTIF_MEDIA_BITRATE_STEP
151 #define BTIF_MEDIA_BITRATE_STEP 5
152 #endif
153
154 /* Middle quality quality setting @ 44.1 khz */
155 #define DEFAULT_SBC_BITRATE 328
156
157 #ifndef BTIF_A2DP_NON_EDR_MAX_RATE
158 #define BTIF_A2DP_NON_EDR_MAX_RATE 229
159 #endif
160
161 #define USEC_PER_SEC 1000000L
162 #define TPUT_STATS_INTERVAL_US (3000*1000)
163
164 /*
165  * CONGESTION COMPENSATION CTRL ::
166  *
167  * Thus setting controls how many buffers we will hold in media task
168  * during temp link congestion. Together with the stack buffer queues
169  * it controls much temporary a2dp link congestion we can
170  * compensate for. It however also depends on the default run level of sinks
171  * jitterbuffers. Depending on type of sink this would vary.
172  * Ideally the (SRC) max tx buffer capacity should equal the sinks
173  * jitterbuffer runlevel including any intermediate buffers on the way
174  * towards the sinks codec.
175  */
176
177 /* fixme -- define this in pcm time instead of buffer count */
178
179 /* The typical runlevel of the tx queue size is ~1 buffer
180    but due to link flow control or thread preemption in lower
181    layers we might need to temporarily buffer up data */
182
183 /* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
184 #define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 18
185
186 #ifndef MAX_PCM_FRAME_NUM_PER_TICK
187 #define MAX_PCM_FRAME_NUM_PER_TICK     14
188 #endif
189
190 /* In case of A2DP SINK, we will delay start by 5 AVDTP Packets*/
191 #define MAX_A2DP_DELAYED_START_FRAME_COUNT 5
192 #define PACKET_PLAYED_PER_TICK_48 8
193 #define PACKET_PLAYED_PER_TICK_44 7
194 #define PACKET_PLAYED_PER_TICK_32 5
195 #define PACKET_PLAYED_PER_TICK_16 3
196
197 typedef struct {
198     UINT16 num_frames_to_be_processed;
199     UINT16 len;
200     UINT16 offset;
201     UINT16 layer_specific;
202 } tBT_SBC_HDR;
203
204 typedef struct {
205     UINT32 aa_frame_counter;
206     INT32  aa_feed_counter;
207     INT32  aa_feed_residue;
208     UINT32 counter;
209     UINT32 bytes_per_tick;  /* pcm bytes read each media task tick */
210 } tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE;
211
212 typedef union {
213     tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE pcm;
214 } tBTIF_AV_MEDIA_FEEDINGS_STATE;
215
216 typedef struct {
217 #if (BTA_AV_INCLUDED == TRUE)
218     BUFFER_Q RxSbcQ;
219     BOOLEAN is_tx_timer;
220     BOOLEAN is_rx_timer;
221     UINT8 busy_level;
222     void *av_sm_hdl;
223     UINT8 a2dp_cmd_pending; /* we can have max one command pending */
224     BOOLEAN rx_flush; /* discards any incoming data when true */
225     UINT8 peer_sep;
226     BOOLEAN data_channel_open;
227     UINT8   frames_to_process;
228
229     UINT32  sample_rate;
230     UINT8   channel_count;
231     osi_alarm_t *decode_alarm;
232 #endif
233
234 } tBTIF_MEDIA_CB;
235
236 typedef struct {
237     long long rx;
238     long long rx_tot;
239     long long tx;
240     long long tx_tot;
241     long long ts_prev_us;
242 } t_stat;
243
244 #if (BTA_AV_SINK_INCLUDED == TRUE)
245 extern OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
246         const OI_BYTE **frameData,
247         unsigned long *frameBytes,
248         OI_INT16 *pcmData,
249         unsigned long *pcmBytes);
250 extern OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
251         unsigned long *decoderData,
252         unsigned long decoderDataBytes,
253         OI_UINT8 maxChannels,
254         OI_UINT8 pcmStride,
255         OI_BOOL enhanced);
256 #endif
257 static void btif_media_flush_q(BUFFER_Q *p_q);
258 static void btif_media_task_aa_handle_stop_decoding(void );
259 static void btif_media_task_aa_rx_flush(void);
260
261 static const char *dump_media_event(UINT16 event);
262 static void btif_media_thread_handle_cmd(fixed_queue_t *queue);
263
264 /* Handle incoming media packets A2DP SINK streaming*/
265 #if (BTA_AV_SINK_INCLUDED == TRUE)
266 static void btif_media_task_handle_inc_media(tBT_SBC_HDR *p_msg);
267 #endif
268
269 #if (BTA_AV_INCLUDED == TRUE)
270 #if (BTA_AV_SINK_INCLUDED == TRUE)
271 static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg);
272 static void btif_media_task_aa_handle_clear_track(void);
273 #endif
274 static void btif_media_task_aa_handle_start_decoding(void);
275 #endif
276 BOOLEAN btif_media_task_clear_track(void);
277 static void btif_media_task_handler(void *arg);
278
279 static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context);
280 static void btif_media_thread_init(UNUSED_ATTR void *context);
281 static void btif_media_thread_cleanup(UNUSED_ATTR void *context);
282 extern BOOLEAN btif_hf_is_call_idle();
283
284 static tBTIF_MEDIA_CB btif_media_cb;
285 static int media_task_running = MEDIA_TASK_STATE_OFF;
286
287 static fixed_queue_t *btif_media_cmd_msg_queue = NULL;
288 static xTaskHandle  xBtifMediaTaskHandle = NULL;
289 static QueueHandle_t xBtifMediaQueue = NULL;
290
291 static esp_a2d_data_cb_t bt_av_sink_data_callback = NULL;
292
293 esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t cb)
294 {
295     // TODO: need protection against race
296     bt_av_sink_data_callback = cb;
297 }
298
299 // TODO: need protection against race
300 #define BTIF_A2D_DATA_CB_TO_APP(data, len)    do { \
301         if (bt_av_sink_data_callback) { \
302             bt_av_sink_data_callback(data, len); \
303         } \
304     } while (0)
305
306 /*****************************************************************************
307  **  temporary hacked functions. TODO: port these functions or remove them?
308  *****************************************************************************/
309 BOOLEAN btif_hf_is_call_idle(void)
310 {
311     return FALSE;
312 }
313
314 /*****************************************************************************
315  **  Misc helper functions
316  *****************************************************************************/
317
318 UNUSED_ATTR static const char *dump_media_event(UINT16 event)
319 {
320     switch (event) {
321         CASE_RETURN_STR(BTIF_MEDIA_START_AA_TX)
322         CASE_RETURN_STR(BTIF_MEDIA_STOP_AA_TX)
323         CASE_RETURN_STR(BTIF_MEDIA_AA_RX_RDY)
324         CASE_RETURN_STR(BTIF_MEDIA_UIPC_RX_RDY)
325         CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_INIT)
326         CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_UPDATE)
327         CASE_RETURN_STR(BTIF_MEDIA_SBC_DEC_INIT)
328         CASE_RETURN_STR(BTIF_MEDIA_VIDEO_DEC_INIT)
329         CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_TX)
330         CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_RX)
331         CASE_RETURN_STR(BTIF_MEDIA_AUDIO_FEEDING_INIT)
332         CASE_RETURN_STR(BTIF_MEDIA_AUDIO_RECEIVING_INIT)
333         CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE)
334         CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK)
335
336     default:
337         return "UNKNOWN MEDIA EVENT";
338     }
339 }
340
341 /*****************************************************************************
342  **  A2DP CTRL PATH
343  *****************************************************************************/
344 #if 0
345 // TODO: consider the necessity to add an API based on this function
346 static void btif_audiopath_detached(void)
347 {
348     APPL_TRACE_EVENT("## AUDIO PATH DETACHED ##");
349
350     /*  send stop request only if we are actively streaming and haven't received
351         a stop request. Potentially audioflinger detached abnormally */
352     if (btif_media_cb.is_tx_timer) {
353         /* post stop event and wait for audio path to stop */
354         btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
355     }
356 }
357 #endif
358
359 /*****************************************************************************
360  **  BTIF ADAPTATION
361  *****************************************************************************/
362
363 static void btif_media_task_post(uint32_t sig)
364 {
365     BtTaskEvt_t *evt = (BtTaskEvt_t *)osi_malloc(sizeof(BtTaskEvt_t));
366     if (evt == NULL) {
367         return;
368     }
369
370     evt->sig = sig;
371     evt->par = 0;
372
373     if (xQueueSend(xBtifMediaQueue, &evt, 10 / portTICK_RATE_MS) != pdTRUE) {
374         APPL_TRACE_ERROR("xBtifMediaQueue failed\n");
375     }
376 }
377
378 static void btif_media_task_handler(void *arg)
379 {
380     BtTaskEvt_t *e;
381     for (;;) {
382         if (pdTRUE == xQueueReceive(xBtifMediaQueue, &e, (portTickType)portMAX_DELAY)) {
383             // LOG_ERROR("med evt %d\n", e->sig);
384             switch (e->sig) {
385             case SIG_MEDIA_TASK_AVK_ALARM_TO:
386                 btif_media_task_avk_handle_timer(NULL);
387                 break;
388             case SIG_MEDIA_TASK_CMD_READY:
389                 fixed_queue_process(btif_media_cmd_msg_queue);
390                 break;
391             case SIG_MEDIA_TASK_INIT:
392                 btif_media_thread_init(NULL);
393                 break;
394             case SIG_MEDIA_TASK_CLEAN_UP:
395                 btif_media_thread_cleanup(NULL);
396                 break;
397             default:
398                 APPL_TRACE_ERROR("media task unhandled evt: 0x%x\n", e->sig);
399             }
400         }
401         osi_free(e);
402     }
403 }
404
405 bool btif_a2dp_start_media_task(void)
406 {
407     if (media_task_running != MEDIA_TASK_STATE_OFF) {
408         APPL_TRACE_ERROR("warning : media task already running");
409         return false;
410     }
411
412     APPL_TRACE_EVENT("## A2DP START MEDIA THREAD ##");
413
414     btif_media_cmd_msg_queue = fixed_queue_new(SIZE_MAX);
415     if (btif_media_cmd_msg_queue == NULL) {
416         goto error_exit;
417     }
418
419     xBtifMediaQueue = xQueueCreate(60, sizeof(void *));
420     if (xBtifMediaQueue == 0) {
421         goto error_exit;
422     }
423     xTaskCreate(btif_media_task_handler, "BtifMediaT\n", 2048, NULL, configMAX_PRIORITIES - 1, &xBtifMediaTaskHandle);
424     if (xBtifMediaTaskHandle == NULL) {
425         goto error_exit;
426     }
427     fixed_queue_register_dequeue(btif_media_cmd_msg_queue, btif_media_thread_handle_cmd);
428     btif_media_task_post(SIG_MEDIA_TASK_INIT);
429
430     APPL_TRACE_EVENT("## A2DP MEDIA THREAD STARTED ##\n");
431
432     return true;
433
434 error_exit:;
435     APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__);
436
437     if (xBtifMediaTaskHandle != NULL) {
438         vTaskDelete(xBtifMediaTaskHandle);
439         xBtifMediaTaskHandle = NULL;
440     }
441
442     if (xBtifMediaQueue != 0) {
443         vQueueDelete(xBtifMediaQueue);
444         xBtifMediaQueue = 0;
445     }
446     fixed_queue_free(btif_media_cmd_msg_queue, NULL);
447     btif_media_cmd_msg_queue = NULL;
448     return false;
449 }
450
451 void btif_a2dp_stop_media_task(void)
452 {
453     APPL_TRACE_EVENT("## A2DP STOP MEDIA THREAD ##\n");
454
455     // Exit thread
456     btif_media_task_post(SIG_MEDIA_TASK_CLEAN_UP);
457     // TODO: wait until CLEAN up is done, then do task delete
458     vTaskDelete(xBtifMediaTaskHandle);
459     xBtifMediaTaskHandle = NULL;
460     vQueueDelete(xBtifMediaQueue);
461     xBtifMediaQueue = NULL;
462
463     fixed_queue_free(btif_media_cmd_msg_queue, NULL);
464     btif_media_cmd_msg_queue = NULL;
465 }
466
467 /*****************************************************************************
468 **
469 ** Function        btif_a2dp_on_init
470 **
471 ** Description
472 **
473 ** Returns
474 **
475 *******************************************************************************/
476
477 void btif_a2dp_on_init(void)
478 {
479     //tput_mon(1, 0, 1);
480 }
481
482
483 /*****************************************************************************
484 **
485 ** Function        btif_a2dp_setup_codec
486 **
487 ** Description
488 **
489 ** Returns
490 **
491 *******************************************************************************/
492
493 void btif_a2dp_setup_codec(void)
494 {
495     tBTIF_AV_MEDIA_FEEDINGS media_feeding;
496     tBTIF_STATUS status;
497
498     APPL_TRACE_EVENT("## A2DP SETUP CODEC ##\n");
499
500     GKI_disable();
501
502     /* for now hardcode 44.1 khz 16 bit stereo PCM format */
503     media_feeding.cfg.pcm.sampling_freq = 44100;
504     media_feeding.cfg.pcm.bit_per_sample = 16;
505     media_feeding.cfg.pcm.num_channel = 2;
506     media_feeding.format = BTIF_AV_CODEC_PCM;
507
508     bta_av_co_audio_set_codec(&media_feeding, &status);
509
510     GKI_enable();
511 }
512
513
514 /*****************************************************************************
515 **
516 ** Function        btif_a2dp_on_idle
517 **
518 ** Description
519 **
520 ** Returns
521 **
522 *******************************************************************************/
523
524 void btif_a2dp_on_idle(void)
525 {
526     APPL_TRACE_EVENT("## ON A2DP IDLE ##\n");
527
528     bta_av_co_init();
529 #if (BTA_AV_SINK_INCLUDED == TRUE)
530     if (btif_media_cb.peer_sep == AVDT_TSEP_SRC) {
531         btif_media_cb.rx_flush = TRUE;
532         btif_media_task_aa_rx_flush_req();
533         btif_media_task_aa_handle_stop_decoding();
534         btif_media_task_clear_track();
535         APPL_TRACE_DEBUG("Stopped BT track");
536     }
537 #endif
538 }
539
540 /*******************************************************************************
541  **
542  ** Function         btif_media_task_clear_track
543  **
544  ** Description
545  **
546  ** Returns          TRUE is success
547  **
548  *******************************************************************************/
549 BOOLEAN btif_media_task_clear_track(void)
550 {
551     BT_HDR *p_buf;
552
553     if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR)))) {
554         return FALSE;
555     }
556
557     p_buf->event = BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK;
558
559     fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
560     btif_media_task_post(SIG_MEDIA_TASK_CMD_READY);
561     return TRUE;
562 }
563
564 /*****************************************************************************
565 **
566 ** Function        btif_reset_decoder
567 **
568 ** Description
569 **
570 ** Returns
571 **
572 *******************************************************************************/
573
574 void btif_reset_decoder(UINT8 *p_av)
575 {
576     APPL_TRACE_EVENT("btif_reset_decoder");
577     APPL_TRACE_DEBUG("btif_reset_decoder p_codec_info[%x:%x:%x:%x:%x:%x]\n",
578             p_av[1], p_av[2], p_av[3],
579             p_av[4], p_av[5], p_av[6]);
580
581     tBTIF_MEDIA_SINK_CFG_UPDATE *p_buf;
582     if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_SINK_CFG_UPDATE)))) {
583         APPL_TRACE_ERROR("btif_reset_decoder No Buffer ");
584         return;
585     }
586
587     memcpy(p_buf->codec_info, p_av, AVDT_CODEC_SIZE);
588     p_buf->hdr.event = BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE;
589
590     fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
591     btif_media_task_post(SIG_MEDIA_TASK_CMD_READY);
592 }
593
594 /*****************************************************************************
595 **
596 ** Function        btif_a2dp_on_stopped
597 **
598 ** Description
599 **
600 ** Returns
601 **
602 *******************************************************************************/
603
604 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av)
605 {
606     APPL_TRACE_EVENT("## ON A2DP STOPPED ##\n");
607     if (btif_media_cb.peer_sep == AVDT_TSEP_SRC) { /*  Handling for A2DP SINK cases*/
608         btif_media_cb.rx_flush = TRUE;
609         btif_media_task_aa_rx_flush_req();
610         btif_media_task_aa_handle_stop_decoding();
611         btif_media_cb.data_channel_open = FALSE;
612         return;
613     }
614 }
615
616
617 /*****************************************************************************
618 **
619 ** Function        btif_a2dp_on_suspended
620 **
621 ** Description
622 **
623 ** Returns
624 **
625 *******************************************************************************/
626
627 void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av)
628 {
629     APPL_TRACE_EVENT("## ON A2DP SUSPENDED ##\n");
630     if (btif_media_cb.peer_sep == AVDT_TSEP_SRC) {
631         btif_media_cb.rx_flush = TRUE;
632         btif_media_task_aa_rx_flush_req();
633         btif_media_task_aa_handle_stop_decoding();
634         return;
635     }
636 }
637
638 /* when true media task discards any rx frames */
639 void btif_a2dp_set_rx_flush(BOOLEAN enable)
640 {
641     APPL_TRACE_EVENT("## DROP RX %d ##\n", enable);
642     btif_media_cb.rx_flush = enable;
643 }
644
645 #if (BTA_AV_SINK_INCLUDED == TRUE)
646 static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context)
647 {
648     UINT8 count;
649     tBT_SBC_HDR *p_msg;
650     int num_sbc_frames;
651     int num_frames_to_process;
652
653     count = btif_media_cb.RxSbcQ._count;
654     if (0 == count) {
655         APPL_TRACE_DEBUG("  QUE  EMPTY ");
656     } else {
657         if (btif_media_cb.rx_flush == TRUE) {
658             btif_media_flush_q(&(btif_media_cb.RxSbcQ));
659             return;
660         }
661
662         num_frames_to_process = btif_media_cb.frames_to_process;
663         APPL_TRACE_DEBUG(" Process Frames + ");
664         do {
665             p_msg = (tBT_SBC_HDR *)GKI_getfirst(&(btif_media_cb.RxSbcQ));
666             if (p_msg == NULL) {
667                 return;
668             }
669             num_sbc_frames  = p_msg->num_frames_to_be_processed; /* num of frames in Que Packets */
670             APPL_TRACE_DEBUG(" Frames left in topmost packet %d\n", num_sbc_frames);
671             APPL_TRACE_DEBUG(" Remaining frames to process in tick %d\n", num_frames_to_process);
672             APPL_TRACE_DEBUG(" Num of Packets in Que %d\n", btif_media_cb.RxSbcQ._count);
673
674             if ( num_sbc_frames > num_frames_to_process) { /*  Que Packet has more frames*/
675                 p_msg->num_frames_to_be_processed = num_frames_to_process;
676                 btif_media_task_handle_inc_media(p_msg);
677                 p_msg->num_frames_to_be_processed = num_sbc_frames - num_frames_to_process;
678                 num_frames_to_process = 0;
679                 break;
680             } else {                                    /*  Que packet has less frames */
681                 btif_media_task_handle_inc_media(p_msg);
682                 p_msg = (tBT_SBC_HDR *)GKI_dequeue(&(btif_media_cb.RxSbcQ));
683                 if ( p_msg == NULL ) {
684                     APPL_TRACE_ERROR("Insufficient data in que ");
685                     break;
686                 }
687                 num_frames_to_process = num_frames_to_process - p_msg->num_frames_to_be_processed;
688                 GKI_freebuf(p_msg);
689             }
690         } while (num_frames_to_process > 0);
691
692         APPL_TRACE_DEBUG(" Process Frames - ");
693     }
694 }
695 #else
696 static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context) {}
697 #endif
698
699 static void btif_media_thread_init(UNUSED_ATTR void *context)
700 {
701     memset(&btif_media_cb, 0, sizeof(btif_media_cb));
702     LOG_ERROR("med thread init\n");
703 #if (UIPC_INCLUDED == TRUE)
704     UIPC_Init(NULL);
705     
706 #if (BTA_AV_INCLUDED == TRUE)
707     UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
708 #endif ( BTA_AV_INCLUDED == TRUE)
709 #endif /* UIPC_INCLUDED == TRUE */
710     btif_media_cb.av_sm_hdl = btif_av_get_sm_handle();
711     raise_priority_a2dp(TASK_HIGH_MEDIA);
712     media_task_running = MEDIA_TASK_STATE_ON;
713 }
714
715 static void btif_media_thread_cleanup(UNUSED_ATTR void *context)
716 {
717     /* make sure no channels are restarted while shutting down */
718     media_task_running = MEDIA_TASK_STATE_SHUTTING_DOWN;
719
720     btif_media_cb.data_channel_open = FALSE;
721     /* Clear media task flag */
722     media_task_running = MEDIA_TASK_STATE_OFF;
723 }
724
725 /*******************************************************************************
726  **
727  ** Function         btif_media_flush_q
728  **
729  ** Description
730  **
731  ** Returns          void
732  **
733  *******************************************************************************/
734 static void btif_media_flush_q(BUFFER_Q *p_q)
735 {
736     while (!GKI_queue_is_empty(p_q)) {
737         GKI_freebuf(GKI_dequeue(p_q));
738     }
739 }
740
741 static void btif_media_thread_handle_cmd(fixed_queue_t *queue)
742 {
743     BT_HDR *p_msg;
744     while (!fixed_queue_is_empty(queue)) {
745         p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
746         LOG_VERBOSE("btif_media_thread_handle_cmd : %d %s\n", p_msg->event,
747                     dump_media_event(p_msg->event));
748
749         switch (p_msg->event) {
750 #if (BTA_AV_INCLUDED == TRUE)
751         case BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE:
752 #if (BTA_AV_SINK_INCLUDED == TRUE)
753             btif_media_task_aa_handle_decoder_reset(p_msg);
754 #endif
755             break;
756         case BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK:
757 #if (BTA_AV_SINK_INCLUDED == TRUE)
758             btif_media_task_aa_handle_clear_track();
759 #endif
760             break;
761         case BTIF_MEDIA_FLUSH_AA_RX:
762             btif_media_task_aa_rx_flush();
763             break;
764 #endif
765         default:
766             APPL_TRACE_ERROR("ERROR in %s unknown event %d\n", __func__, p_msg->event);
767         }
768         GKI_freebuf(p_msg);
769         LOG_VERBOSE("%s: %s DONE\n", __func__, dump_media_event(p_msg->event));
770     }
771 }
772
773
774 #if (BTA_AV_SINK_INCLUDED == TRUE)
775 /*******************************************************************************
776  **
777  ** Function         btif_media_task_handle_inc_media
778  **
779  ** Description
780  **
781  ** Returns          void
782  **
783  *******************************************************************************/
784 static void btif_media_task_handle_inc_media(tBT_SBC_HDR *p_msg)
785 {
786     UINT8 *sbc_start_frame = ((UINT8 *)(p_msg + 1) + p_msg->offset + 1);
787     int count;
788     UINT32 pcmBytes, availPcmBytes;
789     OI_INT16 *pcmDataPointer = pcmData; /*Will be overwritten on next packet receipt*/
790     OI_STATUS status;
791     int num_sbc_frames = p_msg->num_frames_to_be_processed;
792     UINT32 sbc_frame_len = p_msg->len - 1;
793     availPcmBytes = 2 * sizeof(pcmData);
794
795     if ((btif_media_cb.peer_sep == AVDT_TSEP_SNK) || (btif_media_cb.rx_flush)) {
796         APPL_TRACE_DEBUG(" State Changed happened in this tick ");
797         return;
798     }
799
800     // ignore data if no one is listening
801     if (!btif_media_cb.data_channel_open) {
802         return;
803     }
804
805     APPL_TRACE_DEBUG("Number of sbc frames %d, frame_len %d\n", num_sbc_frames, sbc_frame_len);
806     // LOG_ERROR("Number of sbc frames %d, frame_len %d\n", num_sbc_frames, sbc_frame_len);
807     for (count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++) {
808         pcmBytes = availPcmBytes;
809         status = OI_CODEC_SBC_DecodeFrame(&context, (const OI_BYTE **)&sbc_start_frame,
810                                           (OI_UINT32 *)&sbc_frame_len,
811                                           (OI_INT16 *)pcmDataPointer,
812                                           (OI_UINT32 *)&pcmBytes);
813         if (!OI_SUCCESS(status)) {
814             APPL_TRACE_ERROR("Decoding failure: %d\n", status);
815             break;
816         }
817         availPcmBytes -= pcmBytes;
818         pcmDataPointer += pcmBytes / 2;
819         p_msg->offset += (p_msg->len - 1) - sbc_frame_len;
820         p_msg->len = sbc_frame_len + 1;
821     }
822     // LOG_ERROR("pre-send: %d\n", availPcmBytes);
823
824     // UIPC_Send(UIPC_CH_ID_AV_AUDIO, 0, (UINT8 *)pcmData, (2 * sizeof(pcmData) - availPcmBytes));
825     BTIF_A2D_DATA_CB_TO_APP((uint8_t *)pcmData, (2 * sizeof(pcmData) - availPcmBytes));
826
827 }
828 #endif
829
830 #if (BTA_AV_INCLUDED == TRUE)
831
832 /*******************************************************************************
833  **
834  ** Function         btif_media_task_aa_rx_flush_req
835  **
836  ** Description
837  **
838  ** Returns          TRUE is success
839  **
840  *******************************************************************************/
841 BOOLEAN btif_media_task_aa_rx_flush_req(void)
842 {
843     BT_HDR *p_buf;
844
845     if (GKI_queue_is_empty(&(btif_media_cb.RxSbcQ)) == TRUE) { /*  Que is already empty */
846         return TRUE;
847     }
848
849     if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR)))) {
850         return FALSE;
851     }
852
853     p_buf->event = BTIF_MEDIA_FLUSH_AA_RX;
854
855     fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
856     btif_media_task_post(SIG_MEDIA_TASK_CMD_READY);
857     return TRUE;
858 }
859
860 /*******************************************************************************
861  **
862  ** Function         btif_media_task_aa_rx_flush
863  **
864  ** Description
865  **
866  ** Returns          void
867  **
868  *******************************************************************************/
869 static void btif_media_task_aa_rx_flush(void)
870 {
871     /* Flush all enqueued GKI SBC  buffers (encoded) */
872     APPL_TRACE_DEBUG("btif_media_task_aa_rx_flush");
873
874     btif_media_flush_q(&(btif_media_cb.RxSbcQ));
875 }
876
877 int btif_a2dp_get_track_frequency(UINT8 frequency)
878 {
879     int freq = 48000;
880     switch (frequency) {
881     case A2D_SBC_IE_SAMP_FREQ_16:
882         freq = 16000;
883         break;
884     case A2D_SBC_IE_SAMP_FREQ_32:
885         freq = 32000;
886         break;
887     case A2D_SBC_IE_SAMP_FREQ_44:
888         freq = 44100;
889         break;
890     case A2D_SBC_IE_SAMP_FREQ_48:
891         freq = 48000;
892         break;
893     }
894     return freq;
895 }
896
897 int btif_a2dp_get_track_channel_count(UINT8 channeltype)
898 {
899     int count = 1;
900     switch (channeltype) {
901     case A2D_SBC_IE_CH_MD_MONO:
902         count = 1;
903         break;
904     case A2D_SBC_IE_CH_MD_DUAL:
905     case A2D_SBC_IE_CH_MD_STEREO:
906     case A2D_SBC_IE_CH_MD_JOINT:
907         count = 2;
908         break;
909     }
910     return count;
911 }
912
913 void btif_a2dp_set_peer_sep(UINT8 sep)
914 {
915     btif_media_cb.peer_sep = sep;
916 }
917
918 static void btif_decode_alarm_cb(UNUSED_ATTR void *context)
919 {
920     btif_media_task_post(SIG_MEDIA_TASK_AVK_ALARM_TO);
921 }
922
923 static void btif_media_task_aa_handle_stop_decoding(void)
924 {
925     osi_alarm_free(btif_media_cb.decode_alarm);
926     btif_media_cb.decode_alarm = NULL;
927 }
928
929 static void btif_media_task_aa_handle_start_decoding(void)
930 {
931     if (btif_media_cb.decode_alarm) {
932         return;
933     }
934
935     btif_media_cb.decode_alarm = osi_alarm_new("dec_timer\n", btif_decode_alarm_cb, NULL, BTIF_SINK_MEDIA_TIME_TICK, true);
936     if (!btif_media_cb.decode_alarm) {
937         APPL_TRACE_ERROR("%s unable to allocate decode alarm.\n", __func__);
938         return;
939     }
940     osi_alarm_set(btif_media_cb.decode_alarm, BTIF_SINK_MEDIA_TIME_TICK);
941 }
942
943 #if (BTA_AV_SINK_INCLUDED == TRUE)
944
945 static void btif_media_task_aa_handle_clear_track (void)
946 {
947     APPL_TRACE_DEBUG("btif_media_task_aa_handle_clear_track");
948 }
949
950 /*******************************************************************************
951  **
952  ** Function         btif_media_task_aa_handle_decoder_reset
953  **
954  ** Description
955  **
956  ** Returns          void
957  **
958  *******************************************************************************/
959 static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg)
960 {
961     tBTIF_MEDIA_SINK_CFG_UPDATE *p_buf = (tBTIF_MEDIA_SINK_CFG_UPDATE *) p_msg;
962     tA2D_STATUS a2d_status;
963     tA2D_SBC_CIE sbc_cie;
964     OI_STATUS       status;
965     UINT32          freq_multiple = 48 * 20; /* frequency multiple for 20ms of data , initialize with 48K*/
966     UINT32          num_blocks = 16;
967     UINT32          num_subbands = 8;
968
969     APPL_TRACE_EVENT("btif_media_task_aa_handle_decoder_reset p_codec_info[%x:%x:%x:%x:%x:%x]\n",
970               p_buf->codec_info[1], p_buf->codec_info[2], p_buf->codec_info[3],
971               p_buf->codec_info[4], p_buf->codec_info[5], p_buf->codec_info[6]);
972
973     a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_buf->codec_info, FALSE);
974     if (a2d_status != A2D_SUCCESS) {
975         APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
976         return;
977     }
978
979     btif_media_cb.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
980     btif_media_cb.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
981
982     btif_media_cb.rx_flush = FALSE;
983     APPL_TRACE_EVENT("Reset to sink role");
984     status = OI_CODEC_SBC_DecoderReset(&context, contextData, sizeof(contextData), 2, 2, FALSE);
985     if (!OI_SUCCESS(status)) {
986         APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
987     }
988
989     btif_media_cb.data_channel_open = TRUE;
990
991     switch (sbc_cie.samp_freq) {
992     case A2D_SBC_IE_SAMP_FREQ_16:
993         APPL_TRACE_DEBUG("\tsamp_freq:%d (16000)\n", sbc_cie.samp_freq);
994         freq_multiple = 16 * 20;
995         break;
996     case A2D_SBC_IE_SAMP_FREQ_32:
997         APPL_TRACE_DEBUG("\tsamp_freq:%d (32000)\n", sbc_cie.samp_freq);
998         freq_multiple = 32 * 20;
999         break;
1000     case A2D_SBC_IE_SAMP_FREQ_44:
1001         APPL_TRACE_DEBUG("\tsamp_freq:%d (44100)\n", sbc_cie.samp_freq);
1002         freq_multiple = 441 * 2;
1003         break;
1004     case A2D_SBC_IE_SAMP_FREQ_48:
1005         APPL_TRACE_DEBUG("\tsamp_freq:%d (48000)\n", sbc_cie.samp_freq);
1006         freq_multiple = 48 * 20;
1007         break;
1008     default:
1009         APPL_TRACE_DEBUG(" Unknown Frequency ");
1010         break;
1011     }
1012
1013     switch (sbc_cie.ch_mode) {
1014     case A2D_SBC_IE_CH_MD_MONO:
1015         APPL_TRACE_DEBUG("\tch_mode:%d (Mono)\n", sbc_cie.ch_mode);
1016         break;
1017     case A2D_SBC_IE_CH_MD_DUAL:
1018         APPL_TRACE_DEBUG("\tch_mode:%d (DUAL)\n", sbc_cie.ch_mode);
1019         break;
1020     case A2D_SBC_IE_CH_MD_STEREO:
1021         APPL_TRACE_DEBUG("\tch_mode:%d (STEREO)\n", sbc_cie.ch_mode);
1022         break;
1023     case A2D_SBC_IE_CH_MD_JOINT:
1024         APPL_TRACE_DEBUG("\tch_mode:%d (JOINT)\n", sbc_cie.ch_mode);
1025         break;
1026     default:
1027         APPL_TRACE_DEBUG(" Unknown Mode ");
1028         break;
1029     }
1030
1031     switch (sbc_cie.block_len) {
1032     case A2D_SBC_IE_BLOCKS_4:
1033         APPL_TRACE_DEBUG("\tblock_len:%d (4)\n", sbc_cie.block_len);
1034         num_blocks = 4;
1035         break;
1036     case A2D_SBC_IE_BLOCKS_8:
1037         APPL_TRACE_DEBUG("\tblock_len:%d (8)\n", sbc_cie.block_len);
1038         num_blocks = 8;
1039         break;
1040     case A2D_SBC_IE_BLOCKS_12:
1041         APPL_TRACE_DEBUG("\tblock_len:%d (12)\n", sbc_cie.block_len);
1042         num_blocks = 12;
1043         break;
1044     case A2D_SBC_IE_BLOCKS_16:
1045         APPL_TRACE_DEBUG("\tblock_len:%d (16)\n", sbc_cie.block_len);
1046         num_blocks = 16;
1047         break;
1048     default:
1049         APPL_TRACE_DEBUG(" Unknown BlockLen ");
1050         break;
1051     }
1052
1053     switch (sbc_cie.num_subbands) {
1054     case A2D_SBC_IE_SUBBAND_4:
1055         APPL_TRACE_DEBUG("\tnum_subbands:%d (4)\n", sbc_cie.num_subbands);
1056         num_subbands = 4;
1057         break;
1058     case A2D_SBC_IE_SUBBAND_8:
1059         APPL_TRACE_DEBUG("\tnum_subbands:%d (8)\n", sbc_cie.num_subbands);
1060         num_subbands = 8;
1061         break;
1062     default:
1063         APPL_TRACE_DEBUG(" Unknown SubBands ");
1064         break;
1065     }
1066
1067     switch (sbc_cie.alloc_mthd) {
1068     case A2D_SBC_IE_ALLOC_MD_S:
1069         APPL_TRACE_DEBUG("\talloc_mthd:%d (SNR)\n", sbc_cie.alloc_mthd);
1070         break;
1071     case A2D_SBC_IE_ALLOC_MD_L:
1072         APPL_TRACE_DEBUG("\talloc_mthd:%d (Loudness)\n", sbc_cie.alloc_mthd);
1073         break;
1074     default:
1075         APPL_TRACE_DEBUG(" Unknown Allocation Method");
1076         break;
1077     }
1078
1079     APPL_TRACE_EVENT("\tBit pool Min:%d Max:%d\n", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
1080
1081     btif_media_cb.frames_to_process = ((freq_multiple) / (num_blocks * num_subbands)) + 1;
1082     APPL_TRACE_EVENT(" Frames to be processed in 20 ms %d\n", btif_media_cb.frames_to_process);
1083 }
1084 #endif
1085
1086 /*******************************************************************************
1087  **
1088  ** Function         btif_media_sink_enque_buf
1089  **
1090  ** Description      This function is called by the av_co to fill A2DP Sink Queue
1091  **
1092  **
1093  ** Returns          size of the queue
1094  *******************************************************************************/
1095 UINT8 btif_media_sink_enque_buf(BT_HDR *p_pkt)
1096 {
1097     tBT_SBC_HDR *p_msg;
1098
1099     if (btif_media_cb.rx_flush == TRUE) { /* Flush enabled, do not enque*/
1100         return GKI_queue_length(&btif_media_cb.RxSbcQ);
1101     }
1102     if (GKI_queue_length(&btif_media_cb.RxSbcQ) == MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ) {
1103         GKI_freebuf(GKI_dequeue(&(btif_media_cb.RxSbcQ)));
1104     }
1105
1106     BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf + ");
1107
1108     /* allocate and Queue this buffer */
1109     if ((p_msg = (tBT_SBC_HDR *) GKI_getbuf(sizeof(tBT_SBC_HDR) +
1110                                             p_pkt->offset + p_pkt->len)) != NULL) {
1111         memcpy(p_msg, p_pkt, (sizeof(BT_HDR) + p_pkt->offset + p_pkt->len));
1112         p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
1113         BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
1114         // LOG_ERROR("sink enq %d\n", p_msg->num_frames_to_be_processed);
1115         GKI_enqueue(&(btif_media_cb.RxSbcQ), p_msg);
1116         if (GKI_queue_length(&btif_media_cb.RxSbcQ) == MAX_A2DP_DELAYED_START_FRAME_COUNT) {
1117             BTIF_TRACE_DEBUG(" Initiate Decoding ");
1118             btif_media_task_aa_handle_start_decoding();
1119         }
1120     } else {
1121         /* let caller deal with a failed allocation */
1122         BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf No Buffer left - ");
1123     }
1124     return GKI_queue_length(&btif_media_cb.RxSbcQ);
1125 }
1126
1127
1128 /*******************************************************************************
1129  **
1130  ** Function         btif_media_aa_readbuf
1131  **
1132  ** Description      This function is called by the av_co to get the next buffer to send
1133  **
1134  **
1135  ** Returns          void
1136  *******************************************************************************/
1137 BT_HDR *btif_media_aa_readbuf(void)
1138 {
1139     return NULL;
1140 }
1141
1142 #endif /* BTA_AV_INCLUDED == TRUE */
1143 /*******************************************************************************
1144  **
1145  ** Function         dump_codec_info
1146  **
1147  ** Description      Decode and display codec_info (for debug)
1148  **
1149  ** Returns          void
1150  **
1151  *******************************************************************************/
1152 void dump_codec_info(unsigned char *p_codec)
1153 {
1154     tA2D_STATUS a2d_status;
1155     tA2D_SBC_CIE sbc_cie;
1156
1157     a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec, FALSE);
1158     if (a2d_status != A2D_SUCCESS) {
1159         APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
1160         return;
1161     }
1162
1163     APPL_TRACE_DEBUG("dump_codec_info");
1164
1165     if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_16) {
1166         APPL_TRACE_DEBUG("\tsamp_freq:%d (16000)\n", sbc_cie.samp_freq);
1167     } else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_32) {
1168         APPL_TRACE_DEBUG("\tsamp_freq:%d (32000)\n", sbc_cie.samp_freq);
1169     } else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_44) {
1170         APPL_TRACE_DEBUG("\tsamp_freq:%d (44.100)\n", sbc_cie.samp_freq);
1171     } else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_48) {
1172         APPL_TRACE_DEBUG("\tsamp_freq:%d (48000)\n", sbc_cie.samp_freq);
1173     } else {
1174         APPL_TRACE_DEBUG("\tBAD samp_freq:%d\n", sbc_cie.samp_freq);
1175     }
1176
1177     if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_MONO) {
1178         APPL_TRACE_DEBUG("\tch_mode:%d (Mono)\n", sbc_cie.ch_mode);
1179     } else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_DUAL) {
1180         APPL_TRACE_DEBUG("\tch_mode:%d (Dual)\n", sbc_cie.ch_mode);
1181     } else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_STEREO) {
1182         APPL_TRACE_DEBUG("\tch_mode:%d (Stereo)\n", sbc_cie.ch_mode);
1183     } else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_JOINT) {
1184         APPL_TRACE_DEBUG("\tch_mode:%d (Joint)\n", sbc_cie.ch_mode);
1185     } else {
1186         APPL_TRACE_DEBUG("\tBAD ch_mode:%d\n", sbc_cie.ch_mode);
1187     }
1188
1189     if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_4) {
1190         APPL_TRACE_DEBUG("\tblock_len:%d (4)\n", sbc_cie.block_len);
1191     } else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_8) {
1192         APPL_TRACE_DEBUG("\tblock_len:%d (8)\n", sbc_cie.block_len);
1193     } else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_12) {
1194         APPL_TRACE_DEBUG("\tblock_len:%d (12)\n", sbc_cie.block_len);
1195     } else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_16) {
1196         APPL_TRACE_DEBUG("\tblock_len:%d (16)\n", sbc_cie.block_len);
1197     } else {
1198         APPL_TRACE_DEBUG("\tBAD block_len:%d\n", sbc_cie.block_len);
1199     }
1200
1201     if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_4) {
1202         APPL_TRACE_DEBUG("\tnum_subbands:%d (4)\n", sbc_cie.num_subbands);
1203     } else  if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_8) {
1204         APPL_TRACE_DEBUG("\tnum_subbands:%d (8)\n", sbc_cie.num_subbands);
1205     } else {
1206         APPL_TRACE_DEBUG("\tBAD num_subbands:%d\n", sbc_cie.num_subbands);
1207     }
1208
1209     if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_S) {
1210         APPL_TRACE_DEBUG("\talloc_mthd:%d (SNR)\n", sbc_cie.alloc_mthd);
1211     } else  if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L) {
1212         APPL_TRACE_DEBUG("\talloc_mthd:%d (Loundess)\n", sbc_cie.alloc_mthd);
1213     } else {
1214         APPL_TRACE_DEBUG("\tBAD alloc_mthd:%d\n", sbc_cie.alloc_mthd);
1215     }
1216
1217     APPL_TRACE_DEBUG("\tBit pool Min:%d Max:%d\n", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
1218
1219 }