Home | History | Annotate | Download | only in src
      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 #include <string.h>
     30 #include <stdio.h>
     31 #include <sys/types.h>
     32 #include <sys/stat.h>
     33 #include <fcntl.h>
     34 #include <unistd.h>
     35 #include <pthread.h>
     36 #include <stdint.h>
     37 #include <sys/time.h>
     38 #include <errno.h>
     39 
     40 #include "bt_target.h"
     41 #include "gki.h"
     42 #include "bta_api.h"
     43 #include "btu.h"
     44 #include "bta_sys.h"
     45 #include "bta_sys_int.h"
     46 
     47 #include "bta_av_api.h"
     48 #include "a2d_api.h"
     49 #include "a2d_sbc.h"
     50 #include "a2d_int.h"
     51 #include "bta_av_sbc.h"
     52 #include "bta_av_ci.h"
     53 #include "l2c_api.h"
     54 
     55 #include "btif_av_co.h"
     56 #include "btif_media.h"
     57 
     58 #if (BTA_AV_INCLUDED == TRUE)
     59 #include "sbc_encoder.h"
     60 #endif
     61 
     62 #define LOG_TAG "BTIF-MEDIA"
     63 
     64 #include <hardware/bluetooth.h>
     65 #include "audio_a2dp_hw.h"
     66 #include "btif_av.h"
     67 #include "btif_sm.h"
     68 #include "btif_util.h"
     69 #include "bt_utils.h"
     70 
     71 /*****************************************************************************
     72  **  Constants
     73  *****************************************************************************/
     74 
     75 //#define DEBUG_MEDIA_AV_FLOW TRUE
     76 
     77 /* BTIF media task gki event definition */
     78 #define BTIF_MEDIA_TASK_CMD TASK_MBOX_0_EVT_MASK
     79 #define BTIF_MEDIA_TASK_DATA TASK_MBOX_1_EVT_MASK
     80 
     81 #define BTIF_MEDIA_TASK_KILL EVENT_MASK(GKI_SHUTDOWN_EVT)
     82 
     83 #define BTIF_MEDIA_AA_TASK_TIMER_ID TIMER_0
     84 #define BTIF_MEDIA_AV_TASK_TIMER_ID TIMER_1
     85 #define BTIF_MEDIA_AA_TASK_TIMER TIMER_0_EVT_MASK
     86 #define BTIF_MEDIA_AV_TASK_TIMER TIMER_1_EVT_MASK
     87 
     88 #define BTIF_MEDIA_TASK_CMD_MBOX        TASK_MBOX_0     /* cmd mailbox  */
     89 #define BTIF_MEDIA_TASK_DATA_MBOX       TASK_MBOX_1     /* data mailbox  */
     90 
     91 /* BTIF media cmd event definition : BTIF_MEDIA_TASK_CMD */
     92 enum
     93 {
     94     BTIF_MEDIA_START_AA_TX = 1,
     95     BTIF_MEDIA_STOP_AA_TX,
     96     BTIF_MEDIA_AA_RX_RDY,
     97     BTIF_MEDIA_UIPC_RX_RDY,
     98     BTIF_MEDIA_SBC_ENC_INIT,
     99     BTIF_MEDIA_SBC_ENC_UPDATE,
    100     BTIF_MEDIA_SBC_DEC_INIT,
    101     BTIF_MEDIA_VIDEO_DEC_INIT,
    102     BTIF_MEDIA_FLUSH_AA_TX,
    103     BTIF_MEDIA_FLUSH_AA_RX,
    104     BTIF_MEDIA_AUDIO_FEEDING_INIT,
    105     BTIF_MEDIA_AUDIO_RECEIVING_INIT
    106 };
    107 
    108 enum {
    109     MEDIA_TASK_STATE_OFF = 0,
    110     MEDIA_TASK_STATE_ON = 1,
    111     MEDIA_TASK_STATE_SHUTTING_DOWN = 2
    112 };
    113 
    114 /* Macro to multiply the media task tick */
    115 #ifndef BTIF_MEDIA_NUM_TICK
    116 #define BTIF_MEDIA_NUM_TICK      1
    117 #endif
    118 
    119 /* Media task tick in milliseconds, must be set to multiple of
    120    (1000/TICKS_PER_SEC) (10) */
    121 
    122 #define BTIF_MEDIA_TIME_TICK                     (20 * BTIF_MEDIA_NUM_TICK)
    123 
    124 /* buffer pool */
    125 #define BTIF_MEDIA_AA_POOL_ID GKI_POOL_ID_3
    126 #define BTIF_MEDIA_AA_BUF_SIZE GKI_BUF3_SIZE
    127 
    128 /* offset */
    129 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
    130 #define BTIF_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE + 1)
    131 #else
    132 #define BTIF_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE)
    133 #endif
    134 
    135 /* Define the bitrate step when trying to match bitpool value */
    136 #ifndef BTIF_MEDIA_BITRATE_STEP
    137 #define BTIF_MEDIA_BITRATE_STEP 5
    138 #endif
    139 
    140 /* Middle quality quality setting @ 44.1 khz */
    141 #define DEFAULT_SBC_BITRATE 328
    142 
    143 #ifndef BTIF_A2DP_NON_EDR_MAX_RATE
    144 #define BTIF_A2DP_NON_EDR_MAX_RATE 229
    145 #endif
    146 
    147 #ifndef A2DP_MEDIA_TASK_STACK_SIZE
    148 #define A2DP_MEDIA_TASK_STACK_SIZE       0x2000         /* In bytes */
    149 #endif
    150 
    151 #define A2DP_MEDIA_TASK_TASK_STR        ((INT8 *) "A2DP-MEDIA")
    152 static UINT32 a2dp_media_task_stack[(A2DP_MEDIA_TASK_STACK_SIZE + 3) / 4];
    153 
    154 #define BT_MEDIA_TASK A2DP_MEDIA_TASK
    155 
    156 #define USEC_PER_SEC 1000000L
    157 #define TPUT_STATS_INTERVAL_US (3000*1000)
    158 
    159 /*
    160  * CONGESTION COMPENSATION CTRL ::
    161  *
    162  * Thus setting controls how many buffers we will hold in media task
    163  * during temp link congestion. Together with the stack buffer queues
    164  * it controls much temporary a2dp link congestion we can
    165  * compensate for. It however also depends on the default run level of sinks
    166  * jitterbuffers. Depending on type of sink this would vary.
    167  * Ideally the (SRC) max tx buffer capacity should equal the sinks
    168  * jitterbuffer runlevel including any intermediate buffers on the way
    169  * towards the sinks codec.
    170  */
    171 
    172 /* fixme -- define this in pcm time instead of buffer count */
    173 
    174 /* The typical runlevel of the tx queue size is ~1 buffer
    175    but due to link flow control or thread preemption in lower
    176    layers we might need to temporarily buffer up data */
    177 
    178 /* 24 frames is equivalent to 6.89*24*2.9 ~= 480 ms @ 44.1 khz, 20 ms mediatick */
    179 #define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 24
    180 
    181 //#define BTIF_MEDIA_VERBOSE_ENABLED
    182 
    183 #ifdef BTIF_MEDIA_VERBOSE_ENABLED
    184 #define VERBOSE(fmt, ...) \
    185       LogMsg( TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
    186               TRACE_TYPE_ERROR, fmt, ## __VA_ARGS__)
    187 #else
    188 #define VERBOSE(fmt, ...)
    189 #endif
    190 
    191 /*****************************************************************************
    192  **  Data types
    193  *****************************************************************************/
    194 
    195 typedef struct
    196 {
    197     UINT32 aa_frame_counter;
    198     INT32  aa_feed_counter;
    199     INT32  aa_feed_residue;
    200     UINT32 counter;
    201     UINT32 bytes_per_tick;  /* pcm bytes read each media task tick */
    202 } tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE;
    203 
    204 
    205 typedef union
    206 {
    207     tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE pcm;
    208 } tBTIF_AV_MEDIA_FEEDINGS_STATE;
    209 
    210 typedef struct
    211 {
    212 #if (BTA_AV_INCLUDED == TRUE)
    213     BUFFER_Q TxAaQ;
    214     BOOLEAN is_tx_timer;
    215     UINT16 TxAaMtuSize;
    216     UINT32 timestamp;
    217     UINT8 TxTranscoding;
    218     tBTIF_AV_FEEDING_MODE feeding_mode;
    219     tBTIF_AV_MEDIA_FEEDINGS media_feeding;
    220     tBTIF_AV_MEDIA_FEEDINGS_STATE media_feeding_state;
    221     SBC_ENC_PARAMS encoder;
    222     UINT8 busy_level;
    223     void* av_sm_hdl;
    224     UINT8 a2dp_cmd_pending; /* we can have max one command pending */
    225     BOOLEAN tx_flush; /* discards any outgoing data when true */
    226 #endif
    227 
    228 } tBTIF_MEDIA_CB;
    229 
    230 typedef struct {
    231     long long rx;
    232     long long rx_tot;
    233     long long tx;
    234     long long tx_tot;
    235     long long ts_prev_us;
    236 } t_stat;
    237 
    238 /*****************************************************************************
    239  **  Local data
    240  *****************************************************************************/
    241 
    242 static tBTIF_MEDIA_CB btif_media_cb;
    243 static int media_task_running = MEDIA_TASK_STATE_OFF;
    244 
    245 
    246 /*****************************************************************************
    247  **  Local functions
    248  *****************************************************************************/
    249 
    250 static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
    251 static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
    252 static void btif_a2dp_encoder_update(void);
    253 const char* dump_media_event(UINT16 event);
    254 
    255 /*****************************************************************************
    256  **  Externs
    257  *****************************************************************************/
    258 
    259 static void btif_media_task_handle_cmd(BT_HDR *p_msg);
    260 static void btif_media_task_handle_media(BT_HDR *p_msg);
    261 
    262 #if (BTA_AV_INCLUDED == TRUE)
    263 static void btif_media_send_aa_frame(void);
    264 static void btif_media_task_feeding_state_reset(void);
    265 static void btif_media_task_aa_start_tx(void);
    266 static void btif_media_task_aa_stop_tx(void);
    267 static void btif_media_task_enc_init(BT_HDR *p_msg);
    268 static void btif_media_task_enc_update(BT_HDR *p_msg);
    269 static void btif_media_task_audio_feeding_init(BT_HDR *p_msg);
    270 static void btif_media_task_aa_tx_flush(BT_HDR *p_msg);
    271 static void btif_media_aa_prep_2_send(UINT8 nb_frame);
    272 #endif
    273 
    274 
    275 /*****************************************************************************
    276  **  Misc helper functions
    277  *****************************************************************************/
    278 
    279 static void tput_mon(int is_rx, int len, int reset)
    280 {
    281     /* only monitor one connection at a time for now */
    282     static t_stat cur_stat;
    283     struct timespec now;
    284     unsigned long long prev_us;
    285     unsigned long long now_us;
    286 
    287     if (reset == TRUE)
    288     {
    289         memset(&cur_stat, 0, sizeof(t_stat));
    290         return;
    291     }
    292 
    293     if (is_rx)
    294     {
    295         cur_stat.rx+=len;
    296         cur_stat.rx_tot+=len;
    297     }
    298     else
    299     {
    300         cur_stat.tx+=len;
    301         cur_stat.tx_tot+=len;
    302     }
    303     clock_gettime(CLOCK_MONOTONIC, &now);
    304 
    305     now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;
    306 
    307     if ((now_us - cur_stat.ts_prev_us) < TPUT_STATS_INTERVAL_US)
    308         return;
    309 
    310     APPL_TRACE_WARNING4("tput rx:%d, tx:%d (bytes/s)  (tot : rx %d, tx %d bytes)",
    311           (cur_stat.rx*1000000)/((now_us - cur_stat.ts_prev_us)),
    312           (cur_stat.tx*1000000)/((now_us - cur_stat.ts_prev_us)),
    313            cur_stat.rx_tot, cur_stat.tx_tot);
    314 
    315     /* stats dumped. now reset stats for next interval */
    316     cur_stat.rx = 0;
    317     cur_stat.tx = 0;
    318     cur_stat.ts_prev_us = now_us;
    319 }
    320 
    321 
    322 static void log_tstamps_us(char *comment)
    323 {
    324     #define USEC_PER_SEC 1000000L
    325     static struct timespec prev = {0, 0};
    326     struct timespec now, diff;
    327     unsigned int diff_us = 0;
    328     unsigned int now_us = 0;
    329 
    330     clock_gettime(CLOCK_MONOTONIC, &now);
    331     now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;
    332     diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
    333 
    334     APPL_TRACE_DEBUG4("[%s] ts %08d, diff : %08d, queue sz %d", comment, now_us, diff_us,
    335                 btif_media_cb.TxAaQ.count);
    336 
    337     prev = now;
    338 }
    339 
    340 const char* dump_media_event(UINT16 event)
    341 {
    342     switch(event)
    343     {
    344         CASE_RETURN_STR(BTIF_MEDIA_START_AA_TX)
    345         CASE_RETURN_STR(BTIF_MEDIA_STOP_AA_TX)
    346         CASE_RETURN_STR(BTIF_MEDIA_AA_RX_RDY)
    347         CASE_RETURN_STR(BTIF_MEDIA_UIPC_RX_RDY)
    348         CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_INIT)
    349         CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_UPDATE)
    350         CASE_RETURN_STR(BTIF_MEDIA_SBC_DEC_INIT)
    351         CASE_RETURN_STR(BTIF_MEDIA_VIDEO_DEC_INIT)
    352         CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_TX)
    353         CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_RX)
    354         CASE_RETURN_STR(BTIF_MEDIA_AUDIO_FEEDING_INIT)
    355         CASE_RETURN_STR(BTIF_MEDIA_AUDIO_RECEIVING_INIT)
    356 
    357         default:
    358             return "UNKNOWN MEDIA EVENT";
    359     }
    360 }
    361 
    362 /*****************************************************************************
    363  **  A2DP CTRL PATH
    364  *****************************************************************************/
    365 
    366 static const char* dump_a2dp_ctrl_event(UINT8 event)
    367 {
    368     switch(event)
    369     {
    370         CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
    371         CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
    372         CASE_RETURN_STR(A2DP_CTRL_CMD_START)
    373         CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
    374         CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
    375         default:
    376             return "UNKNOWN MSG ID";
    377     }
    378 }
    379 
    380 static void btif_audiopath_detached(void)
    381 {
    382     APPL_TRACE_EVENT0("## AUDIO PATH DETACHED ##");
    383 
    384     /*  send stop request only if we are actively streaming and haven't received
    385         a stop request. Potentially audioflinger detached abnormally */
    386     if (btif_media_cb.is_tx_timer)
    387     {
    388         /* post stop event and wait for audio path to stop */
    389         btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
    390     }
    391 }
    392 
    393 static void a2dp_cmd_acknowledge(int status)
    394 {
    395     UINT8 ack = status;
    396 
    397     APPL_TRACE_EVENT2("## a2dp ack : %s, status %d ##",
    398           dump_a2dp_ctrl_event(btif_media_cb.a2dp_cmd_pending), status);
    399 
    400     /* sanity check */
    401     if (btif_media_cb.a2dp_cmd_pending == A2DP_CTRL_CMD_NONE)
    402     {
    403         APPL_TRACE_ERROR0("warning : no command pending, ignore ack");
    404         return;
    405     }
    406 
    407     /* clear pending */
    408     btif_media_cb.a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
    409 
    410     /* acknowledge start request */
    411     UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, &ack, 1);
    412 }
    413 
    414 
    415 static void btif_recv_ctrl_data(void)
    416 {
    417     UINT8 cmd = 0;
    418     int n;
    419 
    420     n = UIPC_Read(UIPC_CH_ID_AV_CTRL, NULL, &cmd, 1);
    421 
    422     /* detach on ctrl channel means audioflinger process was terminated */
    423     if (n == 0)
    424     {
    425         APPL_TRACE_EVENT0("CTRL CH DETACHED");
    426         UIPC_Close(UIPC_CH_ID_AV_CTRL);
    427         /* we can operate only on datachannel, if af client wants to
    428            do send additional commands the ctrl channel would be reestablished */
    429         //btif_audiopath_detached();
    430         return;
    431     }
    432 
    433     APPL_TRACE_DEBUG1("a2dp-ctrl-cmd : %s", dump_a2dp_ctrl_event(cmd));
    434 
    435     btif_media_cb.a2dp_cmd_pending = cmd;
    436 
    437     switch(cmd)
    438     {
    439         case A2DP_CTRL_CMD_CHECK_READY:
    440 
    441             if (media_task_running == MEDIA_TASK_STATE_SHUTTING_DOWN)
    442             {
    443                 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
    444                 return;
    445             }
    446 
    447             /* check whether av is ready to setup a2dp datapath */
    448             if ((btif_av_stream_ready() == TRUE) || (btif_av_stream_started_ready() == TRUE))
    449             {
    450                 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
    451             }
    452             else
    453             {
    454                 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
    455             }
    456             break;
    457 
    458         case A2DP_CTRL_CMD_START:
    459 
    460             if (btif_av_stream_ready() == TRUE)
    461             {
    462                 /* setup audio data channel listener */
    463                 UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
    464 
    465                 /* post start event and wait for audio path to open */
    466                 btif_dispatch_sm_event(BTIF_AV_START_STREAM_REQ_EVT, NULL, 0);
    467             }
    468             else if (btif_av_stream_started_ready())
    469             {
    470                 /* already started, setup audio data channel listener
    471                    and ack back immediately */
    472                 UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
    473 
    474                 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
    475             }
    476             else
    477             {
    478                 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
    479                 break;
    480             }
    481             break;
    482 
    483         case A2DP_CTRL_CMD_STOP:
    484 
    485             if (btif_media_cb.is_tx_timer == FALSE)
    486             {
    487                 /* we are already stopped, just ack back */
    488                 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
    489                 break;
    490             }
    491 
    492             btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
    493             break;
    494 
    495         case A2DP_CTRL_CMD_SUSPEND:
    496             /* local suspend */
    497             if (btif_av_stream_started_ready())
    498             {
    499                 btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
    500             }
    501             else
    502             {
    503                 /* if we are not in started state, just ack back ok and let
    504                    audioflinger close the channel. This can happen if we are
    505                    remotely suspended */
    506                 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
    507             }
    508             break;
    509 
    510         default:
    511             APPL_TRACE_ERROR1("UNSUPPORTED CMD (%d)", cmd);
    512             a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
    513             break;
    514     }
    515     APPL_TRACE_DEBUG1("a2dp-ctrl-cmd : %s DONE", dump_a2dp_ctrl_event(cmd));
    516 }
    517 
    518 static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
    519 {
    520     APPL_TRACE_DEBUG1("A2DP-CTRL-CHANNEL EVENT %s", dump_uipc_event(event));
    521 
    522     switch(event)
    523     {
    524         case UIPC_OPEN_EVT:
    525             /* fetch av statemachine handle */
    526             btif_media_cb.av_sm_hdl = btif_av_get_sm_handle();
    527             break;
    528 
    529         case UIPC_CLOSE_EVT:
    530             /* restart ctrl server unless we are shutting down */
    531             if (media_task_running == MEDIA_TASK_STATE_ON)
    532                 UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
    533             break;
    534 
    535         case UIPC_RX_DATA_READY_EVT:
    536             btif_recv_ctrl_data();
    537             break;
    538 
    539         default :
    540             APPL_TRACE_ERROR1("### A2DP-CTRL-CHANNEL EVENT %d NOT HANDLED ###", event);
    541             break;
    542     }
    543 }
    544 
    545 static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
    546 {
    547     APPL_TRACE_DEBUG1("BTIF MEDIA (A2DP-DATA) EVENT %s", dump_uipc_event(event));
    548 
    549     switch(event)
    550     {
    551         case UIPC_OPEN_EVT:
    552 
    553             /*  read directly from media task from here on (keep callback for
    554                 connection events */
    555             UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
    556 
    557             /* Start the media task to encode SBC */
    558             btif_media_task_start_aa_req();
    559 
    560             /* make sure we update any changed sbc encoder params */
    561             btif_a2dp_encoder_update();
    562 
    563             /* ack back when media task is fully started */
    564             break;
    565 
    566         case UIPC_CLOSE_EVT:
    567             a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
    568             btif_audiopath_detached();
    569             break;
    570 
    571         default :
    572             APPL_TRACE_ERROR1("### A2DP-DATA EVENT %d NOT HANDLED ###", event);
    573             break;
    574     }
    575 }
    576 
    577 
    578 /*****************************************************************************
    579  **  BTIF ADAPTATION
    580  *****************************************************************************/
    581 
    582 static UINT16 btif_media_task_get_sbc_rate(void)
    583 {
    584     UINT16 rate = DEFAULT_SBC_BITRATE;
    585 
    586     /* restrict bitrate if a2dp link is non-edr */
    587     if (!btif_av_is_peer_edr())
    588     {
    589         rate = BTIF_A2DP_NON_EDR_MAX_RATE;
    590         APPL_TRACE_DEBUG1("non-edr a2dp sink detected, restrict rate to %d", rate);
    591     }
    592 
    593     return rate;
    594 }
    595 
    596 static void btif_a2dp_encoder_init(void)
    597 {
    598     UINT16 minmtu;
    599     tBTIF_MEDIA_INIT_AUDIO msg;
    600     tA2D_SBC_CIE sbc_config;
    601 
    602     /* lookup table for converting channel mode */
    603     UINT16 codec_mode_tbl[5] = { SBC_JOINT_STEREO, SBC_STEREO, SBC_DUAL, 0, SBC_MONO };
    604 
    605     /* lookup table for converting number of blocks */
    606     UINT16 codec_block_tbl[5] = { 16, 12, 8, 0, 4 };
    607 
    608     /* lookup table to convert freq */
    609     UINT16 freq_block_tbl[5] = { SBC_sf48000, SBC_sf44100, SBC_sf32000, 0, SBC_sf16000 };
    610 
    611     APPL_TRACE_DEBUG0("btif_a2dp_encoder_init");
    612 
    613     /* Retrieve the current SBC configuration (default if currently not used) */
    614     bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
    615     msg.NumOfSubBands = (sbc_config.num_subbands == A2D_SBC_IE_SUBBAND_4) ? 4 : 8;
    616     msg.NumOfBlocks = codec_block_tbl[sbc_config.block_len >> 5];
    617     msg.AllocationMethod = (sbc_config.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L) ? SBC_LOUDNESS : SBC_SNR;
    618     msg.ChannelMode = codec_mode_tbl[sbc_config.ch_mode >> 1];
    619     msg.SamplingFreq = freq_block_tbl[sbc_config.samp_freq >> 5];
    620     msg.MtuSize = minmtu;
    621 
    622     APPL_TRACE_EVENT1("msg.ChannelMode %x", msg.ChannelMode);
    623 
    624     /* Init the media task to encode SBC properly */
    625     btif_media_task_enc_init_req(&msg);
    626 }
    627 
    628 static void btif_a2dp_encoder_update(void)
    629 {
    630     UINT16 minmtu;
    631     tA2D_SBC_CIE sbc_config;
    632     tBTIF_MEDIA_UPDATE_AUDIO msg;
    633     UINT8 pref_min;
    634     UINT8 pref_max;
    635 
    636     APPL_TRACE_DEBUG0("btif_a2dp_encoder_update");
    637 
    638     /* Retrieve the current SBC configuration (default if currently not used) */
    639     bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
    640 
    641     APPL_TRACE_DEBUG4("btif_a2dp_encoder_update: Common min_bitpool:%d(0x%x) max_bitpool:%d(0x%x)",
    642             sbc_config.min_bitpool, sbc_config.min_bitpool,
    643             sbc_config.max_bitpool, sbc_config.max_bitpool);
    644 
    645     if (sbc_config.min_bitpool > sbc_config.max_bitpool)
    646     {
    647         APPL_TRACE_ERROR0("btif_a2dp_encoder_update: ERROR btif_a2dp_encoder_update min_bitpool > max_bitpool");
    648     }
    649 
    650     /* check if remote sink has a preferred bitpool range */
    651     if (bta_av_co_get_remote_bitpool_pref(&pref_min, &pref_max) == TRUE)
    652     {
    653         /* adjust our preferred bitpool with the remote preference if within
    654            our capable range */
    655 
    656         if (pref_min < sbc_config.min_bitpool)
    657             pref_min = sbc_config.min_bitpool;
    658 
    659         if (pref_max > sbc_config.max_bitpool)
    660             pref_max = sbc_config.max_bitpool;
    661 
    662         msg.MinBitPool = pref_min;
    663         msg.MaxBitPool = pref_max;
    664 
    665         if ((pref_min != sbc_config.min_bitpool) || (pref_max != sbc_config.max_bitpool))
    666         {
    667             APPL_TRACE_EVENT2("## adjusted our bitpool range to peer pref [%d:%d] ##",
    668                 pref_min, pref_max);
    669         }
    670     }
    671     else
    672     {
    673         msg.MinBitPool = sbc_config.min_bitpool;
    674         msg.MaxBitPool = sbc_config.max_bitpool;
    675     }
    676 
    677     msg.MinMtuSize = minmtu;
    678 
    679     /* Update the media task to encode SBC properly */
    680     btif_media_task_enc_update_req(&msg);
    681 }
    682 
    683 
    684 /*****************************************************************************
    685 **
    686 ** Function        btif_a2dp_start_media_task
    687 **
    688 ** Description
    689 **
    690 ** Returns
    691 **
    692 *******************************************************************************/
    693 
    694 int btif_a2dp_start_media_task(void)
    695 {
    696     int retval;
    697 
    698     if (media_task_running != MEDIA_TASK_STATE_OFF)
    699     {
    700         APPL_TRACE_ERROR0("warning : media task already running");
    701         return GKI_FAILURE;
    702     }
    703 
    704     APPL_TRACE_EVENT0("## A2DP START MEDIA TASK ##");
    705 
    706     /* start a2dp media task */
    707     retval = GKI_create_task((TASKPTR)btif_media_task, A2DP_MEDIA_TASK,
    708                 A2DP_MEDIA_TASK_TASK_STR,
    709                 (UINT16 *) ((UINT8 *)a2dp_media_task_stack + A2DP_MEDIA_TASK_STACK_SIZE),
    710                 sizeof(a2dp_media_task_stack));
    711 
    712     if (retval != GKI_SUCCESS)
    713         return retval;
    714 
    715     /* wait for task to come up to sure we are able to send messages to it */
    716     while (media_task_running == MEDIA_TASK_STATE_OFF)
    717         usleep(10);
    718 
    719     APPL_TRACE_EVENT0("## A2DP MEDIA TASK STARTED ##");
    720 
    721     return retval;
    722 }
    723 
    724 /*****************************************************************************
    725 **
    726 ** Function        btif_a2dp_stop_media_task
    727 **
    728 ** Description
    729 **
    730 ** Returns
    731 **
    732 *******************************************************************************/
    733 
    734 void btif_a2dp_stop_media_task(void)
    735 {
    736     APPL_TRACE_EVENT0("## A2DP STOP MEDIA TASK ##");
    737     GKI_destroy_task(BT_MEDIA_TASK);
    738 }
    739 
    740 /*****************************************************************************
    741 **
    742 ** Function        btif_a2dp_on_init
    743 **
    744 ** Description
    745 **
    746 ** Returns
    747 **
    748 *******************************************************************************/
    749 
    750 void btif_a2dp_on_init(void)
    751 {
    752     //tput_mon(1, 0, 1);
    753 }
    754 
    755 
    756 /*****************************************************************************
    757 **
    758 ** Function        btif_a2dp_setup_codec
    759 **
    760 ** Description
    761 **
    762 ** Returns
    763 **
    764 *******************************************************************************/
    765 
    766 void btif_a2dp_setup_codec(void)
    767 {
    768     tBTIF_AV_MEDIA_FEEDINGS media_feeding;
    769     tBTIF_STATUS status;
    770 
    771     APPL_TRACE_EVENT0("## A2DP SETUP CODEC ##");
    772 
    773     GKI_disable();
    774 
    775     /* for now hardcode 44.1 khz 16 bit stereo PCM format */
    776     media_feeding.cfg.pcm.sampling_freq = 44100;
    777     media_feeding.cfg.pcm.bit_per_sample = 16;
    778     media_feeding.cfg.pcm.num_channel = 2;
    779     media_feeding.format = BTIF_AV_CODEC_PCM;
    780 
    781     if (bta_av_co_audio_set_codec(&media_feeding, &status))
    782     {
    783         tBTIF_MEDIA_INIT_AUDIO_FEEDING mfeed;
    784 
    785         /* Init the encoding task */
    786         btif_a2dp_encoder_init();
    787 
    788         /* Build the media task configuration */
    789         mfeed.feeding = media_feeding;
    790         mfeed.feeding_mode = BTIF_AV_FEEDING_ASYNCHRONOUS;
    791         /* Send message to Media task to configure transcoding */
    792         btif_media_task_audio_feeding_init_req(&mfeed);
    793     }
    794 
    795     GKI_enable();
    796 }
    797 
    798 
    799 /*****************************************************************************
    800 **
    801 ** Function        btif_a2dp_on_idle
    802 **
    803 ** Description
    804 **
    805 ** Returns
    806 **
    807 *******************************************************************************/
    808 
    809 void btif_a2dp_on_idle(void)
    810 {
    811     APPL_TRACE_EVENT0("## ON A2DP IDLE ##");
    812 
    813     /* Make sure media task is stopped */
    814     btif_media_task_stop_aa_req();
    815 
    816     bta_av_co_init();
    817 }
    818 
    819 /*****************************************************************************
    820 **
    821 ** Function        btif_a2dp_on_open
    822 **
    823 ** Description
    824 **
    825 ** Returns
    826 **
    827 *******************************************************************************/
    828 
    829 void btif_a2dp_on_open(void)
    830 {
    831     APPL_TRACE_EVENT0("## ON A2DP OPEN ##");
    832 
    833     /* always use callback to notify socket events */
    834     UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
    835 }
    836 
    837 /*****************************************************************************
    838 **
    839 ** Function        btif_a2dp_on_started
    840 **
    841 ** Description
    842 **
    843 ** Returns
    844 **
    845 *******************************************************************************/
    846 
    847 BOOLEAN btif_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start)
    848 {
    849     tBTIF_STATUS status;
    850     BOOLEAN ack = FALSE;
    851 
    852     APPL_TRACE_EVENT0("## ON A2DP STARTED ##");
    853 
    854     if (p_av == NULL)
    855     {
    856         /* ack back a local start request */
    857         a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
    858         return TRUE;
    859     }
    860 
    861     if (p_av->status == BTA_AV_SUCCESS)
    862     {
    863         if (p_av->suspending == FALSE)
    864         {
    865             if (p_av->initiator)
    866             {
    867                 if (pending_start) {
    868                     a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
    869                     ack = TRUE;
    870                 }
    871             }
    872             else
    873             {
    874                 /* we were remotely started,  make sure codec
    875                    is setup before datapath is started */
    876                 btif_a2dp_setup_codec();
    877             }
    878 
    879             /* media task is autostarted upon a2dp audiopath connection */
    880         }
    881     }
    882     else if (pending_start)
    883     {
    884         a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
    885         ack = TRUE;
    886     }
    887     return ack;
    888 }
    889 
    890 
    891 /*****************************************************************************
    892 **
    893 ** Function        btif_a2dp_ack_fail
    894 **
    895 ** Description
    896 **
    897 ** Returns
    898 **
    899 *******************************************************************************/
    900 
    901 void btif_a2dp_ack_fail(void)
    902 {
    903     tBTIF_STATUS status;
    904 
    905     APPL_TRACE_EVENT0("## A2DP_CTRL_ACK_FAILURE ##");
    906     a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
    907 }
    908 
    909 /*****************************************************************************
    910 **
    911 ** Function        btif_a2dp_on_stopped
    912 **
    913 ** Description
    914 **
    915 ** Returns
    916 **
    917 *******************************************************************************/
    918 
    919 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av)
    920 {
    921     APPL_TRACE_EVENT0("## ON A2DP STOPPED ##");
    922 
    923     /* allow using this api for other than suspend */
    924     if (p_av != NULL)
    925     {
    926         if (p_av->status != BTA_AV_SUCCESS)
    927         {
    928             APPL_TRACE_EVENT1("AV STOP FAILED (%d)", p_av->status);
    929 
    930             if (p_av->initiator)
    931                 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
    932             return;
    933         }
    934     }
    935 
    936     /* ensure tx frames are immediately suspended */
    937     btif_media_cb.tx_flush = 1;
    938 
    939     /* request to stop media task  */
    940     btif_media_task_aa_tx_flush_req();
    941     btif_media_task_stop_aa_req();
    942 
    943     /* once stream is fully stopped we will ack back */
    944 }
    945 
    946 
    947 /*****************************************************************************
    948 **
    949 ** Function        btif_a2dp_on_suspended
    950 **
    951 ** Description
    952 **
    953 ** Returns
    954 **
    955 *******************************************************************************/
    956 
    957 void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av)
    958 {
    959     APPL_TRACE_EVENT0("## ON A2DP SUSPENDED ##");
    960 
    961     /* check for status failures */
    962     if (p_av->status != BTA_AV_SUCCESS)
    963     {
    964         if (p_av->initiator == TRUE)
    965             a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
    966     }
    967 
    968     /* once stream is fully stopped we will ack back */
    969 
    970     /* ensure tx frames are immediately flushed */
    971     btif_media_cb.tx_flush = 1;
    972 
    973     /* stop timer tick */
    974     btif_media_task_stop_aa_req();
    975 }
    976 
    977 /* when true media task discards any tx frames */
    978 void btif_a2dp_set_tx_flush(BOOLEAN enable)
    979 {
    980     APPL_TRACE_EVENT1("## DROP TX %d ##", enable);
    981     btif_media_cb.tx_flush = enable;
    982 }
    983 
    984 /*****************************************************************************
    985 **
    986 ** Function        btif_calc_pcmtime
    987 **
    988 ** Description     Calculates the pcmtime equivalent of a datapacket
    989 **
    990 ** Returns         microseconds
    991 **
    992 *******************************************************************************/
    993 
    994 static int btif_calc_pcmtime(UINT32 bytes_processed)
    995 {
    996     int pcm_time_us = 0;
    997     tBTIF_AV_MEDIA_FEED_CFG *p_cfg;
    998 
    999     p_cfg = &btif_media_cb.media_feeding.cfg;
   1000 
   1001     /* calculate corresponding pcm time based on data processed */
   1002     switch(btif_media_cb.media_feeding.format)
   1003     {
   1004         case BTIF_AV_CODEC_PCM:
   1005             pcm_time_us = (bytes_processed*1000000)/
   1006                           (p_cfg->pcm.num_channel*p_cfg->pcm.sampling_freq*p_cfg->pcm.bit_per_sample/8);
   1007             break;
   1008 
   1009         default :
   1010             APPL_TRACE_ERROR1("mediafeeding format invalid : %d", btif_media_cb.media_feeding.format);
   1011             break;
   1012     }
   1013 
   1014     return pcm_time_us;
   1015 }
   1016 
   1017 
   1018 /*******************************************************************************
   1019  **
   1020  ** Function         btif_media_task_aa_handle_timer
   1021  **
   1022  ** Description
   1023  **
   1024  ** Returns          void
   1025  **
   1026  *******************************************************************************/
   1027 
   1028 static void btif_media_task_aa_handle_timer(void)
   1029 {
   1030 #if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
   1031     static UINT16 Debug = 0;
   1032     APPL_TRACE_DEBUG1("btif_media_task_aa_handle_timer: %d", Debug++);
   1033 #endif
   1034 
   1035     log_tstamps_us("media task tx timer");
   1036 
   1037 #if (BTA_AV_INCLUDED == TRUE)
   1038     btif_media_send_aa_frame();
   1039 #endif
   1040 }
   1041 
   1042 #if (BTA_AV_INCLUDED == TRUE)
   1043 /*******************************************************************************
   1044  **
   1045  ** Function         btif_media_task_aa_handle_timer
   1046  **
   1047  ** Description
   1048  **
   1049  ** Returns          void
   1050  **
   1051  *******************************************************************************/
   1052 static void btif_media_task_aa_handle_uipc_rx_rdy(void)
   1053 {
   1054 #if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
   1055     static UINT16 Debug = 0;
   1056     APPL_TRACE_DEBUG1("btif_media_task_aa_handle_uipc_rx_rdy: %d", Debug++);
   1057 #endif
   1058 
   1059     /* process all the UIPC data */
   1060     btif_media_aa_prep_2_send(0xFF);
   1061 
   1062     /* send it */
   1063     VERBOSE("btif_media_task_aa_handle_uipc_rx_rdy calls bta_av_ci_src_data_ready");
   1064     bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
   1065 }
   1066 #endif
   1067 
   1068 /*******************************************************************************
   1069  **
   1070  ** Function         btif_media_task_init
   1071  **
   1072  ** Description
   1073  **
   1074  ** Returns          void
   1075  **
   1076  *******************************************************************************/
   1077 
   1078 void btif_media_task_init(void)
   1079 {
   1080     memset(&(btif_media_cb), 0, sizeof(btif_media_cb));
   1081 
   1082     UIPC_Init(NULL);
   1083 
   1084 #if (BTA_AV_INCLUDED == TRUE)
   1085     UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
   1086 #endif
   1087 
   1088 
   1089 }
   1090 /*******************************************************************************
   1091  **
   1092  ** Function         btif_media_task
   1093  **
   1094  ** Description      Task for SBC encoder.  This task receives an
   1095  **                  event when the waveIn interface has a pcm data buffer
   1096  **                  ready.  On receiving the event, handle all ready pcm
   1097  **                  data buffers.  If stream is started, run the SBC encoder
   1098  **                  on each chunk of pcm samples and build an output packet
   1099  **                  consisting of one or more encoded SBC frames.
   1100  **
   1101  ** Returns          void
   1102  **
   1103  *******************************************************************************/
   1104 int btif_media_task(void *p)
   1105 {
   1106     UINT16 event;
   1107     BT_HDR *p_msg;
   1108 
   1109     VERBOSE("================ MEDIA TASK STARTING ================");
   1110 
   1111     btif_media_task_init();
   1112 
   1113     media_task_running = MEDIA_TASK_STATE_ON;
   1114 
   1115     raise_priority_a2dp(TASK_HIGH_MEDIA);
   1116 
   1117     while (1)
   1118     {
   1119         event = GKI_wait(0xffff, 0);
   1120 
   1121         VERBOSE("================= MEDIA TASK EVENT %d ===============", event);
   1122 
   1123         if (event & BTIF_MEDIA_TASK_CMD)
   1124         {
   1125             /* Process all messages in the queue */
   1126             while ((p_msg = (BT_HDR *) GKI_read_mbox(BTIF_MEDIA_TASK_CMD_MBOX)) != NULL)
   1127             {
   1128                 btif_media_task_handle_cmd(p_msg);
   1129             }
   1130         }
   1131 
   1132         if (event & BTIF_MEDIA_TASK_DATA)
   1133         {
   1134             /* Process all messages in the queue */
   1135             while ((p_msg = (BT_HDR *) GKI_read_mbox(BTIF_MEDIA_TASK_DATA_MBOX)) != NULL)
   1136             {
   1137                 btif_media_task_handle_media(p_msg);
   1138             }
   1139         }
   1140 
   1141         if (event & BTIF_MEDIA_AA_TASK_TIMER)
   1142         {
   1143             /* advance audio timer expiration */
   1144             btif_media_task_aa_handle_timer();
   1145         }
   1146 
   1147 
   1148         VERBOSE("=============== MEDIA TASK EVENT %d DONE ============", event);
   1149 
   1150         /* When we get this event we exit the task  - should only happen on GKI_shutdown  */
   1151         if (event & BTIF_MEDIA_TASK_KILL)
   1152         {
   1153             /* make sure no channels are restarted while shutting down */
   1154             media_task_running = MEDIA_TASK_STATE_SHUTTING_DOWN;
   1155 
   1156             /* this calls blocks until uipc is fully closed */
   1157             UIPC_Close(UIPC_CH_ID_ALL);
   1158             break;
   1159         }
   1160     }
   1161 
   1162     /* Clear media task flag */
   1163     media_task_running = MEDIA_TASK_STATE_OFF;
   1164 
   1165     APPL_TRACE_DEBUG0("MEDIA TASK EXITING");
   1166 
   1167     return 0;
   1168 }
   1169 
   1170 
   1171 /*******************************************************************************
   1172  **
   1173  ** Function         btif_media_task_send_cmd_evt
   1174  **
   1175  ** Description
   1176  **
   1177  ** Returns          TRUE is success
   1178  **
   1179  *******************************************************************************/
   1180 BOOLEAN btif_media_task_send_cmd_evt(UINT16 Evt)
   1181 {
   1182     BT_HDR *p_buf;
   1183     if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
   1184     {
   1185         return FALSE;
   1186     }
   1187 
   1188     p_buf->event = Evt;
   1189 
   1190     GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
   1191     return TRUE;
   1192 }
   1193 
   1194 /*******************************************************************************
   1195  **
   1196  ** Function         btif_media_flush_q
   1197  **
   1198  ** Description
   1199  **
   1200  ** Returns          void
   1201  **
   1202  *******************************************************************************/
   1203 static void btif_media_flush_q(BUFFER_Q *p_q)
   1204 {
   1205     while (GKI_IS_QUEUE_EMPTY(p_q) == FALSE)
   1206     {
   1207         GKI_freebuf(GKI_dequeue(p_q));
   1208     }
   1209 }
   1210 
   1211 
   1212 /*******************************************************************************
   1213  **
   1214  ** Function         btif_media_task_handle_cmd
   1215  **
   1216  ** Description
   1217  **
   1218  ** Returns          void
   1219  **
   1220  *******************************************************************************/
   1221 static void btif_media_task_handle_cmd(BT_HDR *p_msg)
   1222 {
   1223     VERBOSE("btif_media_task_handle_cmd : %d %s", p_msg->event,
   1224              dump_media_event(p_msg->event));
   1225 
   1226     switch (p_msg->event)
   1227     {
   1228 #if (BTA_AV_INCLUDED == TRUE)
   1229     case BTIF_MEDIA_START_AA_TX:
   1230         btif_media_task_aa_start_tx();
   1231         break;
   1232     case BTIF_MEDIA_STOP_AA_TX:
   1233         btif_media_task_aa_stop_tx();
   1234         break;
   1235     case BTIF_MEDIA_SBC_ENC_INIT:
   1236         btif_media_task_enc_init(p_msg);
   1237         break;
   1238     case BTIF_MEDIA_SBC_ENC_UPDATE:
   1239         btif_media_task_enc_update(p_msg);
   1240         break;
   1241     case BTIF_MEDIA_AUDIO_FEEDING_INIT:
   1242         btif_media_task_audio_feeding_init(p_msg);
   1243         break;
   1244     case BTIF_MEDIA_FLUSH_AA_TX:
   1245         btif_media_task_aa_tx_flush(p_msg);
   1246         break;
   1247     case BTIF_MEDIA_UIPC_RX_RDY:
   1248         btif_media_task_aa_handle_uipc_rx_rdy();
   1249         break;
   1250 #endif
   1251     default:
   1252         APPL_TRACE_ERROR1("ERROR in btif_media_task_handle_cmd unknown event %d", p_msg->event);
   1253     }
   1254     GKI_freebuf(p_msg);
   1255     VERBOSE("btif_media_task_handle_cmd : %s DONE", dump_media_event(p_msg->event));
   1256 }
   1257 
   1258 /*******************************************************************************
   1259  **
   1260  ** Function         btif_media_task_handle_media
   1261  **
   1262  ** Description
   1263  **
   1264  ** Returns          void
   1265  **
   1266  *******************************************************************************/
   1267 static void btif_media_task_handle_media(BT_HDR *p_msg)
   1268 {
   1269     APPL_TRACE_ERROR0("ERROR btif_media_task_handle_media: not in use");
   1270 
   1271     GKI_freebuf(p_msg);
   1272 }
   1273 
   1274 
   1275 
   1276 
   1277 #if (BTA_AV_INCLUDED == TRUE)
   1278 /*******************************************************************************
   1279  **
   1280  ** Function         btif_media_task_enc_init_req
   1281  **
   1282  ** Description
   1283  **
   1284  ** Returns          TRUE is success
   1285  **
   1286  *******************************************************************************/
   1287 BOOLEAN btif_media_task_enc_init_req(tBTIF_MEDIA_INIT_AUDIO *p_msg)
   1288 {
   1289     tBTIF_MEDIA_INIT_AUDIO *p_buf;
   1290     if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO))))
   1291     {
   1292         return FALSE;
   1293     }
   1294 
   1295     memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO));
   1296     p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_INIT;
   1297 
   1298     GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
   1299     return TRUE;
   1300 }
   1301 
   1302 /*******************************************************************************
   1303  **
   1304  ** Function         btif_media_task_enc_update_req
   1305  **
   1306  ** Description
   1307  **
   1308  ** Returns          TRUE is success
   1309  **
   1310  *******************************************************************************/
   1311 BOOLEAN btif_media_task_enc_update_req(tBTIF_MEDIA_UPDATE_AUDIO *p_msg)
   1312 {
   1313     tBTIF_MEDIA_UPDATE_AUDIO *p_buf;
   1314     if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_UPDATE_AUDIO))))
   1315     {
   1316         return FALSE;
   1317     }
   1318 
   1319     memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_UPDATE_AUDIO));
   1320     p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_UPDATE;
   1321 
   1322     GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
   1323     return TRUE;
   1324 }
   1325 
   1326 /*******************************************************************************
   1327  **
   1328  ** Function         btif_media_task_audio_feeding_init_req
   1329  **
   1330  ** Description
   1331  **
   1332  ** Returns          TRUE is success
   1333  **
   1334  *******************************************************************************/
   1335 BOOLEAN btif_media_task_audio_feeding_init_req(tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_msg)
   1336 {
   1337     tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_buf;
   1338     if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING))))
   1339     {
   1340         return FALSE;
   1341     }
   1342 
   1343     memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING));
   1344     p_buf->hdr.event = BTIF_MEDIA_AUDIO_FEEDING_INIT;
   1345 
   1346     GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
   1347     return TRUE;
   1348 }
   1349 
   1350 /*******************************************************************************
   1351  **
   1352  ** Function         btif_media_task_start_aa_req
   1353  **
   1354  ** Description
   1355  **
   1356  ** Returns          TRUE is success
   1357  **
   1358  *******************************************************************************/
   1359 BOOLEAN btif_media_task_start_aa_req(void)
   1360 {
   1361     BT_HDR *p_buf;
   1362     if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
   1363     {
   1364         APPL_TRACE_EVENT0("GKI failed");
   1365         return FALSE;
   1366     }
   1367 
   1368     p_buf->event = BTIF_MEDIA_START_AA_TX;
   1369 
   1370     GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
   1371     return TRUE;
   1372 }
   1373 
   1374 /*******************************************************************************
   1375  **
   1376  ** Function         btif_media_task_stop_aa_req
   1377  **
   1378  ** Description
   1379  **
   1380  ** Returns          TRUE is success
   1381  **
   1382  *******************************************************************************/
   1383 BOOLEAN btif_media_task_stop_aa_req(void)
   1384 {
   1385     BT_HDR *p_buf;
   1386     if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
   1387     {
   1388         return FALSE;
   1389     }
   1390 
   1391     p_buf->event = BTIF_MEDIA_STOP_AA_TX;
   1392 
   1393     GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
   1394     return TRUE;
   1395 }
   1396 
   1397 /*******************************************************************************
   1398  **
   1399  ** Function         btif_media_task_aa_tx_flush_req
   1400  **
   1401  ** Description
   1402  **
   1403  ** Returns          TRUE is success
   1404  **
   1405  *******************************************************************************/
   1406 BOOLEAN btif_media_task_aa_tx_flush_req(void)
   1407 {
   1408     BT_HDR *p_buf;
   1409     if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
   1410     {
   1411         return FALSE;
   1412     }
   1413 
   1414     p_buf->event = BTIF_MEDIA_FLUSH_AA_TX;
   1415 
   1416     GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
   1417     return TRUE;
   1418 }
   1419 
   1420 /*******************************************************************************
   1421  **
   1422  ** Function         btif_media_task_aa_tx_flush
   1423  **
   1424  ** Description
   1425  **
   1426  ** Returns          void
   1427  **
   1428  *******************************************************************************/
   1429 static void btif_media_task_aa_tx_flush(BT_HDR *p_msg)
   1430 {
   1431     /* Flush all enqueued GKI music buffers (encoded) */
   1432     APPL_TRACE_DEBUG0("btif_media_task_aa_tx_flush");
   1433 
   1434     btif_media_cb.media_feeding_state.pcm.counter = 0;
   1435     btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
   1436 
   1437     btif_media_flush_q(&(btif_media_cb.TxAaQ));
   1438 
   1439     UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REQ_RX_FLUSH, NULL);
   1440 }
   1441 
   1442 /*******************************************************************************
   1443  **
   1444  ** Function       btif_media_task_enc_init
   1445  **
   1446  ** Description    Initialize encoding task
   1447  **
   1448  ** Returns        void
   1449  **
   1450  *******************************************************************************/
   1451 static void btif_media_task_enc_init(BT_HDR *p_msg)
   1452 {
   1453     tBTIF_MEDIA_INIT_AUDIO *pInitAudio = (tBTIF_MEDIA_INIT_AUDIO *) p_msg;
   1454 
   1455     APPL_TRACE_DEBUG0("btif_media_task_enc_init");
   1456 
   1457     btif_media_cb.timestamp = 0;
   1458 
   1459     /* SBC encoder config (enforced even if not used) */
   1460     btif_media_cb.encoder.s16ChannelMode = pInitAudio->ChannelMode;
   1461     btif_media_cb.encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
   1462     btif_media_cb.encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks;
   1463     btif_media_cb.encoder.s16AllocationMethod = pInitAudio->AllocationMethod;
   1464     btif_media_cb.encoder.s16SamplingFreq = pInitAudio->SamplingFreq;
   1465 
   1466     btif_media_cb.encoder.u16BitRate = btif_media_task_get_sbc_rate();
   1467 
   1468     /* Default transcoding is PCM to SBC, modified by feeding configuration */
   1469     btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
   1470     btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE-BTIF_MEDIA_AA_SBC_OFFSET-sizeof(BT_HDR))
   1471             < pInitAudio->MtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
   1472             - sizeof(BT_HDR)) : pInitAudio->MtuSize;
   1473 
   1474     APPL_TRACE_EVENT3("btif_media_task_enc_init busy %d, mtu %d, peer mtu %d",
   1475                      btif_media_cb.busy_level, btif_media_cb.TxAaMtuSize, pInitAudio->MtuSize);
   1476     APPL_TRACE_EVENT6("      ch mode %d, subnd %d, nb blk %d, alloc %d, rate %d, freq %d",
   1477             btif_media_cb.encoder.s16ChannelMode, btif_media_cb.encoder.s16NumOfSubBands,
   1478             btif_media_cb.encoder.s16NumOfBlocks,
   1479             btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
   1480             btif_media_cb.encoder.s16SamplingFreq);
   1481 
   1482     /* Reset entirely the SBC encoder */
   1483     SBC_Encoder_Init(&(btif_media_cb.encoder));
   1484     APPL_TRACE_DEBUG1("btif_media_task_enc_init bit pool %d", btif_media_cb.encoder.s16BitPool);
   1485 }
   1486 
   1487 /*******************************************************************************
   1488  **
   1489  ** Function       btif_media_task_enc_update
   1490  **
   1491  ** Description    Update encoding task
   1492  **
   1493  ** Returns        void
   1494  **
   1495  *******************************************************************************/
   1496 
   1497 static void btif_media_task_enc_update(BT_HDR *p_msg)
   1498 {
   1499     tBTIF_MEDIA_UPDATE_AUDIO * pUpdateAudio = (tBTIF_MEDIA_UPDATE_AUDIO *) p_msg;
   1500     SBC_ENC_PARAMS *pstrEncParams = &btif_media_cb.encoder;
   1501     UINT16 s16SamplingFreq;
   1502     SINT16 s16BitPool;
   1503     SINT16 s16BitRate;
   1504     SINT16 s16FrameLen;
   1505     UINT8 protect = 0;
   1506 
   1507     APPL_TRACE_DEBUG3("btif_media_task_enc_update : minmtu %d, maxbp %d minbp %d",
   1508             pUpdateAudio->MinMtuSize, pUpdateAudio->MaxBitPool, pUpdateAudio->MinBitPool);
   1509 
   1510     /* Only update the bitrate and MTU size while timer is running to make sure it has been initialized */
   1511     //if (btif_media_cb.is_tx_timer)
   1512     {
   1513         btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE -
   1514                                       BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR))
   1515                 < pUpdateAudio->MinMtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
   1516                 - sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize;
   1517 
   1518         /* Set the initial target bit rate */
   1519         pstrEncParams->u16BitRate = btif_media_task_get_sbc_rate();
   1520 
   1521         if (pstrEncParams->s16SamplingFreq == SBC_sf16000)
   1522             s16SamplingFreq = 16000;
   1523         else if (pstrEncParams->s16SamplingFreq == SBC_sf32000)
   1524             s16SamplingFreq = 32000;
   1525         else if (pstrEncParams->s16SamplingFreq == SBC_sf44100)
   1526             s16SamplingFreq = 44100;
   1527         else
   1528             s16SamplingFreq = 48000;
   1529 
   1530         do
   1531         {
   1532             if ((pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) ||
   1533                 (pstrEncParams->s16ChannelMode == SBC_STEREO) )
   1534             {
   1535                 s16BitPool = (SINT16)( (pstrEncParams->u16BitRate *
   1536                     pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq)
   1537                     -( (32 + (4 * pstrEncParams->s16NumOfSubBands *
   1538                     pstrEncParams->s16NumOfChannels)
   1539                     + ( (pstrEncParams->s16ChannelMode - 2) *
   1540                     pstrEncParams->s16NumOfSubBands )   )
   1541                     / pstrEncParams->s16NumOfBlocks) );
   1542 
   1543                 s16FrameLen = 4 + (4*pstrEncParams->s16NumOfSubBands*
   1544                     pstrEncParams->s16NumOfChannels)/8
   1545                     + ( ((pstrEncParams->s16ChannelMode - 2) *
   1546                     pstrEncParams->s16NumOfSubBands)
   1547                     + (pstrEncParams->s16NumOfBlocks * s16BitPool) ) / 8;
   1548 
   1549                 s16BitRate = (8 * s16FrameLen * s16SamplingFreq)
   1550                     / (pstrEncParams->s16NumOfSubBands *
   1551                     pstrEncParams->s16NumOfBlocks * 1000);
   1552 
   1553                 if (s16BitRate > pstrEncParams->u16BitRate)
   1554                     s16BitPool--;
   1555 
   1556                 if(pstrEncParams->s16NumOfSubBands == 8)
   1557                     s16BitPool = (s16BitPool > 255) ? 255 : s16BitPool;
   1558                 else
   1559                     s16BitPool = (s16BitPool > 128) ? 128 : s16BitPool;
   1560             }
   1561             else
   1562             {
   1563                 s16BitPool = (SINT16)( ((pstrEncParams->s16NumOfSubBands *
   1564                     pstrEncParams->u16BitRate * 1000)
   1565                     / (s16SamplingFreq * pstrEncParams->s16NumOfChannels))
   1566                     -( ( (32 / pstrEncParams->s16NumOfChannels) +
   1567                     (4 * pstrEncParams->s16NumOfSubBands) )
   1568                     /   pstrEncParams->s16NumOfBlocks ) );
   1569 
   1570                 pstrEncParams->s16BitPool = (s16BitPool >
   1571                     (16 * pstrEncParams->s16NumOfSubBands))
   1572                     ? (16*pstrEncParams->s16NumOfSubBands) : s16BitPool;
   1573             }
   1574 
   1575             if (s16BitPool < 0)
   1576             {
   1577                 s16BitPool = 0;
   1578             }
   1579 
   1580             APPL_TRACE_EVENT2("bitpool candidate : %d (%d kbps)",
   1581                          s16BitPool, pstrEncParams->u16BitRate);
   1582 
   1583             if (s16BitPool > pUpdateAudio->MaxBitPool)
   1584             {
   1585                 APPL_TRACE_DEBUG1("btif_media_task_enc_update computed bitpool too large (%d)",
   1586                                     s16BitPool);
   1587                 /* Decrease bitrate */
   1588                 btif_media_cb.encoder.u16BitRate -= BTIF_MEDIA_BITRATE_STEP;
   1589                 /* Record that we have decreased the bitrate */
   1590                 protect |= 1;
   1591             }
   1592             else if (s16BitPool < pUpdateAudio->MinBitPool)
   1593             {
   1594                 APPL_TRACE_WARNING1("btif_media_task_enc_update computed bitpool too small (%d)", s16BitPool);
   1595                 /* Increase bitrate */
   1596                 btif_media_cb.encoder.u16BitRate += BTIF_MEDIA_BITRATE_STEP;
   1597                 /* Record that we have increased the bitrate */
   1598                 protect |= 2;
   1599             }
   1600             else
   1601             {
   1602                 break;
   1603             }
   1604             /* In case we have already increased and decreased the bitrate, just stop */
   1605             if (protect == 3)
   1606             {
   1607                 APPL_TRACE_ERROR0("btif_media_task_enc_update could not find bitpool in range");
   1608                 break;
   1609             }
   1610         } while (1);
   1611 
   1612         /* Finally update the bitpool in the encoder structure */
   1613         pstrEncParams->s16BitPool = s16BitPool;
   1614 
   1615         APPL_TRACE_DEBUG2("btif_media_task_enc_update final bit rate %d, final bit pool %d",
   1616                 btif_media_cb.encoder.u16BitRate, btif_media_cb.encoder.s16BitPool);
   1617 
   1618         /* make sure we reinitialize encoder with new settings */
   1619         SBC_Encoder_Init(&(btif_media_cb.encoder));
   1620     }
   1621 }
   1622 
   1623 /*******************************************************************************
   1624  **
   1625  ** Function         btif_media_task_pcm2sbc_init
   1626  **
   1627  ** Description      Init encoding task for PCM to SBC according to feeding
   1628  **
   1629  ** Returns          void
   1630  **
   1631  *******************************************************************************/
   1632 static void btif_media_task_pcm2sbc_init(tBTIF_MEDIA_INIT_AUDIO_FEEDING * p_feeding)
   1633 {
   1634     BOOLEAN reconfig_needed = FALSE;
   1635 
   1636     APPL_TRACE_DEBUG0("PCM feeding:");
   1637     APPL_TRACE_DEBUG1("sampling_freq:%d", p_feeding->feeding.cfg.pcm.sampling_freq);
   1638     APPL_TRACE_DEBUG1("num_channel:%d", p_feeding->feeding.cfg.pcm.num_channel);
   1639     APPL_TRACE_DEBUG1("bit_per_sample:%d", p_feeding->feeding.cfg.pcm.bit_per_sample);
   1640 
   1641     /* Check the PCM feeding sampling_freq */
   1642     switch (p_feeding->feeding.cfg.pcm.sampling_freq)
   1643     {
   1644         case  8000:
   1645         case 12000:
   1646         case 16000:
   1647         case 24000:
   1648         case 32000:
   1649         case 48000:
   1650             /* For these sampling_freq the AV connection must be 48000 */
   1651             if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf48000)
   1652             {
   1653                 /* Reconfiguration needed at 48000 */
   1654                 APPL_TRACE_DEBUG0("SBC Reconfiguration needed at 48000");
   1655                 btif_media_cb.encoder.s16SamplingFreq = SBC_sf48000;
   1656                 reconfig_needed = TRUE;
   1657             }
   1658             break;
   1659 
   1660         case 11025:
   1661         case 22050:
   1662         case 44100:
   1663             /* For these sampling_freq the AV connection must be 44100 */
   1664             if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf44100)
   1665             {
   1666                 /* Reconfiguration needed at 44100 */
   1667                 APPL_TRACE_DEBUG0("SBC Reconfiguration needed at 44100");
   1668                 btif_media_cb.encoder.s16SamplingFreq = SBC_sf44100;
   1669                 reconfig_needed = TRUE;
   1670             }
   1671             break;
   1672         default:
   1673             APPL_TRACE_DEBUG0("Feeding PCM sampling_freq unsupported");
   1674             break;
   1675     }
   1676 
   1677     /* Some AV Headsets do not support Mono => always ask for Stereo */
   1678     if (btif_media_cb.encoder.s16ChannelMode == SBC_MONO)
   1679     {
   1680         APPL_TRACE_DEBUG0("SBC Reconfiguration needed in Stereo");
   1681         btif_media_cb.encoder.s16ChannelMode = SBC_JOINT_STEREO;
   1682         reconfig_needed = TRUE;
   1683     }
   1684 
   1685     if (reconfig_needed != FALSE)
   1686     {
   1687         APPL_TRACE_DEBUG1("btif_media_task_pcm2sbc_init :: mtu %d", btif_media_cb.TxAaMtuSize);
   1688         APPL_TRACE_DEBUG6("ch mode %d, nbsubd %d, nb %d, alloc %d, rate %d, freq %d",
   1689                 btif_media_cb.encoder.s16ChannelMode,
   1690                 btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks,
   1691                 btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
   1692                 btif_media_cb.encoder.s16SamplingFreq);
   1693 
   1694         SBC_Encoder_Init(&(btif_media_cb.encoder));
   1695     }
   1696     else
   1697     {
   1698         APPL_TRACE_DEBUG0("btif_media_task_pcm2sbc_init no SBC reconfig needed");
   1699     }
   1700 }
   1701 
   1702 
   1703 /*******************************************************************************
   1704  **
   1705  ** Function         btif_media_task_audio_feeding_init
   1706  **
   1707  ** Description      Initialize the audio path according to the feeding format
   1708  **
   1709  ** Returns          void
   1710  **
   1711  *******************************************************************************/
   1712 static void btif_media_task_audio_feeding_init(BT_HDR *p_msg)
   1713 {
   1714     tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_feeding = (tBTIF_MEDIA_INIT_AUDIO_FEEDING *) p_msg;
   1715 
   1716     APPL_TRACE_DEBUG1("btif_media_task_audio_feeding_init format:%d", p_feeding->feeding.format);
   1717 
   1718     /* Save Media Feeding information */
   1719     btif_media_cb.feeding_mode = p_feeding->feeding_mode;
   1720     btif_media_cb.media_feeding = p_feeding->feeding;
   1721 
   1722     /* Handle different feeding formats */
   1723     switch (p_feeding->feeding.format)
   1724     {
   1725         case BTIF_AV_CODEC_PCM:
   1726             btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
   1727             btif_media_task_pcm2sbc_init(p_feeding);
   1728             break;
   1729 
   1730         default :
   1731             APPL_TRACE_ERROR1("unknown feeding format %d", p_feeding->feeding.format);
   1732             break;
   1733     }
   1734 }
   1735 
   1736 /*******************************************************************************
   1737  **
   1738  ** Function         btif_media_task_uipc_cback
   1739  **
   1740  ** Description      UIPC call back function for synchronous mode only
   1741  **
   1742  ** Returns          void
   1743  **
   1744  *******************************************************************************/
   1745 static void btif_media_task_uipc_cback(BT_HDR *p_msg)
   1746 {
   1747     /* Sanity check */
   1748     if (NULL == p_msg)
   1749     {
   1750         return;
   1751     }
   1752 
   1753     /* Just handle RX_EVT */
   1754     if (p_msg->event != UIPC_RX_DATA_EVT)
   1755     {
   1756         return;
   1757     }
   1758 
   1759     p_msg->event = BTIF_MEDIA_UIPC_RX_RDY;
   1760 
   1761     GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_msg);
   1762 }
   1763 
   1764 /*******************************************************************************
   1765  **
   1766  ** Function         btif_media_task_feeding_state_reset
   1767  **
   1768  ** Description      Reset the media feeding state
   1769  **
   1770  ** Returns          void
   1771  **
   1772  *******************************************************************************/
   1773 static void btif_media_task_feeding_state_reset(void)
   1774 {
   1775     /* By default, just clear the entire state */
   1776     memset(&btif_media_cb.media_feeding_state, 0, sizeof(btif_media_cb.media_feeding_state));
   1777 
   1778     if (btif_media_cb.TxTranscoding == BTIF_MEDIA_TRSCD_PCM_2_SBC)
   1779     {
   1780         btif_media_cb.media_feeding_state.pcm.bytes_per_tick =
   1781                 (btif_media_cb.media_feeding.cfg.pcm.sampling_freq *
   1782                  btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8 *
   1783                  btif_media_cb.media_feeding.cfg.pcm.num_channel *
   1784                  BTIF_MEDIA_TIME_TICK)/1000;
   1785 
   1786         APPL_TRACE_WARNING1("pcm bytes per tick %d",
   1787                             (int)btif_media_cb.media_feeding_state.pcm.bytes_per_tick);
   1788     }
   1789 }
   1790 /*******************************************************************************
   1791  **
   1792  ** Function         btif_media_task_aa_start_tx
   1793  **
   1794  ** Description      Start media task encoding
   1795  **
   1796  ** Returns          void
   1797  **
   1798  *******************************************************************************/
   1799 static void btif_media_task_aa_start_tx(void)
   1800 {
   1801     APPL_TRACE_DEBUG2("btif_media_task_aa_start_tx is timer %d, feeding mode %d",
   1802              btif_media_cb.is_tx_timer, btif_media_cb.feeding_mode);
   1803 
   1804     /* Use a timer to poll the UIPC, get rid of the UIPC call back */
   1805     // UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_CBACK, NULL);
   1806 
   1807     btif_media_cb.is_tx_timer = TRUE;
   1808 
   1809     /* Reset the media feeding state */
   1810     btif_media_task_feeding_state_reset();
   1811 
   1812     APPL_TRACE_EVENT2("starting timer %d ticks (%d)",
   1813                   GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TICKS_PER_SEC);
   1814 
   1815     GKI_start_timer(BTIF_MEDIA_AA_TASK_TIMER_ID, GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TRUE);
   1816 }
   1817 
   1818 /*******************************************************************************
   1819  **
   1820  ** Function         btif_media_task_aa_stop_tx
   1821  **
   1822  ** Description      Stop media task encoding
   1823  **
   1824  ** Returns          void
   1825  **
   1826  *******************************************************************************/
   1827 static void btif_media_task_aa_stop_tx(void)
   1828 {
   1829     APPL_TRACE_DEBUG1("btif_media_task_aa_stop_tx is timer: %d", btif_media_cb.is_tx_timer);
   1830 
   1831     /* Stop the timer first */
   1832     GKI_stop_timer(BTIF_MEDIA_AA_TASK_TIMER_ID);
   1833     btif_media_cb.is_tx_timer = FALSE;
   1834 
   1835     UIPC_Close(UIPC_CH_ID_AV_AUDIO);
   1836 
   1837     /* audio engine stopped, reset tx suspended flag */
   1838     btif_media_cb.tx_flush = 0;
   1839 
   1840     /* Reset the media feeding state */
   1841     btif_media_task_feeding_state_reset();
   1842 }
   1843 
   1844 /*******************************************************************************
   1845  **
   1846  ** Function         btif_get_num_aa_frame
   1847  **
   1848  ** Description
   1849  **
   1850  ** Returns          The number of media frames in this time slice
   1851  **
   1852  *******************************************************************************/
   1853 static UINT8 btif_get_num_aa_frame(void)
   1854 {
   1855     UINT8 result=0;
   1856 
   1857     switch (btif_media_cb.TxTranscoding)
   1858     {
   1859         case BTIF_MEDIA_TRSCD_PCM_2_SBC:
   1860            {
   1861             UINT32 pcm_bytes_per_frame = btif_media_cb.encoder.s16NumOfSubBands *
   1862                              btif_media_cb.encoder.s16NumOfBlocks *
   1863                              btif_media_cb.media_feeding.cfg.pcm.num_channel *
   1864                              btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
   1865 
   1866             btif_media_cb.media_feeding_state.pcm.counter +=
   1867                                 btif_media_cb.media_feeding_state.pcm.bytes_per_tick;
   1868 
   1869             /* calculate nbr of frames pending for this media tick */
   1870             result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
   1871             btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
   1872 
   1873             VERBOSE("WRITE %d FRAMES", result);
   1874         }
   1875         break;
   1876 
   1877         default:
   1878             APPL_TRACE_ERROR1("ERROR btif_get_num_aa_frame Unsupported transcoding format 0x%x",
   1879                     btif_media_cb.TxTranscoding);
   1880             result = 0;
   1881             break;
   1882     }
   1883 
   1884 #if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
   1885     APPL_TRACE_DEBUG1("btif_get_num_aa_frame returns %d", result);
   1886 #endif
   1887 
   1888     return result;
   1889 }
   1890 
   1891 /*******************************************************************************
   1892  **
   1893  ** Function         btif_media_aa_readbuf
   1894  **
   1895  ** Description      This function is called by the av_co to get the next buffer to send
   1896  **
   1897  **
   1898  ** Returns          void
   1899  *******************************************************************************/
   1900 BT_HDR *btif_media_aa_readbuf(void)
   1901 {
   1902     return GKI_dequeue(&(btif_media_cb.TxAaQ));
   1903 }
   1904 
   1905 /*******************************************************************************
   1906  **
   1907  ** Function         btif_media_aa_read_feeding
   1908  **
   1909  ** Description
   1910  **
   1911  ** Returns          void
   1912  **
   1913  *******************************************************************************/
   1914 
   1915 BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
   1916 {
   1917     UINT16 event;
   1918     UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * \
   1919                              btif_media_cb.encoder.s16NumOfBlocks;
   1920     UINT32 read_size;
   1921     UINT16 sbc_sampling = 48000;
   1922     UINT32 src_samples;
   1923     UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * \
   1924                           btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
   1925     static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
   1926             * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2];
   1927     static UINT16 read_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
   1928             * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
   1929     UINT32 src_size_used;
   1930     UINT32 dst_size_used;
   1931     BOOLEAN fract_needed;
   1932     INT32   fract_max;
   1933     INT32   fract_threshold;
   1934     UINT32  nb_byte_read;
   1935 
   1936     /* Get the SBC sampling rate */
   1937     switch (btif_media_cb.encoder.s16SamplingFreq)
   1938     {
   1939     case SBC_sf48000:
   1940         sbc_sampling = 48000;
   1941         break;
   1942     case SBC_sf44100:
   1943         sbc_sampling = 44100;
   1944         break;
   1945     case SBC_sf32000:
   1946         sbc_sampling = 32000;
   1947         break;
   1948     case SBC_sf16000:
   1949         sbc_sampling = 16000;
   1950         break;
   1951     }
   1952 
   1953     if (sbc_sampling == btif_media_cb.media_feeding.cfg.pcm.sampling_freq) {
   1954         read_size = bytes_needed - btif_media_cb.media_feeding_state.pcm.aa_feed_residue;
   1955         nb_byte_read = UIPC_Read(channel_id, &event,
   1956                   ((UINT8 *)btif_media_cb.encoder.as16PcmBuffer) +
   1957                   btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
   1958                   read_size);
   1959         if (nb_byte_read == read_size) {
   1960             btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
   1961             return TRUE;
   1962         } else {
   1963             APPL_TRACE_WARNING2("### UNDERFLOW :: ONLY READ %d BYTES OUT OF %d ###",
   1964                 nb_byte_read, read_size);
   1965             btif_media_cb.media_feeding_state.pcm.aa_feed_residue += nb_byte_read;
   1966             return FALSE;
   1967         }
   1968     }
   1969 
   1970     /* Some Feeding PCM frequencies require to split the number of sample */
   1971     /* to read. */
   1972     /* E.g 128/6=21.3333 => read 22 and 21 and 21 => max = 2; threshold = 0*/
   1973     fract_needed = FALSE;   /* Default */
   1974     switch (btif_media_cb.media_feeding.cfg.pcm.sampling_freq)
   1975     {
   1976     case 32000:
   1977     case 8000:
   1978         fract_needed = TRUE;
   1979         fract_max = 2;          /* 0, 1 and 2 */
   1980         fract_threshold = 0;    /* Add one for the first */
   1981         break;
   1982     case 16000:
   1983         fract_needed = TRUE;
   1984         fract_max = 2;          /* 0, 1 and 2 */
   1985         fract_threshold = 1;    /* Add one for the first two frames*/
   1986         break;
   1987     }
   1988 
   1989     /* Compute number of sample to read from source */
   1990     src_samples = blocm_x_subband;
   1991     src_samples *= btif_media_cb.media_feeding.cfg.pcm.sampling_freq;
   1992     src_samples /= sbc_sampling;
   1993 
   1994     /* The previous division may have a remainder not null */
   1995     if (fract_needed)
   1996     {
   1997         if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter <= fract_threshold)
   1998         {
   1999             src_samples++; /* for every read before threshold add one sample */
   2000         }
   2001 
   2002         /* do nothing if counter >= threshold */
   2003         btif_media_cb.media_feeding_state.pcm.aa_feed_counter++; /* one more read */
   2004         if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter > fract_max)
   2005         {
   2006             btif_media_cb.media_feeding_state.pcm.aa_feed_counter = 0;
   2007         }
   2008     }
   2009 
   2010     /* Compute number of bytes to read from source */
   2011     read_size = src_samples;
   2012     read_size *= btif_media_cb.media_feeding.cfg.pcm.num_channel;
   2013     read_size *= (btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8);
   2014 
   2015     /* Read Data from UIPC channel */
   2016     nb_byte_read = UIPC_Read(channel_id, &event, (UINT8 *)read_buffer, read_size);
   2017 
   2018     //tput_mon(TRUE, nb_byte_read, FALSE);
   2019 
   2020     if (nb_byte_read < read_size)
   2021     {
   2022         APPL_TRACE_WARNING2("### UNDERRUN :: ONLY READ %d BYTES OUT OF %d ###",
   2023                 nb_byte_read, read_size);
   2024 
   2025         if (nb_byte_read == 0)
   2026             return FALSE;
   2027 
   2028         if(btif_media_cb.feeding_mode == BTIF_AV_FEEDING_ASYNCHRONOUS)
   2029         {
   2030             /* Fill the unfilled part of the read buffer with silence (0) */
   2031             memset(((UINT8 *)read_buffer) + nb_byte_read, 0, read_size - nb_byte_read);
   2032             nb_byte_read = read_size;
   2033         }
   2034     }
   2035 
   2036     /* Initialize PCM up-sampling engine */
   2037     bta_av_sbc_init_up_sample(btif_media_cb.media_feeding.cfg.pcm.sampling_freq,
   2038             sbc_sampling, btif_media_cb.media_feeding.cfg.pcm.bit_per_sample,
   2039             btif_media_cb.media_feeding.cfg.pcm.num_channel);
   2040 
   2041     /* re-sample read buffer */
   2042     /* The output PCM buffer will be stereo, 16 bit per sample */
   2043     dst_size_used = bta_av_sbc_up_sample((UINT8 *)read_buffer,
   2044             (UINT8 *)up_sampled_buffer + btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
   2045             nb_byte_read,
   2046             sizeof(up_sampled_buffer) - btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
   2047             &src_size_used);
   2048 
   2049 #if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
   2050     APPL_TRACE_DEBUG3("btif_media_aa_read_feeding readsz:%d src_size_used:%d dst_size_used:%d",
   2051             read_size, src_size_used, dst_size_used);
   2052 #endif
   2053 
   2054     /* update the residue */
   2055     btif_media_cb.media_feeding_state.pcm.aa_feed_residue += dst_size_used;
   2056 
   2057     /* only copy the pcm sample when we have up-sampled enough PCM */
   2058     if(btif_media_cb.media_feeding_state.pcm.aa_feed_residue >= bytes_needed)
   2059     {
   2060         /* Copy the output pcm samples in SBC encoding buffer */
   2061         memcpy((UINT8 *)btif_media_cb.encoder.as16PcmBuffer,
   2062                 (UINT8 *)up_sampled_buffer,
   2063                 bytes_needed);
   2064         /* update the residue */
   2065         btif_media_cb.media_feeding_state.pcm.aa_feed_residue -= bytes_needed;
   2066 
   2067         if (btif_media_cb.media_feeding_state.pcm.aa_feed_residue != 0)
   2068         {
   2069             memcpy((UINT8 *)up_sampled_buffer,
   2070                    (UINT8 *)up_sampled_buffer + bytes_needed,
   2071                    btif_media_cb.media_feeding_state.pcm.aa_feed_residue);
   2072         }
   2073         return TRUE;
   2074     }
   2075 
   2076 #if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
   2077     APPL_TRACE_DEBUG3("btif_media_aa_read_feeding residue:%d, dst_size_used %d, bytes_needed %d",
   2078             btif_media_cb.media_feeding_state.pcm.aa_feed_residue, dst_size_used, bytes_needed);
   2079 #endif
   2080 
   2081     return FALSE;
   2082 }
   2083 
   2084 /*******************************************************************************
   2085  **
   2086  ** Function         btif_media_aa_prep_sbc_2_send
   2087  **
   2088  ** Description
   2089  **
   2090  ** Returns          void
   2091  **
   2092  *******************************************************************************/
   2093 static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)
   2094 {
   2095     BT_HDR * p_buf;
   2096     UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands *
   2097                              btif_media_cb.encoder.s16NumOfBlocks;
   2098 
   2099 #if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
   2100     APPL_TRACE_DEBUG2("btif_media_aa_prep_sbc_2_send nb_frame %d, TxAaQ %d",
   2101                        nb_frame, btif_media_cb.TxAaQ.count);
   2102 #endif
   2103     while (nb_frame)
   2104     {
   2105         if (NULL == (p_buf = GKI_getpoolbuf(BTIF_MEDIA_AA_POOL_ID)))
   2106         {
   2107             APPL_TRACE_ERROR1 ("ERROR btif_media_aa_prep_sbc_2_send no buffer TxCnt %d ",
   2108                                 btif_media_cb.TxAaQ.count);
   2109             return;
   2110         }
   2111 
   2112         /* Init buffer */
   2113         p_buf->offset = BTIF_MEDIA_AA_SBC_OFFSET;
   2114         p_buf->len = 0;
   2115         p_buf->layer_specific = 0;
   2116 
   2117         do
   2118         {
   2119             /* Write @ of allocated buffer in encoder.pu8Packet */
   2120             btif_media_cb.encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
   2121             /* Fill allocated buffer with 0 */
   2122             memset(btif_media_cb.encoder.as16PcmBuffer, 0, blocm_x_subband
   2123                     * btif_media_cb.encoder.s16NumOfChannels);
   2124 
   2125             /* Read PCM data and upsample them if needed */
   2126             if (btif_media_aa_read_feeding(UIPC_CH_ID_AV_AUDIO))
   2127             {
   2128                 /* SBC encode and descramble frame */
   2129                 SBC_Encoder(&(btif_media_cb.encoder));
   2130                 A2D_SbcChkFrInit(btif_media_cb.encoder.pu8Packet);
   2131                 A2D_SbcDescramble(btif_media_cb.encoder.pu8Packet, btif_media_cb.encoder.u16PacketLength);
   2132                 /* Update SBC frame length */
   2133                 p_buf->len += btif_media_cb.encoder.u16PacketLength;
   2134                 nb_frame--;
   2135                 p_buf->layer_specific++;
   2136             }
   2137             else
   2138             {
   2139                 APPL_TRACE_WARNING2("btif_media_aa_prep_sbc_2_send underflow %d, %d",
   2140                     nb_frame, btif_media_cb.media_feeding_state.pcm.aa_feed_residue);
   2141                 btif_media_cb.media_feeding_state.pcm.counter += nb_frame *
   2142                      btif_media_cb.encoder.s16NumOfSubBands *
   2143                      btif_media_cb.encoder.s16NumOfBlocks *
   2144                      btif_media_cb.media_feeding.cfg.pcm.num_channel *
   2145                      btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
   2146                 /* no more pcm to read */
   2147                 nb_frame = 0;
   2148 
   2149                 /* break read loop if timer was stopped (media task stopped) */
   2150                 if ( btif_media_cb.is_tx_timer == FALSE )
   2151                     return;
   2152             }
   2153 
   2154         } while (((p_buf->len + btif_media_cb.encoder.u16PacketLength) < btif_media_cb.TxAaMtuSize)
   2155                 && (p_buf->layer_specific < 0x0F) && nb_frame);
   2156 
   2157         if(p_buf->len)
   2158         {
   2159             /* timestamp of the media packet header represent the TS of the first SBC frame
   2160                i.e the timestamp before including this frame */
   2161             *((UINT32 *) (p_buf + 1)) = btif_media_cb.timestamp;
   2162 
   2163             btif_media_cb.timestamp += p_buf->layer_specific * blocm_x_subband;
   2164 
   2165             VERBOSE("TX QUEUE NOW %d", btif_media_cb.TxAaQ.count);
   2166 
   2167             if (btif_media_cb.tx_flush)
   2168             {
   2169                 APPL_TRACE_DEBUG0("### tx suspended, discarded frame ###");
   2170 
   2171                 if (btif_media_cb.TxAaQ.count > 0)
   2172                     btif_media_flush_q(&(btif_media_cb.TxAaQ));
   2173 
   2174                 GKI_freebuf(p_buf);
   2175                 return;
   2176             }
   2177 
   2178             /* Enqueue the encoded SBC frame in AA Tx Queue */
   2179             GKI_enqueue(&(btif_media_cb.TxAaQ), p_buf);
   2180         }
   2181         else
   2182         {
   2183             GKI_freebuf(p_buf);
   2184         }
   2185     }
   2186 }
   2187 
   2188 
   2189 /*******************************************************************************
   2190  **
   2191  ** Function         btif_media_aa_prep_2_send
   2192  **
   2193  ** Description
   2194  **
   2195  ** Returns          void
   2196  **
   2197  *******************************************************************************/
   2198 
   2199 static void btif_media_aa_prep_2_send(UINT8 nb_frame)
   2200 {
   2201     VERBOSE("btif_media_aa_prep_2_send : %d frames (queue %d)", nb_frame,
   2202                        btif_media_cb.TxAaQ.count);
   2203 
   2204     while (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ)
   2205     {
   2206         APPL_TRACE_WARNING1("btif_media_aa_prep_2_send congestion buf count %d",
   2207                              btif_media_cb.TxAaQ.count);
   2208         GKI_freebuf(GKI_dequeue(&(btif_media_cb.TxAaQ)));
   2209     }
   2210 
   2211     switch (btif_media_cb.TxTranscoding)
   2212     {
   2213     case BTIF_MEDIA_TRSCD_PCM_2_SBC:
   2214         btif_media_aa_prep_sbc_2_send(nb_frame);
   2215         break;
   2216 
   2217 
   2218     default:
   2219         APPL_TRACE_ERROR1("ERROR btif_media_aa_prep_2_send unsupported transcoding format 0x%x",btif_media_cb.TxTranscoding);
   2220         break;
   2221     }
   2222 }
   2223 
   2224 /*******************************************************************************
   2225  **
   2226  ** Function         btif_media_send_aa_frame
   2227  **
   2228  ** Description
   2229  **
   2230  ** Returns          void
   2231  **
   2232  *******************************************************************************/
   2233 static void btif_media_send_aa_frame(void)
   2234 {
   2235     UINT8 nb_frame_2_send;
   2236 
   2237     /* get the number of frame to send */
   2238     nb_frame_2_send = btif_get_num_aa_frame();
   2239 
   2240     /* format and Q buffer to send */
   2241     btif_media_aa_prep_2_send(nb_frame_2_send);
   2242 
   2243     /* send it */
   2244     VERBOSE("btif_media_send_aa_frame : send %d frames", nb_frame_2_send);
   2245     bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
   2246 }
   2247 
   2248 #endif /* BTA_AV_INCLUDED == TRUE */
   2249 
   2250 /*******************************************************************************
   2251  **
   2252  ** Function         dump_codec_info
   2253  **
   2254  ** Description      Decode and display codec_info (for debug)
   2255  **
   2256  ** Returns          void
   2257  **
   2258  *******************************************************************************/
   2259 void dump_codec_info(unsigned char *p_codec)
   2260 {
   2261     tA2D_STATUS a2d_status;
   2262     tA2D_SBC_CIE sbc_cie;
   2263 
   2264     a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec, FALSE);
   2265     if (a2d_status != A2D_SUCCESS)
   2266     {
   2267         APPL_TRACE_ERROR1("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
   2268         return;
   2269     }
   2270 
   2271     APPL_TRACE_DEBUG0("dump_codec_info");
   2272 
   2273     if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_16)
   2274     {    APPL_TRACE_DEBUG1("\tsamp_freq:%d (16000)", sbc_cie.samp_freq);}
   2275     else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_32)
   2276     {    APPL_TRACE_DEBUG1("\tsamp_freq:%d (32000)", sbc_cie.samp_freq);}
   2277     else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_44)
   2278     {    APPL_TRACE_DEBUG1("\tsamp_freq:%d (44.100)", sbc_cie.samp_freq);}
   2279     else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_48)
   2280     {    APPL_TRACE_DEBUG1("\tsamp_freq:%d (48000)", sbc_cie.samp_freq);}
   2281     else
   2282     {    APPL_TRACE_DEBUG1("\tBAD samp_freq:%d", sbc_cie.samp_freq);}
   2283 
   2284     if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_MONO)
   2285     {    APPL_TRACE_DEBUG1("\tch_mode:%d (Mono)", sbc_cie.ch_mode);}
   2286     else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_DUAL)
   2287     {    APPL_TRACE_DEBUG1("\tch_mode:%d (Dual)", sbc_cie.ch_mode);}
   2288     else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_STEREO)
   2289     {    APPL_TRACE_DEBUG1("\tch_mode:%d (Stereo)", sbc_cie.ch_mode);}
   2290     else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_JOINT)
   2291     {    APPL_TRACE_DEBUG1("\tch_mode:%d (Joint)", sbc_cie.ch_mode);}
   2292     else
   2293     {    APPL_TRACE_DEBUG1("\tBAD ch_mode:%d", sbc_cie.ch_mode);}
   2294 
   2295     if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_4)
   2296     {    APPL_TRACE_DEBUG1("\tblock_len:%d (4)", sbc_cie.block_len);}
   2297     else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_8)
   2298     {    APPL_TRACE_DEBUG1("\tblock_len:%d (8)", sbc_cie.block_len);}
   2299     else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_12)
   2300     {    APPL_TRACE_DEBUG1("\tblock_len:%d (12)", sbc_cie.block_len);}
   2301     else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_16)
   2302     {    APPL_TRACE_DEBUG1("\tblock_len:%d (16)", sbc_cie.block_len);}
   2303     else
   2304     {    APPL_TRACE_DEBUG1("\tBAD block_len:%d", sbc_cie.block_len);}
   2305 
   2306     if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_4)
   2307     {    APPL_TRACE_DEBUG1("\tnum_subbands:%d (4)", sbc_cie.num_subbands);}
   2308     else  if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_8)
   2309     {    APPL_TRACE_DEBUG1("\tnum_subbands:%d (8)", sbc_cie.num_subbands);}
   2310     else
   2311     {    APPL_TRACE_DEBUG1("\tBAD num_subbands:%d", sbc_cie.num_subbands);}
   2312 
   2313     if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_S)
   2314     {    APPL_TRACE_DEBUG1("\talloc_mthd:%d (SNR)", sbc_cie.alloc_mthd);}
   2315     else  if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L)
   2316     {    APPL_TRACE_DEBUG1("\talloc_mthd:%d (Loundess)", sbc_cie.alloc_mthd);}
   2317     else
   2318     {    APPL_TRACE_DEBUG1("\tBAD alloc_mthd:%d", sbc_cie.alloc_mthd);}
   2319 
   2320     APPL_TRACE_DEBUG2("\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
   2321 
   2322 }
   2323