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#if (BTA_AV_SINK_INCLUDED == TRUE)
70#include "oi_codec_sbc.h"
71#include "oi_status.h"
72#endif
73#include "stdio.h"
74#include <dlfcn.h>
75
76//#define DEBUG_MEDIA_AV_FLOW TRUE
77
78#if (BTA_AV_SINK_INCLUDED == TRUE)
79OI_CODEC_SBC_DECODER_CONTEXT context;
80OI_UINT32 contextData[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
81OI_INT16 pcmData[15*SBC_MAX_SAMPLES_PER_FRAME*SBC_MAX_CHANNELS];
82#endif
83
84/*****************************************************************************
85 **  Constants
86 *****************************************************************************/
87
88#ifndef AUDIO_CHANNEL_OUT_MONO
89#define AUDIO_CHANNEL_OUT_MONO 0x01
90#endif
91
92#ifndef AUDIO_CHANNEL_OUT_STEREO
93#define AUDIO_CHANNEL_OUT_STEREO 0x03
94#endif
95
96/* BTIF media task gki event definition */
97#define BTIF_MEDIA_TASK_CMD TASK_MBOX_0_EVT_MASK
98#define BTIF_MEDIA_TASK_DATA TASK_MBOX_1_EVT_MASK
99
100#define BTIF_MEDIA_TASK_KILL EVENT_MASK(GKI_SHUTDOWN_EVT)
101
102#define BTIF_MEDIA_AA_TASK_TIMER_ID TIMER_0
103#define BTIF_MEDIA_AV_TASK_TIMER_ID TIMER_1
104#define BTIF_MEDIA_AVK_TASK_TIMER_ID TIMER_2
105
106#define BTIF_MEDIA_AA_TASK_TIMER TIMER_0_EVT_MASK
107#define BTIF_MEDIA_AV_TASK_TIMER TIMER_1_EVT_MASK
108#define BTIF_MEDIA_AVK_TASK_TIMER TIMER_2_EVT_MASK
109
110
111#define BTIF_MEDIA_TASK_CMD_MBOX        TASK_MBOX_0     /* cmd mailbox  */
112#define BTIF_MEDIA_TASK_DATA_MBOX       TASK_MBOX_1     /* data mailbox  */
113
114
115/* BTIF media cmd event definition : BTIF_MEDIA_TASK_CMD */
116enum
117{
118    BTIF_MEDIA_START_AA_TX = 1,
119    BTIF_MEDIA_STOP_AA_TX,
120    BTIF_MEDIA_AA_RX_RDY,
121    BTIF_MEDIA_UIPC_RX_RDY,
122    BTIF_MEDIA_SBC_ENC_INIT,
123    BTIF_MEDIA_SBC_ENC_UPDATE,
124    BTIF_MEDIA_SBC_DEC_INIT,
125    BTIF_MEDIA_VIDEO_DEC_INIT,
126    BTIF_MEDIA_FLUSH_AA_TX,
127    BTIF_MEDIA_FLUSH_AA_RX,
128    BTIF_MEDIA_AUDIO_FEEDING_INIT,
129    BTIF_MEDIA_AUDIO_RECEIVING_INIT,
130    BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE,
131    BTIF_MEDIA_AUDIO_SINK_START_DECODING,
132    BTIF_MEDIA_AUDIO_SINK_STOP_DECODING,
133    BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK
134};
135
136enum {
137    MEDIA_TASK_STATE_OFF = 0,
138    MEDIA_TASK_STATE_ON = 1,
139    MEDIA_TASK_STATE_SHUTTING_DOWN = 2
140};
141
142/* Macro to multiply the media task tick */
143#ifndef BTIF_MEDIA_NUM_TICK
144#define BTIF_MEDIA_NUM_TICK      1
145#endif
146
147/* Media task tick in milliseconds, must be set to multiple of
148   (1000/TICKS_PER_SEC) (10) */
149
150#define BTIF_MEDIA_TIME_TICK                     (20 * BTIF_MEDIA_NUM_TICK)
151#define A2DP_DATA_READ_POLL_MS    (BTIF_MEDIA_TIME_TICK / 2)
152#define BTIF_SINK_MEDIA_TIME_TICK                (20 * BTIF_MEDIA_NUM_TICK)
153
154
155/* buffer pool */
156#define BTIF_MEDIA_AA_POOL_ID GKI_POOL_ID_3
157#define BTIF_MEDIA_AA_BUF_SIZE GKI_BUF3_SIZE
158
159/* offset */
160#if (BTA_AV_CO_CP_SCMS_T == TRUE)
161#define BTIF_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE + 1)
162#else
163#define BTIF_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE)
164#endif
165
166/* Define the bitrate step when trying to match bitpool value */
167#ifndef BTIF_MEDIA_BITRATE_STEP
168#define BTIF_MEDIA_BITRATE_STEP 5
169#endif
170
171/* Middle quality quality setting @ 44.1 khz */
172#define DEFAULT_SBC_BITRATE 328
173
174#ifndef BTIF_A2DP_NON_EDR_MAX_RATE
175#define BTIF_A2DP_NON_EDR_MAX_RATE 229
176#endif
177
178#ifndef A2DP_MEDIA_TASK_STACK_SIZE
179#define A2DP_MEDIA_TASK_STACK_SIZE       0x2000         /* In bytes */
180#endif
181
182#define A2DP_MEDIA_TASK_TASK_STR        ((INT8 *) "A2DP-MEDIA")
183static UINT32 a2dp_media_task_stack[(A2DP_MEDIA_TASK_STACK_SIZE + 3) / 4];
184
185#define BT_MEDIA_TASK A2DP_MEDIA_TASK
186
187#define USEC_PER_SEC 1000000L
188#define TPUT_STATS_INTERVAL_US (3000*1000)
189
190/*
191 * CONGESTION COMPENSATION CTRL ::
192 *
193 * Thus setting controls how many buffers we will hold in media task
194 * during temp link congestion. Together with the stack buffer queues
195 * it controls much temporary a2dp link congestion we can
196 * compensate for. It however also depends on the default run level of sinks
197 * jitterbuffers. Depending on type of sink this would vary.
198 * Ideally the (SRC) max tx buffer capacity should equal the sinks
199 * jitterbuffer runlevel including any intermediate buffers on the way
200 * towards the sinks codec.
201 */
202
203/* fixme -- define this in pcm time instead of buffer count */
204
205/* The typical runlevel of the tx queue size is ~1 buffer
206   but due to link flow control or thread preemption in lower
207   layers we might need to temporarily buffer up data */
208
209/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
210#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 18
211#define A2DP_PACKET_COUNT_LOW_WATERMARK 5
212#define MAX_PCM_FRAME_NUM_PER_TICK     10
213#define RESET_RATE_COUNTER_THRESHOLD_MS    2000
214
215//#define BTIF_MEDIA_VERBOSE_ENABLED
216/* In case of A2DP SINK, we will delay start by 5 AVDTP Packets*/
217#define MAX_A2DP_DELAYED_START_FRAME_COUNT 5
218#define PACKET_PLAYED_PER_TICK_48 8
219#define PACKET_PLAYED_PER_TICK_44 7
220#define PACKET_PLAYED_PER_TICK_32 5
221#define PACKET_PLAYED_PER_TICK_16 3
222
223
224#ifdef BTIF_MEDIA_VERBOSE_ENABLED
225#define VERBOSE(fmt, ...) \
226      LogMsg( TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
227              TRACE_TYPE_ERROR, fmt, ## __VA_ARGS__)
228#else
229#define VERBOSE(fmt, ...)
230#endif
231
232/*****************************************************************************
233 **  Data types
234 *****************************************************************************/
235typedef struct
236{
237    UINT16 num_frames_to_be_processed;
238    UINT16 len;
239    UINT16 offset;
240    UINT16 layer_specific;
241} tBT_SBC_HDR;
242
243typedef struct
244{
245    UINT32 aa_frame_counter;
246    INT32  aa_feed_counter;
247    INT32  aa_feed_residue;
248    UINT32 counter;
249    UINT32 bytes_per_tick;  /* pcm bytes read each media task tick */
250    UINT32 max_counter_exit;
251    UINT32 max_counter_enter;
252    UINT32 overflow_count;
253    BOOLEAN overflow;
254} tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE;
255
256
257typedef union
258{
259    tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE pcm;
260} tBTIF_AV_MEDIA_FEEDINGS_STATE;
261
262typedef struct
263{
264#if (BTA_AV_INCLUDED == TRUE)
265    BUFFER_Q TxAaQ;
266    BUFFER_Q RxSbcQ;
267    BOOLEAN is_tx_timer;
268    BOOLEAN is_rx_timer;
269    UINT16 TxAaMtuSize;
270    UINT32 timestamp;
271    UINT8 TxTranscoding;
272    tBTIF_AV_FEEDING_MODE feeding_mode;
273    tBTIF_AV_MEDIA_FEEDINGS media_feeding;
274    tBTIF_AV_MEDIA_FEEDINGS_STATE media_feeding_state;
275    SBC_ENC_PARAMS encoder;
276    UINT8 busy_level;
277    void* av_sm_hdl;
278    UINT8 a2dp_cmd_pending; /* we can have max one command pending */
279    BOOLEAN tx_flush; /* discards any outgoing data when true */
280    BOOLEAN rx_flush; /* discards any incoming data when true */
281    UINT8 peer_sep;
282    BOOLEAN data_channel_open;
283    UINT8   frames_to_process;
284
285    UINT32  sample_rate;
286    UINT8   channel_count;
287#endif
288
289} tBTIF_MEDIA_CB;
290
291typedef struct {
292    long long rx;
293    long long rx_tot;
294    long long tx;
295    long long tx_tot;
296    long long ts_prev_us;
297} t_stat;
298
299/*****************************************************************************
300 **  Local data
301 *****************************************************************************/
302
303static tBTIF_MEDIA_CB btif_media_cb;
304static int media_task_running = MEDIA_TASK_STATE_OFF;
305static UINT64 last_frame_us = 0;
306
307
308/*****************************************************************************
309 **  Local functions
310 *****************************************************************************/
311
312static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
313static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
314static void btif_a2dp_encoder_update(void);
315const char* dump_media_event(UINT16 event);
316#if (BTA_AV_SINK_INCLUDED == TRUE)
317extern OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
318                                          const OI_BYTE **frameData,
319                                          unsigned long *frameBytes,
320                                          OI_INT16 *pcmData,
321                                          unsigned long *pcmBytes);
322extern OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
323                                           unsigned long *decoderData,
324                                           unsigned long decoderDataBytes,
325                                           OI_UINT8 maxChannels,
326                                           OI_UINT8 pcmStride,
327                                           OI_BOOL enhanced);
328#endif
329static void btif_media_flush_q(BUFFER_Q *p_q);
330static void btif_media_task_aa_handle_stop_decoding(void );
331static void btif_media_task_aa_rx_flush(void);
332static BOOLEAN btif_media_task_stop_decoding_req(void);
333
334/*****************************************************************************
335 **  Externs
336 *****************************************************************************/
337
338static void btif_media_task_handle_cmd(BT_HDR *p_msg);
339static void btif_media_task_handle_media(BT_HDR*p_msg);
340/* Handle incoming media packets A2DP SINK streaming*/
341#if (BTA_AV_SINK_INCLUDED == TRUE)
342static void btif_media_task_handle_inc_media(tBT_SBC_HDR*p_msg);
343#endif
344
345#if (BTA_AV_INCLUDED == TRUE)
346static void btif_media_send_aa_frame(void);
347static void btif_media_task_feeding_state_reset(void);
348static void btif_media_task_aa_start_tx(void);
349static void btif_media_task_aa_stop_tx(void);
350static void btif_media_task_enc_init(BT_HDR *p_msg);
351static void btif_media_task_enc_update(BT_HDR *p_msg);
352static void btif_media_task_audio_feeding_init(BT_HDR *p_msg);
353static void btif_media_task_aa_tx_flush(BT_HDR *p_msg);
354static void btif_media_aa_prep_2_send(UINT8 nb_frame);
355#if (BTA_AV_SINK_INCLUDED == TRUE)
356static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg);
357static void btif_media_task_aa_handle_clear_track(void);
358#endif
359static void btif_media_task_aa_handle_start_decoding(void );
360#endif
361BOOLEAN btif_media_task_start_decoding_req(void);
362BOOLEAN btif_media_task_clear_track(void);
363/*****************************************************************************
364 **  Misc helper functions
365 *****************************************************************************/
366
367static UINT64 time_now_us()
368{
369    struct timespec ts_now;
370    clock_gettime(CLOCK_BOOTTIME, &ts_now);
371    return ((UINT64)ts_now.tv_sec * USEC_PER_SEC) + ((UINT64)ts_now.tv_nsec / 1000);
372}
373
374static void log_tstamps_us(char *comment)
375{
376    static UINT64 prev_us = 0;
377    const UINT64 now_us = time_now_us();
378    APPL_TRACE_DEBUG("[%s] ts %08llu, diff : %08llu, queue sz %d", comment, now_us, now_us - prev_us,
379                btif_media_cb.TxAaQ.count);
380    prev_us = now_us;
381}
382
383const char* dump_media_event(UINT16 event)
384{
385    switch(event)
386    {
387        CASE_RETURN_STR(BTIF_MEDIA_START_AA_TX)
388        CASE_RETURN_STR(BTIF_MEDIA_STOP_AA_TX)
389        CASE_RETURN_STR(BTIF_MEDIA_AA_RX_RDY)
390        CASE_RETURN_STR(BTIF_MEDIA_UIPC_RX_RDY)
391        CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_INIT)
392        CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_UPDATE)
393        CASE_RETURN_STR(BTIF_MEDIA_SBC_DEC_INIT)
394        CASE_RETURN_STR(BTIF_MEDIA_VIDEO_DEC_INIT)
395        CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_TX)
396        CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_RX)
397        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_FEEDING_INIT)
398        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_RECEIVING_INIT)
399        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE)
400        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_START_DECODING)
401        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_STOP_DECODING)
402        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK)
403
404        default:
405            return "UNKNOWN MEDIA EVENT";
406    }
407}
408
409/*****************************************************************************
410 **  A2DP CTRL PATH
411 *****************************************************************************/
412
413static const char* dump_a2dp_ctrl_event(UINT8 event)
414{
415    switch(event)
416    {
417        CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
418        CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
419        CASE_RETURN_STR(A2DP_CTRL_CMD_START)
420        CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
421        CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
422        default:
423            return "UNKNOWN MSG ID";
424    }
425}
426
427static void btif_audiopath_detached(void)
428{
429    APPL_TRACE_EVENT("## AUDIO PATH DETACHED ##");
430
431    /*  send stop request only if we are actively streaming and haven't received
432        a stop request. Potentially audioflinger detached abnormally */
433    if (btif_media_cb.is_tx_timer)
434    {
435        /* post stop event and wait for audio path to stop */
436        btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
437    }
438}
439
440static void a2dp_cmd_acknowledge(int status)
441{
442    UINT8 ack = status;
443
444    APPL_TRACE_EVENT("## a2dp ack : %s, status %d ##",
445          dump_a2dp_ctrl_event(btif_media_cb.a2dp_cmd_pending), status);
446
447    /* sanity check */
448    if (btif_media_cb.a2dp_cmd_pending == A2DP_CTRL_CMD_NONE)
449    {
450        APPL_TRACE_ERROR("warning : no command pending, ignore ack");
451        return;
452    }
453
454    /* clear pending */
455    btif_media_cb.a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
456
457    /* acknowledge start request */
458    UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, &ack, 1);
459}
460
461
462static void btif_recv_ctrl_data(void)
463{
464    UINT8 cmd = 0;
465    int n;
466    n = UIPC_Read(UIPC_CH_ID_AV_CTRL, NULL, &cmd, 1);
467
468    /* detach on ctrl channel means audioflinger process was terminated */
469    if (n == 0)
470    {
471        APPL_TRACE_EVENT("CTRL CH DETACHED");
472        UIPC_Close(UIPC_CH_ID_AV_CTRL);
473        /* we can operate only on datachannel, if af client wants to
474           do send additional commands the ctrl channel would be reestablished */
475        //btif_audiopath_detached();
476        return;
477    }
478
479    APPL_TRACE_DEBUG("a2dp-ctrl-cmd : %s", dump_a2dp_ctrl_event(cmd));
480
481    btif_media_cb.a2dp_cmd_pending = cmd;
482
483    switch(cmd)
484    {
485        case A2DP_CTRL_CMD_CHECK_READY:
486
487            if (media_task_running == MEDIA_TASK_STATE_SHUTTING_DOWN)
488            {
489                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
490                return;
491            }
492
493            /* check whether av is ready to setup a2dp datapath */
494            if ((btif_av_stream_ready() == TRUE) || (btif_av_stream_started_ready() == TRUE))
495            {
496                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
497            }
498            else
499            {
500                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
501            }
502            break;
503
504        case A2DP_CTRL_CMD_START:
505
506            if (btif_av_stream_ready() == TRUE)
507            {
508                /* setup audio data channel listener */
509                UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
510
511                /* post start event and wait for audio path to open */
512                btif_dispatch_sm_event(BTIF_AV_START_STREAM_REQ_EVT, NULL, 0);
513
514#if (BTA_AV_SINK_INCLUDED == TRUE)
515                if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
516                    a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
517#endif
518            }
519            else if (btif_av_stream_started_ready())
520            {
521                /* already started, setup audio data channel listener
522                   and ack back immediately */
523                UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
524
525                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
526            }
527            else
528            {
529                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
530                break;
531            }
532            break;
533
534        case A2DP_CTRL_CMD_STOP:
535            if (btif_media_cb.peer_sep == AVDT_TSEP_SNK && btif_media_cb.is_tx_timer == FALSE)
536            {
537                /* we are already stopped, just ack back */
538                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
539                break;
540            }
541
542            btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
543            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
544            break;
545
546        case A2DP_CTRL_CMD_SUSPEND:
547            /* local suspend */
548            if (btif_av_stream_started_ready())
549            {
550                btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
551            }
552            else
553            {
554                /* if we are not in started state, just ack back ok and let
555                   audioflinger close the channel. This can happen if we are
556                   remotely suspended */
557                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
558            }
559            break;
560
561        case A2DP_CTRL_GET_AUDIO_CONFIG:
562        {
563            uint32_t sample_rate = btif_media_cb.sample_rate;
564            uint8_t channel_count = btif_media_cb.channel_count;
565
566            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
567            UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, (UINT8 *)&sample_rate, 4);
568            UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, &channel_count, 1);
569            break;
570        }
571
572        default:
573            APPL_TRACE_ERROR("UNSUPPORTED CMD (%d)", cmd);
574            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
575            break;
576    }
577    APPL_TRACE_DEBUG("a2dp-ctrl-cmd : %s DONE", dump_a2dp_ctrl_event(cmd));
578}
579
580static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
581{
582    UNUSED(ch_id);
583
584    APPL_TRACE_DEBUG("A2DP-CTRL-CHANNEL EVENT %s", dump_uipc_event(event));
585
586    switch(event)
587    {
588        case UIPC_OPEN_EVT:
589            /* fetch av statemachine handle */
590            btif_media_cb.av_sm_hdl = btif_av_get_sm_handle();
591            break;
592
593        case UIPC_CLOSE_EVT:
594            /* restart ctrl server unless we are shutting down */
595            if (media_task_running == MEDIA_TASK_STATE_ON)
596                UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
597            break;
598
599        case UIPC_RX_DATA_READY_EVT:
600            btif_recv_ctrl_data();
601            break;
602
603        default :
604            APPL_TRACE_ERROR("### A2DP-CTRL-CHANNEL EVENT %d NOT HANDLED ###", event);
605            break;
606    }
607}
608
609static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
610{
611    UNUSED(ch_id);
612
613    APPL_TRACE_DEBUG("BTIF MEDIA (A2DP-DATA) EVENT %s", dump_uipc_event(event));
614
615    switch(event)
616    {
617        case UIPC_OPEN_EVT:
618
619            /*  read directly from media task from here on (keep callback for
620                connection events */
621            UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
622            UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
623                       (void *)A2DP_DATA_READ_POLL_MS);
624
625            if (btif_media_cb.peer_sep == AVDT_TSEP_SNK) {
626                /* Start the media task to encode SBC */
627                btif_media_task_start_aa_req();
628
629                /* make sure we update any changed sbc encoder params */
630                btif_a2dp_encoder_update();
631            }
632            btif_media_cb.data_channel_open = TRUE;
633
634            /* ack back when media task is fully started */
635            break;
636
637        case UIPC_CLOSE_EVT:
638            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
639            btif_audiopath_detached();
640            btif_media_cb.data_channel_open = FALSE;
641            break;
642
643        default :
644            APPL_TRACE_ERROR("### A2DP-DATA EVENT %d NOT HANDLED ###", event);
645            break;
646    }
647}
648
649
650/*****************************************************************************
651 **  BTIF ADAPTATION
652 *****************************************************************************/
653
654static UINT16 btif_media_task_get_sbc_rate(void)
655{
656    UINT16 rate = DEFAULT_SBC_BITRATE;
657
658    /* restrict bitrate if a2dp link is non-edr */
659    if (!btif_av_is_peer_edr())
660    {
661        rate = BTIF_A2DP_NON_EDR_MAX_RATE;
662        APPL_TRACE_DEBUG("non-edr a2dp sink detected, restrict rate to %d", rate);
663    }
664
665    return rate;
666}
667
668static void btif_a2dp_encoder_init(void)
669{
670    UINT16 minmtu;
671    tBTIF_MEDIA_INIT_AUDIO msg;
672    tA2D_SBC_CIE sbc_config;
673
674    /* lookup table for converting channel mode */
675    UINT16 codec_mode_tbl[5] = { SBC_JOINT_STEREO, SBC_STEREO, SBC_DUAL, 0, SBC_MONO };
676
677    /* lookup table for converting number of blocks */
678    UINT16 codec_block_tbl[5] = { 16, 12, 8, 0, 4 };
679
680    /* lookup table to convert freq */
681    UINT16 freq_block_tbl[5] = { SBC_sf48000, SBC_sf44100, SBC_sf32000, 0, SBC_sf16000 };
682
683    APPL_TRACE_DEBUG("btif_a2dp_encoder_init");
684
685    /* Retrieve the current SBC configuration (default if currently not used) */
686    bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
687    msg.NumOfSubBands = (sbc_config.num_subbands == A2D_SBC_IE_SUBBAND_4) ? 4 : 8;
688    msg.NumOfBlocks = codec_block_tbl[sbc_config.block_len >> 5];
689    msg.AllocationMethod = (sbc_config.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L) ? SBC_LOUDNESS : SBC_SNR;
690    msg.ChannelMode = codec_mode_tbl[sbc_config.ch_mode >> 1];
691    msg.SamplingFreq = freq_block_tbl[sbc_config.samp_freq >> 5];
692    msg.MtuSize = minmtu;
693
694    APPL_TRACE_EVENT("msg.ChannelMode %x", msg.ChannelMode);
695
696    /* Init the media task to encode SBC properly */
697    btif_media_task_enc_init_req(&msg);
698}
699
700static void btif_a2dp_encoder_update(void)
701{
702    UINT16 minmtu;
703    tA2D_SBC_CIE sbc_config;
704    tBTIF_MEDIA_UPDATE_AUDIO msg;
705    UINT8 pref_min;
706    UINT8 pref_max;
707
708    APPL_TRACE_DEBUG("btif_a2dp_encoder_update");
709
710    /* Retrieve the current SBC configuration (default if currently not used) */
711    bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
712
713    APPL_TRACE_DEBUG("btif_a2dp_encoder_update: Common min_bitpool:%d(0x%x) max_bitpool:%d(0x%x)",
714            sbc_config.min_bitpool, sbc_config.min_bitpool,
715            sbc_config.max_bitpool, sbc_config.max_bitpool);
716
717    if (sbc_config.min_bitpool > sbc_config.max_bitpool)
718    {
719        APPL_TRACE_ERROR("btif_a2dp_encoder_update: ERROR btif_a2dp_encoder_update min_bitpool > max_bitpool");
720    }
721
722    /* check if remote sink has a preferred bitpool range */
723    if (bta_av_co_get_remote_bitpool_pref(&pref_min, &pref_max) == TRUE)
724    {
725        /* adjust our preferred bitpool with the remote preference if within
726           our capable range */
727
728        if (pref_min < sbc_config.min_bitpool)
729            pref_min = sbc_config.min_bitpool;
730
731        if (pref_max > sbc_config.max_bitpool)
732            pref_max = sbc_config.max_bitpool;
733
734        msg.MinBitPool = pref_min;
735        msg.MaxBitPool = pref_max;
736
737        if ((pref_min != sbc_config.min_bitpool) || (pref_max != sbc_config.max_bitpool))
738        {
739            APPL_TRACE_EVENT("## adjusted our bitpool range to peer pref [%d:%d] ##",
740                pref_min, pref_max);
741        }
742    }
743    else
744    {
745        msg.MinBitPool = sbc_config.min_bitpool;
746        msg.MaxBitPool = sbc_config.max_bitpool;
747    }
748
749    msg.MinMtuSize = minmtu;
750
751    /* Update the media task to encode SBC properly */
752    btif_media_task_enc_update_req(&msg);
753}
754
755
756/*****************************************************************************
757**
758** Function        btif_a2dp_start_media_task
759**
760** Description
761**
762** Returns
763**
764*******************************************************************************/
765
766int btif_a2dp_start_media_task(void)
767{
768    int retval;
769
770    if (media_task_running != MEDIA_TASK_STATE_OFF)
771    {
772        APPL_TRACE_ERROR("warning : media task already running");
773        return GKI_FAILURE;
774    }
775
776    APPL_TRACE_EVENT("## A2DP START MEDIA TASK ##");
777
778    /* start a2dp media task */
779    retval = GKI_create_task((TASKPTR)btif_media_task, A2DP_MEDIA_TASK,
780                A2DP_MEDIA_TASK_TASK_STR,
781                (UINT16 *) ((UINT8 *)a2dp_media_task_stack + A2DP_MEDIA_TASK_STACK_SIZE),
782                sizeof(a2dp_media_task_stack));
783
784    if (retval != GKI_SUCCESS)
785        return retval;
786
787    /* wait for task to come up to sure we are able to send messages to it */
788    while (media_task_running == MEDIA_TASK_STATE_OFF)
789        usleep(10);
790
791    APPL_TRACE_EVENT("## A2DP MEDIA TASK STARTED ##");
792
793    return retval;
794}
795
796/*****************************************************************************
797**
798** Function        btif_a2dp_stop_media_task
799**
800** Description
801**
802** Returns
803**
804*******************************************************************************/
805
806void btif_a2dp_stop_media_task(void)
807{
808    APPL_TRACE_EVENT("## A2DP STOP MEDIA TASK ##");
809    GKI_destroy_task(BT_MEDIA_TASK);
810}
811
812/*****************************************************************************
813**
814** Function        btif_a2dp_on_init
815**
816** Description
817**
818** Returns
819**
820*******************************************************************************/
821
822void btif_a2dp_on_init(void)
823{
824    //tput_mon(1, 0, 1);
825}
826
827
828/*****************************************************************************
829**
830** Function        btif_a2dp_setup_codec
831**
832** Description
833**
834** Returns
835**
836*******************************************************************************/
837
838void btif_a2dp_setup_codec(void)
839{
840    tBTIF_AV_MEDIA_FEEDINGS media_feeding;
841    tBTIF_STATUS status;
842
843    APPL_TRACE_EVENT("## A2DP SETUP CODEC ##");
844
845    GKI_disable();
846
847    /* for now hardcode 44.1 khz 16 bit stereo PCM format */
848    media_feeding.cfg.pcm.sampling_freq = 44100;
849    media_feeding.cfg.pcm.bit_per_sample = 16;
850    media_feeding.cfg.pcm.num_channel = 2;
851    media_feeding.format = BTIF_AV_CODEC_PCM;
852
853    if (bta_av_co_audio_set_codec(&media_feeding, &status))
854    {
855        tBTIF_MEDIA_INIT_AUDIO_FEEDING mfeed;
856
857        /* Init the encoding task */
858        btif_a2dp_encoder_init();
859
860        /* Build the media task configuration */
861        mfeed.feeding = media_feeding;
862        mfeed.feeding_mode = BTIF_AV_FEEDING_ASYNCHRONOUS;
863        /* Send message to Media task to configure transcoding */
864        btif_media_task_audio_feeding_init_req(&mfeed);
865    }
866
867    GKI_enable();
868}
869
870
871/*****************************************************************************
872**
873** Function        btif_a2dp_on_idle
874**
875** Description
876**
877** Returns
878**
879*******************************************************************************/
880
881void btif_a2dp_on_idle(void)
882{
883    APPL_TRACE_EVENT("## ON A2DP IDLE ##");
884    if (btif_media_cb.peer_sep == AVDT_TSEP_SNK)
885    {
886        /* Make sure media task is stopped */
887        btif_media_task_stop_aa_req();
888    }
889
890    bta_av_co_init();
891#if (BTA_AV_SINK_INCLUDED == TRUE)
892    if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
893    {
894        btif_media_cb.rx_flush = TRUE;
895        btif_media_task_aa_rx_flush_req();
896        btif_media_task_stop_decoding_req();
897        btif_media_task_clear_track();
898        APPL_TRACE_DEBUG("Stopped BT track");
899    }
900#endif
901}
902
903/*****************************************************************************
904**
905** Function        btif_a2dp_on_open
906**
907** Description
908**
909** Returns
910**
911*******************************************************************************/
912
913void btif_a2dp_on_open(void)
914{
915    APPL_TRACE_EVENT("## ON A2DP OPEN ##");
916
917    /* always use callback to notify socket events */
918    UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
919}
920
921/*******************************************************************************
922 **
923 ** Function         btif_media_task_clear_track
924 **
925 ** Description
926 **
927 ** Returns          TRUE is success
928 **
929 *******************************************************************************/
930BOOLEAN btif_media_task_clear_track(void)
931{
932    BT_HDR *p_buf;
933
934    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
935    {
936        return FALSE;
937    }
938
939    p_buf->event = BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK;
940
941    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
942    return TRUE;
943}
944/*******************************************************************************
945 **
946 ** Function         btif_media_task_stop_decoding_req
947 **
948 ** Description
949 **
950 ** Returns          TRUE is success
951 **
952 *******************************************************************************/
953BOOLEAN btif_media_task_stop_decoding_req(void)
954{
955    BT_HDR *p_buf;
956
957    if (!btif_media_cb.is_rx_timer)
958        return TRUE;   /*  if timer is not running no need to send message */
959
960    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
961    {
962        return FALSE;
963    }
964
965    p_buf->event = BTIF_MEDIA_AUDIO_SINK_STOP_DECODING;
966
967    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
968    return TRUE;
969}
970
971/*******************************************************************************
972 **
973 ** Function         btif_media_task_start_decoding_req
974 **
975 ** Description
976 **
977 ** Returns          TRUE is success
978 **
979 *******************************************************************************/
980BOOLEAN btif_media_task_start_decoding_req(void)
981{
982    BT_HDR *p_buf;
983
984    if(btif_media_cb.is_rx_timer)
985        return FALSE;   /*  if timer is already running no need to send message */
986
987    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
988    {
989        return FALSE;
990    }
991
992    p_buf->event = BTIF_MEDIA_AUDIO_SINK_START_DECODING;
993
994    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
995    return TRUE;
996}
997
998/*****************************************************************************
999**
1000** Function        btif_reset_decoder
1001**
1002** Description
1003**
1004** Returns
1005**
1006*******************************************************************************/
1007
1008void btif_reset_decoder(UINT8 *p_av)
1009{
1010    APPL_TRACE_EVENT("btif_reset_decoder");
1011    APPL_TRACE_DEBUG("btif_reset_decoder p_codec_info[%x:%x:%x:%x:%x:%x]",
1012            p_av[1], p_av[2], p_av[3],
1013            p_av[4], p_av[5], p_av[6]);
1014
1015    tBTIF_MEDIA_SINK_CFG_UPDATE *p_buf;
1016    if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_SINK_CFG_UPDATE))))
1017    {
1018        APPL_TRACE_EVENT("btif_reset_decoder No Buffer ");
1019        return;
1020    }
1021
1022    memcpy(p_buf->codec_info,p_av, AVDT_CODEC_SIZE);
1023    p_buf->hdr.event = BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE;
1024
1025    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1026}
1027
1028/*****************************************************************************
1029**
1030** Function        btif_a2dp_on_started
1031**
1032** Description
1033**
1034** Returns
1035**
1036*******************************************************************************/
1037
1038BOOLEAN btif_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start)
1039{
1040    tBTIF_STATUS status;
1041    BOOLEAN ack = FALSE;
1042
1043    APPL_TRACE_EVENT("## ON A2DP STARTED ##");
1044
1045    if (p_av == NULL)
1046    {
1047        /* ack back a local start request */
1048        a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
1049        return TRUE;
1050    }
1051
1052    if (p_av->status == BTA_AV_SUCCESS)
1053    {
1054        if (p_av->suspending == FALSE)
1055        {
1056            if (p_av->initiator)
1057            {
1058                if (pending_start) {
1059                    a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
1060                    ack = TRUE;
1061                }
1062            }
1063            else
1064            {
1065                /* we were remotely started,  make sure codec
1066                   is setup before datapath is started */
1067                btif_a2dp_setup_codec();
1068            }
1069
1070            /* media task is autostarted upon a2dp audiopath connection */
1071        }
1072    }
1073    else if (pending_start)
1074    {
1075        a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
1076        ack = TRUE;
1077    }
1078    return ack;
1079}
1080
1081
1082/*****************************************************************************
1083**
1084** Function        btif_a2dp_ack_fail
1085**
1086** Description
1087**
1088** Returns
1089**
1090*******************************************************************************/
1091
1092void btif_a2dp_ack_fail(void)
1093{
1094    tBTIF_STATUS status;
1095
1096    APPL_TRACE_EVENT("## A2DP_CTRL_ACK_FAILURE ##");
1097    a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
1098}
1099
1100/*****************************************************************************
1101**
1102** Function        btif_a2dp_on_stopped
1103**
1104** Description
1105**
1106** Returns
1107**
1108*******************************************************************************/
1109
1110void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av)
1111{
1112    APPL_TRACE_EVENT("## ON A2DP STOPPED ##");
1113    if (btif_media_cb.peer_sep == AVDT_TSEP_SRC) /*  Handling for A2DP SINK cases*/
1114    {
1115        btif_media_cb.rx_flush = TRUE;
1116        btif_media_task_aa_rx_flush_req();
1117        btif_media_task_stop_decoding_req();
1118        UIPC_Close(UIPC_CH_ID_AV_AUDIO);
1119        btif_media_cb.data_channel_open = FALSE;
1120        return;
1121    }
1122    /* allow using this api for other than suspend */
1123    if (p_av != NULL)
1124    {
1125        if (p_av->status != BTA_AV_SUCCESS)
1126        {
1127            APPL_TRACE_EVENT("AV STOP FAILED (%d)", p_av->status);
1128
1129            if (p_av->initiator)
1130                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
1131            return;
1132        }
1133    }
1134
1135    /* ensure tx frames are immediately suspended */
1136    btif_media_cb.tx_flush = 1;
1137
1138    /* request to stop media task  */
1139    btif_media_task_aa_tx_flush_req();
1140    btif_media_task_stop_aa_req();
1141
1142    /* once stream is fully stopped we will ack back */
1143}
1144
1145
1146/*****************************************************************************
1147**
1148** Function        btif_a2dp_on_suspended
1149**
1150** Description
1151**
1152** Returns
1153**
1154*******************************************************************************/
1155
1156void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av)
1157{
1158    APPL_TRACE_EVENT("## ON A2DP SUSPENDED ##");
1159    if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
1160    {
1161        btif_media_cb.rx_flush = TRUE;
1162        btif_media_task_aa_rx_flush_req();
1163        btif_media_task_stop_decoding_req();
1164        return;
1165    }
1166
1167    /* check for status failures */
1168    if (p_av->status != BTA_AV_SUCCESS)
1169    {
1170        if (p_av->initiator == TRUE)
1171            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
1172    }
1173
1174    /* once stream is fully stopped we will ack back */
1175
1176    /* ensure tx frames are immediately flushed */
1177    btif_media_cb.tx_flush = 1;
1178
1179    /* stop timer tick */
1180    btif_media_task_stop_aa_req();
1181}
1182
1183/* when true media task discards any rx frames */
1184void btif_a2dp_set_rx_flush(BOOLEAN enable)
1185{
1186    APPL_TRACE_EVENT("## DROP RX %d ##", enable);
1187    btif_media_cb.rx_flush = enable;
1188}
1189
1190/* when true media task discards any tx frames */
1191void btif_a2dp_set_tx_flush(BOOLEAN enable)
1192{
1193    APPL_TRACE_EVENT("## DROP TX %d ##", enable);
1194    btif_media_cb.tx_flush = enable;
1195}
1196
1197#if (BTA_AV_SINK_INCLUDED == TRUE)
1198/*******************************************************************************
1199 **
1200 ** Function         btif_media_task_avk_handle_timer
1201 **
1202 ** Description
1203 **
1204 ** Returns          void
1205 **
1206 *******************************************************************************/
1207static void btif_media_task_avk_handle_timer ( void )
1208{
1209    UINT8 count;
1210    tBT_SBC_HDR *p_msg;
1211    int num_sbc_frames;
1212    int num_frames_to_process;
1213
1214    count = btif_media_cb.RxSbcQ.count;
1215    if (0 == count)
1216    {
1217        APPL_TRACE_DEBUG("  QUE  EMPTY ");
1218    }
1219    else
1220    {
1221        if (btif_media_cb.rx_flush == TRUE)
1222        {
1223            btif_media_flush_q(&(btif_media_cb.RxSbcQ));
1224            return;
1225        }
1226
1227        num_frames_to_process = btif_media_cb.frames_to_process;
1228        APPL_TRACE_DEBUG(" Process Frames + ");
1229
1230        do
1231        {
1232            p_msg = (tBT_SBC_HDR *)GKI_getfirst(&(btif_media_cb.RxSbcQ));
1233            if (p_msg == NULL)
1234                return;
1235            num_sbc_frames  = p_msg->num_frames_to_be_processed; /* num of frames in Que Packets */
1236            APPL_TRACE_DEBUG(" Frames left in topmost packet %d", num_sbc_frames);
1237            APPL_TRACE_DEBUG(" Remaining frames to process in tick %d", num_frames_to_process);
1238            APPL_TRACE_DEBUG(" Num of Packets in Que %d", btif_media_cb.RxSbcQ.count);
1239
1240            if ( num_sbc_frames > num_frames_to_process) /*  Que Packet has more frames*/
1241            {
1242                 p_msg->num_frames_to_be_processed= num_frames_to_process;
1243                 btif_media_task_handle_inc_media(p_msg);
1244                 p_msg->num_frames_to_be_processed = num_sbc_frames - num_frames_to_process;
1245                 num_frames_to_process = 0;
1246                 break;
1247            }
1248            else                                        /*  Que packet has less frames */
1249            {
1250                btif_media_task_handle_inc_media(p_msg);
1251                p_msg = (tBT_SBC_HDR *)GKI_dequeue(&(btif_media_cb.RxSbcQ));
1252                if( p_msg == NULL )
1253                {
1254                     APPL_TRACE_ERROR("Insufficient data in que ");
1255                     break;
1256                }
1257                num_frames_to_process = num_frames_to_process - p_msg->num_frames_to_be_processed;
1258                GKI_freebuf(p_msg);
1259            }
1260        }while(num_frames_to_process > 0);
1261
1262        APPL_TRACE_DEBUG(" Process Frames - ");
1263    }
1264}
1265#endif
1266
1267/*******************************************************************************
1268 **
1269 ** Function         btif_media_task_aa_handle_timer
1270 **
1271 ** Description
1272 **
1273 ** Returns          void
1274 **
1275 *******************************************************************************/
1276
1277static void btif_media_task_aa_handle_timer(void)
1278{
1279#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
1280    static UINT16 Debug = 0;
1281    APPL_TRACE_DEBUG("btif_media_task_aa_handle_timer: %d", Debug++);
1282#endif
1283
1284    log_tstamps_us("media task tx timer");
1285
1286#if (BTA_AV_INCLUDED == TRUE)
1287    if(btif_media_cb.is_tx_timer == TRUE)
1288    {
1289        btif_media_send_aa_frame();
1290    }
1291    else
1292    {
1293        APPL_TRACE_ERROR("ERROR Media task Scheduled after Suspend");
1294    }
1295#endif
1296}
1297
1298#if (BTA_AV_INCLUDED == TRUE)
1299/*******************************************************************************
1300 **
1301 ** Function         btif_media_task_aa_handle_timer
1302 **
1303 ** Description
1304 **
1305 ** Returns          void
1306 **
1307 *******************************************************************************/
1308static void btif_media_task_aa_handle_uipc_rx_rdy(void)
1309{
1310#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
1311    static UINT16 Debug = 0;
1312    APPL_TRACE_DEBUG("btif_media_task_aa_handle_uipc_rx_rdy: %d", Debug++);
1313#endif
1314
1315    /* process all the UIPC data */
1316    btif_media_aa_prep_2_send(0xFF);
1317
1318    /* send it */
1319    VERBOSE("btif_media_task_aa_handle_uipc_rx_rdy calls bta_av_ci_src_data_ready");
1320    bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
1321}
1322#endif
1323
1324/*******************************************************************************
1325 **
1326 ** Function         btif_media_task_init
1327 **
1328 ** Description
1329 **
1330 ** Returns          void
1331 **
1332 *******************************************************************************/
1333
1334void btif_media_task_init(void)
1335{
1336    memset(&(btif_media_cb), 0, sizeof(btif_media_cb));
1337
1338    UIPC_Init(NULL);
1339
1340#if (BTA_AV_INCLUDED == TRUE)
1341    UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
1342#endif
1343}
1344/*******************************************************************************
1345 **
1346 ** Function         btif_media_task
1347 **
1348 ** Description      Task for SBC encoder.  This task receives an
1349 **                  event when the waveIn interface has a pcm data buffer
1350 **                  ready.  On receiving the event, handle all ready pcm
1351 **                  data buffers.  If stream is started, run the SBC encoder
1352 **                  on each chunk of pcm samples and build an output packet
1353 **                  consisting of one or more encoded SBC frames.
1354 **
1355 ** Returns          void
1356 **
1357 *******************************************************************************/
1358int btif_media_task(void *p)
1359{
1360    UINT16 event;
1361    BT_HDR *p_msg;
1362    UNUSED(p);
1363
1364    VERBOSE("================ MEDIA TASK STARTING ================");
1365
1366    btif_media_task_init();
1367
1368    media_task_running = MEDIA_TASK_STATE_ON;
1369
1370    raise_priority_a2dp(TASK_HIGH_MEDIA);
1371
1372    while (1)
1373    {
1374        event = GKI_wait(0xffff, 0);
1375
1376        VERBOSE("================= MEDIA TASK EVENT %d ===============", event);
1377
1378        if (event & BTIF_MEDIA_TASK_CMD)
1379        {
1380            /* Process all messages in the queue */
1381            while ((p_msg = (BT_HDR *) GKI_read_mbox(BTIF_MEDIA_TASK_CMD_MBOX)) != NULL)
1382            {
1383                btif_media_task_handle_cmd(p_msg);
1384            }
1385        }
1386
1387        if (event & BTIF_MEDIA_TASK_DATA)
1388        {
1389            VERBOSE("================= Received Media Packets %d ===============", event);
1390            /* Process all messages in the queue */
1391            while ((p_msg = (BT_HDR *) GKI_read_mbox(BTIF_MEDIA_TASK_DATA_MBOX)) != NULL)
1392            {
1393                btif_media_task_handle_media(p_msg);
1394            }
1395        }
1396
1397        if (event & BTIF_MEDIA_AA_TASK_TIMER)
1398        {
1399            /* advance audio timer expiration */
1400            btif_media_task_aa_handle_timer();
1401        }
1402
1403        if (event & BTIF_MEDIA_AVK_TASK_TIMER)
1404        {
1405#if (BTA_AV_SINK_INCLUDED == TRUE)
1406            /* advance audio timer expiration for a2dp sink */
1407            btif_media_task_avk_handle_timer();
1408#endif
1409        }
1410
1411
1412
1413        VERBOSE("=============== MEDIA TASK EVENT %d DONE ============", event);
1414
1415        /* When we get this event we exit the task  - should only happen on GKI_shutdown  */
1416        if (event & BTIF_MEDIA_TASK_KILL)
1417        {
1418            /* make sure no channels are restarted while shutting down */
1419            media_task_running = MEDIA_TASK_STATE_SHUTTING_DOWN;
1420
1421            /* this calls blocks until uipc is fully closed */
1422            UIPC_Close(UIPC_CH_ID_ALL);
1423            break;
1424        }
1425    }
1426
1427    /* Clear media task flag */
1428    media_task_running = MEDIA_TASK_STATE_OFF;
1429
1430    APPL_TRACE_DEBUG("MEDIA TASK EXITING");
1431
1432    return 0;
1433}
1434
1435
1436/*******************************************************************************
1437 **
1438 ** Function         btif_media_task_send_cmd_evt
1439 **
1440 ** Description
1441 **
1442 ** Returns          TRUE is success
1443 **
1444 *******************************************************************************/
1445BOOLEAN btif_media_task_send_cmd_evt(UINT16 Evt)
1446{
1447    BT_HDR *p_buf;
1448    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1449    {
1450        return FALSE;
1451    }
1452
1453    p_buf->event = Evt;
1454
1455    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1456    return TRUE;
1457}
1458
1459/*******************************************************************************
1460 **
1461 ** Function         btif_media_flush_q
1462 **
1463 ** Description
1464 **
1465 ** Returns          void
1466 **
1467 *******************************************************************************/
1468static void btif_media_flush_q(BUFFER_Q *p_q)
1469{
1470    while (!GKI_queue_is_empty(p_q))
1471    {
1472        GKI_freebuf(GKI_dequeue(p_q));
1473    }
1474}
1475
1476
1477/*******************************************************************************
1478 **
1479 ** Function         btif_media_task_handle_cmd
1480 **
1481 ** Description
1482 **
1483 ** Returns          void
1484 **
1485 *******************************************************************************/
1486static void btif_media_task_handle_cmd(BT_HDR *p_msg)
1487{
1488    VERBOSE("btif_media_task_handle_cmd : %d %s", p_msg->event,
1489             dump_media_event(p_msg->event));
1490
1491    switch (p_msg->event)
1492    {
1493#if (BTA_AV_INCLUDED == TRUE)
1494    case BTIF_MEDIA_START_AA_TX:
1495        btif_media_task_aa_start_tx();
1496        break;
1497    case BTIF_MEDIA_STOP_AA_TX:
1498        btif_media_task_aa_stop_tx();
1499        break;
1500    case BTIF_MEDIA_SBC_ENC_INIT:
1501        btif_media_task_enc_init(p_msg);
1502        break;
1503    case BTIF_MEDIA_SBC_ENC_UPDATE:
1504        btif_media_task_enc_update(p_msg);
1505        break;
1506    case BTIF_MEDIA_AUDIO_FEEDING_INIT:
1507        btif_media_task_audio_feeding_init(p_msg);
1508        break;
1509    case BTIF_MEDIA_FLUSH_AA_TX:
1510        btif_media_task_aa_tx_flush(p_msg);
1511        break;
1512    case BTIF_MEDIA_UIPC_RX_RDY:
1513        btif_media_task_aa_handle_uipc_rx_rdy();
1514        break;
1515    case BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE:
1516#if (BTA_AV_SINK_INCLUDED == TRUE)
1517        btif_media_task_aa_handle_decoder_reset(p_msg);
1518#endif
1519        break;
1520    case BTIF_MEDIA_AUDIO_SINK_START_DECODING:
1521        btif_media_task_aa_handle_start_decoding();
1522        break;
1523    case BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK:
1524#if (BTA_AV_SINK_INCLUDED == TRUE)
1525        btif_media_task_aa_handle_clear_track();
1526#endif
1527        break;
1528    case BTIF_MEDIA_AUDIO_SINK_STOP_DECODING:
1529        btif_media_task_aa_handle_stop_decoding();
1530        break;
1531     case BTIF_MEDIA_FLUSH_AA_RX:
1532        btif_media_task_aa_rx_flush();
1533        break;
1534#endif
1535    default:
1536        APPL_TRACE_ERROR("ERROR in btif_media_task_handle_cmd unknown event %d", p_msg->event);
1537    }
1538    GKI_freebuf(p_msg);
1539    VERBOSE("btif_media_task_handle_cmd : %s DONE", dump_media_event(p_msg->event));
1540}
1541
1542#if (BTA_AV_SINK_INCLUDED == TRUE)
1543/*******************************************************************************
1544 **
1545 ** Function         btif_media_task_handle_inc_media
1546 **
1547 ** Description
1548 **
1549 ** Returns          void
1550 **
1551 *******************************************************************************/
1552static void btif_media_task_handle_inc_media(tBT_SBC_HDR*p_msg)
1553{
1554    UINT8 *sbc_start_frame = ((UINT8*)(p_msg + 1) + p_msg->offset + 1);
1555    int count;
1556    UINT32 pcmBytes, availPcmBytes;
1557    OI_INT16 *pcmDataPointer = pcmData; /*Will be overwritten on next packet receipt*/
1558    OI_STATUS status;
1559    int num_sbc_frames = p_msg->num_frames_to_be_processed;
1560    UINT32 sbc_frame_len = p_msg->len - 1;
1561    availPcmBytes = 2*sizeof(pcmData);
1562
1563    if ((btif_media_cb.peer_sep == AVDT_TSEP_SNK) || (btif_media_cb.rx_flush))
1564    {
1565        APPL_TRACE_DEBUG(" State Changed happened in this tick ");
1566        return;
1567    }
1568
1569    // ignore data if no one is listening
1570    if (!btif_media_cb.data_channel_open)
1571        return;
1572
1573    APPL_TRACE_DEBUG("Number of sbc frames %d, frame_len %d", num_sbc_frames, sbc_frame_len);
1574
1575    for(count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++)
1576    {
1577        pcmBytes = availPcmBytes;
1578        status = OI_CODEC_SBC_DecodeFrame(&context, (const OI_BYTE**)&sbc_start_frame,
1579                                                        (OI_UINT32 *)&sbc_frame_len,
1580                                                        (OI_INT16 *)pcmDataPointer,
1581                                                        (OI_UINT32 *)&pcmBytes);
1582        if (!OI_SUCCESS(status)) {
1583            APPL_TRACE_ERROR("Decoding failure: %d\n", status);
1584            break;
1585        }
1586        availPcmBytes -= pcmBytes;
1587        pcmDataPointer += pcmBytes/2;
1588        p_msg->offset += (p_msg->len - 1) - sbc_frame_len;
1589        p_msg->len = sbc_frame_len + 1;
1590    }
1591
1592    UIPC_Send(UIPC_CH_ID_AV_AUDIO, 0, (UINT8 *)pcmData, (2*sizeof(pcmData) - availPcmBytes));
1593}
1594#endif
1595
1596/*******************************************************************************
1597 **
1598 ** Function         btif_media_task_handle_media
1599 **
1600 ** Description
1601 **
1602 ** Returns          void
1603 **
1604 *******************************************************************************/
1605static void btif_media_task_handle_media(BT_HDR*p_msg)
1606{
1607    APPL_TRACE_DEBUG(" btif_media_task_handle_media ");
1608    GKI_freebuf(p_msg);
1609}
1610#if (BTA_AV_INCLUDED == TRUE)
1611/*******************************************************************************
1612 **
1613 ** Function         btif_media_task_enc_init_req
1614 **
1615 ** Description
1616 **
1617 ** Returns          TRUE is success
1618 **
1619 *******************************************************************************/
1620BOOLEAN btif_media_task_enc_init_req(tBTIF_MEDIA_INIT_AUDIO *p_msg)
1621{
1622    tBTIF_MEDIA_INIT_AUDIO *p_buf;
1623    if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO))))
1624    {
1625        return FALSE;
1626    }
1627
1628    memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO));
1629    p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_INIT;
1630
1631    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1632    return TRUE;
1633}
1634
1635/*******************************************************************************
1636 **
1637 ** Function         btif_media_task_enc_update_req
1638 **
1639 ** Description
1640 **
1641 ** Returns          TRUE is success
1642 **
1643 *******************************************************************************/
1644BOOLEAN btif_media_task_enc_update_req(tBTIF_MEDIA_UPDATE_AUDIO *p_msg)
1645{
1646    tBTIF_MEDIA_UPDATE_AUDIO *p_buf;
1647    if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_UPDATE_AUDIO))))
1648    {
1649        return FALSE;
1650    }
1651
1652    memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_UPDATE_AUDIO));
1653    p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_UPDATE;
1654
1655    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1656    return TRUE;
1657}
1658
1659/*******************************************************************************
1660 **
1661 ** Function         btif_media_task_audio_feeding_init_req
1662 **
1663 ** Description
1664 **
1665 ** Returns          TRUE is success
1666 **
1667 *******************************************************************************/
1668BOOLEAN btif_media_task_audio_feeding_init_req(tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_msg)
1669{
1670    tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_buf;
1671    if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING))))
1672    {
1673        return FALSE;
1674    }
1675
1676    memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING));
1677    p_buf->hdr.event = BTIF_MEDIA_AUDIO_FEEDING_INIT;
1678
1679    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1680    return TRUE;
1681}
1682
1683/*******************************************************************************
1684 **
1685 ** Function         btif_media_task_start_aa_req
1686 **
1687 ** Description
1688 **
1689 ** Returns          TRUE is success
1690 **
1691 *******************************************************************************/
1692BOOLEAN btif_media_task_start_aa_req(void)
1693{
1694    BT_HDR *p_buf;
1695    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1696    {
1697        APPL_TRACE_EVENT("GKI failed");
1698        return FALSE;
1699    }
1700
1701    p_buf->event = BTIF_MEDIA_START_AA_TX;
1702
1703    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1704    return TRUE;
1705}
1706
1707/*******************************************************************************
1708 **
1709 ** Function         btif_media_task_stop_aa_req
1710 **
1711 ** Description
1712 **
1713 ** Returns          TRUE is success
1714 **
1715 *******************************************************************************/
1716BOOLEAN btif_media_task_stop_aa_req(void)
1717{
1718    BT_HDR *p_buf;
1719    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1720    {
1721        return FALSE;
1722    }
1723
1724    p_buf->event = BTIF_MEDIA_STOP_AA_TX;
1725
1726    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1727    return TRUE;
1728}
1729/*******************************************************************************
1730 **
1731 ** Function         btif_media_task_aa_rx_flush_req
1732 **
1733 ** Description
1734 **
1735 ** Returns          TRUE is success
1736 **
1737 *******************************************************************************/
1738BOOLEAN btif_media_task_aa_rx_flush_req(void)
1739{
1740    BT_HDR *p_buf;
1741
1742    if (GKI_queue_is_empty(&(btif_media_cb.RxSbcQ))== TRUE) /*  Que is already empty */
1743        return TRUE;
1744
1745    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1746    {
1747        return FALSE;
1748    }
1749
1750    p_buf->event = BTIF_MEDIA_FLUSH_AA_RX;
1751
1752    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1753    return TRUE;
1754}
1755
1756/*******************************************************************************
1757 **
1758 ** Function         btif_media_task_aa_tx_flush_req
1759 **
1760 ** Description
1761 **
1762 ** Returns          TRUE is success
1763 **
1764 *******************************************************************************/
1765BOOLEAN btif_media_task_aa_tx_flush_req(void)
1766{
1767    BT_HDR *p_buf;
1768    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1769    {
1770        return FALSE;
1771    }
1772
1773    p_buf->event = BTIF_MEDIA_FLUSH_AA_TX;
1774
1775    GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1776    return TRUE;
1777}
1778/*******************************************************************************
1779 **
1780 ** Function         btif_media_task_aa_rx_flush
1781 **
1782 ** Description
1783 **
1784 ** Returns          void
1785 **
1786 *******************************************************************************/
1787static void btif_media_task_aa_rx_flush(void)
1788{
1789    /* Flush all enqueued GKI SBC  buffers (encoded) */
1790    APPL_TRACE_DEBUG("btif_media_task_aa_rx_flush");
1791
1792    btif_media_flush_q(&(btif_media_cb.RxSbcQ));
1793}
1794
1795
1796/*******************************************************************************
1797 **
1798 ** Function         btif_media_task_aa_tx_flush
1799 **
1800 ** Description
1801 **
1802 ** Returns          void
1803 **
1804 *******************************************************************************/
1805static void btif_media_task_aa_tx_flush(BT_HDR *p_msg)
1806{
1807    UNUSED(p_msg);
1808
1809    /* Flush all enqueued GKI music buffers (encoded) */
1810    APPL_TRACE_DEBUG("btif_media_task_aa_tx_flush");
1811
1812    btif_media_cb.media_feeding_state.pcm.counter = 0;
1813    btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
1814
1815    btif_media_flush_q(&(btif_media_cb.TxAaQ));
1816
1817    UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REQ_RX_FLUSH, NULL);
1818}
1819
1820/*******************************************************************************
1821 **
1822 ** Function       btif_media_task_enc_init
1823 **
1824 ** Description    Initialize encoding task
1825 **
1826 ** Returns        void
1827 **
1828 *******************************************************************************/
1829static void btif_media_task_enc_init(BT_HDR *p_msg)
1830{
1831    tBTIF_MEDIA_INIT_AUDIO *pInitAudio = (tBTIF_MEDIA_INIT_AUDIO *) p_msg;
1832
1833    APPL_TRACE_DEBUG("btif_media_task_enc_init");
1834
1835    btif_media_cb.timestamp = 0;
1836
1837    /* SBC encoder config (enforced even if not used) */
1838    btif_media_cb.encoder.s16ChannelMode = pInitAudio->ChannelMode;
1839    btif_media_cb.encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
1840    btif_media_cb.encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks;
1841    btif_media_cb.encoder.s16AllocationMethod = pInitAudio->AllocationMethod;
1842    btif_media_cb.encoder.s16SamplingFreq = pInitAudio->SamplingFreq;
1843
1844    btif_media_cb.encoder.u16BitRate = btif_media_task_get_sbc_rate();
1845
1846    /* Default transcoding is PCM to SBC, modified by feeding configuration */
1847    btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
1848    btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE-BTIF_MEDIA_AA_SBC_OFFSET-sizeof(BT_HDR))
1849            < pInitAudio->MtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
1850            - sizeof(BT_HDR)) : pInitAudio->MtuSize;
1851
1852    APPL_TRACE_EVENT("btif_media_task_enc_init busy %d, mtu %d, peer mtu %d",
1853                     btif_media_cb.busy_level, btif_media_cb.TxAaMtuSize, pInitAudio->MtuSize);
1854    APPL_TRACE_EVENT("      ch mode %d, subnd %d, nb blk %d, alloc %d, rate %d, freq %d",
1855            btif_media_cb.encoder.s16ChannelMode, btif_media_cb.encoder.s16NumOfSubBands,
1856            btif_media_cb.encoder.s16NumOfBlocks,
1857            btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
1858            btif_media_cb.encoder.s16SamplingFreq);
1859
1860    /* Reset entirely the SBC encoder */
1861    SBC_Encoder_Init(&(btif_media_cb.encoder));
1862    APPL_TRACE_DEBUG("btif_media_task_enc_init bit pool %d", btif_media_cb.encoder.s16BitPool);
1863}
1864
1865/*******************************************************************************
1866 **
1867 ** Function       btif_media_task_enc_update
1868 **
1869 ** Description    Update encoding task
1870 **
1871 ** Returns        void
1872 **
1873 *******************************************************************************/
1874
1875static void btif_media_task_enc_update(BT_HDR *p_msg)
1876{
1877    tBTIF_MEDIA_UPDATE_AUDIO * pUpdateAudio = (tBTIF_MEDIA_UPDATE_AUDIO *) p_msg;
1878    SBC_ENC_PARAMS *pstrEncParams = &btif_media_cb.encoder;
1879    UINT16 s16SamplingFreq;
1880    SINT16 s16BitPool = 0;
1881    SINT16 s16BitRate;
1882    SINT16 s16FrameLen;
1883    UINT8 protect = 0;
1884
1885    APPL_TRACE_DEBUG("btif_media_task_enc_update : minmtu %d, maxbp %d minbp %d",
1886            pUpdateAudio->MinMtuSize, pUpdateAudio->MaxBitPool, pUpdateAudio->MinBitPool);
1887
1888    /* Only update the bitrate and MTU size while timer is running to make sure it has been initialized */
1889    //if (btif_media_cb.is_tx_timer)
1890    {
1891        btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE -
1892                                      BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR))
1893                < pUpdateAudio->MinMtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
1894                - sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize;
1895
1896        /* Set the initial target bit rate */
1897        pstrEncParams->u16BitRate = btif_media_task_get_sbc_rate();
1898
1899        if (pstrEncParams->s16SamplingFreq == SBC_sf16000)
1900            s16SamplingFreq = 16000;
1901        else if (pstrEncParams->s16SamplingFreq == SBC_sf32000)
1902            s16SamplingFreq = 32000;
1903        else if (pstrEncParams->s16SamplingFreq == SBC_sf44100)
1904            s16SamplingFreq = 44100;
1905        else
1906            s16SamplingFreq = 48000;
1907
1908        do
1909        {
1910            if (pstrEncParams->s16NumOfBlocks == 0 || pstrEncParams->s16NumOfSubBands == 0
1911                || pstrEncParams->s16NumOfChannels == 0)
1912            {
1913                APPL_TRACE_ERROR("btif_media_task_enc_update() - Avoiding division by zero...");
1914                APPL_TRACE_ERROR("btif_media_task_enc_update() - block=%d, subBands=%d, channels=%d",
1915                    pstrEncParams->s16NumOfBlocks, pstrEncParams->s16NumOfSubBands,
1916                    pstrEncParams->s16NumOfChannels);
1917                break;
1918            }
1919
1920            if ((pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) ||
1921                (pstrEncParams->s16ChannelMode == SBC_STEREO) )
1922            {
1923                s16BitPool = (SINT16)( (pstrEncParams->u16BitRate *
1924                    pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq)
1925                    -( (32 + (4 * pstrEncParams->s16NumOfSubBands *
1926                    pstrEncParams->s16NumOfChannels)
1927                    + ( (pstrEncParams->s16ChannelMode - 2) *
1928                    pstrEncParams->s16NumOfSubBands )   )
1929                    / pstrEncParams->s16NumOfBlocks) );
1930
1931                s16FrameLen = 4 + (4*pstrEncParams->s16NumOfSubBands*
1932                    pstrEncParams->s16NumOfChannels)/8
1933                    + ( ((pstrEncParams->s16ChannelMode - 2) *
1934                    pstrEncParams->s16NumOfSubBands)
1935                    + (pstrEncParams->s16NumOfBlocks * s16BitPool) ) / 8;
1936
1937                s16BitRate = (8 * s16FrameLen * s16SamplingFreq)
1938                    / (pstrEncParams->s16NumOfSubBands *
1939                    pstrEncParams->s16NumOfBlocks * 1000);
1940
1941                if (s16BitRate > pstrEncParams->u16BitRate)
1942                    s16BitPool--;
1943
1944                if(pstrEncParams->s16NumOfSubBands == 8)
1945                    s16BitPool = (s16BitPool > 255) ? 255 : s16BitPool;
1946                else
1947                    s16BitPool = (s16BitPool > 128) ? 128 : s16BitPool;
1948            }
1949            else
1950            {
1951                s16BitPool = (SINT16)( ((pstrEncParams->s16NumOfSubBands *
1952                    pstrEncParams->u16BitRate * 1000)
1953                    / (s16SamplingFreq * pstrEncParams->s16NumOfChannels))
1954                    -( ( (32 / pstrEncParams->s16NumOfChannels) +
1955                    (4 * pstrEncParams->s16NumOfSubBands) )
1956                    /   pstrEncParams->s16NumOfBlocks ) );
1957
1958                pstrEncParams->s16BitPool = (s16BitPool >
1959                    (16 * pstrEncParams->s16NumOfSubBands))
1960                    ? (16*pstrEncParams->s16NumOfSubBands) : s16BitPool;
1961            }
1962
1963            if (s16BitPool < 0)
1964            {
1965                s16BitPool = 0;
1966            }
1967
1968            APPL_TRACE_EVENT("bitpool candidate : %d (%d kbps)",
1969                         s16BitPool, pstrEncParams->u16BitRate);
1970
1971            if (s16BitPool > pUpdateAudio->MaxBitPool)
1972            {
1973                APPL_TRACE_DEBUG("btif_media_task_enc_update computed bitpool too large (%d)",
1974                                    s16BitPool);
1975                /* Decrease bitrate */
1976                btif_media_cb.encoder.u16BitRate -= BTIF_MEDIA_BITRATE_STEP;
1977                /* Record that we have decreased the bitrate */
1978                protect |= 1;
1979            }
1980            else if (s16BitPool < pUpdateAudio->MinBitPool)
1981            {
1982                APPL_TRACE_WARNING("btif_media_task_enc_update computed bitpool too small (%d)", s16BitPool);
1983
1984                /* Increase bitrate */
1985                UINT16 previous_u16BitRate = btif_media_cb.encoder.u16BitRate;
1986                btif_media_cb.encoder.u16BitRate += BTIF_MEDIA_BITRATE_STEP;
1987                /* Record that we have increased the bitrate */
1988                protect |= 2;
1989                /* Check over-flow */
1990                if (btif_media_cb.encoder.u16BitRate < previous_u16BitRate)
1991                    protect |= 3;
1992            }
1993            else
1994            {
1995                break;
1996            }
1997            /* In case we have already increased and decreased the bitrate, just stop */
1998            if (protect == 3)
1999            {
2000                APPL_TRACE_ERROR("btif_media_task_enc_update could not find bitpool in range");
2001                break;
2002            }
2003        } while (1);
2004
2005        /* Finally update the bitpool in the encoder structure */
2006        pstrEncParams->s16BitPool = s16BitPool;
2007
2008        APPL_TRACE_DEBUG("btif_media_task_enc_update final bit rate %d, final bit pool %d",
2009                btif_media_cb.encoder.u16BitRate, btif_media_cb.encoder.s16BitPool);
2010
2011        /* make sure we reinitialize encoder with new settings */
2012        SBC_Encoder_Init(&(btif_media_cb.encoder));
2013    }
2014}
2015
2016/*******************************************************************************
2017 **
2018 ** Function         btif_media_task_pcm2sbc_init
2019 **
2020 ** Description      Init encoding task for PCM to SBC according to feeding
2021 **
2022 ** Returns          void
2023 **
2024 *******************************************************************************/
2025static void btif_media_task_pcm2sbc_init(tBTIF_MEDIA_INIT_AUDIO_FEEDING * p_feeding)
2026{
2027    BOOLEAN reconfig_needed = FALSE;
2028
2029    APPL_TRACE_DEBUG("PCM feeding:");
2030    APPL_TRACE_DEBUG("sampling_freq:%d", p_feeding->feeding.cfg.pcm.sampling_freq);
2031    APPL_TRACE_DEBUG("num_channel:%d", p_feeding->feeding.cfg.pcm.num_channel);
2032    APPL_TRACE_DEBUG("bit_per_sample:%d", p_feeding->feeding.cfg.pcm.bit_per_sample);
2033
2034    /* Check the PCM feeding sampling_freq */
2035    switch (p_feeding->feeding.cfg.pcm.sampling_freq)
2036    {
2037        case  8000:
2038        case 12000:
2039        case 16000:
2040        case 24000:
2041        case 32000:
2042        case 48000:
2043            /* For these sampling_freq the AV connection must be 48000 */
2044            if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf48000)
2045            {
2046                /* Reconfiguration needed at 48000 */
2047                APPL_TRACE_DEBUG("SBC Reconfiguration needed at 48000");
2048                btif_media_cb.encoder.s16SamplingFreq = SBC_sf48000;
2049                reconfig_needed = TRUE;
2050            }
2051            break;
2052
2053        case 11025:
2054        case 22050:
2055        case 44100:
2056            /* For these sampling_freq the AV connection must be 44100 */
2057            if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf44100)
2058            {
2059                /* Reconfiguration needed at 44100 */
2060                APPL_TRACE_DEBUG("SBC Reconfiguration needed at 44100");
2061                btif_media_cb.encoder.s16SamplingFreq = SBC_sf44100;
2062                reconfig_needed = TRUE;
2063            }
2064            break;
2065        default:
2066            APPL_TRACE_DEBUG("Feeding PCM sampling_freq unsupported");
2067            break;
2068    }
2069
2070    /* Some AV Headsets do not support Mono => always ask for Stereo */
2071    if (btif_media_cb.encoder.s16ChannelMode == SBC_MONO)
2072    {
2073        APPL_TRACE_DEBUG("SBC Reconfiguration needed in Stereo");
2074        btif_media_cb.encoder.s16ChannelMode = SBC_JOINT_STEREO;
2075        reconfig_needed = TRUE;
2076    }
2077
2078    if (reconfig_needed != FALSE)
2079    {
2080        APPL_TRACE_DEBUG("btif_media_task_pcm2sbc_init :: mtu %d", btif_media_cb.TxAaMtuSize);
2081        APPL_TRACE_DEBUG("ch mode %d, nbsubd %d, nb %d, alloc %d, rate %d, freq %d",
2082                btif_media_cb.encoder.s16ChannelMode,
2083                btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks,
2084                btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
2085                btif_media_cb.encoder.s16SamplingFreq);
2086
2087        SBC_Encoder_Init(&(btif_media_cb.encoder));
2088    }
2089    else
2090    {
2091        APPL_TRACE_DEBUG("btif_media_task_pcm2sbc_init no SBC reconfig needed");
2092    }
2093}
2094
2095
2096/*******************************************************************************
2097 **
2098 ** Function         btif_media_task_audio_feeding_init
2099 **
2100 ** Description      Initialize the audio path according to the feeding format
2101 **
2102 ** Returns          void
2103 **
2104 *******************************************************************************/
2105static void btif_media_task_audio_feeding_init(BT_HDR *p_msg)
2106{
2107    tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_feeding = (tBTIF_MEDIA_INIT_AUDIO_FEEDING *) p_msg;
2108
2109    APPL_TRACE_DEBUG("btif_media_task_audio_feeding_init format:%d", p_feeding->feeding.format);
2110
2111    /* Save Media Feeding information */
2112    btif_media_cb.feeding_mode = p_feeding->feeding_mode;
2113    btif_media_cb.media_feeding = p_feeding->feeding;
2114
2115    /* Handle different feeding formats */
2116    switch (p_feeding->feeding.format)
2117    {
2118        case BTIF_AV_CODEC_PCM:
2119            btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
2120            btif_media_task_pcm2sbc_init(p_feeding);
2121            break;
2122
2123        default :
2124            APPL_TRACE_ERROR("unknown feeding format %d", p_feeding->feeding.format);
2125            break;
2126    }
2127}
2128
2129int btif_a2dp_get_track_frequency(UINT8 frequency) {
2130    int freq = 48000;
2131    switch (frequency) {
2132        case A2D_SBC_IE_SAMP_FREQ_16:
2133            freq = 16000;
2134            break;
2135        case A2D_SBC_IE_SAMP_FREQ_32:
2136            freq = 32000;
2137            break;
2138        case A2D_SBC_IE_SAMP_FREQ_44:
2139            freq = 44100;
2140            break;
2141        case A2D_SBC_IE_SAMP_FREQ_48:
2142            freq = 48000;
2143            break;
2144    }
2145    return freq;
2146}
2147
2148int btif_a2dp_get_track_channel_count(UINT8 channeltype) {
2149    int count = 1;
2150    switch (channeltype) {
2151        case A2D_SBC_IE_CH_MD_MONO:
2152            count = 1;
2153            break;
2154        case A2D_SBC_IE_CH_MD_DUAL:
2155        case A2D_SBC_IE_CH_MD_STEREO:
2156        case A2D_SBC_IE_CH_MD_JOINT:
2157            count = 2;
2158            break;
2159    }
2160    return count;
2161}
2162
2163void btif_a2dp_set_peer_sep(UINT8 sep) {
2164    btif_media_cb.peer_sep = sep;
2165}
2166
2167/*******************************************************************************
2168 **
2169 ** Function         btif_media_task_aa_handle_stop_decoding
2170 **
2171 ** Description
2172 **
2173 ** Returns          void
2174 **
2175 *******************************************************************************/
2176static void btif_media_task_aa_handle_stop_decoding(void )
2177{
2178    btif_media_cb.is_rx_timer = FALSE;
2179    GKI_stop_timer(BTIF_MEDIA_AVK_TASK_TIMER_ID);
2180}
2181
2182/*******************************************************************************
2183 **
2184 ** Function         btif_media_task_aa_handle_start_decoding
2185 **
2186 ** Description
2187 **
2188 ** Returns          void
2189 **
2190 *******************************************************************************/
2191static void btif_media_task_aa_handle_start_decoding(void )
2192{
2193    if(btif_media_cb.is_rx_timer == TRUE)
2194        return;
2195    btif_media_cb.is_rx_timer = TRUE;
2196    GKI_start_timer(BTIF_MEDIA_AVK_TASK_TIMER_ID, GKI_MS_TO_TICKS(BTIF_SINK_MEDIA_TIME_TICK), TRUE);
2197}
2198
2199#if (BTA_AV_SINK_INCLUDED == TRUE)
2200
2201static void btif_media_task_aa_handle_clear_track (void)
2202{
2203    APPL_TRACE_DEBUG("btif_media_task_aa_handle_clear_track");
2204}
2205
2206/*******************************************************************************
2207 **
2208 ** Function         btif_media_task_aa_handle_decoder_reset
2209 **
2210 ** Description
2211 **
2212 ** Returns          void
2213 **
2214 *******************************************************************************/
2215static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg)
2216{
2217    tBTIF_MEDIA_SINK_CFG_UPDATE *p_buf = (tBTIF_MEDIA_SINK_CFG_UPDATE*) p_msg;
2218    tA2D_STATUS a2d_status;
2219    tA2D_SBC_CIE sbc_cie;
2220    OI_STATUS       status;
2221    UINT32          freq_multiple = 48*20; /* frequency multiple for 20ms of data , initialize with 48K*/
2222    UINT32          num_blocks = 16;
2223    UINT32          num_subbands = 8;
2224
2225    APPL_TRACE_DEBUG("btif_media_task_aa_handle_decoder_reset p_codec_info[%x:%x:%x:%x:%x:%x]",
2226            p_buf->codec_info[1], p_buf->codec_info[2], p_buf->codec_info[3],
2227            p_buf->codec_info[4], p_buf->codec_info[5], p_buf->codec_info[6]);
2228
2229    a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_buf->codec_info, FALSE);
2230    if (a2d_status != A2D_SUCCESS)
2231    {
2232        APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
2233        return;
2234    }
2235
2236    btif_media_cb.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
2237    btif_media_cb.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
2238
2239    btif_media_cb.rx_flush = FALSE;
2240    APPL_TRACE_DEBUG("Reset to sink role");
2241    status = OI_CODEC_SBC_DecoderReset(&context, contextData, sizeof(contextData), 2, 2, FALSE);
2242    if (!OI_SUCCESS(status)) {
2243        APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
2244    }
2245
2246    UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
2247
2248    switch(sbc_cie.samp_freq)
2249    {
2250        case A2D_SBC_IE_SAMP_FREQ_16:
2251            APPL_TRACE_DEBUG("\tsamp_freq:%d (16000)", sbc_cie.samp_freq);
2252            freq_multiple = 16*20;
2253            break;
2254        case A2D_SBC_IE_SAMP_FREQ_32:
2255            APPL_TRACE_DEBUG("\tsamp_freq:%d (32000)", sbc_cie.samp_freq);
2256            freq_multiple = 32*20;
2257            break;
2258        case A2D_SBC_IE_SAMP_FREQ_44:
2259            APPL_TRACE_DEBUG("\tsamp_freq:%d (44100)", sbc_cie.samp_freq);
2260            freq_multiple = 441*2;
2261            break;
2262        case A2D_SBC_IE_SAMP_FREQ_48:
2263            APPL_TRACE_DEBUG("\tsamp_freq:%d (48000)", sbc_cie.samp_freq);
2264            freq_multiple = 48*20;
2265            break;
2266        default:
2267            APPL_TRACE_DEBUG(" Unknown Frequency ");
2268            break;
2269    }
2270
2271    switch(sbc_cie.ch_mode)
2272    {
2273        case A2D_SBC_IE_CH_MD_MONO:
2274            APPL_TRACE_DEBUG("\tch_mode:%d (Mono)", sbc_cie.ch_mode);
2275            break;
2276        case A2D_SBC_IE_CH_MD_DUAL:
2277            APPL_TRACE_DEBUG("\tch_mode:%d (DUAL)", sbc_cie.ch_mode);
2278            break;
2279        case A2D_SBC_IE_CH_MD_STEREO:
2280            APPL_TRACE_DEBUG("\tch_mode:%d (STEREO)", sbc_cie.ch_mode);
2281            break;
2282        case A2D_SBC_IE_CH_MD_JOINT:
2283            APPL_TRACE_DEBUG("\tch_mode:%d (JOINT)", sbc_cie.ch_mode);
2284            break;
2285        default:
2286            APPL_TRACE_DEBUG(" Unknown Mode ");
2287            break;
2288    }
2289
2290    switch(sbc_cie.block_len)
2291    {
2292        case A2D_SBC_IE_BLOCKS_4:
2293            APPL_TRACE_DEBUG("\tblock_len:%d (4)", sbc_cie.block_len);
2294            num_blocks = 4;
2295            break;
2296        case A2D_SBC_IE_BLOCKS_8:
2297            APPL_TRACE_DEBUG("\tblock_len:%d (8)", sbc_cie.block_len);
2298            num_blocks = 8;
2299            break;
2300        case A2D_SBC_IE_BLOCKS_12:
2301            APPL_TRACE_DEBUG("\tblock_len:%d (12)", sbc_cie.block_len);
2302            num_blocks = 12;
2303            break;
2304        case A2D_SBC_IE_BLOCKS_16:
2305            APPL_TRACE_DEBUG("\tblock_len:%d (16)", sbc_cie.block_len);
2306            num_blocks = 16;
2307            break;
2308        default:
2309            APPL_TRACE_DEBUG(" Unknown BlockLen ");
2310            break;
2311    }
2312
2313    switch(sbc_cie.num_subbands)
2314    {
2315        case A2D_SBC_IE_SUBBAND_4:
2316            APPL_TRACE_DEBUG("\tnum_subbands:%d (4)", sbc_cie.num_subbands);
2317            num_subbands = 4;
2318            break;
2319        case A2D_SBC_IE_SUBBAND_8:
2320            APPL_TRACE_DEBUG("\tnum_subbands:%d (8)", sbc_cie.num_subbands);
2321            num_subbands = 8;
2322            break;
2323        default:
2324            APPL_TRACE_DEBUG(" Unknown SubBands ");
2325            break;
2326    }
2327
2328    switch(sbc_cie.alloc_mthd)
2329    {
2330        case A2D_SBC_IE_ALLOC_MD_S:
2331            APPL_TRACE_DEBUG("\talloc_mthd:%d (SNR)", sbc_cie.alloc_mthd);
2332            break;
2333        case A2D_SBC_IE_ALLOC_MD_L:
2334            APPL_TRACE_DEBUG("\talloc_mthd:%d (Loudness)", sbc_cie.alloc_mthd);
2335            break;
2336        default:
2337            APPL_TRACE_DEBUG(" Unknown Allocation Method");
2338            break;
2339    }
2340
2341    APPL_TRACE_DEBUG("\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
2342
2343    btif_media_cb.frames_to_process = ((freq_multiple)/(num_blocks*num_subbands)) + 1;
2344    APPL_TRACE_DEBUG(" Frames to be processed in 20 ms %d",btif_media_cb.frames_to_process);
2345}
2346#endif
2347
2348/*******************************************************************************
2349 **
2350 ** Function         btif_media_task_feeding_state_reset
2351 **
2352 ** Description      Reset the media feeding state
2353 **
2354 ** Returns          void
2355 **
2356 *******************************************************************************/
2357static void btif_media_task_feeding_state_reset(void)
2358{
2359    APPL_TRACE_WARNING("overflow %d, enter %d, exit %d",
2360        btif_media_cb.media_feeding_state.pcm.overflow_count,
2361        btif_media_cb.media_feeding_state.pcm.max_counter_enter,
2362        btif_media_cb.media_feeding_state.pcm.max_counter_exit);
2363
2364    /* By default, just clear the entire state */
2365    memset(&btif_media_cb.media_feeding_state, 0, sizeof(btif_media_cb.media_feeding_state));
2366
2367    if (btif_media_cb.TxTranscoding == BTIF_MEDIA_TRSCD_PCM_2_SBC)
2368    {
2369        btif_media_cb.media_feeding_state.pcm.bytes_per_tick =
2370                (btif_media_cb.media_feeding.cfg.pcm.sampling_freq *
2371                 btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8 *
2372                 btif_media_cb.media_feeding.cfg.pcm.num_channel *
2373                 BTIF_MEDIA_TIME_TICK)/1000;
2374
2375        APPL_TRACE_WARNING("pcm bytes per tick %d",
2376                            (int)btif_media_cb.media_feeding_state.pcm.bytes_per_tick);
2377    }
2378}
2379/*******************************************************************************
2380 **
2381 ** Function         btif_media_task_aa_start_tx
2382 **
2383 ** Description      Start media task encoding
2384 **
2385 ** Returns          void
2386 **
2387 *******************************************************************************/
2388static void btif_media_task_aa_start_tx(void)
2389{
2390    APPL_TRACE_DEBUG("btif_media_task_aa_start_tx is timer %d, feeding mode %d",
2391             btif_media_cb.is_tx_timer, btif_media_cb.feeding_mode);
2392
2393    /* Use a timer to poll the UIPC, get rid of the UIPC call back */
2394    // UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_CBACK, NULL);
2395
2396    btif_media_cb.is_tx_timer = TRUE;
2397    last_frame_us = 0;
2398
2399    /* Reset the media feeding state */
2400    btif_media_task_feeding_state_reset();
2401
2402    APPL_TRACE_EVENT("starting timer %d ticks (%d)",
2403                  GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TICKS_PER_SEC);
2404
2405    GKI_start_timer(BTIF_MEDIA_AA_TASK_TIMER_ID, GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TRUE);
2406}
2407
2408/*******************************************************************************
2409 **
2410 ** Function         btif_media_task_aa_stop_tx
2411 **
2412 ** Description      Stop media task encoding
2413 **
2414 ** Returns          void
2415 **
2416 *******************************************************************************/
2417static void btif_media_task_aa_stop_tx(void)
2418{
2419    APPL_TRACE_DEBUG("btif_media_task_aa_stop_tx is timer: %d", btif_media_cb.is_tx_timer);
2420
2421    /* Stop the timer first */
2422    GKI_stop_timer(BTIF_MEDIA_AA_TASK_TIMER_ID);
2423    btif_media_cb.is_tx_timer = FALSE;
2424
2425    UIPC_Close(UIPC_CH_ID_AV_AUDIO);
2426
2427    /* audio engine stopped, reset tx suspended flag */
2428    btif_media_cb.tx_flush = 0;
2429    last_frame_us = 0;
2430
2431    /* Reset the media feeding state */
2432    btif_media_task_feeding_state_reset();
2433}
2434
2435/*******************************************************************************
2436 **
2437 ** Function         btif_get_num_aa_frame
2438 **
2439 ** Description
2440 **
2441 ** Returns          The number of media frames in this time slice
2442 **
2443 *******************************************************************************/
2444static UINT8 btif_get_num_aa_frame(void)
2445{
2446    UINT32 result=0;
2447
2448    switch (btif_media_cb.TxTranscoding)
2449    {
2450        case BTIF_MEDIA_TRSCD_PCM_2_SBC:
2451           {
2452            UINT32 pcm_bytes_per_frame = btif_media_cb.encoder.s16NumOfSubBands *
2453                             btif_media_cb.encoder.s16NumOfBlocks *
2454                             btif_media_cb.media_feeding.cfg.pcm.num_channel *
2455                             btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
2456
2457            UINT32 us_this_tick = BTIF_MEDIA_TIME_TICK * 1000;
2458            UINT64 now_us = time_now_us();
2459            if (last_frame_us != 0)
2460                us_this_tick = (now_us - last_frame_us);
2461            last_frame_us = now_us;
2462
2463            btif_media_cb.media_feeding_state.pcm.counter +=
2464                                btif_media_cb.media_feeding_state.pcm.bytes_per_tick *
2465                                us_this_tick / (BTIF_MEDIA_TIME_TICK * 1000);
2466            if ((!btif_media_cb.media_feeding_state.pcm.overflow) ||
2467                (btif_media_cb.TxAaQ.count < A2DP_PACKET_COUNT_LOW_WATERMARK)) {
2468                if (btif_media_cb.media_feeding_state.pcm.overflow) {
2469                    btif_media_cb.media_feeding_state.pcm.overflow = FALSE;
2470
2471                    if (btif_media_cb.media_feeding_state.pcm.counter >
2472                        btif_media_cb.media_feeding_state.pcm.max_counter_exit) {
2473                        btif_media_cb.media_feeding_state.pcm.max_counter_exit =
2474                            btif_media_cb.media_feeding_state.pcm.counter;
2475                    }
2476                }
2477                /* calculate nbr of frames pending for this media tick */
2478                result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
2479                if (result > MAX_PCM_FRAME_NUM_PER_TICK)
2480                {
2481                    APPL_TRACE_ERROR("%s() - Limiting frames to be sent from %d to %d"
2482                        , __FUNCTION__, result, MAX_PCM_FRAME_NUM_PER_TICK);
2483                    result = MAX_PCM_FRAME_NUM_PER_TICK;
2484                }
2485                btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
2486            } else {
2487                result = 0;
2488            }
2489
2490            VERBOSE("WRITE %d FRAMES", result);
2491        }
2492        break;
2493
2494        default:
2495            APPL_TRACE_ERROR("ERROR btif_get_num_aa_frame Unsupported transcoding format 0x%x",
2496                    btif_media_cb.TxTranscoding);
2497            result = 0;
2498            break;
2499    }
2500
2501#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
2502    APPL_TRACE_DEBUG("btif_get_num_aa_frame returns %d", result);
2503#endif
2504
2505    return (UINT8)result;
2506}
2507
2508/*******************************************************************************
2509 **
2510 ** Function         btif_media_sink_enque_buf
2511 **
2512 ** Description      This function is called by the av_co to fill A2DP Sink Queue
2513 **
2514 **
2515 ** Returns          size of the queue
2516 *******************************************************************************/
2517UINT8 btif_media_sink_enque_buf(BT_HDR *p_pkt)
2518{
2519    tBT_SBC_HDR *p_msg;
2520
2521    if(btif_media_cb.rx_flush == TRUE) /* Flush enabled, do not enque*/
2522        return btif_media_cb.RxSbcQ.count;
2523    if(btif_media_cb.RxSbcQ.count == MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ)
2524    {
2525        GKI_freebuf(GKI_dequeue(&(btif_media_cb.RxSbcQ)));
2526    }
2527
2528    BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf + ");
2529    /* allocate and Queue this buffer */
2530    if ((p_msg = (tBT_SBC_HDR *) GKI_getbuf(sizeof(tBT_SBC_HDR) +
2531                        p_pkt->offset+ p_pkt->len)) != NULL)
2532    {
2533        memcpy(p_msg, p_pkt, (sizeof(BT_HDR) + p_pkt->offset + p_pkt->len));
2534        p_msg->num_frames_to_be_processed = (*((UINT8*)(p_msg + 1) + p_msg->offset)) & 0x0f;
2535        BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf + ", p_msg->num_frames_to_be_processed);
2536        GKI_enqueue(&(btif_media_cb.RxSbcQ), p_msg);
2537        if(btif_media_cb.RxSbcQ.count == MAX_A2DP_DELAYED_START_FRAME_COUNT)
2538        {
2539            BTIF_TRACE_DEBUG(" Initiate Decoding ");
2540            btif_media_task_start_decoding_req();
2541        }
2542    }
2543    else
2544    {
2545        /* let caller deal with a failed allocation */
2546        BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf No Buffer left - ");
2547    }
2548    return btif_media_cb.RxSbcQ.count;
2549}
2550
2551/*******************************************************************************
2552 **
2553 ** Function         btif_media_aa_readbuf
2554 **
2555 ** Description      This function is called by the av_co to get the next buffer to send
2556 **
2557 **
2558 ** Returns          void
2559 *******************************************************************************/
2560BT_HDR *btif_media_aa_readbuf(void)
2561{
2562    return GKI_dequeue(&(btif_media_cb.TxAaQ));
2563}
2564
2565/*******************************************************************************
2566 **
2567 ** Function         btif_media_aa_read_feeding
2568 **
2569 ** Description
2570 **
2571 ** Returns          void
2572 **
2573 *******************************************************************************/
2574
2575BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
2576{
2577    UINT16 event;
2578    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * \
2579                             btif_media_cb.encoder.s16NumOfBlocks;
2580    UINT32 read_size;
2581    UINT16 sbc_sampling = 48000;
2582    UINT32 src_samples;
2583    UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * \
2584                          btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
2585    static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
2586            * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2];
2587    static UINT16 read_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
2588            * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
2589    UINT32 src_size_used;
2590    UINT32 dst_size_used;
2591    BOOLEAN fract_needed;
2592    INT32   fract_max;
2593    INT32   fract_threshold;
2594    UINT32  nb_byte_read;
2595
2596    /* Get the SBC sampling rate */
2597    switch (btif_media_cb.encoder.s16SamplingFreq)
2598    {
2599    case SBC_sf48000:
2600        sbc_sampling = 48000;
2601        break;
2602    case SBC_sf44100:
2603        sbc_sampling = 44100;
2604        break;
2605    case SBC_sf32000:
2606        sbc_sampling = 32000;
2607        break;
2608    case SBC_sf16000:
2609        sbc_sampling = 16000;
2610        break;
2611    }
2612
2613    if (sbc_sampling == btif_media_cb.media_feeding.cfg.pcm.sampling_freq) {
2614        read_size = bytes_needed - btif_media_cb.media_feeding_state.pcm.aa_feed_residue;
2615        nb_byte_read = UIPC_Read(channel_id, &event,
2616                  ((UINT8 *)btif_media_cb.encoder.as16PcmBuffer) +
2617                  btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
2618                  read_size);
2619        if (nb_byte_read == read_size) {
2620            btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
2621            return TRUE;
2622        } else {
2623            APPL_TRACE_WARNING("### UNDERFLOW :: ONLY READ %d BYTES OUT OF %d ###",
2624                nb_byte_read, read_size);
2625            btif_media_cb.media_feeding_state.pcm.aa_feed_residue += nb_byte_read;
2626            return FALSE;
2627        }
2628    }
2629
2630    /* Some Feeding PCM frequencies require to split the number of sample */
2631    /* to read. */
2632    /* E.g 128/6=21.3333 => read 22 and 21 and 21 => max = 2; threshold = 0*/
2633    fract_needed = FALSE;   /* Default */
2634    switch (btif_media_cb.media_feeding.cfg.pcm.sampling_freq)
2635    {
2636    case 32000:
2637    case 8000:
2638        fract_needed = TRUE;
2639        fract_max = 2;          /* 0, 1 and 2 */
2640        fract_threshold = 0;    /* Add one for the first */
2641        break;
2642    case 16000:
2643        fract_needed = TRUE;
2644        fract_max = 2;          /* 0, 1 and 2 */
2645        fract_threshold = 1;    /* Add one for the first two frames*/
2646        break;
2647    }
2648
2649    /* Compute number of sample to read from source */
2650    src_samples = blocm_x_subband;
2651    src_samples *= btif_media_cb.media_feeding.cfg.pcm.sampling_freq;
2652    src_samples /= sbc_sampling;
2653
2654    /* The previous division may have a remainder not null */
2655    if (fract_needed)
2656    {
2657        if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter <= fract_threshold)
2658        {
2659            src_samples++; /* for every read before threshold add one sample */
2660        }
2661
2662        /* do nothing if counter >= threshold */
2663        btif_media_cb.media_feeding_state.pcm.aa_feed_counter++; /* one more read */
2664        if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter > fract_max)
2665        {
2666            btif_media_cb.media_feeding_state.pcm.aa_feed_counter = 0;
2667        }
2668    }
2669
2670    /* Compute number of bytes to read from source */
2671    read_size = src_samples;
2672    read_size *= btif_media_cb.media_feeding.cfg.pcm.num_channel;
2673    read_size *= (btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8);
2674
2675    /* Read Data from UIPC channel */
2676    nb_byte_read = UIPC_Read(channel_id, &event, (UINT8 *)read_buffer, read_size);
2677
2678    //tput_mon(TRUE, nb_byte_read, FALSE);
2679
2680    if (nb_byte_read < read_size)
2681    {
2682        APPL_TRACE_WARNING("### UNDERRUN :: ONLY READ %d BYTES OUT OF %d ###",
2683                nb_byte_read, read_size);
2684
2685        if (nb_byte_read == 0)
2686            return FALSE;
2687
2688        if(btif_media_cb.feeding_mode == BTIF_AV_FEEDING_ASYNCHRONOUS)
2689        {
2690            /* Fill the unfilled part of the read buffer with silence (0) */
2691            memset(((UINT8 *)read_buffer) + nb_byte_read, 0, read_size - nb_byte_read);
2692            nb_byte_read = read_size;
2693        }
2694    }
2695
2696    /* Initialize PCM up-sampling engine */
2697    bta_av_sbc_init_up_sample(btif_media_cb.media_feeding.cfg.pcm.sampling_freq,
2698            sbc_sampling, btif_media_cb.media_feeding.cfg.pcm.bit_per_sample,
2699            btif_media_cb.media_feeding.cfg.pcm.num_channel);
2700
2701    /* re-sample read buffer */
2702    /* The output PCM buffer will be stereo, 16 bit per sample */
2703    dst_size_used = bta_av_sbc_up_sample((UINT8 *)read_buffer,
2704            (UINT8 *)up_sampled_buffer + btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
2705            nb_byte_read,
2706            sizeof(up_sampled_buffer) - btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
2707            &src_size_used);
2708
2709#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
2710    APPL_TRACE_DEBUG("btif_media_aa_read_feeding readsz:%d src_size_used:%d dst_size_used:%d",
2711            read_size, src_size_used, dst_size_used);
2712#endif
2713
2714    /* update the residue */
2715    btif_media_cb.media_feeding_state.pcm.aa_feed_residue += dst_size_used;
2716
2717    /* only copy the pcm sample when we have up-sampled enough PCM */
2718    if(btif_media_cb.media_feeding_state.pcm.aa_feed_residue >= bytes_needed)
2719    {
2720        /* Copy the output pcm samples in SBC encoding buffer */
2721        memcpy((UINT8 *)btif_media_cb.encoder.as16PcmBuffer,
2722                (UINT8 *)up_sampled_buffer,
2723                bytes_needed);
2724        /* update the residue */
2725        btif_media_cb.media_feeding_state.pcm.aa_feed_residue -= bytes_needed;
2726
2727        if (btif_media_cb.media_feeding_state.pcm.aa_feed_residue != 0)
2728        {
2729            memcpy((UINT8 *)up_sampled_buffer,
2730                   (UINT8 *)up_sampled_buffer + bytes_needed,
2731                   btif_media_cb.media_feeding_state.pcm.aa_feed_residue);
2732        }
2733        return TRUE;
2734    }
2735
2736#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
2737    APPL_TRACE_DEBUG("btif_media_aa_read_feeding residue:%d, dst_size_used %d, bytes_needed %d",
2738            btif_media_cb.media_feeding_state.pcm.aa_feed_residue, dst_size_used, bytes_needed);
2739#endif
2740
2741    return FALSE;
2742}
2743
2744/*******************************************************************************
2745 **
2746 ** Function         btif_media_aa_prep_sbc_2_send
2747 **
2748 ** Description
2749 **
2750 ** Returns          void
2751 **
2752 *******************************************************************************/
2753static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)
2754{
2755    BT_HDR * p_buf;
2756    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands *
2757                             btif_media_cb.encoder.s16NumOfBlocks;
2758
2759#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
2760    APPL_TRACE_DEBUG("btif_media_aa_prep_sbc_2_send nb_frame %d, TxAaQ %d",
2761                       nb_frame, btif_media_cb.TxAaQ.count);
2762#endif
2763    while (nb_frame)
2764    {
2765        if (NULL == (p_buf = GKI_getpoolbuf(BTIF_MEDIA_AA_POOL_ID)))
2766        {
2767            APPL_TRACE_ERROR ("ERROR btif_media_aa_prep_sbc_2_send no buffer TxCnt %d ",
2768                                btif_media_cb.TxAaQ.count);
2769            return;
2770        }
2771
2772        /* Init buffer */
2773        p_buf->offset = BTIF_MEDIA_AA_SBC_OFFSET;
2774        p_buf->len = 0;
2775        p_buf->layer_specific = 0;
2776
2777        do
2778        {
2779            /* Write @ of allocated buffer in encoder.pu8Packet */
2780            btif_media_cb.encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
2781            /* Fill allocated buffer with 0 */
2782            memset(btif_media_cb.encoder.as16PcmBuffer, 0, blocm_x_subband
2783                    * btif_media_cb.encoder.s16NumOfChannels);
2784
2785            /* Read PCM data and upsample them if needed */
2786            if (btif_media_aa_read_feeding(UIPC_CH_ID_AV_AUDIO))
2787            {
2788                /* SBC encode and descramble frame */
2789                SBC_Encoder(&(btif_media_cb.encoder));
2790                A2D_SbcChkFrInit(btif_media_cb.encoder.pu8Packet);
2791                A2D_SbcDescramble(btif_media_cb.encoder.pu8Packet, btif_media_cb.encoder.u16PacketLength);
2792                /* Update SBC frame length */
2793                p_buf->len += btif_media_cb.encoder.u16PacketLength;
2794                nb_frame--;
2795                p_buf->layer_specific++;
2796            }
2797            else
2798            {
2799                APPL_TRACE_WARNING("btif_media_aa_prep_sbc_2_send underflow %d, %d",
2800                    nb_frame, btif_media_cb.media_feeding_state.pcm.aa_feed_residue);
2801                btif_media_cb.media_feeding_state.pcm.counter += nb_frame *
2802                     btif_media_cb.encoder.s16NumOfSubBands *
2803                     btif_media_cb.encoder.s16NumOfBlocks *
2804                     btif_media_cb.media_feeding.cfg.pcm.num_channel *
2805                     btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
2806                /* no more pcm to read */
2807                nb_frame = 0;
2808
2809                /* break read loop if timer was stopped (media task stopped) */
2810                if ( btif_media_cb.is_tx_timer == FALSE )
2811                {
2812                    GKI_freebuf(p_buf);
2813                    return;
2814                }
2815            }
2816
2817        } while (((p_buf->len + btif_media_cb.encoder.u16PacketLength) < btif_media_cb.TxAaMtuSize)
2818                && (p_buf->layer_specific < 0x0F) && nb_frame);
2819
2820        if(p_buf->len)
2821        {
2822            /* timestamp of the media packet header represent the TS of the first SBC frame
2823               i.e the timestamp before including this frame */
2824            *((UINT32 *) (p_buf + 1)) = btif_media_cb.timestamp;
2825
2826            btif_media_cb.timestamp += p_buf->layer_specific * blocm_x_subband;
2827
2828            VERBOSE("TX QUEUE NOW %d", btif_media_cb.TxAaQ.count);
2829
2830            if (btif_media_cb.tx_flush)
2831            {
2832                APPL_TRACE_DEBUG("### tx suspended, discarded frame ###");
2833
2834                if (btif_media_cb.TxAaQ.count > 0)
2835                    btif_media_flush_q(&(btif_media_cb.TxAaQ));
2836
2837                GKI_freebuf(p_buf);
2838                return;
2839            }
2840
2841            /* Enqueue the encoded SBC frame in AA Tx Queue */
2842            GKI_enqueue(&(btif_media_cb.TxAaQ), p_buf);
2843        }
2844        else
2845        {
2846            GKI_freebuf(p_buf);
2847        }
2848
2849        if (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ) {
2850            UINT32 reset_rate_bytes = btif_media_cb.media_feeding_state.pcm.bytes_per_tick *
2851                                (RESET_RATE_COUNTER_THRESHOLD_MS / BTIF_MEDIA_TIME_TICK);
2852            btif_media_cb.media_feeding_state.pcm.overflow = TRUE;
2853            btif_media_cb.media_feeding_state.pcm.counter += nb_frame *
2854                     btif_media_cb.encoder.s16NumOfSubBands *
2855                     btif_media_cb.encoder.s16NumOfBlocks *
2856                     btif_media_cb.media_feeding.cfg.pcm.num_channel *
2857                     btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
2858
2859            btif_media_cb.media_feeding_state.pcm.overflow_count++;
2860            if (btif_media_cb.media_feeding_state.pcm.counter >
2861                btif_media_cb.media_feeding_state.pcm.max_counter_enter) {
2862                btif_media_cb.media_feeding_state.pcm.max_counter_enter =
2863                    btif_media_cb.media_feeding_state.pcm.counter;
2864            }
2865
2866            if (btif_media_cb.media_feeding_state.pcm.counter > reset_rate_bytes) {
2867                btif_media_cb.media_feeding_state.pcm.counter = 0;
2868                APPL_TRACE_WARNING("btif_media_aa_prep_sbc_2_send:reset rate counter");
2869            }
2870
2871            /* no more pcm to read */
2872            nb_frame = 0;
2873        }
2874    }
2875}
2876
2877
2878/*******************************************************************************
2879 **
2880 ** Function         btif_media_aa_prep_2_send
2881 **
2882 ** Description
2883 **
2884 ** Returns          void
2885 **
2886 *******************************************************************************/
2887
2888static void btif_media_aa_prep_2_send(UINT8 nb_frame)
2889{
2890    VERBOSE("btif_media_aa_prep_2_send : %d frames (queue %d)", nb_frame,
2891                       btif_media_cb.TxAaQ.count);
2892
2893    switch (btif_media_cb.TxTranscoding)
2894    {
2895    case BTIF_MEDIA_TRSCD_PCM_2_SBC:
2896        btif_media_aa_prep_sbc_2_send(nb_frame);
2897        break;
2898
2899
2900    default:
2901        APPL_TRACE_ERROR("ERROR btif_media_aa_prep_2_send unsupported transcoding format 0x%x",btif_media_cb.TxTranscoding);
2902        break;
2903    }
2904}
2905
2906/*******************************************************************************
2907 **
2908 ** Function         btif_media_send_aa_frame
2909 **
2910 ** Description
2911 **
2912 ** Returns          void
2913 **
2914 *******************************************************************************/
2915static void btif_media_send_aa_frame(void)
2916{
2917    UINT8 nb_frame_2_send;
2918
2919    /* get the number of frame to send */
2920    nb_frame_2_send = btif_get_num_aa_frame();
2921
2922    if (nb_frame_2_send != 0) {
2923        /* format and Q buffer to send */
2924        btif_media_aa_prep_2_send(nb_frame_2_send);
2925    }
2926
2927    /* send it */
2928    VERBOSE("btif_media_send_aa_frame : send %d frames", nb_frame_2_send);
2929    bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
2930}
2931
2932#endif /* BTA_AV_INCLUDED == TRUE */
2933
2934/*******************************************************************************
2935 **
2936 ** Function         dump_codec_info
2937 **
2938 ** Description      Decode and display codec_info (for debug)
2939 **
2940 ** Returns          void
2941 **
2942 *******************************************************************************/
2943void dump_codec_info(unsigned char *p_codec)
2944{
2945    tA2D_STATUS a2d_status;
2946    tA2D_SBC_CIE sbc_cie;
2947
2948    a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec, FALSE);
2949    if (a2d_status != A2D_SUCCESS)
2950    {
2951        APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
2952        return;
2953    }
2954
2955    APPL_TRACE_DEBUG("dump_codec_info");
2956
2957    if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_16)
2958    {    APPL_TRACE_DEBUG("\tsamp_freq:%d (16000)", sbc_cie.samp_freq);}
2959    else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_32)
2960    {    APPL_TRACE_DEBUG("\tsamp_freq:%d (32000)", sbc_cie.samp_freq);}
2961    else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_44)
2962    {    APPL_TRACE_DEBUG("\tsamp_freq:%d (44.100)", sbc_cie.samp_freq);}
2963    else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_48)
2964    {    APPL_TRACE_DEBUG("\tsamp_freq:%d (48000)", sbc_cie.samp_freq);}
2965    else
2966    {    APPL_TRACE_DEBUG("\tBAD samp_freq:%d", sbc_cie.samp_freq);}
2967
2968    if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_MONO)
2969    {    APPL_TRACE_DEBUG("\tch_mode:%d (Mono)", sbc_cie.ch_mode);}
2970    else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_DUAL)
2971    {    APPL_TRACE_DEBUG("\tch_mode:%d (Dual)", sbc_cie.ch_mode);}
2972    else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_STEREO)
2973    {    APPL_TRACE_DEBUG("\tch_mode:%d (Stereo)", sbc_cie.ch_mode);}
2974    else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_JOINT)
2975    {    APPL_TRACE_DEBUG("\tch_mode:%d (Joint)", sbc_cie.ch_mode);}
2976    else
2977    {    APPL_TRACE_DEBUG("\tBAD ch_mode:%d", sbc_cie.ch_mode);}
2978
2979    if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_4)
2980    {    APPL_TRACE_DEBUG("\tblock_len:%d (4)", sbc_cie.block_len);}
2981    else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_8)
2982    {    APPL_TRACE_DEBUG("\tblock_len:%d (8)", sbc_cie.block_len);}
2983    else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_12)
2984    {    APPL_TRACE_DEBUG("\tblock_len:%d (12)", sbc_cie.block_len);}
2985    else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_16)
2986    {    APPL_TRACE_DEBUG("\tblock_len:%d (16)", sbc_cie.block_len);}
2987    else
2988    {    APPL_TRACE_DEBUG("\tBAD block_len:%d", sbc_cie.block_len);}
2989
2990    if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_4)
2991    {    APPL_TRACE_DEBUG("\tnum_subbands:%d (4)", sbc_cie.num_subbands);}
2992    else  if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_8)
2993    {    APPL_TRACE_DEBUG("\tnum_subbands:%d (8)", sbc_cie.num_subbands);}
2994    else
2995    {    APPL_TRACE_DEBUG("\tBAD num_subbands:%d", sbc_cie.num_subbands);}
2996
2997    if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_S)
2998    {    APPL_TRACE_DEBUG("\talloc_mthd:%d (SNR)", sbc_cie.alloc_mthd);}
2999    else  if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L)
3000    {    APPL_TRACE_DEBUG("\talloc_mthd:%d (Loundess)", sbc_cie.alloc_mthd);}
3001    else
3002    {    APPL_TRACE_DEBUG("\tBAD alloc_mthd:%d", sbc_cie.alloc_mthd);}
3003
3004    APPL_TRACE_DEBUG("\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
3005
3006}
3007
3008