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)
79 OI_CODEC_SBC_DECODER_CONTEXT context;
80 OI_UINT32 contextData[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
81 OI_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 */
116 enum
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
136 enum {
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")
183 static 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 *****************************************************************************/
235 typedef struct
236 {
237 UINT16 num_frames_to_be_processed;
238 UINT16 len;
239 UINT16 offset;
240 UINT16 layer_specific;
241 } tBT_SBC_HDR;
242
243 typedef 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
257 typedef union
258 {
259 tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE pcm;
260 } tBTIF_AV_MEDIA_FEEDINGS_STATE;
261
262 typedef 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
291 typedef 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
303 static tBTIF_MEDIA_CB btif_media_cb;
304 static int media_task_running = MEDIA_TASK_STATE_OFF;
305 static UINT64 last_frame_us = 0;
306
307
308 /*****************************************************************************
309 ** Local functions
310 *****************************************************************************/
311
312 static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
313 static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
314 static void btif_a2dp_encoder_update(void);
315 const char* dump_media_event(UINT16 event);
316 #if (BTA_AV_SINK_INCLUDED == TRUE)
317 extern 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);
322 extern 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
329 static void btif_media_flush_q(BUFFER_Q *p_q);
330 static void btif_media_task_aa_handle_stop_decoding(void );
331 static void btif_media_task_aa_rx_flush(void);
332 static BOOLEAN btif_media_task_stop_decoding_req(void);
333
334 /*****************************************************************************
335 ** Externs
336 *****************************************************************************/
337
338 static void btif_media_task_handle_cmd(BT_HDR *p_msg);
339 static 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)
342 static void btif_media_task_handle_inc_media(tBT_SBC_HDR*p_msg);
343 #endif
344
345 #if (BTA_AV_INCLUDED == TRUE)
346 static void btif_media_send_aa_frame(void);
347 static void btif_media_task_feeding_state_reset(void);
348 static void btif_media_task_aa_start_tx(void);
349 static void btif_media_task_aa_stop_tx(void);
350 static void btif_media_task_enc_init(BT_HDR *p_msg);
351 static void btif_media_task_enc_update(BT_HDR *p_msg);
352 static void btif_media_task_audio_feeding_init(BT_HDR *p_msg);
353 static void btif_media_task_aa_tx_flush(BT_HDR *p_msg);
354 static void btif_media_aa_prep_2_send(UINT8 nb_frame);
355 #if (BTA_AV_SINK_INCLUDED == TRUE)
356 static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg);
357 static void btif_media_task_aa_handle_clear_track(void);
358 #endif
359 static void btif_media_task_aa_handle_start_decoding(void );
360 #endif
361 BOOLEAN btif_media_task_start_decoding_req(void);
362 BOOLEAN btif_media_task_clear_track(void);
363 /*****************************************************************************
364 ** Misc helper functions
365 *****************************************************************************/
366
time_now_us()367 static 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
log_tstamps_us(char * comment)374 static 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
dump_media_event(UINT16 event)383 const 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
dump_a2dp_ctrl_event(UINT8 event)413 static 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
btif_audiopath_detached(void)427 static 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
a2dp_cmd_acknowledge(int status)440 static 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
btif_recv_ctrl_data(void)462 static 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
btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id,tUIPC_EVENT event)580 static 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
btif_a2dp_data_cb(tUIPC_CH_ID ch_id,tUIPC_EVENT event)609 static 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
btif_media_task_get_sbc_rate(void)654 static 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
btif_a2dp_encoder_init(void)668 static 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
btif_a2dp_encoder_update(void)700 static 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
btif_a2dp_start_media_task(void)766 int 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
btif_a2dp_stop_media_task(void)806 void 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
btif_a2dp_on_init(void)822 void 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
btif_a2dp_setup_codec(void)838 void 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
btif_a2dp_on_idle(void)881 void 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
btif_a2dp_on_open(void)913 void 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 *******************************************************************************/
btif_media_task_clear_track(void)930 BOOLEAN 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 *******************************************************************************/
btif_media_task_stop_decoding_req(void)953 BOOLEAN 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 *******************************************************************************/
btif_media_task_start_decoding_req(void)980 BOOLEAN 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
btif_reset_decoder(UINT8 * p_av)1008 void 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
btif_a2dp_on_started(tBTA_AV_START * p_av,BOOLEAN pending_start)1038 BOOLEAN 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
btif_a2dp_ack_fail(void)1092 void 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
btif_a2dp_on_stopped(tBTA_AV_SUSPEND * p_av)1110 void 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
btif_a2dp_on_suspended(tBTA_AV_SUSPEND * p_av)1156 void 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 */
btif_a2dp_set_rx_flush(BOOLEAN enable)1184 void 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 */
btif_a2dp_set_tx_flush(BOOLEAN enable)1191 void 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 *******************************************************************************/
btif_media_task_avk_handle_timer(void)1207 static 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
btif_media_task_aa_handle_timer(void)1277 static 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 *******************************************************************************/
btif_media_task_aa_handle_uipc_rx_rdy(void)1308 static 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
btif_media_task_init(void)1334 void 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 *******************************************************************************/
btif_media_task(void * p)1358 int 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 *******************************************************************************/
btif_media_task_send_cmd_evt(UINT16 Evt)1445 BOOLEAN 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 *******************************************************************************/
btif_media_flush_q(BUFFER_Q * p_q)1468 static 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 *******************************************************************************/
btif_media_task_handle_cmd(BT_HDR * p_msg)1486 static 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 *******************************************************************************/
btif_media_task_handle_inc_media(tBT_SBC_HDR * p_msg)1552 static 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 *******************************************************************************/
btif_media_task_handle_media(BT_HDR * p_msg)1605 static 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 *******************************************************************************/
btif_media_task_enc_init_req(tBTIF_MEDIA_INIT_AUDIO * p_msg)1620 BOOLEAN 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 *******************************************************************************/
btif_media_task_enc_update_req(tBTIF_MEDIA_UPDATE_AUDIO * p_msg)1644 BOOLEAN 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 *******************************************************************************/
btif_media_task_audio_feeding_init_req(tBTIF_MEDIA_INIT_AUDIO_FEEDING * p_msg)1668 BOOLEAN 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 *******************************************************************************/
btif_media_task_start_aa_req(void)1692 BOOLEAN 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 *******************************************************************************/
btif_media_task_stop_aa_req(void)1716 BOOLEAN 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 *******************************************************************************/
btif_media_task_aa_rx_flush_req(void)1738 BOOLEAN 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 *******************************************************************************/
btif_media_task_aa_tx_flush_req(void)1765 BOOLEAN 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 *******************************************************************************/
btif_media_task_aa_rx_flush(void)1787 static 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 *******************************************************************************/
btif_media_task_aa_tx_flush(BT_HDR * p_msg)1805 static 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 *******************************************************************************/
btif_media_task_enc_init(BT_HDR * p_msg)1829 static 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
btif_media_task_enc_update(BT_HDR * p_msg)1875 static 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 *******************************************************************************/
btif_media_task_pcm2sbc_init(tBTIF_MEDIA_INIT_AUDIO_FEEDING * p_feeding)2025 static 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 *******************************************************************************/
btif_media_task_audio_feeding_init(BT_HDR * p_msg)2105 static 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
btif_a2dp_get_track_frequency(UINT8 frequency)2129 int 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
btif_a2dp_get_track_channel_count(UINT8 channeltype)2148 int 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
btif_a2dp_set_peer_sep(UINT8 sep)2163 void 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 *******************************************************************************/
btif_media_task_aa_handle_stop_decoding(void)2176 static 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 *******************************************************************************/
btif_media_task_aa_handle_start_decoding(void)2191 static 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
btif_media_task_aa_handle_clear_track(void)2201 static 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 *******************************************************************************/
btif_media_task_aa_handle_decoder_reset(BT_HDR * p_msg)2215 static 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 *******************************************************************************/
btif_media_task_feeding_state_reset(void)2357 static 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 *******************************************************************************/
btif_media_task_aa_start_tx(void)2388 static 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 *******************************************************************************/
btif_media_task_aa_stop_tx(void)2417 static 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 *******************************************************************************/
btif_get_num_aa_frame(void)2444 static 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 *******************************************************************************/
btif_media_sink_enque_buf(BT_HDR * p_pkt)2517 UINT8 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 *******************************************************************************/
btif_media_aa_readbuf(void)2560 BT_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
btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)2575 BOOLEAN 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 *******************************************************************************/
btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)2753 static 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
btif_media_aa_prep_2_send(UINT8 nb_frame)2888 static 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 *******************************************************************************/
btif_media_send_aa_frame(void)2915 static 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 *******************************************************************************/
dump_codec_info(unsigned char * p_codec)2943 void 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