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