am b8ceaa48: Set default a2dp sbc encoding quality to high
* commit 'b8ceaa484a09be14263d5f10d022a272f9602378':
Set default a2dp sbc encoding quality to high
diff --git a/btif/include/btif_av.h b/btif/include/btif_av.h
old mode 100755
new mode 100644
index 1053e6c..9e537cd
--- a/btif/include/btif_av.h
+++ b/btif/include/btif_av.h
@@ -125,4 +125,20 @@
BOOLEAN btif_av_is_connected(void);
+
+/*******************************************************************************
+**
+** Function btif_av_is_peer_edr
+**
+** Description Check if the connected a2dp device supports
+** EDR or not. Only when connected this function
+** will accurately provide a true capability of
+** remote peer. If not connected it will always be false.
+**
+** Returns TRUE if remote device is capable of EDR
+**
+*******************************************************************************/
+
+BOOLEAN btif_av_is_peer_edr(void);
+
#endif /* BTIF_AV_H */
diff --git a/btif/include/btif_media.h b/btif/include/btif_media.h
index 55c88d5..9e20e21 100755
--- a/btif/include/btif_media.h
+++ b/btif/include/btif_media.h
@@ -244,6 +244,4 @@
void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av);
void btif_a2dp_set_tx_flush(BOOLEAN enable);
-void btif_media_check_iop_exceptions(UINT8 *peer_bda);
-
#endif
diff --git a/btif/src/btif_av.c b/btif/src/btif_av.c
index 934c937..748b204 100755
--- a/btif/src/btif_av.c
+++ b/btif/src/btif_av.c
@@ -75,6 +75,7 @@
bt_bdaddr_t peer_bda;
btif_sm_handle_t sm_handle;
UINT8 flags;
+ tBTA_AV_EDR edr;
} btif_av_cb_t;
/*****************************************************************************
@@ -237,6 +238,7 @@
/* clear the peer_bda */
memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
btif_av_cb.flags = 0;
+ btif_av_cb.edr = 0;
btif_a2dp_on_idle();
break;
@@ -340,12 +342,14 @@
tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
btav_connection_state_t state;
btif_sm_state_t av_state;
- BTIF_TRACE_DEBUG1("status:%d", p_bta_data->open.status);
+ BTIF_TRACE_DEBUG2("status:%d, edr 0x%x",p_bta_data->open.status,
+ p_bta_data->open.edr);
if (p_bta_data->open.status == BTA_AV_SUCCESS)
{
state = BTAV_CONNECTION_STATE_CONNECTED;
av_state = BTIF_AV_STATE_OPENED;
+ btif_av_cb.edr = p_bta_data->open.edr;
}
else
{
@@ -467,8 +471,7 @@
case BTIF_SM_ENTER_EVT:
btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
- btif_media_check_iop_exceptions(btif_av_cb.peer_bda.address);
- break;
+ break;
case BTIF_SM_EXIT_EVT:
btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
@@ -1008,3 +1011,26 @@
btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
}
+
+/*******************************************************************************
+**
+** Function btif_av_is_peer_edr
+**
+** Description Check if the connected a2dp device supports
+** EDR or not. Only when connected this function
+** will accurately provide a true capability of
+** remote peer. If not connected it will always be false.
+**
+** Returns TRUE if remote device is capable of EDR
+**
+*******************************************************************************/
+BOOLEAN btif_av_is_peer_edr(void)
+{
+ ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
+
+ if (btif_av_cb.edr)
+ return TRUE;
+ else
+ return FALSE;
+}
+
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index 3c15b27..7fe04fd 100755
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -116,26 +116,11 @@
#define BTIF_MEDIA_NUM_TICK 1
#endif
-/* Media task tick in milliseconds */
+/* Media task tick in milliseconds, must be set to multiple of
+ (1000/TICKS_PER_SEC) (10) */
+
#define BTIF_MEDIA_TIME_TICK (20 * BTIF_MEDIA_NUM_TICK)
-/* Number of frames per media task tick.
- Configure value rounded up to closest integer and
- adjust any deltas in btif_get_num_aa_frame */
-
-/* 7.5 frames/tick @ 20 ms tick (every 2nd frame send one less) */
-#define BTIF_MEDIA_FR_PER_TICKS_48 (8 * BTIF_MEDIA_NUM_TICK)
-
-/* 6.89 frames/tick @ 20 ms tick (7 out of 64 frames send one less */
-#define BTIF_MEDIA_FR_PER_TICKS_44_1 (7 * BTIF_MEDIA_NUM_TICK)
-
-/* 5.0 frames/tick @ 20 ms tick */
-#define BTIF_MEDIA_FR_PER_TICKS_32 (5 * BTIF_MEDIA_NUM_TICK)
-
-/* 2.5 frames/tick @ 20 ms tick (every 2nd frame send one less) */
-#define BTIF_MEDIA_FR_PER_TICKS_16 (3 * BTIF_MEDIA_NUM_TICK)
-
-
/* buffer pool */
#define BTIF_MEDIA_AA_POOL_ID GKI_POOL_ID_3
#define BTIF_MEDIA_AA_BUF_SIZE GKI_BUF3_SIZE
@@ -153,7 +138,11 @@
#endif
/* Middle quality quality setting @ 44.1 khz */
-#define DEFAULT_SBC_BITRATE 229
+#define DEFAULT_SBC_BITRATE 328
+
+#ifndef BTIF_A2DP_NON_EDR_MAX_RATE
+#define BTIF_A2DP_NON_EDR_MAX_RATE 229
+#endif
#ifndef A2DP_MEDIA_TASK_STACK_SIZE
#define A2DP_MEDIA_TASK_STACK_SIZE 0x2000 /* In bytes */
@@ -181,8 +170,13 @@
*/
/* fixme -- define this in pcm time instead of buffer count */
-/* fixme -- tune optimal value. For now set a large buffer capacity */
-#define MAX_OUTPUT_BUFFER_QUEUE_SZ 24
+
+/* The typical runlevel of the tx queue size is ~1 buffer
+ but due to link flow control or thread preemption in lower
+ layers we might need to temporarily buffer up data */
+
+/* 24 frames is equivalent to 6.89*24*2.9 ~= 480 ms @ 44.1 khz, 20 ms mediatick */
+#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 24
//#define BTIF_MEDIA_VERBOSE_ENABLED
@@ -203,6 +197,8 @@
UINT32 aa_frame_counter;
INT32 aa_feed_counter;
INT32 aa_feed_residue;
+ UINT32 counter;
+ UINT32 bytes_per_tick; /* pcm bytes read each media task tick */
} tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE;
@@ -227,7 +223,6 @@
void* av_sm_hdl;
UINT8 a2dp_cmd_pending; /* we can have max one command pending */
BOOLEAN tx_flush; /* discards any outgoing data when true */
- BOOLEAN scaling_disabled;
#endif
} tBTIF_MEDIA_CB;
@@ -584,6 +579,20 @@
** BTIF ADAPTATION
*****************************************************************************/
+static UINT16 btif_media_task_get_sbc_rate(void)
+{
+ UINT16 rate = DEFAULT_SBC_BITRATE;
+
+ /* restrict bitrate if a2dp link is non-edr */
+ if (!btif_av_is_peer_edr())
+ {
+ rate = BTIF_A2DP_NON_EDR_MAX_RATE;
+ APPL_TRACE_DEBUG1("non-edr a2dp sink detected, restrict rate to %d", rate);
+ }
+
+ return rate;
+}
+
static void btif_a2dp_encoder_init(void)
{
UINT16 minmtu;
@@ -763,7 +772,7 @@
GKI_disable();
- /* for now hardcode 44.1 khz 16 bit stereo */
+ /* for now hardcode 44.1 khz 16 bit stereo PCM format */
media_feeding.cfg.pcm.sampling_freq = 44100;
media_feeding.cfg.pcm.bit_per_sample = 16;
media_feeding.cfg.pcm.num_channel = 2;
@@ -1416,6 +1425,9 @@
/* Flush all enqueued GKI music buffers (encoded) */
APPL_TRACE_DEBUG0("btif_media_task_aa_tx_flush");
+ btif_media_cb.media_feeding_state.pcm.counter = 0;
+ btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
+
btif_media_flush_q(&(btif_media_cb.TxAaQ));
UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REQ_RX_FLUSH, NULL);
@@ -1445,7 +1457,8 @@
btif_media_cb.encoder.s16AllocationMethod = pInitAudio->AllocationMethod;
btif_media_cb.encoder.s16SamplingFreq = pInitAudio->SamplingFreq;
- btif_media_cb.encoder.u16BitRate = DEFAULT_SBC_BITRATE;
+ btif_media_cb.encoder.u16BitRate = btif_media_task_get_sbc_rate();
+
/* Default transcoding is PCM to SBC, modified by feeding configuration */
btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE-BTIF_MEDIA_AA_SBC_OFFSET-sizeof(BT_HDR))
@@ -1497,7 +1510,7 @@
- sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize;
/* Set the initial target bit rate */
- pstrEncParams->u16BitRate = DEFAULT_SBC_BITRATE;
+ pstrEncParams->u16BitRate = btif_media_task_get_sbc_rate();
if (pstrEncParams->s16SamplingFreq == SBC_sf16000)
s16SamplingFreq = 16000;
@@ -1755,6 +1768,18 @@
{
/* By default, just clear the entire state */
memset(&btif_media_cb.media_feeding_state, 0, sizeof(btif_media_cb.media_feeding_state));
+
+ if (btif_media_cb.TxTranscoding == BTIF_MEDIA_TRSCD_PCM_2_SBC)
+ {
+ btif_media_cb.media_feeding_state.pcm.bytes_per_tick =
+ (btif_media_cb.media_feeding.cfg.pcm.sampling_freq *
+ btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8 *
+ btif_media_cb.media_feeding.cfg.pcm.num_channel *
+ BTIF_MEDIA_TIME_TICK)/1000;
+
+ APPL_TRACE_WARNING1("pcm bytes per tick %d",
+ (int)btif_media_cb.media_feeding_state.pcm.bytes_per_tick);
+ }
}
/*******************************************************************************
**
@@ -1826,51 +1851,22 @@
switch (btif_media_cb.TxTranscoding)
{
case BTIF_MEDIA_TRSCD_PCM_2_SBC:
- switch (btif_media_cb.encoder.s16SamplingFreq)
- {
- case SBC_sf16000:
- if (!btif_media_cb.scaling_disabled &&
- (btif_media_cb.media_feeding_state.pcm.aa_frame_counter++ % 2) == 0)
- {
- result = BTIF_MEDIA_FR_PER_TICKS_16-1;
- }
- else
- {
- result = BTIF_MEDIA_FR_PER_TICKS_16;
- }
- break;
+ {
+ UINT32 pcm_bytes_per_frame = btif_media_cb.encoder.s16NumOfSubBands *
+ btif_media_cb.encoder.s16NumOfBlocks *
+ btif_media_cb.media_feeding.cfg.pcm.num_channel *
+ btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
- case SBC_sf32000:
- result = BTIF_MEDIA_FR_PER_TICKS_32;
- break;
+ btif_media_cb.media_feeding_state.pcm.counter +=
+ btif_media_cb.media_feeding_state.pcm.bytes_per_tick;
- case SBC_sf48000:
- if (!btif_media_cb.scaling_disabled &&
- (btif_media_cb.media_feeding_state.pcm.aa_frame_counter++ % 2) == 0)
- {
- result = BTIF_MEDIA_FR_PER_TICKS_48-1;
- }
- else
- {
- result = BTIF_MEDIA_FR_PER_TICKS_48;
- }
- break;
-
- case SBC_sf44100:
- if (!btif_media_cb.scaling_disabled &&
- (btif_media_cb.media_feeding_state.pcm.aa_frame_counter++ % 64) < 7)
- {
- result = BTIF_MEDIA_FR_PER_TICKS_44_1-1;
- }
- else
- {
- result = BTIF_MEDIA_FR_PER_TICKS_44_1;
- }
- break;
- }
+ /* calculate nbr of frames pending for this media tick */
+ result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
+ btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
VERBOSE("WRITE %d FRAMES", result);
- break;
+ }
+ break;
default:
APPL_TRACE_ERROR1("ERROR btif_get_num_aa_frame Unsupported transcoding format 0x%x",
@@ -1919,7 +1915,7 @@
UINT16 sbc_sampling = 48000;
UINT32 src_samples;
UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * \
- sizeof(SINT16);
+ btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
* SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2];
static UINT16 read_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
@@ -1948,6 +1944,23 @@
break;
}
+ if (sbc_sampling == btif_media_cb.media_feeding.cfg.pcm.sampling_freq) {
+ read_size = bytes_needed - btif_media_cb.media_feeding_state.pcm.aa_feed_residue;
+ nb_byte_read = UIPC_Read(channel_id, &event,
+ ((UINT8 *)btif_media_cb.encoder.as16PcmBuffer) +
+ btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
+ read_size);
+ if (nb_byte_read == read_size) {
+ btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
+ return TRUE;
+ } else {
+ APPL_TRACE_WARNING2("### UNDERFLOW :: ONLY READ %d BYTES OUT OF %d ###",
+ nb_byte_read, read_size);
+ btif_media_cb.media_feeding_state.pcm.aa_feed_residue += nb_byte_read;
+ return FALSE;
+ }
+ }
+
/* Some Feeding PCM frequencies require to split the number of sample */
/* to read. */
/* E.g 128/6=21.3333 => read 22 and 21 and 21 => max = 2; threshold = 0*/
@@ -2117,6 +2130,13 @@
}
else
{
+ APPL_TRACE_WARNING2("btif_media_aa_prep_sbc_2_send underflow %d, %d",
+ nb_frame, btif_media_cb.media_feeding_state.pcm.aa_feed_residue);
+ btif_media_cb.media_feeding_state.pcm.counter += nb_frame *
+ btif_media_cb.encoder.s16NumOfSubBands *
+ btif_media_cb.encoder.s16NumOfBlocks *
+ btif_media_cb.media_feeding.cfg.pcm.num_channel *
+ btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
/* no more pcm to read */
nb_frame = 0;
@@ -2175,10 +2195,10 @@
VERBOSE("btif_media_aa_prep_2_send : %d frames (queue %d)", nb_frame,
btif_media_cb.TxAaQ.count);
- /* Remove all the buffers not sent until there are only 4 in the queue */
- while (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_BUFFER_QUEUE_SZ)
+ while (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ)
{
- APPL_TRACE_WARNING1("btif_media_aa_prep_2_send congestion buf count %d",btif_media_cb.TxAaQ.count);
+ APPL_TRACE_WARNING1("btif_media_aa_prep_2_send congestion buf count %d",
+ btif_media_cb.TxAaQ.count);
GKI_freebuf(GKI_dequeue(&(btif_media_cb.TxAaQ)));
}
@@ -2219,33 +2239,6 @@
bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
}
-/*******************************************************************************
- **
- ** Function btif_media_check_iop_exceptions
- **
- ** Description Perform any device specific iop changes
- **
- ** Returns void
- **
- *******************************************************************************/
-
-void btif_media_check_iop_exceptions(UINT8 *peer_bda)
-{
- /* disable rate scaling for pcm carkit */
- if ((peer_bda[0] == 0x00) &&
- (peer_bda[1] == 0x0E) &&
- (peer_bda[2] == 0x9F))
- {
- BTIF_TRACE_WARNING0("detected pcm carkit, disable rate scaling");
- btif_media_cb.scaling_disabled = TRUE;
- }
- else
- {
- btif_media_cb.scaling_disabled = FALSE;
- }
-}
-
-
#endif /* BTA_AV_INCLUDED == TRUE */
/*******************************************************************************
@@ -2321,4 +2314,3 @@
APPL_TRACE_DEBUG2("\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
}
-
diff --git a/include/bt_target.h b/include/bt_target.h
index 6f3df8a..7363456 100644
--- a/include/bt_target.h
+++ b/include/bt_target.h
@@ -335,10 +335,6 @@
#define BTA_AG_SCO_PKT_TYPES (BTM_SCO_LINK_ONLY_MASK | BTM_SCO_PKT_TYPES_MASK_EV3 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV5)
#endif
-#ifndef BTA_AV_MAX_A2DP_MTU
-#define BTA_AV_MAX_A2DP_MTU 668
-#endif
-
#ifndef BTA_AV_RET_TOUT
#define BTA_AV_RET_TOUT 15
#endif