blob: b85589c24e9c00786ae414c089094de5d78dc63a [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"
lungtsai_lin6718c6d2014-07-02 20:39:02 +080069#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +053070#include "oi_codec_sbc.h"
71#include "oi_status.h"
72#endif
73#include "stdio.h"
74#include <dlfcn.h>
Hemant Guptaf7dd9f52013-10-24 15:37:17 +053075
76//#define DEBUG_MEDIA_AV_FLOW TRUE
77
lungtsai_lin6718c6d2014-07-02 20:39:02 +080078#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +053079OI_CODEC_SBC_DECODER_CONTEXT context;
80OI_UINT32 contextData[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
81OI_INT16 pcmData[15*SBC_MAX_SAMPLES_PER_FRAME*SBC_MAX_CHANNELS];
Hemant Guptaf7dd9f52013-10-24 15:37:17 +053082#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -080083
84/*****************************************************************************
85 ** Constants
86 *****************************************************************************/
87
Hemant Guptaf7dd9f52013-10-24 15:37:17 +053088#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
The Android Open Source Project5738f832012-12-12 16:00:35 -080095
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
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530104#define BTIF_MEDIA_AVK_TASK_TIMER_ID TIMER_2
105
The Android Open Source Project5738f832012-12-12 16:00:35 -0800106#define BTIF_MEDIA_AA_TASK_TIMER TIMER_0_EVT_MASK
107#define BTIF_MEDIA_AV_TASK_TIMER TIMER_1_EVT_MASK
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530108#define BTIF_MEDIA_AVK_TASK_TIMER TIMER_2_EVT_MASK
109
The Android Open Source Project5738f832012-12-12 16:00:35 -0800110
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
Zhihai Xu01c686c2013-09-15 19:59:37 -0700114
The Android Open Source Project5738f832012-12-12 16:00:35 -0800115/* BTIF media cmd event definition : BTIF_MEDIA_TASK_CMD */
116enum
117{
118 BTIF_MEDIA_START_AA_TX = 1,
119 BTIF_MEDIA_STOP_AA_TX,
120 BTIF_MEDIA_AA_RX_RDY,
121 BTIF_MEDIA_UIPC_RX_RDY,
122 BTIF_MEDIA_SBC_ENC_INIT,
123 BTIF_MEDIA_SBC_ENC_UPDATE,
124 BTIF_MEDIA_SBC_DEC_INIT,
125 BTIF_MEDIA_VIDEO_DEC_INIT,
126 BTIF_MEDIA_FLUSH_AA_TX,
127 BTIF_MEDIA_FLUSH_AA_RX,
128 BTIF_MEDIA_AUDIO_FEEDING_INIT,
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530129 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
The Android Open Source Project5738f832012-12-12 16:00:35 -0800134};
135
136enum {
137 MEDIA_TASK_STATE_OFF = 0,
138 MEDIA_TASK_STATE_ON = 1,
139 MEDIA_TASK_STATE_SHUTTING_DOWN = 2
140};
141
142/* Macro to multiply the media task tick */
143#ifndef BTIF_MEDIA_NUM_TICK
144#define BTIF_MEDIA_NUM_TICK 1
145#endif
146
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200147/* Media task tick in milliseconds, must be set to multiple of
148 (1000/TICKS_PER_SEC) (10) */
149
The Android Open Source Project5738f832012-12-12 16:00:35 -0800150#define BTIF_MEDIA_TIME_TICK (20 * BTIF_MEDIA_NUM_TICK)
Zhihai Xu01c686c2013-09-15 19:59:37 -0700151#define A2DP_DATA_READ_POLL_MS (BTIF_MEDIA_TIME_TICK / 2)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530152#define BTIF_SINK_MEDIA_TIME_TICK (20 * BTIF_MEDIA_NUM_TICK)
153
The Android Open Source Project5738f832012-12-12 16:00:35 -0800154
The Android Open Source Project5738f832012-12-12 16:00:35 -0800155/* 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 */
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200172#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
The Android Open Source Project5738f832012-12-12 16:00:35 -0800177
178#ifndef A2DP_MEDIA_TASK_STACK_SIZE
179#define A2DP_MEDIA_TASK_STACK_SIZE 0x2000 /* In bytes */
180#endif
181
182#define A2DP_MEDIA_TASK_TASK_STR ((INT8 *) "A2DP-MEDIA")
183static UINT32 a2dp_media_task_stack[(A2DP_MEDIA_TASK_STACK_SIZE + 3) / 4];
184
185#define BT_MEDIA_TASK A2DP_MEDIA_TASK
186
187#define USEC_PER_SEC 1000000L
Mattias Agren5fd74f02013-04-05 19:04:35 +0200188#define TPUT_STATS_INTERVAL_US (3000*1000)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800189
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 */
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200204
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
Zhihai Xu4aebca42013-09-19 11:30:44 -0700209/* 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
Andre Eisenbach26e80aa2015-01-07 14:30:28 -0800211
212#ifndef MAX_PCM_FRAME_NUM_PER_TICK
213#define MAX_PCM_FRAME_NUM_PER_TICK 14
214#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800215
216//#define BTIF_MEDIA_VERBOSE_ENABLED
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530217/* In case of A2DP SINK, we will delay start by 5 AVDTP Packets*/
218#define MAX_A2DP_DELAYED_START_FRAME_COUNT 5
219#define PACKET_PLAYED_PER_TICK_48 8
220#define PACKET_PLAYED_PER_TICK_44 7
221#define PACKET_PLAYED_PER_TICK_32 5
222#define PACKET_PLAYED_PER_TICK_16 3
223
The Android Open Source Project5738f832012-12-12 16:00:35 -0800224
225#ifdef BTIF_MEDIA_VERBOSE_ENABLED
226#define VERBOSE(fmt, ...) \
227 LogMsg( TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
228 TRACE_TYPE_ERROR, fmt, ## __VA_ARGS__)
229#else
230#define VERBOSE(fmt, ...)
231#endif
232
233/*****************************************************************************
234 ** Data types
235 *****************************************************************************/
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530236typedef struct
237{
238 UINT16 num_frames_to_be_processed;
239 UINT16 len;
240 UINT16 offset;
241 UINT16 layer_specific;
242} tBT_SBC_HDR;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800243
244typedef struct
245{
246 UINT32 aa_frame_counter;
247 INT32 aa_feed_counter;
248 INT32 aa_feed_residue;
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200249 UINT32 counter;
250 UINT32 bytes_per_tick; /* pcm bytes read each media task tick */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800251} tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE;
252
253
254typedef union
255{
256 tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE pcm;
257} tBTIF_AV_MEDIA_FEEDINGS_STATE;
258
259typedef struct
260{
261#if (BTA_AV_INCLUDED == TRUE)
262 BUFFER_Q TxAaQ;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530263 BUFFER_Q RxSbcQ;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800264 BOOLEAN is_tx_timer;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530265 BOOLEAN is_rx_timer;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800266 UINT16 TxAaMtuSize;
267 UINT32 timestamp;
268 UINT8 TxTranscoding;
269 tBTIF_AV_FEEDING_MODE feeding_mode;
270 tBTIF_AV_MEDIA_FEEDINGS media_feeding;
271 tBTIF_AV_MEDIA_FEEDINGS_STATE media_feeding_state;
272 SBC_ENC_PARAMS encoder;
273 UINT8 busy_level;
274 void* av_sm_hdl;
275 UINT8 a2dp_cmd_pending; /* we can have max one command pending */
276 BOOLEAN tx_flush; /* discards any outgoing data when true */
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530277 BOOLEAN rx_flush; /* discards any incoming data when true */
Mike Lockwood3e8a242f2014-05-23 12:42:24 -0700278 UINT8 peer_sep;
279 BOOLEAN data_channel_open;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530280 UINT8 frames_to_process;
Mike Lockwood3e8a242f2014-05-23 12:42:24 -0700281
282 UINT32 sample_rate;
283 UINT8 channel_count;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800284#endif
285
286} tBTIF_MEDIA_CB;
287
288typedef struct {
Mattias Agren5fd74f02013-04-05 19:04:35 +0200289 long long rx;
290 long long rx_tot;
291 long long tx;
292 long long tx_tot;
293 long long ts_prev_us;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800294} t_stat;
295
296/*****************************************************************************
297 ** Local data
298 *****************************************************************************/
299
300static tBTIF_MEDIA_CB btif_media_cb;
301static int media_task_running = MEDIA_TASK_STATE_OFF;
Andre Eisenbachf13db8a2014-07-11 16:57:24 -0700302static UINT64 last_frame_us = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800303
304
305/*****************************************************************************
306 ** Local functions
307 *****************************************************************************/
308
309static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
310static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
311static void btif_a2dp_encoder_update(void);
Mattias Agren5fd74f02013-04-05 19:04:35 +0200312const char* dump_media_event(UINT16 event);
lungtsai_lin6718c6d2014-07-02 20:39:02 +0800313#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptace247652014-03-20 20:47:04 +0530314extern OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
315 const OI_BYTE **frameData,
316 unsigned long *frameBytes,
317 OI_INT16 *pcmData,
318 unsigned long *pcmBytes);
319extern OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
320 unsigned long *decoderData,
321 unsigned long decoderDataBytes,
322 OI_UINT8 maxChannels,
323 OI_UINT8 pcmStride,
324 OI_BOOL enhanced);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530325#endif
326static void btif_media_flush_q(BUFFER_Q *p_q);
327static void btif_media_task_aa_handle_stop_decoding(void );
328static void btif_media_task_aa_rx_flush(void);
329static BOOLEAN btif_media_task_stop_decoding_req(void);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800330
331/*****************************************************************************
332 ** Externs
333 *****************************************************************************/
334
335static void btif_media_task_handle_cmd(BT_HDR *p_msg);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530336static void btif_media_task_handle_media(BT_HDR*p_msg);
337/* Handle incoming media packets A2DP SINK streaming*/
lungtsai_lin6718c6d2014-07-02 20:39:02 +0800338#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530339static void btif_media_task_handle_inc_media(tBT_SBC_HDR*p_msg);
340#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800341
342#if (BTA_AV_INCLUDED == TRUE)
343static void btif_media_send_aa_frame(void);
344static void btif_media_task_feeding_state_reset(void);
345static void btif_media_task_aa_start_tx(void);
346static void btif_media_task_aa_stop_tx(void);
347static void btif_media_task_enc_init(BT_HDR *p_msg);
348static void btif_media_task_enc_update(BT_HDR *p_msg);
349static void btif_media_task_audio_feeding_init(BT_HDR *p_msg);
350static void btif_media_task_aa_tx_flush(BT_HDR *p_msg);
351static void btif_media_aa_prep_2_send(UINT8 nb_frame);
lungtsai_lin6718c6d2014-07-02 20:39:02 +0800352#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530353static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg);
354static void btif_media_task_aa_handle_clear_track(void);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800355#endif
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530356static void btif_media_task_aa_handle_start_decoding(void );
357#endif
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530358BOOLEAN btif_media_task_start_decoding_req(void);
359BOOLEAN btif_media_task_clear_track(void);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800360/*****************************************************************************
361 ** Misc helper functions
362 *****************************************************************************/
363
Andre Eisenbachf13db8a2014-07-11 16:57:24 -0700364static UINT64 time_now_us()
365{
366 struct timespec ts_now;
367 clock_gettime(CLOCK_BOOTTIME, &ts_now);
Andre Eisenbach25067c02014-07-21 16:52:28 -0700368 return ((UINT64)ts_now.tv_sec * USEC_PER_SEC) + ((UINT64)ts_now.tv_nsec / 1000);
Andre Eisenbachf13db8a2014-07-11 16:57:24 -0700369}
370
The Android Open Source Project5738f832012-12-12 16:00:35 -0800371static void log_tstamps_us(char *comment)
372{
Andre Eisenbachf13db8a2014-07-11 16:57:24 -0700373 static UINT64 prev_us = 0;
374 const UINT64 now_us = time_now_us();
375 APPL_TRACE_DEBUG("[%s] ts %08llu, diff : %08llu, queue sz %d", comment, now_us, now_us - prev_us,
Chris Mantonfe7216c2014-05-06 10:35:42 -0700376 GKI_queue_length(&btif_media_cb.TxAaQ));
Andre Eisenbachf13db8a2014-07-11 16:57:24 -0700377 prev_us = now_us;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800378}
379
380const char* dump_media_event(UINT16 event)
381{
382 switch(event)
383 {
384 CASE_RETURN_STR(BTIF_MEDIA_START_AA_TX)
385 CASE_RETURN_STR(BTIF_MEDIA_STOP_AA_TX)
386 CASE_RETURN_STR(BTIF_MEDIA_AA_RX_RDY)
387 CASE_RETURN_STR(BTIF_MEDIA_UIPC_RX_RDY)
388 CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_INIT)
389 CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_UPDATE)
390 CASE_RETURN_STR(BTIF_MEDIA_SBC_DEC_INIT)
391 CASE_RETURN_STR(BTIF_MEDIA_VIDEO_DEC_INIT)
392 CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_TX)
393 CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_RX)
394 CASE_RETURN_STR(BTIF_MEDIA_AUDIO_FEEDING_INIT)
395 CASE_RETURN_STR(BTIF_MEDIA_AUDIO_RECEIVING_INIT)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530396 CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE)
397 CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_START_DECODING)
398 CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_STOP_DECODING)
399 CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800400
401 default:
402 return "UNKNOWN MEDIA EVENT";
403 }
404}
405
406/*****************************************************************************
407 ** A2DP CTRL PATH
408 *****************************************************************************/
409
410static const char* dump_a2dp_ctrl_event(UINT8 event)
411{
412 switch(event)
413 {
414 CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
415 CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
416 CASE_RETURN_STR(A2DP_CTRL_CMD_START)
417 CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
418 CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
419 default:
420 return "UNKNOWN MSG ID";
421 }
422}
423
424static void btif_audiopath_detached(void)
425{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700426 APPL_TRACE_EVENT("## AUDIO PATH DETACHED ##");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800427
428 /* send stop request only if we are actively streaming and haven't received
429 a stop request. Potentially audioflinger detached abnormally */
430 if (btif_media_cb.is_tx_timer)
431 {
432 /* post stop event and wait for audio path to stop */
433 btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
434 }
435}
436
437static void a2dp_cmd_acknowledge(int status)
438{
439 UINT8 ack = status;
440
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700441 APPL_TRACE_EVENT("## a2dp ack : %s, status %d ##",
Mattias Agren5fd74f02013-04-05 19:04:35 +0200442 dump_a2dp_ctrl_event(btif_media_cb.a2dp_cmd_pending), status);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800443
444 /* sanity check */
445 if (btif_media_cb.a2dp_cmd_pending == A2DP_CTRL_CMD_NONE)
446 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700447 APPL_TRACE_ERROR("warning : no command pending, ignore ack");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800448 return;
449 }
450
451 /* clear pending */
452 btif_media_cb.a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
453
454 /* acknowledge start request */
455 UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, &ack, 1);
456}
457
458
459static void btif_recv_ctrl_data(void)
460{
461 UINT8 cmd = 0;
462 int n;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800463 n = UIPC_Read(UIPC_CH_ID_AV_CTRL, NULL, &cmd, 1);
464
465 /* detach on ctrl channel means audioflinger process was terminated */
466 if (n == 0)
467 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700468 APPL_TRACE_EVENT("CTRL CH DETACHED");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800469 UIPC_Close(UIPC_CH_ID_AV_CTRL);
470 /* we can operate only on datachannel, if af client wants to
471 do send additional commands the ctrl channel would be reestablished */
472 //btif_audiopath_detached();
473 return;
474 }
475
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700476 APPL_TRACE_DEBUG("a2dp-ctrl-cmd : %s", dump_a2dp_ctrl_event(cmd));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800477
478 btif_media_cb.a2dp_cmd_pending = cmd;
479
480 switch(cmd)
481 {
482 case A2DP_CTRL_CMD_CHECK_READY:
483
484 if (media_task_running == MEDIA_TASK_STATE_SHUTTING_DOWN)
485 {
486 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
487 return;
488 }
489
490 /* check whether av is ready to setup a2dp datapath */
491 if ((btif_av_stream_ready() == TRUE) || (btif_av_stream_started_ready() == TRUE))
492 {
493 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
494 }
495 else
496 {
497 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
498 }
499 break;
500
501 case A2DP_CTRL_CMD_START:
502
503 if (btif_av_stream_ready() == TRUE)
504 {
505 /* setup audio data channel listener */
506 UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
507
508 /* post start event and wait for audio path to open */
509 btif_dispatch_sm_event(BTIF_AV_START_STREAM_REQ_EVT, NULL, 0);
Andre Eisenbachae13ec92014-09-03 12:48:44 -0700510
511#if (BTA_AV_SINK_INCLUDED == TRUE)
512 if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
513 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
514#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800515 }
516 else if (btif_av_stream_started_ready())
517 {
518 /* already started, setup audio data channel listener
519 and ack back immediately */
520 UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
521
522 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
523 }
524 else
525 {
526 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
527 break;
528 }
529 break;
530
531 case A2DP_CTRL_CMD_STOP:
Mike Lockwood3e8a242f2014-05-23 12:42:24 -0700532 if (btif_media_cb.peer_sep == AVDT_TSEP_SNK && btif_media_cb.is_tx_timer == FALSE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800533 {
534 /* we are already stopped, just ack back */
535 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
536 break;
537 }
538
539 btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
Mike Lockwood3e8a242f2014-05-23 12:42:24 -0700540 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800541 break;
542
543 case A2DP_CTRL_CMD_SUSPEND:
544 /* local suspend */
545 if (btif_av_stream_started_ready())
546 {
547 btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
548 }
549 else
550 {
551 /* if we are not in started state, just ack back ok and let
552 audioflinger close the channel. This can happen if we are
553 remotely suspended */
554 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
555 }
556 break;
557
Mike Lockwood3e8a242f2014-05-23 12:42:24 -0700558 case A2DP_CTRL_GET_AUDIO_CONFIG:
559 {
560 uint32_t sample_rate = btif_media_cb.sample_rate;
561 uint8_t channel_count = btif_media_cb.channel_count;
562
563 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
564 UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, (UINT8 *)&sample_rate, 4);
565 UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, &channel_count, 1);
566 break;
567 }
568
The Android Open Source Project5738f832012-12-12 16:00:35 -0800569 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700570 APPL_TRACE_ERROR("UNSUPPORTED CMD (%d)", cmd);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800571 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
572 break;
573 }
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700574 APPL_TRACE_DEBUG("a2dp-ctrl-cmd : %s DONE", dump_a2dp_ctrl_event(cmd));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800575}
576
577static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
578{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800579 UNUSED(ch_id);
580
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700581 APPL_TRACE_DEBUG("A2DP-CTRL-CHANNEL EVENT %s", dump_uipc_event(event));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800582
583 switch(event)
584 {
585 case UIPC_OPEN_EVT:
586 /* fetch av statemachine handle */
587 btif_media_cb.av_sm_hdl = btif_av_get_sm_handle();
588 break;
589
590 case UIPC_CLOSE_EVT:
591 /* restart ctrl server unless we are shutting down */
592 if (media_task_running == MEDIA_TASK_STATE_ON)
593 UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
594 break;
595
596 case UIPC_RX_DATA_READY_EVT:
597 btif_recv_ctrl_data();
598 break;
599
600 default :
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700601 APPL_TRACE_ERROR("### A2DP-CTRL-CHANNEL EVENT %d NOT HANDLED ###", event);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800602 break;
603 }
604}
605
606static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
607{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800608 UNUSED(ch_id);
609
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700610 APPL_TRACE_DEBUG("BTIF MEDIA (A2DP-DATA) EVENT %s", dump_uipc_event(event));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800611
612 switch(event)
613 {
614 case UIPC_OPEN_EVT:
615
616 /* read directly from media task from here on (keep callback for
617 connection events */
618 UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
Zhihai Xu01c686c2013-09-15 19:59:37 -0700619 UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
620 (void *)A2DP_DATA_READ_POLL_MS);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800621
Mike Lockwood3e8a242f2014-05-23 12:42:24 -0700622 if (btif_media_cb.peer_sep == AVDT_TSEP_SNK) {
623 /* Start the media task to encode SBC */
624 btif_media_task_start_aa_req();
625
626 /* make sure we update any changed sbc encoder params */
627 btif_a2dp_encoder_update();
628 }
629 btif_media_cb.data_channel_open = TRUE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800630
631 /* ack back when media task is fully started */
632 break;
633
634 case UIPC_CLOSE_EVT:
635 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
636 btif_audiopath_detached();
Mike Lockwood3e8a242f2014-05-23 12:42:24 -0700637 btif_media_cb.data_channel_open = FALSE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800638 break;
639
640 default :
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700641 APPL_TRACE_ERROR("### A2DP-DATA EVENT %d NOT HANDLED ###", event);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800642 break;
643 }
644}
645
646
647/*****************************************************************************
648 ** BTIF ADAPTATION
649 *****************************************************************************/
650
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200651static UINT16 btif_media_task_get_sbc_rate(void)
652{
653 UINT16 rate = DEFAULT_SBC_BITRATE;
654
655 /* restrict bitrate if a2dp link is non-edr */
656 if (!btif_av_is_peer_edr())
657 {
658 rate = BTIF_A2DP_NON_EDR_MAX_RATE;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700659 APPL_TRACE_DEBUG("non-edr a2dp sink detected, restrict rate to %d", rate);
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200660 }
661
662 return rate;
663}
664
The Android Open Source Project5738f832012-12-12 16:00:35 -0800665static void btif_a2dp_encoder_init(void)
666{
667 UINT16 minmtu;
668 tBTIF_MEDIA_INIT_AUDIO msg;
669 tA2D_SBC_CIE sbc_config;
670
671 /* lookup table for converting channel mode */
672 UINT16 codec_mode_tbl[5] = { SBC_JOINT_STEREO, SBC_STEREO, SBC_DUAL, 0, SBC_MONO };
673
674 /* lookup table for converting number of blocks */
675 UINT16 codec_block_tbl[5] = { 16, 12, 8, 0, 4 };
676
677 /* lookup table to convert freq */
678 UINT16 freq_block_tbl[5] = { SBC_sf48000, SBC_sf44100, SBC_sf32000, 0, SBC_sf16000 };
679
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700680 APPL_TRACE_DEBUG("btif_a2dp_encoder_init");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800681
682 /* Retrieve the current SBC configuration (default if currently not used) */
683 bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
684 msg.NumOfSubBands = (sbc_config.num_subbands == A2D_SBC_IE_SUBBAND_4) ? 4 : 8;
685 msg.NumOfBlocks = codec_block_tbl[sbc_config.block_len >> 5];
686 msg.AllocationMethod = (sbc_config.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L) ? SBC_LOUDNESS : SBC_SNR;
687 msg.ChannelMode = codec_mode_tbl[sbc_config.ch_mode >> 1];
688 msg.SamplingFreq = freq_block_tbl[sbc_config.samp_freq >> 5];
689 msg.MtuSize = minmtu;
690
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700691 APPL_TRACE_EVENT("msg.ChannelMode %x", msg.ChannelMode);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800692
693 /* Init the media task to encode SBC properly */
694 btif_media_task_enc_init_req(&msg);
695}
696
697static void btif_a2dp_encoder_update(void)
698{
699 UINT16 minmtu;
700 tA2D_SBC_CIE sbc_config;
701 tBTIF_MEDIA_UPDATE_AUDIO msg;
702 UINT8 pref_min;
703 UINT8 pref_max;
704
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700705 APPL_TRACE_DEBUG("btif_a2dp_encoder_update");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800706
707 /* Retrieve the current SBC configuration (default if currently not used) */
708 bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
709
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700710 APPL_TRACE_DEBUG("btif_a2dp_encoder_update: Common min_bitpool:%d(0x%x) max_bitpool:%d(0x%x)",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800711 sbc_config.min_bitpool, sbc_config.min_bitpool,
712 sbc_config.max_bitpool, sbc_config.max_bitpool);
713
714 if (sbc_config.min_bitpool > sbc_config.max_bitpool)
715 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700716 APPL_TRACE_ERROR("btif_a2dp_encoder_update: ERROR btif_a2dp_encoder_update min_bitpool > max_bitpool");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800717 }
718
719 /* check if remote sink has a preferred bitpool range */
720 if (bta_av_co_get_remote_bitpool_pref(&pref_min, &pref_max) == TRUE)
721 {
722 /* adjust our preferred bitpool with the remote preference if within
723 our capable range */
724
725 if (pref_min < sbc_config.min_bitpool)
726 pref_min = sbc_config.min_bitpool;
727
728 if (pref_max > sbc_config.max_bitpool)
729 pref_max = sbc_config.max_bitpool;
730
731 msg.MinBitPool = pref_min;
732 msg.MaxBitPool = pref_max;
733
734 if ((pref_min != sbc_config.min_bitpool) || (pref_max != sbc_config.max_bitpool))
735 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700736 APPL_TRACE_EVENT("## adjusted our bitpool range to peer pref [%d:%d] ##",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800737 pref_min, pref_max);
738 }
739 }
740 else
741 {
742 msg.MinBitPool = sbc_config.min_bitpool;
743 msg.MaxBitPool = sbc_config.max_bitpool;
744 }
745
746 msg.MinMtuSize = minmtu;
747
748 /* Update the media task to encode SBC properly */
749 btif_media_task_enc_update_req(&msg);
750}
751
752
753/*****************************************************************************
754**
755** Function btif_a2dp_start_media_task
756**
757** Description
758**
759** Returns
760**
761*******************************************************************************/
762
763int btif_a2dp_start_media_task(void)
764{
765 int retval;
766
767 if (media_task_running != MEDIA_TASK_STATE_OFF)
768 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700769 APPL_TRACE_ERROR("warning : media task already running");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800770 return GKI_FAILURE;
771 }
772
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700773 APPL_TRACE_EVENT("## A2DP START MEDIA TASK ##");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800774
775 /* start a2dp media task */
776 retval = GKI_create_task((TASKPTR)btif_media_task, A2DP_MEDIA_TASK,
777 A2DP_MEDIA_TASK_TASK_STR,
778 (UINT16 *) ((UINT8 *)a2dp_media_task_stack + A2DP_MEDIA_TASK_STACK_SIZE),
779 sizeof(a2dp_media_task_stack));
780
781 if (retval != GKI_SUCCESS)
782 return retval;
783
784 /* wait for task to come up to sure we are able to send messages to it */
785 while (media_task_running == MEDIA_TASK_STATE_OFF)
786 usleep(10);
787
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700788 APPL_TRACE_EVENT("## A2DP MEDIA TASK STARTED ##");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800789
790 return retval;
791}
792
793/*****************************************************************************
794**
795** Function btif_a2dp_stop_media_task
796**
797** Description
798**
799** Returns
800**
801*******************************************************************************/
802
803void btif_a2dp_stop_media_task(void)
804{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700805 APPL_TRACE_EVENT("## A2DP STOP MEDIA TASK ##");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800806 GKI_destroy_task(BT_MEDIA_TASK);
807}
808
809/*****************************************************************************
810**
811** Function btif_a2dp_on_init
812**
813** Description
814**
815** Returns
816**
817*******************************************************************************/
818
819void btif_a2dp_on_init(void)
820{
821 //tput_mon(1, 0, 1);
822}
823
824
825/*****************************************************************************
826**
827** Function btif_a2dp_setup_codec
828**
829** Description
830**
831** Returns
832**
833*******************************************************************************/
834
835void btif_a2dp_setup_codec(void)
836{
837 tBTIF_AV_MEDIA_FEEDINGS media_feeding;
838 tBTIF_STATUS status;
839
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700840 APPL_TRACE_EVENT("## A2DP SETUP CODEC ##");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800841
842 GKI_disable();
843
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200844 /* for now hardcode 44.1 khz 16 bit stereo PCM format */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800845 media_feeding.cfg.pcm.sampling_freq = 44100;
846 media_feeding.cfg.pcm.bit_per_sample = 16;
847 media_feeding.cfg.pcm.num_channel = 2;
848 media_feeding.format = BTIF_AV_CODEC_PCM;
849
850 if (bta_av_co_audio_set_codec(&media_feeding, &status))
851 {
852 tBTIF_MEDIA_INIT_AUDIO_FEEDING mfeed;
853
854 /* Init the encoding task */
855 btif_a2dp_encoder_init();
856
857 /* Build the media task configuration */
858 mfeed.feeding = media_feeding;
859 mfeed.feeding_mode = BTIF_AV_FEEDING_ASYNCHRONOUS;
860 /* Send message to Media task to configure transcoding */
861 btif_media_task_audio_feeding_init_req(&mfeed);
862 }
863
864 GKI_enable();
865}
866
867
868/*****************************************************************************
869**
870** Function btif_a2dp_on_idle
871**
872** Description
873**
874** Returns
875**
876*******************************************************************************/
877
878void btif_a2dp_on_idle(void)
879{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700880 APPL_TRACE_EVENT("## ON A2DP IDLE ##");
Mike Lockwood3e8a242f2014-05-23 12:42:24 -0700881 if (btif_media_cb.peer_sep == AVDT_TSEP_SNK)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530882 {
883 /* Make sure media task is stopped */
884 btif_media_task_stop_aa_req();
885 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800886
887 bta_av_co_init();
lungtsai_lin6718c6d2014-07-02 20:39:02 +0800888#if (BTA_AV_SINK_INCLUDED == TRUE)
Mike Lockwood3e8a242f2014-05-23 12:42:24 -0700889 if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530890 {
891 btif_media_cb.rx_flush = TRUE;
892 btif_media_task_aa_rx_flush_req();
893 btif_media_task_stop_decoding_req();
894 btif_media_task_clear_track();
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700895 APPL_TRACE_DEBUG("Stopped BT track");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530896 }
897#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800898}
899
900/*****************************************************************************
901**
902** Function btif_a2dp_on_open
903**
904** Description
905**
906** Returns
907**
908*******************************************************************************/
909
910void btif_a2dp_on_open(void)
911{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700912 APPL_TRACE_EVENT("## ON A2DP OPEN ##");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800913
914 /* always use callback to notify socket events */
915 UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
916}
917
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530918/*******************************************************************************
919 **
920 ** Function btif_media_task_clear_track
921 **
922 ** Description
923 **
924 ** Returns TRUE is success
925 **
926 *******************************************************************************/
927BOOLEAN btif_media_task_clear_track(void)
928{
929 BT_HDR *p_buf;
930
931 if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
932 {
933 return FALSE;
934 }
935
936 p_buf->event = BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK;
937
938 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
939 return TRUE;
940}
941/*******************************************************************************
942 **
943 ** Function btif_media_task_stop_decoding_req
944 **
945 ** Description
946 **
947 ** Returns TRUE is success
948 **
949 *******************************************************************************/
950BOOLEAN btif_media_task_stop_decoding_req(void)
951{
952 BT_HDR *p_buf;
953
954 if (!btif_media_cb.is_rx_timer)
955 return TRUE; /* if timer is not running no need to send message */
956
957 if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
958 {
959 return FALSE;
960 }
961
962 p_buf->event = BTIF_MEDIA_AUDIO_SINK_STOP_DECODING;
963
964 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
965 return TRUE;
966}
967
968/*******************************************************************************
969 **
970 ** Function btif_media_task_start_decoding_req
971 **
972 ** Description
973 **
974 ** Returns TRUE is success
975 **
976 *******************************************************************************/
977BOOLEAN btif_media_task_start_decoding_req(void)
978{
979 BT_HDR *p_buf;
980
981 if(btif_media_cb.is_rx_timer)
982 return FALSE; /* if timer is already running no need to send message */
983
984 if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
985 {
986 return FALSE;
987 }
988
989 p_buf->event = BTIF_MEDIA_AUDIO_SINK_START_DECODING;
990
991 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
992 return TRUE;
993}
994
995/*****************************************************************************
996**
997** Function btif_reset_decoder
998**
999** Description
1000**
1001** Returns
1002**
1003*******************************************************************************/
1004
1005void btif_reset_decoder(UINT8 *p_av)
1006{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001007 APPL_TRACE_EVENT("btif_reset_decoder");
1008 APPL_TRACE_DEBUG("btif_reset_decoder p_codec_info[%x:%x:%x:%x:%x:%x]",
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301009 p_av[1], p_av[2], p_av[3],
1010 p_av[4], p_av[5], p_av[6]);
1011
1012 tBTIF_MEDIA_SINK_CFG_UPDATE *p_buf;
1013 if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_SINK_CFG_UPDATE))))
1014 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001015 APPL_TRACE_EVENT("btif_reset_decoder No Buffer ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301016 return;
1017 }
1018
1019 memcpy(p_buf->codec_info,p_av, AVDT_CODEC_SIZE);
1020 p_buf->hdr.event = BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE;
1021
1022 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1023}
1024
The Android Open Source Project5738f832012-12-12 16:00:35 -08001025/*****************************************************************************
1026**
1027** Function btif_a2dp_on_started
1028**
1029** Description
1030**
1031** Returns
1032**
1033*******************************************************************************/
1034
Zhihai Xu379743b2013-09-29 13:42:13 -07001035BOOLEAN btif_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001036{
The Android Open Source Project5738f832012-12-12 16:00:35 -08001037 tBTIF_STATUS status;
Zhihai Xu379743b2013-09-29 13:42:13 -07001038 BOOLEAN ack = FALSE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001039
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001040 APPL_TRACE_EVENT("## ON A2DP STARTED ##");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001041
Mattias Agren5fd74f02013-04-05 19:04:35 +02001042 if (p_av == NULL)
1043 {
1044 /* ack back a local start request */
1045 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
Zhihai Xu379743b2013-09-29 13:42:13 -07001046 return TRUE;
Mattias Agren5fd74f02013-04-05 19:04:35 +02001047 }
1048
The Android Open Source Project5738f832012-12-12 16:00:35 -08001049 if (p_av->status == BTA_AV_SUCCESS)
1050 {
1051 if (p_av->suspending == FALSE)
1052 {
1053 if (p_av->initiator)
1054 {
Zhihai Xu379743b2013-09-29 13:42:13 -07001055 if (pending_start) {
1056 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
1057 ack = TRUE;
1058 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001059 }
1060 else
1061 {
1062 /* we were remotely started, make sure codec
1063 is setup before datapath is started */
1064 btif_a2dp_setup_codec();
1065 }
1066
1067 /* media task is autostarted upon a2dp audiopath connection */
1068 }
1069 }
Zhihai Xu379743b2013-09-29 13:42:13 -07001070 else if (pending_start)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001071 {
1072 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
Zhihai Xu379743b2013-09-29 13:42:13 -07001073 ack = TRUE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001074 }
Zhihai Xu379743b2013-09-29 13:42:13 -07001075 return ack;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001076}
1077
1078
1079/*****************************************************************************
1080**
Mattias Agren5fd74f02013-04-05 19:04:35 +02001081** Function btif_a2dp_ack_fail
1082**
1083** Description
1084**
1085** Returns
1086**
1087*******************************************************************************/
1088
1089void btif_a2dp_ack_fail(void)
1090{
1091 tBTIF_STATUS status;
1092
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001093 APPL_TRACE_EVENT("## A2DP_CTRL_ACK_FAILURE ##");
Mattias Agren5fd74f02013-04-05 19:04:35 +02001094 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
1095}
1096
1097/*****************************************************************************
1098**
The Android Open Source Project5738f832012-12-12 16:00:35 -08001099** Function btif_a2dp_on_stopped
1100**
1101** Description
1102**
1103** Returns
1104**
1105*******************************************************************************/
1106
1107void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av)
1108{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001109 APPL_TRACE_EVENT("## ON A2DP STOPPED ##");
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07001110 if (btif_media_cb.peer_sep == AVDT_TSEP_SRC) /* Handling for A2DP SINK cases*/
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301111 {
1112 btif_media_cb.rx_flush = TRUE;
1113 btif_media_task_aa_rx_flush_req();
1114 btif_media_task_stop_decoding_req();
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07001115 UIPC_Close(UIPC_CH_ID_AV_AUDIO);
1116 btif_media_cb.data_channel_open = FALSE;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301117 return;
1118 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001119 /* allow using this api for other than suspend */
1120 if (p_av != NULL)
1121 {
1122 if (p_av->status != BTA_AV_SUCCESS)
1123 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001124 APPL_TRACE_EVENT("AV STOP FAILED (%d)", p_av->status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001125
1126 if (p_av->initiator)
1127 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
1128 return;
1129 }
1130 }
1131
1132 /* ensure tx frames are immediately suspended */
1133 btif_media_cb.tx_flush = 1;
1134
1135 /* request to stop media task */
1136 btif_media_task_aa_tx_flush_req();
1137 btif_media_task_stop_aa_req();
1138
1139 /* once stream is fully stopped we will ack back */
1140}
1141
1142
1143/*****************************************************************************
1144**
1145** Function btif_a2dp_on_suspended
1146**
1147** Description
1148**
1149** Returns
1150**
1151*******************************************************************************/
1152
1153void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av)
1154{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001155 APPL_TRACE_EVENT("## ON A2DP SUSPENDED ##");
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07001156 if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301157 {
1158 btif_media_cb.rx_flush = TRUE;
1159 btif_media_task_aa_rx_flush_req();
1160 btif_media_task_stop_decoding_req();
1161 return;
1162 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001163
1164 /* check for status failures */
1165 if (p_av->status != BTA_AV_SUCCESS)
1166 {
1167 if (p_av->initiator == TRUE)
1168 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
1169 }
1170
1171 /* once stream is fully stopped we will ack back */
1172
1173 /* ensure tx frames are immediately flushed */
1174 btif_media_cb.tx_flush = 1;
1175
1176 /* stop timer tick */
1177 btif_media_task_stop_aa_req();
1178}
1179
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301180/* when true media task discards any rx frames */
1181void btif_a2dp_set_rx_flush(BOOLEAN enable)
1182{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001183 APPL_TRACE_EVENT("## DROP RX %d ##", enable);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301184 btif_media_cb.rx_flush = enable;
1185}
1186
The Android Open Source Project5738f832012-12-12 16:00:35 -08001187/* when true media task discards any tx frames */
1188void btif_a2dp_set_tx_flush(BOOLEAN enable)
1189{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001190 APPL_TRACE_EVENT("## DROP TX %d ##", enable);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001191 btif_media_cb.tx_flush = enable;
1192}
1193
lungtsai_lin6718c6d2014-07-02 20:39:02 +08001194#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301195/*******************************************************************************
1196 **
1197 ** Function btif_media_task_avk_handle_timer
1198 **
1199 ** Description
1200 **
1201 ** Returns void
1202 **
1203 *******************************************************************************/
1204static void btif_media_task_avk_handle_timer ( void )
1205{
1206 UINT8 count;
1207 tBT_SBC_HDR *p_msg;
1208 int num_sbc_frames;
1209 int num_frames_to_process;
1210
1211 count = btif_media_cb.RxSbcQ.count;
1212 if (0 == count)
1213 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001214 APPL_TRACE_DEBUG(" QUE EMPTY ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301215 }
1216 else
1217 {
1218 if (btif_media_cb.rx_flush == TRUE)
1219 {
1220 btif_media_flush_q(&(btif_media_cb.RxSbcQ));
1221 return;
1222 }
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301223
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301224 num_frames_to_process = btif_media_cb.frames_to_process;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001225 APPL_TRACE_DEBUG(" Process Frames + ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301226
1227 do
1228 {
1229 p_msg = (tBT_SBC_HDR *)GKI_getfirst(&(btif_media_cb.RxSbcQ));
1230 if (p_msg == NULL)
1231 return;
1232 num_sbc_frames = p_msg->num_frames_to_be_processed; /* num of frames in Que Packets */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001233 APPL_TRACE_DEBUG(" Frames left in topmost packet %d", num_sbc_frames);
1234 APPL_TRACE_DEBUG(" Remaining frames to process in tick %d", num_frames_to_process);
1235 APPL_TRACE_DEBUG(" Num of Packets in Que %d", btif_media_cb.RxSbcQ.count);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301236
1237 if ( num_sbc_frames > num_frames_to_process) /* Que Packet has more frames*/
1238 {
1239 p_msg->num_frames_to_be_processed= num_frames_to_process;
1240 btif_media_task_handle_inc_media(p_msg);
1241 p_msg->num_frames_to_be_processed = num_sbc_frames - num_frames_to_process;
1242 num_frames_to_process = 0;
1243 break;
1244 }
1245 else /* Que packet has less frames */
1246 {
1247 btif_media_task_handle_inc_media(p_msg);
1248 p_msg = (tBT_SBC_HDR *)GKI_dequeue(&(btif_media_cb.RxSbcQ));
1249 if( p_msg == NULL )
1250 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001251 APPL_TRACE_ERROR("Insufficient data in que ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301252 break;
1253 }
1254 num_frames_to_process = num_frames_to_process - p_msg->num_frames_to_be_processed;
1255 GKI_freebuf(p_msg);
1256 }
1257 }while(num_frames_to_process > 0);
1258
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001259 APPL_TRACE_DEBUG(" Process Frames - ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301260 }
1261}
1262#endif
1263
The Android Open Source Project5738f832012-12-12 16:00:35 -08001264/*******************************************************************************
1265 **
1266 ** Function btif_media_task_aa_handle_timer
1267 **
1268 ** Description
1269 **
1270 ** Returns void
1271 **
1272 *******************************************************************************/
1273
1274static void btif_media_task_aa_handle_timer(void)
1275{
1276#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
1277 static UINT16 Debug = 0;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001278 APPL_TRACE_DEBUG("btif_media_task_aa_handle_timer: %d", Debug++);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001279#endif
1280
1281 log_tstamps_us("media task tx timer");
1282
1283#if (BTA_AV_INCLUDED == TRUE)
Hemant Guptae7c4f992013-09-05 19:42:50 +05301284 if(btif_media_cb.is_tx_timer == TRUE)
1285 {
1286 btif_media_send_aa_frame();
1287 }
1288 else
1289 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001290 APPL_TRACE_ERROR("ERROR Media task Scheduled after Suspend");
Hemant Guptae7c4f992013-09-05 19:42:50 +05301291 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001292#endif
1293}
1294
1295#if (BTA_AV_INCLUDED == TRUE)
1296/*******************************************************************************
1297 **
1298 ** Function btif_media_task_aa_handle_timer
1299 **
1300 ** Description
1301 **
1302 ** Returns void
1303 **
1304 *******************************************************************************/
1305static void btif_media_task_aa_handle_uipc_rx_rdy(void)
1306{
1307#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
1308 static UINT16 Debug = 0;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001309 APPL_TRACE_DEBUG("btif_media_task_aa_handle_uipc_rx_rdy: %d", Debug++);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001310#endif
1311
1312 /* process all the UIPC data */
1313 btif_media_aa_prep_2_send(0xFF);
1314
1315 /* send it */
1316 VERBOSE("btif_media_task_aa_handle_uipc_rx_rdy calls bta_av_ci_src_data_ready");
1317 bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
1318}
1319#endif
1320
1321/*******************************************************************************
1322 **
1323 ** Function btif_media_task_init
1324 **
1325 ** Description
1326 **
1327 ** Returns void
1328 **
1329 *******************************************************************************/
1330
1331void btif_media_task_init(void)
1332{
1333 memset(&(btif_media_cb), 0, sizeof(btif_media_cb));
1334
1335 UIPC_Init(NULL);
1336
1337#if (BTA_AV_INCLUDED == TRUE)
1338 UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
1339#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -08001340}
1341/*******************************************************************************
1342 **
1343 ** Function btif_media_task
1344 **
1345 ** Description Task for SBC encoder. This task receives an
1346 ** event when the waveIn interface has a pcm data buffer
1347 ** ready. On receiving the event, handle all ready pcm
1348 ** data buffers. If stream is started, run the SBC encoder
1349 ** on each chunk of pcm samples and build an output packet
1350 ** consisting of one or more encoded SBC frames.
1351 **
1352 ** Returns void
1353 **
1354 *******************************************************************************/
1355int btif_media_task(void *p)
1356{
1357 UINT16 event;
1358 BT_HDR *p_msg;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001359 UNUSED(p);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001360
1361 VERBOSE("================ MEDIA TASK STARTING ================");
1362
1363 btif_media_task_init();
1364
1365 media_task_running = MEDIA_TASK_STATE_ON;
1366
1367 raise_priority_a2dp(TASK_HIGH_MEDIA);
1368
1369 while (1)
1370 {
1371 event = GKI_wait(0xffff, 0);
1372
1373 VERBOSE("================= MEDIA TASK EVENT %d ===============", event);
1374
1375 if (event & BTIF_MEDIA_TASK_CMD)
1376 {
1377 /* Process all messages in the queue */
1378 while ((p_msg = (BT_HDR *) GKI_read_mbox(BTIF_MEDIA_TASK_CMD_MBOX)) != NULL)
1379 {
1380 btif_media_task_handle_cmd(p_msg);
1381 }
1382 }
1383
1384 if (event & BTIF_MEDIA_TASK_DATA)
1385 {
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301386 VERBOSE("================= Received Media Packets %d ===============", event);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001387 /* Process all messages in the queue */
1388 while ((p_msg = (BT_HDR *) GKI_read_mbox(BTIF_MEDIA_TASK_DATA_MBOX)) != NULL)
1389 {
1390 btif_media_task_handle_media(p_msg);
1391 }
1392 }
1393
1394 if (event & BTIF_MEDIA_AA_TASK_TIMER)
1395 {
1396 /* advance audio timer expiration */
1397 btif_media_task_aa_handle_timer();
1398 }
1399
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301400 if (event & BTIF_MEDIA_AVK_TASK_TIMER)
1401 {
lungtsai_lin6718c6d2014-07-02 20:39:02 +08001402#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301403 /* advance audio timer expiration for a2dp sink */
1404 btif_media_task_avk_handle_timer();
1405#endif
1406 }
1407
1408
The Android Open Source Project5738f832012-12-12 16:00:35 -08001409
1410 VERBOSE("=============== MEDIA TASK EVENT %d DONE ============", event);
1411
1412 /* When we get this event we exit the task - should only happen on GKI_shutdown */
1413 if (event & BTIF_MEDIA_TASK_KILL)
1414 {
1415 /* make sure no channels are restarted while shutting down */
1416 media_task_running = MEDIA_TASK_STATE_SHUTTING_DOWN;
1417
1418 /* this calls blocks until uipc is fully closed */
1419 UIPC_Close(UIPC_CH_ID_ALL);
1420 break;
1421 }
1422 }
1423
1424 /* Clear media task flag */
1425 media_task_running = MEDIA_TASK_STATE_OFF;
1426
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001427 APPL_TRACE_DEBUG("MEDIA TASK EXITING");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001428
1429 return 0;
1430}
1431
1432
1433/*******************************************************************************
1434 **
1435 ** Function btif_media_task_send_cmd_evt
1436 **
1437 ** Description
1438 **
1439 ** Returns TRUE is success
1440 **
1441 *******************************************************************************/
1442BOOLEAN btif_media_task_send_cmd_evt(UINT16 Evt)
1443{
1444 BT_HDR *p_buf;
1445 if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1446 {
1447 return FALSE;
1448 }
1449
1450 p_buf->event = Evt;
1451
1452 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1453 return TRUE;
1454}
1455
1456/*******************************************************************************
1457 **
1458 ** Function btif_media_flush_q
1459 **
1460 ** Description
1461 **
1462 ** Returns void
1463 **
1464 *******************************************************************************/
1465static void btif_media_flush_q(BUFFER_Q *p_q)
1466{
Sharvil Nanavati6449e492014-06-06 01:26:23 -07001467 while (!GKI_queue_is_empty(p_q))
The Android Open Source Project5738f832012-12-12 16:00:35 -08001468 {
1469 GKI_freebuf(GKI_dequeue(p_q));
1470 }
1471}
1472
1473
1474/*******************************************************************************
1475 **
1476 ** Function btif_media_task_handle_cmd
1477 **
1478 ** Description
1479 **
1480 ** Returns void
1481 **
1482 *******************************************************************************/
1483static void btif_media_task_handle_cmd(BT_HDR *p_msg)
1484{
Mattias Agren5fd74f02013-04-05 19:04:35 +02001485 VERBOSE("btif_media_task_handle_cmd : %d %s", p_msg->event,
1486 dump_media_event(p_msg->event));
The Android Open Source Project5738f832012-12-12 16:00:35 -08001487
1488 switch (p_msg->event)
1489 {
1490#if (BTA_AV_INCLUDED == TRUE)
1491 case BTIF_MEDIA_START_AA_TX:
1492 btif_media_task_aa_start_tx();
1493 break;
1494 case BTIF_MEDIA_STOP_AA_TX:
1495 btif_media_task_aa_stop_tx();
1496 break;
1497 case BTIF_MEDIA_SBC_ENC_INIT:
1498 btif_media_task_enc_init(p_msg);
1499 break;
1500 case BTIF_MEDIA_SBC_ENC_UPDATE:
1501 btif_media_task_enc_update(p_msg);
1502 break;
1503 case BTIF_MEDIA_AUDIO_FEEDING_INIT:
1504 btif_media_task_audio_feeding_init(p_msg);
1505 break;
1506 case BTIF_MEDIA_FLUSH_AA_TX:
1507 btif_media_task_aa_tx_flush(p_msg);
1508 break;
1509 case BTIF_MEDIA_UIPC_RX_RDY:
1510 btif_media_task_aa_handle_uipc_rx_rdy();
1511 break;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301512 case BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE:
lungtsai_lin6718c6d2014-07-02 20:39:02 +08001513#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301514 btif_media_task_aa_handle_decoder_reset(p_msg);
1515#endif
1516 break;
1517 case BTIF_MEDIA_AUDIO_SINK_START_DECODING:
1518 btif_media_task_aa_handle_start_decoding();
1519 break;
1520 case BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK:
lungtsai_lin6718c6d2014-07-02 20:39:02 +08001521#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301522 btif_media_task_aa_handle_clear_track();
1523#endif
1524 break;
1525 case BTIF_MEDIA_AUDIO_SINK_STOP_DECODING:
1526 btif_media_task_aa_handle_stop_decoding();
1527 break;
1528 case BTIF_MEDIA_FLUSH_AA_RX:
1529 btif_media_task_aa_rx_flush();
1530 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001531#endif
1532 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001533 APPL_TRACE_ERROR("ERROR in btif_media_task_handle_cmd unknown event %d", p_msg->event);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001534 }
1535 GKI_freebuf(p_msg);
1536 VERBOSE("btif_media_task_handle_cmd : %s DONE", dump_media_event(p_msg->event));
1537}
1538
lungtsai_lin6718c6d2014-07-02 20:39:02 +08001539#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301540/*******************************************************************************
1541 **
1542 ** Function btif_media_task_handle_inc_media
1543 **
1544 ** Description
1545 **
1546 ** Returns void
1547 **
1548 *******************************************************************************/
1549static void btif_media_task_handle_inc_media(tBT_SBC_HDR*p_msg)
1550{
1551 UINT8 *sbc_start_frame = ((UINT8*)(p_msg + 1) + p_msg->offset + 1);
1552 int count;
1553 UINT32 pcmBytes, availPcmBytes;
1554 OI_INT16 *pcmDataPointer = pcmData; /*Will be overwritten on next packet receipt*/
1555 OI_STATUS status;
1556 int num_sbc_frames = p_msg->num_frames_to_be_processed;
1557 UINT32 sbc_frame_len = p_msg->len - 1;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301558 availPcmBytes = 2*sizeof(pcmData);
1559
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07001560 if ((btif_media_cb.peer_sep == AVDT_TSEP_SNK) || (btif_media_cb.rx_flush))
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301561 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001562 APPL_TRACE_DEBUG(" State Changed happened in this tick ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301563 return;
1564 }
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07001565
1566 // ignore data if no one is listening
1567 if (!btif_media_cb.data_channel_open)
1568 return;
1569
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001570 APPL_TRACE_DEBUG("Number of sbc frames %d, frame_len %d", num_sbc_frames, sbc_frame_len);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301571
1572 for(count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++)
1573 {
1574 pcmBytes = availPcmBytes;
Hemant Guptace247652014-03-20 20:47:04 +05301575 status = OI_CODEC_SBC_DecodeFrame(&context, (const OI_BYTE**)&sbc_start_frame,
1576 (OI_UINT32 *)&sbc_frame_len,
1577 (OI_INT16 *)pcmDataPointer,
1578 (OI_UINT32 *)&pcmBytes);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301579 if (!OI_SUCCESS(status)) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001580 APPL_TRACE_ERROR("Decoding failure: %d\n", status);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301581 break;
1582 }
1583 availPcmBytes -= pcmBytes;
1584 pcmDataPointer += pcmBytes/2;
1585 p_msg->offset += (p_msg->len - 1) - sbc_frame_len;
1586 p_msg->len = sbc_frame_len + 1;
1587 }
1588
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07001589 UIPC_Send(UIPC_CH_ID_AV_AUDIO, 0, (UINT8 *)pcmData, (2*sizeof(pcmData) - availPcmBytes));
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301590}
1591#endif
1592
The Android Open Source Project5738f832012-12-12 16:00:35 -08001593/*******************************************************************************
1594 **
1595 ** Function btif_media_task_handle_media
1596 **
1597 ** Description
1598 **
1599 ** Returns void
1600 **
1601 *******************************************************************************/
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301602static void btif_media_task_handle_media(BT_HDR*p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001603{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001604 APPL_TRACE_DEBUG(" btif_media_task_handle_media ");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001605 GKI_freebuf(p_msg);
1606}
The Android Open Source Project5738f832012-12-12 16:00:35 -08001607#if (BTA_AV_INCLUDED == TRUE)
1608/*******************************************************************************
1609 **
1610 ** Function btif_media_task_enc_init_req
1611 **
1612 ** Description
1613 **
1614 ** Returns TRUE is success
1615 **
1616 *******************************************************************************/
1617BOOLEAN btif_media_task_enc_init_req(tBTIF_MEDIA_INIT_AUDIO *p_msg)
1618{
1619 tBTIF_MEDIA_INIT_AUDIO *p_buf;
1620 if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO))))
1621 {
1622 return FALSE;
1623 }
1624
1625 memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO));
1626 p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_INIT;
1627
1628 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1629 return TRUE;
1630}
1631
1632/*******************************************************************************
1633 **
1634 ** Function btif_media_task_enc_update_req
1635 **
1636 ** Description
1637 **
1638 ** Returns TRUE is success
1639 **
1640 *******************************************************************************/
1641BOOLEAN btif_media_task_enc_update_req(tBTIF_MEDIA_UPDATE_AUDIO *p_msg)
1642{
1643 tBTIF_MEDIA_UPDATE_AUDIO *p_buf;
1644 if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_UPDATE_AUDIO))))
1645 {
1646 return FALSE;
1647 }
1648
1649 memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_UPDATE_AUDIO));
1650 p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_UPDATE;
1651
1652 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1653 return TRUE;
1654}
1655
1656/*******************************************************************************
1657 **
1658 ** Function btif_media_task_audio_feeding_init_req
1659 **
1660 ** Description
1661 **
1662 ** Returns TRUE is success
1663 **
1664 *******************************************************************************/
1665BOOLEAN btif_media_task_audio_feeding_init_req(tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_msg)
1666{
1667 tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_buf;
1668 if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING))))
1669 {
1670 return FALSE;
1671 }
1672
1673 memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING));
1674 p_buf->hdr.event = BTIF_MEDIA_AUDIO_FEEDING_INIT;
1675
1676 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1677 return TRUE;
1678}
1679
1680/*******************************************************************************
1681 **
1682 ** Function btif_media_task_start_aa_req
1683 **
1684 ** Description
1685 **
1686 ** Returns TRUE is success
1687 **
1688 *******************************************************************************/
1689BOOLEAN btif_media_task_start_aa_req(void)
1690{
1691 BT_HDR *p_buf;
1692 if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1693 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001694 APPL_TRACE_EVENT("GKI failed");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001695 return FALSE;
1696 }
1697
1698 p_buf->event = BTIF_MEDIA_START_AA_TX;
1699
1700 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1701 return TRUE;
1702}
1703
1704/*******************************************************************************
1705 **
1706 ** Function btif_media_task_stop_aa_req
1707 **
1708 ** Description
1709 **
1710 ** Returns TRUE is success
1711 **
1712 *******************************************************************************/
1713BOOLEAN btif_media_task_stop_aa_req(void)
1714{
1715 BT_HDR *p_buf;
1716 if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1717 {
1718 return FALSE;
1719 }
1720
1721 p_buf->event = BTIF_MEDIA_STOP_AA_TX;
1722
1723 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1724 return TRUE;
1725}
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301726/*******************************************************************************
1727 **
1728 ** Function btif_media_task_aa_rx_flush_req
1729 **
1730 ** Description
1731 **
1732 ** Returns TRUE is success
1733 **
1734 *******************************************************************************/
1735BOOLEAN btif_media_task_aa_rx_flush_req(void)
1736{
1737 BT_HDR *p_buf;
1738
1739 if (GKI_queue_is_empty(&(btif_media_cb.RxSbcQ))== TRUE) /* Que is already empty */
1740 return TRUE;
1741
1742 if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1743 {
1744 return FALSE;
1745 }
1746
1747 p_buf->event = BTIF_MEDIA_FLUSH_AA_RX;
1748
1749 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1750 return TRUE;
1751}
The Android Open Source Project5738f832012-12-12 16:00:35 -08001752
1753/*******************************************************************************
1754 **
1755 ** Function btif_media_task_aa_tx_flush_req
1756 **
1757 ** Description
1758 **
1759 ** Returns TRUE is success
1760 **
1761 *******************************************************************************/
1762BOOLEAN btif_media_task_aa_tx_flush_req(void)
1763{
1764 BT_HDR *p_buf;
1765 if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
1766 {
1767 return FALSE;
1768 }
1769
1770 p_buf->event = BTIF_MEDIA_FLUSH_AA_TX;
1771
1772 GKI_send_msg(BT_MEDIA_TASK, BTIF_MEDIA_TASK_CMD_MBOX, p_buf);
1773 return TRUE;
1774}
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301775/*******************************************************************************
1776 **
1777 ** Function btif_media_task_aa_rx_flush
1778 **
1779 ** Description
1780 **
1781 ** Returns void
1782 **
1783 *******************************************************************************/
1784static void btif_media_task_aa_rx_flush(void)
1785{
1786 /* Flush all enqueued GKI SBC buffers (encoded) */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001787 APPL_TRACE_DEBUG("btif_media_task_aa_rx_flush");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301788
1789 btif_media_flush_q(&(btif_media_cb.RxSbcQ));
1790}
1791
The Android Open Source Project5738f832012-12-12 16:00:35 -08001792
1793/*******************************************************************************
1794 **
1795 ** Function btif_media_task_aa_tx_flush
1796 **
1797 ** Description
1798 **
1799 ** Returns void
1800 **
1801 *******************************************************************************/
1802static void btif_media_task_aa_tx_flush(BT_HDR *p_msg)
1803{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001804 UNUSED(p_msg);
1805
The Android Open Source Project5738f832012-12-12 16:00:35 -08001806 /* Flush all enqueued GKI music buffers (encoded) */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001807 APPL_TRACE_DEBUG("btif_media_task_aa_tx_flush");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001808
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02001809 btif_media_cb.media_feeding_state.pcm.counter = 0;
1810 btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
1811
The Android Open Source Project5738f832012-12-12 16:00:35 -08001812 btif_media_flush_q(&(btif_media_cb.TxAaQ));
1813
1814 UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REQ_RX_FLUSH, NULL);
1815}
1816
1817/*******************************************************************************
1818 **
1819 ** Function btif_media_task_enc_init
1820 **
1821 ** Description Initialize encoding task
1822 **
1823 ** Returns void
1824 **
1825 *******************************************************************************/
1826static void btif_media_task_enc_init(BT_HDR *p_msg)
1827{
1828 tBTIF_MEDIA_INIT_AUDIO *pInitAudio = (tBTIF_MEDIA_INIT_AUDIO *) p_msg;
1829
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001830 APPL_TRACE_DEBUG("btif_media_task_enc_init");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001831
1832 btif_media_cb.timestamp = 0;
1833
1834 /* SBC encoder config (enforced even if not used) */
1835 btif_media_cb.encoder.s16ChannelMode = pInitAudio->ChannelMode;
1836 btif_media_cb.encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
1837 btif_media_cb.encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks;
1838 btif_media_cb.encoder.s16AllocationMethod = pInitAudio->AllocationMethod;
1839 btif_media_cb.encoder.s16SamplingFreq = pInitAudio->SamplingFreq;
1840
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02001841 btif_media_cb.encoder.u16BitRate = btif_media_task_get_sbc_rate();
1842
The Android Open Source Project5738f832012-12-12 16:00:35 -08001843 /* Default transcoding is PCM to SBC, modified by feeding configuration */
1844 btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
1845 btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE-BTIF_MEDIA_AA_SBC_OFFSET-sizeof(BT_HDR))
1846 < pInitAudio->MtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
1847 - sizeof(BT_HDR)) : pInitAudio->MtuSize;
1848
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001849 APPL_TRACE_EVENT("btif_media_task_enc_init busy %d, mtu %d, peer mtu %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001850 btif_media_cb.busy_level, btif_media_cb.TxAaMtuSize, pInitAudio->MtuSize);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001851 APPL_TRACE_EVENT(" ch mode %d, subnd %d, nb blk %d, alloc %d, rate %d, freq %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001852 btif_media_cb.encoder.s16ChannelMode, btif_media_cb.encoder.s16NumOfSubBands,
1853 btif_media_cb.encoder.s16NumOfBlocks,
1854 btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
1855 btif_media_cb.encoder.s16SamplingFreq);
1856
1857 /* Reset entirely the SBC encoder */
1858 SBC_Encoder_Init(&(btif_media_cb.encoder));
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001859 APPL_TRACE_DEBUG("btif_media_task_enc_init bit pool %d", btif_media_cb.encoder.s16BitPool);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001860}
1861
1862/*******************************************************************************
1863 **
1864 ** Function btif_media_task_enc_update
1865 **
1866 ** Description Update encoding task
1867 **
1868 ** Returns void
1869 **
1870 *******************************************************************************/
1871
1872static void btif_media_task_enc_update(BT_HDR *p_msg)
1873{
1874 tBTIF_MEDIA_UPDATE_AUDIO * pUpdateAudio = (tBTIF_MEDIA_UPDATE_AUDIO *) p_msg;
1875 SBC_ENC_PARAMS *pstrEncParams = &btif_media_cb.encoder;
1876 UINT16 s16SamplingFreq;
Andre Eisenbacha391bf12014-08-08 20:22:31 -07001877 SINT16 s16BitPool = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001878 SINT16 s16BitRate;
1879 SINT16 s16FrameLen;
1880 UINT8 protect = 0;
1881
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001882 APPL_TRACE_DEBUG("btif_media_task_enc_update : minmtu %d, maxbp %d minbp %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001883 pUpdateAudio->MinMtuSize, pUpdateAudio->MaxBitPool, pUpdateAudio->MinBitPool);
1884
1885 /* Only update the bitrate and MTU size while timer is running to make sure it has been initialized */
1886 //if (btif_media_cb.is_tx_timer)
1887 {
Mattias Agren5fd74f02013-04-05 19:04:35 +02001888 btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE -
1889 BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR))
The Android Open Source Project5738f832012-12-12 16:00:35 -08001890 < pUpdateAudio->MinMtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
1891 - sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize;
1892
1893 /* Set the initial target bit rate */
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02001894 pstrEncParams->u16BitRate = btif_media_task_get_sbc_rate();
The Android Open Source Project5738f832012-12-12 16:00:35 -08001895
1896 if (pstrEncParams->s16SamplingFreq == SBC_sf16000)
1897 s16SamplingFreq = 16000;
1898 else if (pstrEncParams->s16SamplingFreq == SBC_sf32000)
1899 s16SamplingFreq = 32000;
1900 else if (pstrEncParams->s16SamplingFreq == SBC_sf44100)
1901 s16SamplingFreq = 44100;
1902 else
1903 s16SamplingFreq = 48000;
1904
1905 do
1906 {
Andre Eisenbacha391bf12014-08-08 20:22:31 -07001907 if (pstrEncParams->s16NumOfBlocks == 0 || pstrEncParams->s16NumOfSubBands == 0
1908 || pstrEncParams->s16NumOfChannels == 0)
1909 {
1910 APPL_TRACE_ERROR("btif_media_task_enc_update() - Avoiding division by zero...");
1911 APPL_TRACE_ERROR("btif_media_task_enc_update() - block=%d, subBands=%d, channels=%d",
1912 pstrEncParams->s16NumOfBlocks, pstrEncParams->s16NumOfSubBands,
1913 pstrEncParams->s16NumOfChannels);
1914 break;
1915 }
1916
The Android Open Source Project5738f832012-12-12 16:00:35 -08001917 if ((pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) ||
1918 (pstrEncParams->s16ChannelMode == SBC_STEREO) )
1919 {
1920 s16BitPool = (SINT16)( (pstrEncParams->u16BitRate *
1921 pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq)
1922 -( (32 + (4 * pstrEncParams->s16NumOfSubBands *
1923 pstrEncParams->s16NumOfChannels)
1924 + ( (pstrEncParams->s16ChannelMode - 2) *
1925 pstrEncParams->s16NumOfSubBands ) )
1926 / pstrEncParams->s16NumOfBlocks) );
1927
1928 s16FrameLen = 4 + (4*pstrEncParams->s16NumOfSubBands*
1929 pstrEncParams->s16NumOfChannels)/8
1930 + ( ((pstrEncParams->s16ChannelMode - 2) *
1931 pstrEncParams->s16NumOfSubBands)
1932 + (pstrEncParams->s16NumOfBlocks * s16BitPool) ) / 8;
1933
1934 s16BitRate = (8 * s16FrameLen * s16SamplingFreq)
1935 / (pstrEncParams->s16NumOfSubBands *
1936 pstrEncParams->s16NumOfBlocks * 1000);
1937
1938 if (s16BitRate > pstrEncParams->u16BitRate)
1939 s16BitPool--;
1940
1941 if(pstrEncParams->s16NumOfSubBands == 8)
1942 s16BitPool = (s16BitPool > 255) ? 255 : s16BitPool;
1943 else
1944 s16BitPool = (s16BitPool > 128) ? 128 : s16BitPool;
1945 }
1946 else
1947 {
1948 s16BitPool = (SINT16)( ((pstrEncParams->s16NumOfSubBands *
1949 pstrEncParams->u16BitRate * 1000)
1950 / (s16SamplingFreq * pstrEncParams->s16NumOfChannels))
1951 -( ( (32 / pstrEncParams->s16NumOfChannels) +
1952 (4 * pstrEncParams->s16NumOfSubBands) )
1953 / pstrEncParams->s16NumOfBlocks ) );
1954
1955 pstrEncParams->s16BitPool = (s16BitPool >
1956 (16 * pstrEncParams->s16NumOfSubBands))
1957 ? (16*pstrEncParams->s16NumOfSubBands) : s16BitPool;
1958 }
1959
1960 if (s16BitPool < 0)
1961 {
1962 s16BitPool = 0;
1963 }
1964
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001965 APPL_TRACE_EVENT("bitpool candidate : %d (%d kbps)",
Mattias Agren5fd74f02013-04-05 19:04:35 +02001966 s16BitPool, pstrEncParams->u16BitRate);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001967
1968 if (s16BitPool > pUpdateAudio->MaxBitPool)
1969 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001970 APPL_TRACE_DEBUG("btif_media_task_enc_update computed bitpool too large (%d)",
Mattias Agren5fd74f02013-04-05 19:04:35 +02001971 s16BitPool);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001972 /* Decrease bitrate */
1973 btif_media_cb.encoder.u16BitRate -= BTIF_MEDIA_BITRATE_STEP;
1974 /* Record that we have decreased the bitrate */
1975 protect |= 1;
1976 }
1977 else if (s16BitPool < pUpdateAudio->MinBitPool)
1978 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001979 APPL_TRACE_WARNING("btif_media_task_enc_update computed bitpool too small (%d)", s16BitPool);
Andre Eisenbach4e3593a2014-07-08 12:33:38 -07001980
The Android Open Source Project5738f832012-12-12 16:00:35 -08001981 /* Increase bitrate */
Andre Eisenbach4e3593a2014-07-08 12:33:38 -07001982 UINT16 previous_u16BitRate = btif_media_cb.encoder.u16BitRate;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001983 btif_media_cb.encoder.u16BitRate += BTIF_MEDIA_BITRATE_STEP;
1984 /* Record that we have increased the bitrate */
1985 protect |= 2;
Andre Eisenbach4e3593a2014-07-08 12:33:38 -07001986 /* Check over-flow */
1987 if (btif_media_cb.encoder.u16BitRate < previous_u16BitRate)
1988 protect |= 3;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001989 }
1990 else
1991 {
1992 break;
1993 }
1994 /* In case we have already increased and decreased the bitrate, just stop */
1995 if (protect == 3)
1996 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001997 APPL_TRACE_ERROR("btif_media_task_enc_update could not find bitpool in range");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001998 break;
1999 }
2000 } while (1);
2001
2002 /* Finally update the bitpool in the encoder structure */
2003 pstrEncParams->s16BitPool = s16BitPool;
2004
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002005 APPL_TRACE_DEBUG("btif_media_task_enc_update final bit rate %d, final bit pool %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002006 btif_media_cb.encoder.u16BitRate, btif_media_cb.encoder.s16BitPool);
2007
2008 /* make sure we reinitialize encoder with new settings */
2009 SBC_Encoder_Init(&(btif_media_cb.encoder));
2010 }
2011}
2012
2013/*******************************************************************************
2014 **
2015 ** Function btif_media_task_pcm2sbc_init
2016 **
2017 ** Description Init encoding task for PCM to SBC according to feeding
2018 **
2019 ** Returns void
2020 **
2021 *******************************************************************************/
2022static void btif_media_task_pcm2sbc_init(tBTIF_MEDIA_INIT_AUDIO_FEEDING * p_feeding)
2023{
2024 BOOLEAN reconfig_needed = FALSE;
2025
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002026 APPL_TRACE_DEBUG("PCM feeding:");
2027 APPL_TRACE_DEBUG("sampling_freq:%d", p_feeding->feeding.cfg.pcm.sampling_freq);
2028 APPL_TRACE_DEBUG("num_channel:%d", p_feeding->feeding.cfg.pcm.num_channel);
2029 APPL_TRACE_DEBUG("bit_per_sample:%d", p_feeding->feeding.cfg.pcm.bit_per_sample);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002030
The Android Open Source Project5738f832012-12-12 16:00:35 -08002031 /* Check the PCM feeding sampling_freq */
2032 switch (p_feeding->feeding.cfg.pcm.sampling_freq)
2033 {
2034 case 8000:
2035 case 12000:
2036 case 16000:
2037 case 24000:
2038 case 32000:
2039 case 48000:
2040 /* For these sampling_freq the AV connection must be 48000 */
2041 if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf48000)
2042 {
2043 /* Reconfiguration needed at 48000 */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002044 APPL_TRACE_DEBUG("SBC Reconfiguration needed at 48000");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002045 btif_media_cb.encoder.s16SamplingFreq = SBC_sf48000;
2046 reconfig_needed = TRUE;
2047 }
2048 break;
2049
2050 case 11025:
2051 case 22050:
2052 case 44100:
2053 /* For these sampling_freq the AV connection must be 44100 */
2054 if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf44100)
2055 {
2056 /* Reconfiguration needed at 44100 */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002057 APPL_TRACE_DEBUG("SBC Reconfiguration needed at 44100");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002058 btif_media_cb.encoder.s16SamplingFreq = SBC_sf44100;
2059 reconfig_needed = TRUE;
2060 }
2061 break;
2062 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002063 APPL_TRACE_DEBUG("Feeding PCM sampling_freq unsupported");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002064 break;
2065 }
2066
2067 /* Some AV Headsets do not support Mono => always ask for Stereo */
2068 if (btif_media_cb.encoder.s16ChannelMode == SBC_MONO)
2069 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002070 APPL_TRACE_DEBUG("SBC Reconfiguration needed in Stereo");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002071 btif_media_cb.encoder.s16ChannelMode = SBC_JOINT_STEREO;
2072 reconfig_needed = TRUE;
2073 }
2074
2075 if (reconfig_needed != FALSE)
2076 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002077 APPL_TRACE_DEBUG("btif_media_task_pcm2sbc_init :: mtu %d", btif_media_cb.TxAaMtuSize);
2078 APPL_TRACE_DEBUG("ch mode %d, nbsubd %d, nb %d, alloc %d, rate %d, freq %d",
Mattias Agren5fd74f02013-04-05 19:04:35 +02002079 btif_media_cb.encoder.s16ChannelMode,
2080 btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks,
2081 btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
2082 btif_media_cb.encoder.s16SamplingFreq);
2083
The Android Open Source Project5738f832012-12-12 16:00:35 -08002084 SBC_Encoder_Init(&(btif_media_cb.encoder));
2085 }
2086 else
2087 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002088 APPL_TRACE_DEBUG("btif_media_task_pcm2sbc_init no SBC reconfig needed");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002089 }
2090}
2091
2092
2093/*******************************************************************************
2094 **
2095 ** Function btif_media_task_audio_feeding_init
2096 **
2097 ** Description Initialize the audio path according to the feeding format
2098 **
2099 ** Returns void
2100 **
2101 *******************************************************************************/
2102static void btif_media_task_audio_feeding_init(BT_HDR *p_msg)
2103{
2104 tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_feeding = (tBTIF_MEDIA_INIT_AUDIO_FEEDING *) p_msg;
2105
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002106 APPL_TRACE_DEBUG("btif_media_task_audio_feeding_init format:%d", p_feeding->feeding.format);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002107
2108 /* Save Media Feeding information */
2109 btif_media_cb.feeding_mode = p_feeding->feeding_mode;
2110 btif_media_cb.media_feeding = p_feeding->feeding;
2111
2112 /* Handle different feeding formats */
2113 switch (p_feeding->feeding.format)
2114 {
2115 case BTIF_AV_CODEC_PCM:
2116 btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
2117 btif_media_task_pcm2sbc_init(p_feeding);
2118 break;
2119
2120 default :
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002121 APPL_TRACE_ERROR("unknown feeding format %d", p_feeding->feeding.format);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002122 break;
2123 }
2124}
2125
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07002126int btif_a2dp_get_track_frequency(UINT8 frequency) {
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302127 int freq = 48000;
2128 switch (frequency) {
2129 case A2D_SBC_IE_SAMP_FREQ_16:
2130 freq = 16000;
2131 break;
2132 case A2D_SBC_IE_SAMP_FREQ_32:
2133 freq = 32000;
2134 break;
2135 case A2D_SBC_IE_SAMP_FREQ_44:
2136 freq = 44100;
2137 break;
2138 case A2D_SBC_IE_SAMP_FREQ_48:
2139 freq = 48000;
2140 break;
2141 }
2142 return freq;
2143}
2144
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07002145int btif_a2dp_get_track_channel_count(UINT8 channeltype) {
2146 int count = 1;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302147 switch (channeltype) {
2148 case A2D_SBC_IE_CH_MD_MONO:
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07002149 count = 1;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302150 break;
2151 case A2D_SBC_IE_CH_MD_DUAL:
2152 case A2D_SBC_IE_CH_MD_STEREO:
2153 case A2D_SBC_IE_CH_MD_JOINT:
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07002154 count = 2;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302155 break;
2156 }
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07002157 return count;
2158}
2159
2160void btif_a2dp_set_peer_sep(UINT8 sep) {
2161 btif_media_cb.peer_sep = sep;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302162}
2163
2164/*******************************************************************************
2165 **
2166 ** Function btif_media_task_aa_handle_stop_decoding
2167 **
2168 ** Description
2169 **
2170 ** Returns void
2171 **
2172 *******************************************************************************/
2173static void btif_media_task_aa_handle_stop_decoding(void )
2174{
2175 btif_media_cb.is_rx_timer = FALSE;
2176 GKI_stop_timer(BTIF_MEDIA_AVK_TASK_TIMER_ID);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302177}
2178
2179/*******************************************************************************
2180 **
2181 ** Function btif_media_task_aa_handle_start_decoding
2182 **
2183 ** Description
2184 **
2185 ** Returns void
2186 **
2187 *******************************************************************************/
2188static void btif_media_task_aa_handle_start_decoding(void )
2189{
2190 if(btif_media_cb.is_rx_timer == TRUE)
2191 return;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302192 btif_media_cb.is_rx_timer = TRUE;
2193 GKI_start_timer(BTIF_MEDIA_AVK_TASK_TIMER_ID, GKI_MS_TO_TICKS(BTIF_SINK_MEDIA_TIME_TICK), TRUE);
2194}
2195
lungtsai_lin6718c6d2014-07-02 20:39:02 +08002196#if (BTA_AV_SINK_INCLUDED == TRUE)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302197
2198static void btif_media_task_aa_handle_clear_track (void)
2199{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002200 APPL_TRACE_DEBUG("btif_media_task_aa_handle_clear_track");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302201}
2202
2203/*******************************************************************************
2204 **
2205 ** Function btif_media_task_aa_handle_decoder_reset
2206 **
2207 ** Description
2208 **
2209 ** Returns void
2210 **
2211 *******************************************************************************/
2212static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg)
2213{
2214 tBTIF_MEDIA_SINK_CFG_UPDATE *p_buf = (tBTIF_MEDIA_SINK_CFG_UPDATE*) p_msg;
2215 tA2D_STATUS a2d_status;
2216 tA2D_SBC_CIE sbc_cie;
2217 OI_STATUS status;
Hemant Guptace247652014-03-20 20:47:04 +05302218 UINT32 freq_multiple = 48*20; /* frequency multiple for 20ms of data , initialize with 48K*/
2219 UINT32 num_blocks = 16;
2220 UINT32 num_subbands = 8;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302221
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002222 APPL_TRACE_DEBUG("btif_media_task_aa_handle_decoder_reset p_codec_info[%x:%x:%x:%x:%x:%x]",
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302223 p_buf->codec_info[1], p_buf->codec_info[2], p_buf->codec_info[3],
2224 p_buf->codec_info[4], p_buf->codec_info[5], p_buf->codec_info[6]);
2225
2226 a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_buf->codec_info, FALSE);
2227 if (a2d_status != A2D_SUCCESS)
2228 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002229 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302230 return;
2231 }
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07002232
2233 btif_media_cb.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
2234 btif_media_cb.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
2235
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302236 btif_media_cb.rx_flush = FALSE;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002237 APPL_TRACE_DEBUG("Reset to sink role");
Hemant Guptace247652014-03-20 20:47:04 +05302238 status = OI_CODEC_SBC_DecoderReset(&context, contextData, sizeof(contextData), 2, 2, FALSE);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302239 if (!OI_SUCCESS(status)) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002240 APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302241 }
Mike Lockwood3e8a242f2014-05-23 12:42:24 -07002242
2243 UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302244
2245 switch(sbc_cie.samp_freq)
2246 {
2247 case A2D_SBC_IE_SAMP_FREQ_16:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002248 APPL_TRACE_DEBUG("\tsamp_freq:%d (16000)", sbc_cie.samp_freq);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302249 freq_multiple = 16*20;
2250 break;
2251 case A2D_SBC_IE_SAMP_FREQ_32:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002252 APPL_TRACE_DEBUG("\tsamp_freq:%d (32000)", sbc_cie.samp_freq);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302253 freq_multiple = 32*20;
2254 break;
2255 case A2D_SBC_IE_SAMP_FREQ_44:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002256 APPL_TRACE_DEBUG("\tsamp_freq:%d (44100)", sbc_cie.samp_freq);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302257 freq_multiple = 441*2;
2258 break;
2259 case A2D_SBC_IE_SAMP_FREQ_48:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002260 APPL_TRACE_DEBUG("\tsamp_freq:%d (48000)", sbc_cie.samp_freq);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302261 freq_multiple = 48*20;
2262 break;
2263 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002264 APPL_TRACE_DEBUG(" Unknown Frequency ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302265 break;
2266 }
2267
2268 switch(sbc_cie.ch_mode)
2269 {
2270 case A2D_SBC_IE_CH_MD_MONO:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002271 APPL_TRACE_DEBUG("\tch_mode:%d (Mono)", sbc_cie.ch_mode);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302272 break;
2273 case A2D_SBC_IE_CH_MD_DUAL:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002274 APPL_TRACE_DEBUG("\tch_mode:%d (DUAL)", sbc_cie.ch_mode);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302275 break;
2276 case A2D_SBC_IE_CH_MD_STEREO:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002277 APPL_TRACE_DEBUG("\tch_mode:%d (STEREO)", sbc_cie.ch_mode);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302278 break;
2279 case A2D_SBC_IE_CH_MD_JOINT:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002280 APPL_TRACE_DEBUG("\tch_mode:%d (JOINT)", sbc_cie.ch_mode);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302281 break;
2282 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002283 APPL_TRACE_DEBUG(" Unknown Mode ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302284 break;
2285 }
2286
2287 switch(sbc_cie.block_len)
2288 {
2289 case A2D_SBC_IE_BLOCKS_4:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002290 APPL_TRACE_DEBUG("\tblock_len:%d (4)", sbc_cie.block_len);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302291 num_blocks = 4;
2292 break;
2293 case A2D_SBC_IE_BLOCKS_8:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002294 APPL_TRACE_DEBUG("\tblock_len:%d (8)", sbc_cie.block_len);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302295 num_blocks = 8;
2296 break;
2297 case A2D_SBC_IE_BLOCKS_12:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002298 APPL_TRACE_DEBUG("\tblock_len:%d (12)", sbc_cie.block_len);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302299 num_blocks = 12;
2300 break;
2301 case A2D_SBC_IE_BLOCKS_16:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002302 APPL_TRACE_DEBUG("\tblock_len:%d (16)", sbc_cie.block_len);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302303 num_blocks = 16;
2304 break;
2305 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002306 APPL_TRACE_DEBUG(" Unknown BlockLen ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302307 break;
2308 }
2309
2310 switch(sbc_cie.num_subbands)
2311 {
2312 case A2D_SBC_IE_SUBBAND_4:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002313 APPL_TRACE_DEBUG("\tnum_subbands:%d (4)", sbc_cie.num_subbands);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302314 num_subbands = 4;
2315 break;
2316 case A2D_SBC_IE_SUBBAND_8:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002317 APPL_TRACE_DEBUG("\tnum_subbands:%d (8)", sbc_cie.num_subbands);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302318 num_subbands = 8;
2319 break;
2320 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002321 APPL_TRACE_DEBUG(" Unknown SubBands ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302322 break;
2323 }
2324
2325 switch(sbc_cie.alloc_mthd)
2326 {
2327 case A2D_SBC_IE_ALLOC_MD_S:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002328 APPL_TRACE_DEBUG("\talloc_mthd:%d (SNR)", sbc_cie.alloc_mthd);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302329 break;
2330 case A2D_SBC_IE_ALLOC_MD_L:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002331 APPL_TRACE_DEBUG("\talloc_mthd:%d (Loudness)", sbc_cie.alloc_mthd);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302332 break;
2333 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002334 APPL_TRACE_DEBUG(" Unknown Allocation Method");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302335 break;
2336 }
2337
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002338 APPL_TRACE_DEBUG("\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302339
2340 btif_media_cb.frames_to_process = ((freq_multiple)/(num_blocks*num_subbands)) + 1;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002341 APPL_TRACE_DEBUG(" Frames to be processed in 20 ms %d",btif_media_cb.frames_to_process);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302342}
2343#endif
2344
The Android Open Source Project5738f832012-12-12 16:00:35 -08002345/*******************************************************************************
2346 **
The Android Open Source Project5738f832012-12-12 16:00:35 -08002347 ** Function btif_media_task_feeding_state_reset
2348 **
2349 ** Description Reset the media feeding state
2350 **
2351 ** Returns void
2352 **
2353 *******************************************************************************/
2354static void btif_media_task_feeding_state_reset(void)
2355{
2356 /* By default, just clear the entire state */
2357 memset(&btif_media_cb.media_feeding_state, 0, sizeof(btif_media_cb.media_feeding_state));
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02002358
2359 if (btif_media_cb.TxTranscoding == BTIF_MEDIA_TRSCD_PCM_2_SBC)
2360 {
2361 btif_media_cb.media_feeding_state.pcm.bytes_per_tick =
2362 (btif_media_cb.media_feeding.cfg.pcm.sampling_freq *
2363 btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8 *
2364 btif_media_cb.media_feeding.cfg.pcm.num_channel *
2365 BTIF_MEDIA_TIME_TICK)/1000;
2366
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002367 APPL_TRACE_WARNING("pcm bytes per tick %d",
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02002368 (int)btif_media_cb.media_feeding_state.pcm.bytes_per_tick);
2369 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002370}
2371/*******************************************************************************
2372 **
2373 ** Function btif_media_task_aa_start_tx
2374 **
2375 ** Description Start media task encoding
2376 **
2377 ** Returns void
2378 **
2379 *******************************************************************************/
2380static void btif_media_task_aa_start_tx(void)
2381{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002382 APPL_TRACE_DEBUG("btif_media_task_aa_start_tx is timer %d, feeding mode %d",
Mattias Agren5fd74f02013-04-05 19:04:35 +02002383 btif_media_cb.is_tx_timer, btif_media_cb.feeding_mode);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002384
2385 /* Use a timer to poll the UIPC, get rid of the UIPC call back */
2386 // UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_CBACK, NULL);
2387
2388 btif_media_cb.is_tx_timer = TRUE;
Andre Eisenbachf13db8a2014-07-11 16:57:24 -07002389 last_frame_us = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002390
2391 /* Reset the media feeding state */
2392 btif_media_task_feeding_state_reset();
2393
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002394 APPL_TRACE_EVENT("starting timer %d ticks (%d)",
Mattias Agren5fd74f02013-04-05 19:04:35 +02002395 GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TICKS_PER_SEC);
2396
The Android Open Source Project5738f832012-12-12 16:00:35 -08002397 GKI_start_timer(BTIF_MEDIA_AA_TASK_TIMER_ID, GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TRUE);
2398}
2399
2400/*******************************************************************************
2401 **
2402 ** Function btif_media_task_aa_stop_tx
2403 **
2404 ** Description Stop media task encoding
2405 **
2406 ** Returns void
2407 **
2408 *******************************************************************************/
2409static void btif_media_task_aa_stop_tx(void)
2410{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002411 APPL_TRACE_DEBUG("btif_media_task_aa_stop_tx is timer: %d", btif_media_cb.is_tx_timer);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002412
2413 /* Stop the timer first */
2414 GKI_stop_timer(BTIF_MEDIA_AA_TASK_TIMER_ID);
2415 btif_media_cb.is_tx_timer = FALSE;
2416
2417 UIPC_Close(UIPC_CH_ID_AV_AUDIO);
2418
2419 /* audio engine stopped, reset tx suspended flag */
2420 btif_media_cb.tx_flush = 0;
Andre Eisenbachf13db8a2014-07-11 16:57:24 -07002421 last_frame_us = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002422
2423 /* Reset the media feeding state */
2424 btif_media_task_feeding_state_reset();
2425}
2426
2427/*******************************************************************************
2428 **
2429 ** Function btif_get_num_aa_frame
2430 **
2431 ** Description
2432 **
2433 ** Returns The number of media frames in this time slice
2434 **
2435 *******************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -08002436static UINT8 btif_get_num_aa_frame(void)
2437{
Andre Eisenbachc5916e92014-11-07 15:46:04 -08002438 UINT8 result=0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002439
2440 switch (btif_media_cb.TxTranscoding)
2441 {
2442 case BTIF_MEDIA_TRSCD_PCM_2_SBC:
Andre Eisenbachc5916e92014-11-07 15:46:04 -08002443 {
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02002444 UINT32 pcm_bytes_per_frame = btif_media_cb.encoder.s16NumOfSubBands *
2445 btif_media_cb.encoder.s16NumOfBlocks *
2446 btif_media_cb.media_feeding.cfg.pcm.num_channel *
2447 btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002448
Andre Eisenbachf13db8a2014-07-11 16:57:24 -07002449 UINT32 us_this_tick = BTIF_MEDIA_TIME_TICK * 1000;
2450 UINT64 now_us = time_now_us();
2451 if (last_frame_us != 0)
2452 us_this_tick = (now_us - last_frame_us);
2453 last_frame_us = now_us;
2454
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02002455 btif_media_cb.media_feeding_state.pcm.counter +=
Andre Eisenbachf13db8a2014-07-11 16:57:24 -07002456 btif_media_cb.media_feeding_state.pcm.bytes_per_tick *
2457 us_this_tick / (BTIF_MEDIA_TIME_TICK * 1000);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002458
Andre Eisenbachc5916e92014-11-07 15:46:04 -08002459 /* calculate nbr of frames pending for this media tick */
2460 result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
2461 if (result > MAX_PCM_FRAME_NUM_PER_TICK)
2462 {
2463 APPL_TRACE_WARNING("%s() - Limiting frames to be sent from %d to %d"
2464 , __FUNCTION__, result, MAX_PCM_FRAME_NUM_PER_TICK);
2465 result = MAX_PCM_FRAME_NUM_PER_TICK;
Zhihai Xu4aebca42013-09-19 11:30:44 -07002466 }
Andre Eisenbachc5916e92014-11-07 15:46:04 -08002467 btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
Mattias Agrenf061e742014-10-09 01:16:12 +02002468
The Android Open Source Project5738f832012-12-12 16:00:35 -08002469 VERBOSE("WRITE %d FRAMES", result);
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02002470 }
2471 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002472
2473 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002474 APPL_TRACE_ERROR("ERROR btif_get_num_aa_frame Unsupported transcoding format 0x%x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002475 btif_media_cb.TxTranscoding);
2476 result = 0;
2477 break;
2478 }
2479
2480#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002481 APPL_TRACE_DEBUG("btif_get_num_aa_frame returns %d", result);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002482#endif
2483
Zhihai Xu4aebca42013-09-19 11:30:44 -07002484 return (UINT8)result;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002485}
2486
2487/*******************************************************************************
2488 **
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302489 ** Function btif_media_sink_enque_buf
2490 **
2491 ** Description This function is called by the av_co to fill A2DP Sink Queue
2492 **
2493 **
2494 ** Returns size of the queue
2495 *******************************************************************************/
2496UINT8 btif_media_sink_enque_buf(BT_HDR *p_pkt)
2497{
2498 tBT_SBC_HDR *p_msg;
2499
2500 if(btif_media_cb.rx_flush == TRUE) /* Flush enabled, do not enque*/
Chris Mantonfe7216c2014-05-06 10:35:42 -07002501 return GKI_queue_length(&btif_media_cb.RxSbcQ);
2502 if(GKI_queue_length(&btif_media_cb.RxSbcQ) == MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302503 {
2504 GKI_freebuf(GKI_dequeue(&(btif_media_cb.RxSbcQ)));
2505 }
2506
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002507 BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf + ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302508 /* allocate and Queue this buffer */
2509 if ((p_msg = (tBT_SBC_HDR *) GKI_getbuf(sizeof(tBT_SBC_HDR) +
2510 p_pkt->offset+ p_pkt->len)) != NULL)
2511 {
2512 memcpy(p_msg, p_pkt, (sizeof(BT_HDR) + p_pkt->offset + p_pkt->len));
2513 p_msg->num_frames_to_be_processed = (*((UINT8*)(p_msg + 1) + p_msg->offset)) & 0x0f;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002514 BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf + ", p_msg->num_frames_to_be_processed);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302515 GKI_enqueue(&(btif_media_cb.RxSbcQ), p_msg);
Chris Mantonfe7216c2014-05-06 10:35:42 -07002516 if(GKI_queue_length(&btif_media_cb.RxSbcQ) == MAX_A2DP_DELAYED_START_FRAME_COUNT)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302517 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002518 BTIF_TRACE_DEBUG(" Initiate Decoding ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302519 btif_media_task_start_decoding_req();
2520 }
2521 }
2522 else
2523 {
2524 /* let caller deal with a failed allocation */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002525 BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf No Buffer left - ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302526 }
Chris Mantonfe7216c2014-05-06 10:35:42 -07002527 return GKI_queue_length(&btif_media_cb.RxSbcQ);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302528}
2529
2530/*******************************************************************************
2531 **
The Android Open Source Project5738f832012-12-12 16:00:35 -08002532 ** Function btif_media_aa_readbuf
2533 **
2534 ** Description This function is called by the av_co to get the next buffer to send
2535 **
2536 **
2537 ** Returns void
2538 *******************************************************************************/
2539BT_HDR *btif_media_aa_readbuf(void)
2540{
2541 return GKI_dequeue(&(btif_media_cb.TxAaQ));
2542}
2543
2544/*******************************************************************************
2545 **
2546 ** Function btif_media_aa_read_feeding
2547 **
2548 ** Description
2549 **
2550 ** Returns void
2551 **
2552 *******************************************************************************/
2553
2554BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
2555{
2556 UINT16 event;
Mattias Agren5fd74f02013-04-05 19:04:35 +02002557 UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * \
2558 btif_media_cb.encoder.s16NumOfBlocks;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002559 UINT32 read_size;
2560 UINT16 sbc_sampling = 48000;
2561 UINT32 src_samples;
Mattias Agren5fd74f02013-04-05 19:04:35 +02002562 UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * \
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02002563 btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002564 static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
2565 * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2];
2566 static UINT16 read_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
2567 * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
2568 UINT32 src_size_used;
2569 UINT32 dst_size_used;
2570 BOOLEAN fract_needed;
2571 INT32 fract_max;
2572 INT32 fract_threshold;
2573 UINT32 nb_byte_read;
2574
2575 /* Get the SBC sampling rate */
2576 switch (btif_media_cb.encoder.s16SamplingFreq)
2577 {
2578 case SBC_sf48000:
2579 sbc_sampling = 48000;
2580 break;
2581 case SBC_sf44100:
2582 sbc_sampling = 44100;
2583 break;
2584 case SBC_sf32000:
2585 sbc_sampling = 32000;
2586 break;
2587 case SBC_sf16000:
2588 sbc_sampling = 16000;
2589 break;
2590 }
2591
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02002592 if (sbc_sampling == btif_media_cb.media_feeding.cfg.pcm.sampling_freq) {
2593 read_size = bytes_needed - btif_media_cb.media_feeding_state.pcm.aa_feed_residue;
2594 nb_byte_read = UIPC_Read(channel_id, &event,
2595 ((UINT8 *)btif_media_cb.encoder.as16PcmBuffer) +
2596 btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
2597 read_size);
2598 if (nb_byte_read == read_size) {
2599 btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
2600 return TRUE;
2601 } else {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002602 APPL_TRACE_WARNING("### UNDERFLOW :: ONLY READ %d BYTES OUT OF %d ###",
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02002603 nb_byte_read, read_size);
2604 btif_media_cb.media_feeding_state.pcm.aa_feed_residue += nb_byte_read;
2605 return FALSE;
2606 }
2607 }
2608
The Android Open Source Project5738f832012-12-12 16:00:35 -08002609 /* Some Feeding PCM frequencies require to split the number of sample */
2610 /* to read. */
2611 /* E.g 128/6=21.3333 => read 22 and 21 and 21 => max = 2; threshold = 0*/
2612 fract_needed = FALSE; /* Default */
2613 switch (btif_media_cb.media_feeding.cfg.pcm.sampling_freq)
2614 {
2615 case 32000:
2616 case 8000:
2617 fract_needed = TRUE;
2618 fract_max = 2; /* 0, 1 and 2 */
2619 fract_threshold = 0; /* Add one for the first */
2620 break;
2621 case 16000:
2622 fract_needed = TRUE;
2623 fract_max = 2; /* 0, 1 and 2 */
2624 fract_threshold = 1; /* Add one for the first two frames*/
2625 break;
2626 }
2627
2628 /* Compute number of sample to read from source */
2629 src_samples = blocm_x_subband;
2630 src_samples *= btif_media_cb.media_feeding.cfg.pcm.sampling_freq;
2631 src_samples /= sbc_sampling;
2632
2633 /* The previous division may have a remainder not null */
2634 if (fract_needed)
2635 {
2636 if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter <= fract_threshold)
2637 {
2638 src_samples++; /* for every read before threshold add one sample */
2639 }
2640
2641 /* do nothing if counter >= threshold */
2642 btif_media_cb.media_feeding_state.pcm.aa_feed_counter++; /* one more read */
2643 if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter > fract_max)
2644 {
2645 btif_media_cb.media_feeding_state.pcm.aa_feed_counter = 0;
2646 }
2647 }
2648
2649 /* Compute number of bytes to read from source */
2650 read_size = src_samples;
2651 read_size *= btif_media_cb.media_feeding.cfg.pcm.num_channel;
2652 read_size *= (btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8);
2653
2654 /* Read Data from UIPC channel */
2655 nb_byte_read = UIPC_Read(channel_id, &event, (UINT8 *)read_buffer, read_size);
2656
2657 //tput_mon(TRUE, nb_byte_read, FALSE);
2658
2659 if (nb_byte_read < read_size)
2660 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002661 APPL_TRACE_WARNING("### UNDERRUN :: ONLY READ %d BYTES OUT OF %d ###",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002662 nb_byte_read, read_size);
2663
2664 if (nb_byte_read == 0)
2665 return FALSE;
2666
2667 if(btif_media_cb.feeding_mode == BTIF_AV_FEEDING_ASYNCHRONOUS)
2668 {
2669 /* Fill the unfilled part of the read buffer with silence (0) */
2670 memset(((UINT8 *)read_buffer) + nb_byte_read, 0, read_size - nb_byte_read);
2671 nb_byte_read = read_size;
2672 }
2673 }
2674
2675 /* Initialize PCM up-sampling engine */
2676 bta_av_sbc_init_up_sample(btif_media_cb.media_feeding.cfg.pcm.sampling_freq,
2677 sbc_sampling, btif_media_cb.media_feeding.cfg.pcm.bit_per_sample,
2678 btif_media_cb.media_feeding.cfg.pcm.num_channel);
2679
2680 /* re-sample read buffer */
Mattias Agren5fd74f02013-04-05 19:04:35 +02002681 /* The output PCM buffer will be stereo, 16 bit per sample */
The Android Open Source Project5738f832012-12-12 16:00:35 -08002682 dst_size_used = bta_av_sbc_up_sample((UINT8 *)read_buffer,
2683 (UINT8 *)up_sampled_buffer + btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
2684 nb_byte_read,
2685 sizeof(up_sampled_buffer) - btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
2686 &src_size_used);
2687
2688#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002689 APPL_TRACE_DEBUG("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 -08002690 read_size, src_size_used, dst_size_used);
2691#endif
2692
2693 /* update the residue */
2694 btif_media_cb.media_feeding_state.pcm.aa_feed_residue += dst_size_used;
2695
2696 /* only copy the pcm sample when we have up-sampled enough PCM */
2697 if(btif_media_cb.media_feeding_state.pcm.aa_feed_residue >= bytes_needed)
2698 {
2699 /* Copy the output pcm samples in SBC encoding buffer */
2700 memcpy((UINT8 *)btif_media_cb.encoder.as16PcmBuffer,
2701 (UINT8 *)up_sampled_buffer,
2702 bytes_needed);
2703 /* update the residue */
2704 btif_media_cb.media_feeding_state.pcm.aa_feed_residue -= bytes_needed;
2705
2706 if (btif_media_cb.media_feeding_state.pcm.aa_feed_residue != 0)
2707 {
2708 memcpy((UINT8 *)up_sampled_buffer,
2709 (UINT8 *)up_sampled_buffer + bytes_needed,
2710 btif_media_cb.media_feeding_state.pcm.aa_feed_residue);
2711 }
2712 return TRUE;
2713 }
2714
2715#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002716 APPL_TRACE_DEBUG("btif_media_aa_read_feeding residue:%d, dst_size_used %d, bytes_needed %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002717 btif_media_cb.media_feeding_state.pcm.aa_feed_residue, dst_size_used, bytes_needed);
2718#endif
2719
2720 return FALSE;
2721}
2722
2723/*******************************************************************************
2724 **
2725 ** Function btif_media_aa_prep_sbc_2_send
2726 **
2727 ** Description
2728 **
2729 ** Returns void
2730 **
2731 *******************************************************************************/
2732static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)
2733{
2734 BT_HDR * p_buf;
Mattias Agren5fd74f02013-04-05 19:04:35 +02002735 UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands *
2736 btif_media_cb.encoder.s16NumOfBlocks;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002737
2738#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002739 APPL_TRACE_DEBUG("btif_media_aa_prep_sbc_2_send nb_frame %d, TxAaQ %d",
Mattias Agren5fd74f02013-04-05 19:04:35 +02002740 nb_frame, btif_media_cb.TxAaQ.count);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002741#endif
2742 while (nb_frame)
2743 {
2744 if (NULL == (p_buf = GKI_getpoolbuf(BTIF_MEDIA_AA_POOL_ID)))
2745 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002746 APPL_TRACE_ERROR ("ERROR btif_media_aa_prep_sbc_2_send no buffer TxCnt %d ",
Chris Mantonfe7216c2014-05-06 10:35:42 -07002747 GKI_queue_length(&btif_media_cb.TxAaQ));
The Android Open Source Project5738f832012-12-12 16:00:35 -08002748 return;
2749 }
2750
2751 /* Init buffer */
2752 p_buf->offset = BTIF_MEDIA_AA_SBC_OFFSET;
2753 p_buf->len = 0;
2754 p_buf->layer_specific = 0;
2755
2756 do
2757 {
2758 /* Write @ of allocated buffer in encoder.pu8Packet */
2759 btif_media_cb.encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
2760 /* Fill allocated buffer with 0 */
The Android Open Source Project5738f832012-12-12 16:00:35 -08002761 memset(btif_media_cb.encoder.as16PcmBuffer, 0, blocm_x_subband
2762 * btif_media_cb.encoder.s16NumOfChannels);
2763
2764 /* Read PCM data and upsample them if needed */
2765 if (btif_media_aa_read_feeding(UIPC_CH_ID_AV_AUDIO))
2766 {
2767 /* SBC encode and descramble frame */
2768 SBC_Encoder(&(btif_media_cb.encoder));
2769 A2D_SbcChkFrInit(btif_media_cb.encoder.pu8Packet);
2770 A2D_SbcDescramble(btif_media_cb.encoder.pu8Packet, btif_media_cb.encoder.u16PacketLength);
2771 /* Update SBC frame length */
2772 p_buf->len += btif_media_cb.encoder.u16PacketLength;
2773 nb_frame--;
2774 p_buf->layer_specific++;
2775 }
2776 else
2777 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002778 APPL_TRACE_WARNING("btif_media_aa_prep_sbc_2_send underflow %d, %d",
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02002779 nb_frame, btif_media_cb.media_feeding_state.pcm.aa_feed_residue);
2780 btif_media_cb.media_feeding_state.pcm.counter += nb_frame *
2781 btif_media_cb.encoder.s16NumOfSubBands *
2782 btif_media_cb.encoder.s16NumOfBlocks *
2783 btif_media_cb.media_feeding.cfg.pcm.num_channel *
2784 btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002785 /* no more pcm to read */
2786 nb_frame = 0;
2787
2788 /* break read loop if timer was stopped (media task stopped) */
2789 if ( btif_media_cb.is_tx_timer == FALSE )
Hemant Guptae7c4f992013-09-05 19:42:50 +05302790 {
2791 GKI_freebuf(p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002792 return;
Hemant Guptae7c4f992013-09-05 19:42:50 +05302793 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002794 }
2795
2796 } while (((p_buf->len + btif_media_cb.encoder.u16PacketLength) < btif_media_cb.TxAaMtuSize)
2797 && (p_buf->layer_specific < 0x0F) && nb_frame);
2798
Ganesh Ganapathi Batta45f5f902013-02-08 11:02:57 -08002799 if(p_buf->len)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002800 {
Mattias Agren5fd74f02013-04-05 19:04:35 +02002801 /* timestamp of the media packet header represent the TS of the first SBC frame
2802 i.e the timestamp before including this frame */
Ganesh Ganapathi Batta45f5f902013-02-08 11:02:57 -08002803 *((UINT32 *) (p_buf + 1)) = btif_media_cb.timestamp;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002804
Mattias Agren5fd74f02013-04-05 19:04:35 +02002805 btif_media_cb.timestamp += p_buf->layer_specific * blocm_x_subband;
2806
Ganesh Ganapathi Batta45f5f902013-02-08 11:02:57 -08002807 VERBOSE("TX QUEUE NOW %d", btif_media_cb.TxAaQ.count);
2808
2809 if (btif_media_cb.tx_flush)
2810 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002811 APPL_TRACE_DEBUG("### tx suspended, discarded frame ###");
Ganesh Ganapathi Batta45f5f902013-02-08 11:02:57 -08002812
Chris Mantonfe7216c2014-05-06 10:35:42 -07002813 if (GKI_queue_length(&btif_media_cb.TxAaQ) > 0)
Ganesh Ganapathi Batta45f5f902013-02-08 11:02:57 -08002814 btif_media_flush_q(&(btif_media_cb.TxAaQ));
2815
2816 GKI_freebuf(p_buf);
2817 return;
2818 }
2819
2820 /* Enqueue the encoded SBC frame in AA Tx Queue */
2821 GKI_enqueue(&(btif_media_cb.TxAaQ), p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002822 }
Ganesh Ganapathi Batta45f5f902013-02-08 11:02:57 -08002823 else
2824 {
2825 GKI_freebuf(p_buf);
2826 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002827 }
2828}
2829
2830
2831/*******************************************************************************
2832 **
2833 ** Function btif_media_aa_prep_2_send
2834 **
2835 ** Description
2836 **
2837 ** Returns void
2838 **
2839 *******************************************************************************/
2840
2841static void btif_media_aa_prep_2_send(UINT8 nb_frame)
2842{
Andre Eisenbachc5916e92014-11-07 15:46:04 -08002843 VERBOSE("%s() - frames=%d (queue=%d)", __FUNCTION__, nb_frame, btif_media_cb.TxAaQ.count);
2844
Chris Mantonfe7216c2014-05-06 10:35:42 -07002845 while (GKI_queue_length(&btif_media_cb.TxAaQ) >= (MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ-nb_frame))
Andre Eisenbachc5916e92014-11-07 15:46:04 -08002846 {
2847 APPL_TRACE_WARNING("%s() - TX queue buffer count %d",
Chris Mantonfe7216c2014-05-06 10:35:42 -07002848 __FUNCTION__, GKI_queue_length(&btif_media_cb.TxAaQ));
Andre Eisenbachc5916e92014-11-07 15:46:04 -08002849 GKI_freebuf(GKI_dequeue(&(btif_media_cb.TxAaQ)));
2850 }
2851
Chris Mantonfe7216c2014-05-06 10:35:42 -07002852 if (GKI_queue_length(&btif_media_cb.TxAaQ)) --nb_frame;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002853
The Android Open Source Project5738f832012-12-12 16:00:35 -08002854 switch (btif_media_cb.TxTranscoding)
2855 {
2856 case BTIF_MEDIA_TRSCD_PCM_2_SBC:
2857 btif_media_aa_prep_sbc_2_send(nb_frame);
2858 break;
2859
2860
2861 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002862 APPL_TRACE_ERROR("ERROR btif_media_aa_prep_2_send unsupported transcoding format 0x%x",btif_media_cb.TxTranscoding);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002863 break;
2864 }
2865}
2866
2867/*******************************************************************************
2868 **
2869 ** Function btif_media_send_aa_frame
2870 **
2871 ** Description
2872 **
2873 ** Returns void
2874 **
2875 *******************************************************************************/
2876static void btif_media_send_aa_frame(void)
2877{
2878 UINT8 nb_frame_2_send;
2879
2880 /* get the number of frame to send */
2881 nb_frame_2_send = btif_get_num_aa_frame();
2882
Andre Eisenbachc5916e92014-11-07 15:46:04 -08002883 if (nb_frame_2_send != 0)
2884 {
Zhihai Xu4aebca42013-09-19 11:30:44 -07002885 /* format and Q buffer to send */
2886 btif_media_aa_prep_2_send(nb_frame_2_send);
2887 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002888
2889 /* send it */
2890 VERBOSE("btif_media_send_aa_frame : send %d frames", nb_frame_2_send);
2891 bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
2892}
2893
The Android Open Source Project5738f832012-12-12 16:00:35 -08002894#endif /* BTA_AV_INCLUDED == TRUE */
2895
2896/*******************************************************************************
2897 **
2898 ** Function dump_codec_info
2899 **
2900 ** Description Decode and display codec_info (for debug)
2901 **
2902 ** Returns void
2903 **
2904 *******************************************************************************/
2905void dump_codec_info(unsigned char *p_codec)
2906{
2907 tA2D_STATUS a2d_status;
2908 tA2D_SBC_CIE sbc_cie;
2909
2910 a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec, FALSE);
2911 if (a2d_status != A2D_SUCCESS)
2912 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002913 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002914 return;
2915 }
2916
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002917 APPL_TRACE_DEBUG("dump_codec_info");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002918
2919 if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_16)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002920 { APPL_TRACE_DEBUG("\tsamp_freq:%d (16000)", sbc_cie.samp_freq);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002921 else if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_32)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002922 { APPL_TRACE_DEBUG("\tsamp_freq:%d (32000)", sbc_cie.samp_freq);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002923 else if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_44)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002924 { APPL_TRACE_DEBUG("\tsamp_freq:%d (44.100)", sbc_cie.samp_freq);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002925 else if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_48)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002926 { APPL_TRACE_DEBUG("\tsamp_freq:%d (48000)", sbc_cie.samp_freq);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002927 else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002928 { APPL_TRACE_DEBUG("\tBAD samp_freq:%d", sbc_cie.samp_freq);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002929
2930 if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_MONO)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002931 { APPL_TRACE_DEBUG("\tch_mode:%d (Mono)", sbc_cie.ch_mode);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002932 else if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_DUAL)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002933 { APPL_TRACE_DEBUG("\tch_mode:%d (Dual)", sbc_cie.ch_mode);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002934 else if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_STEREO)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002935 { APPL_TRACE_DEBUG("\tch_mode:%d (Stereo)", sbc_cie.ch_mode);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002936 else if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_JOINT)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002937 { APPL_TRACE_DEBUG("\tch_mode:%d (Joint)", sbc_cie.ch_mode);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002938 else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002939 { APPL_TRACE_DEBUG("\tBAD ch_mode:%d", sbc_cie.ch_mode);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002940
2941 if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_4)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002942 { APPL_TRACE_DEBUG("\tblock_len:%d (4)", sbc_cie.block_len);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002943 else if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_8)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002944 { APPL_TRACE_DEBUG("\tblock_len:%d (8)", sbc_cie.block_len);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002945 else if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_12)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002946 { APPL_TRACE_DEBUG("\tblock_len:%d (12)", sbc_cie.block_len);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002947 else if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_16)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002948 { APPL_TRACE_DEBUG("\tblock_len:%d (16)", sbc_cie.block_len);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002949 else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002950 { APPL_TRACE_DEBUG("\tBAD block_len:%d", sbc_cie.block_len);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002951
2952 if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_4)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002953 { APPL_TRACE_DEBUG("\tnum_subbands:%d (4)", sbc_cie.num_subbands);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002954 else if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_8)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002955 { APPL_TRACE_DEBUG("\tnum_subbands:%d (8)", sbc_cie.num_subbands);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002956 else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002957 { APPL_TRACE_DEBUG("\tBAD num_subbands:%d", sbc_cie.num_subbands);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002958
2959 if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_S)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002960 { APPL_TRACE_DEBUG("\talloc_mthd:%d (SNR)", sbc_cie.alloc_mthd);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002961 else if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002962 { APPL_TRACE_DEBUG("\talloc_mthd:%d (Loundess)", sbc_cie.alloc_mthd);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002963 else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002964 { APPL_TRACE_DEBUG("\tBAD alloc_mthd:%d", sbc_cie.alloc_mthd);}
The Android Open Source Project5738f832012-12-12 16:00:35 -08002965
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002966 APPL_TRACE_DEBUG("\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002967
2968}
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302969