summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio_a2dp_hw/audio_a2dp_hw.c12
-rwxr-xr-x[-rw-r--r--]btif/src/btif_core.c31
-rwxr-xr-x[-rw-r--r--]btif/src/btif_media_task.c95
-rwxr-xr-x[-rw-r--r--]gki/ulinux/gki_ulinux.c101
4 files changed, 161 insertions, 78 deletions
diff --git a/audio_a2dp_hw/audio_a2dp_hw.c b/audio_a2dp_hw/audio_a2dp_hw.c
index 9f4b238..42e416e 100644
--- a/audio_a2dp_hw/audio_a2dp_hw.c
+++ b/audio_a2dp_hw/audio_a2dp_hw.c
@@ -494,7 +494,7 @@ static uint32_t out_get_sample_rate(const struct audio_stream *stream)
{
struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
- INFO("rate %d", out->cfg.rate);
+ DEBUG("rate %d", out->cfg.rate);
return out->cfg.rate;
}
@@ -503,7 +503,7 @@ static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
{
struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
- INFO("out_set_sample_rate : %d", rate);
+ DEBUG("out_set_sample_rate : %d", rate);
if (rate != AUDIO_STREAM_DEFAULT_RATE)
{
@@ -520,7 +520,7 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
{
struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
- INFO("buffer_size : %d", out->buffer_sz);
+ DEBUG("buffer_size : %d", out->buffer_sz);
return out->buffer_sz;
}
@@ -529,7 +529,7 @@ static uint32_t out_get_channels(const struct audio_stream *stream)
{
struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
- INFO("channels 0x%x", out->cfg.channel_flags);
+ DEBUG("channels 0x%x", out->cfg.channel_flags);
return out->cfg.channel_flags;
}
@@ -537,14 +537,14 @@ static uint32_t out_get_channels(const struct audio_stream *stream)
static audio_format_t out_get_format(const struct audio_stream *stream)
{
struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
- INFO("format 0x%x", out->cfg.format);
+ DEBUG("format 0x%x", out->cfg.format);
return out->cfg.format;
}
static int out_set_format(struct audio_stream *stream, audio_format_t format)
{
struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
- ALOGW("setting format not yet supported (0x%x)", format);
+ DEBUG("setting format not yet supported (0x%x)", format);
return -ENOSYS;
}
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 29e493d..3440685 100644..100755
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -342,17 +342,9 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
{
char val[256];
uint8_t valid_bda = FALSE;
+ int val_size = 0;
const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
- BTIF_TRACE_DEBUG1("Look for bdaddr storage path in prop %s", PROPERTY_BT_BDADDR_PATH);
- int val_size = sizeof(val);
- if(btif_config_get_str("Local", "Adapter", "Address", val, &val_size))
- {
- str2bd(val, local_addr);
- BTIF_TRACE_DEBUG1("local bdaddr from bt_config.xml is %s", val);
- return;
- }
-
/* Get local bdaddr storage path from property */
if (property_get(PROPERTY_BT_BDADDR_PATH, val, NULL))
{
@@ -378,6 +370,18 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
}
}
+ if(!valid_bda)
+ {
+ val_size = sizeof(val);
+ BTIF_TRACE_DEBUG1("Look for bdaddr storage path in prop %s", PROPERTY_BT_BDADDR_PATH);
+ if(btif_config_get_str("Local", "Adapter", "Address", val, &val_size))
+ {
+ str2bd(val, local_addr);
+ BTIF_TRACE_DEBUG1("local bdaddr from bt_config.xml is %s", val);
+ return;
+ }
+ }
+
/* No factory BDADDR found. Look for previously generated random BDA */
if ((!valid_bda) && \
(property_get(PERSIST_BDADDR_PROPERTY, val, NULL)))
@@ -416,6 +420,15 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
//save the bd address to config file
bdstr_t bdstr;
bd2str(local_addr, &bdstr);
+ val_size = sizeof(val);
+ if (btif_config_get_str("Local", "Adapter", "Address", val, &val_size))
+ {
+ if (strcmp(bdstr, val) ==0)
+ {
+ // BDA is already present in the config file.
+ return;
+ }
+ }
btif_config_set_str("Local", "Adapter", "Address", bdstr);
btif_config_save();
}
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index 1b39137..6847696 100644..100755
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -117,14 +117,17 @@ enum {
#endif
/* Media task tick in milliseconds */
-#define BTIF_MEDIA_TIME_TICK (40 * BTIF_MEDIA_NUM_TICK)
+#define BTIF_MEDIA_TIME_TICK (20 * BTIF_MEDIA_NUM_TICK)
/* Number of frames per media task tick */
-#define BTIF_MEDIA_FR_PER_TICKS_48 (15 * BTIF_MEDIA_NUM_TICK)
-#define BTIF_MEDIA_FR_PER_TICKS_44_1_H (14 * BTIF_MEDIA_NUM_TICK)
-#define BTIF_MEDIA_FR_PER_TICKS_44_1_L (13 * BTIF_MEDIA_NUM_TICK)
-#define BTIF_MEDIA_FR_PER_TICKS_32 (10 * BTIF_MEDIA_NUM_TICK)
-#define BTIF_MEDIA_FR_PER_TICKS_16 ( 5 * BTIF_MEDIA_NUM_TICK)
+/* 7.5 frames/tick @ 20 ms tick */
+#define BTIF_MEDIA_FR_PER_TICKS_48 (7 * BTIF_MEDIA_NUM_TICK)
+/* 6.89 frames/tick @ 20 ms tick */
+#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 */
+#define BTIF_MEDIA_FR_PER_TICKS_16 (3 * BTIF_MEDIA_NUM_TICK)
/* buffer pool */
@@ -143,7 +146,8 @@ enum {
#define BTIF_MEDIA_BITRATE_STEP 5
#endif
-#define DEFAULT_SBC_BITRATE 220
+/* Middle quality quality setting @ 44.1 khz */
+#define DEFAULT_SBC_BITRATE 229
#ifndef A2DP_MEDIA_TASK_STACK_SIZE
#define A2DP_MEDIA_TASK_STACK_SIZE 0x2000 /* In bytes */
@@ -234,11 +238,6 @@ typedef struct
UINT8 a2dp_cmd_pending; /* we can have max one command pending */
BOOLEAN tx_flush; /* discards any outgoing data when true */
tBTIF_MEDIA_RA ra; /* tx rate adjustment logic */
-
-#if ((defined(BTIF_MEDIA_OVERFEED_INCLUDED) && (BTIF_MEDIA_OVERFEED_INCLUDED == TRUE)) || \
- (defined(BTIF_MEDIA_UNDERFEED_INCLUDED) && (BTIF_MEDIA_UNDERFEED_INCLUDED == TRUE)))
- UINT8 tx_counter;
-#endif
#endif
} tBTIF_MEDIA_CB;
@@ -1034,13 +1033,15 @@ static void ra_update(UINT32 bytes_processed)
/* converts adjusted frame count to adjusted pcmtime equivalent */
btif_media_cb.ra.ra_adjust_pcmtime += (btif_media_cb.ra.ra_adjust_cnt)*pcmtime_equivalent;
- VERBOSE("ra adjust %d %d", btif_media_cb.ra.ra_adjust_cnt, btif_media_cb.ra.ra_adjust_pcmtime);
+ //VERBOSE("ra update %d %d %d", btif_media_cb.ra.ra_adjust_cnt,
+ // btif_media_cb.ra.ra_adjust_pcmtime, ra_stats_update);
/* check pcmtime adjustments every stats interval */
if (ra_stats_update > (RA_STATS_INTERVAL*1000000L))
{
- APPL_TRACE_EVENT2("ra estimate : %d us (%d ppm)", btif_media_cb.ra.ra_adjust_pcmtime,
- btif_media_cb.ra.ra_adjust_pcmtime/RA_STATS_INTERVAL);
+ APPL_TRACE_DEBUG3("ra estimate : %d us for %d secs (%d ppm)",
+ btif_media_cb.ra.ra_adjust_pcmtime, RA_STATS_INTERVAL,
+ btif_media_cb.ra.ra_adjust_pcmtime/RA_STATS_INTERVAL);
btif_media_cb.ra.ra_adjust_pcmtime = 0;
ra_stats_update = 0;
@@ -1076,11 +1077,8 @@ static int ra_adjust(void)
clock_gettime(CLOCK_MONOTONIC, &now);
- time_elapsed_us = ((unsigned long long)(now.tv_sec - btif_media_cb.ra.time_start.tv_sec)) * USEC_PER_SEC + \
- (now.tv_nsec - btif_media_cb.ra.time_start.tv_nsec)/1000;
-
- VERBOSE("tx_pcmtime_us : %llu us, elapsed : %llu us", btif_media_cb.ra.tx_pcmtime_us,
- time_elapsed_us);
+ time_elapsed_us = ((unsigned long long)(now.tv_sec - btif_media_cb.ra.time_start.tv_sec))\
+ * USEC_PER_SEC + (now.tv_nsec - btif_media_cb.ra.time_start.tv_nsec)/1000;
/* compare elapsed time vs read pcm time */
if (btif_media_cb.ra.tx_pcmtime_us > time_elapsed_us)
@@ -1250,7 +1248,7 @@ int btif_media_task(void *p)
/* make sure no channels are restarted while shutting down */
media_task_running = MEDIA_TASK_STATE_SHUTTING_DOWN;
- /* this calls blocks until uipc is fully closed */
+ /* this calls blocks until uipc is fully closed */
UIPC_Close(UIPC_CH_ID_ALL);
break;
}
@@ -1559,14 +1557,17 @@ static void btif_media_task_enc_init(BT_HDR *p_msg)
btif_media_cb.encoder.u16BitRate = DEFAULT_SBC_BITRATE;
/* 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))
+ btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE-BTIF_MEDIA_AA_SBC_OFFSET-sizeof(BT_HDR))
< pInitAudio->MtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
- sizeof(BT_HDR)) : pInitAudio->MtuSize;
- APPL_TRACE_DEBUG3("btif_media_task_enc_init busy %d, mtu %d, peer mtu %d", btif_media_cb.busy_level, btif_media_cb.TxAaMtuSize, pInitAudio->MtuSize);
- APPL_TRACE_DEBUG6("btif_media_task_enc_init ch mode %d, nbsubd %d, nb blk %d, alloc method %d, bit rate %d, Smp freq %d",
- btif_media_cb.encoder.s16ChannelMode, btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks,
- btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate, btif_media_cb.encoder.s16SamplingFreq);
+ APPL_TRACE_EVENT3("btif_media_task_enc_init busy %d, mtu %d, peer mtu %d",
+ btif_media_cb.busy_level, btif_media_cb.TxAaMtuSize, pInitAudio->MtuSize);
+ APPL_TRACE_EVENT6(" ch mode %d, subnd %d, nb blk %d, alloc %d, rate %d, freq %d",
+ btif_media_cb.encoder.s16ChannelMode, btif_media_cb.encoder.s16NumOfSubBands,
+ btif_media_cb.encoder.s16NumOfBlocks,
+ btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
+ btif_media_cb.encoder.s16SamplingFreq);
/* Reset entirely the SBC encoder */
SBC_Encoder_Init(&(btif_media_cb.encoder));
@@ -1885,11 +1886,6 @@ static void btif_media_task_aa_start_tx(void)
btif_media_cb.is_tx_timer = TRUE;
-#if ((defined(BTIF_MEDIA_OVERFEED_INCLUDED) && (BTIF_MEDIA_OVERFEED_INCLUDED == TRUE)) || \
- (defined(BTIF_MEDIA_UNDERFEED_INCLUDED) && (BTIF_MEDIA_UNDERFEED_INCLUDED == TRUE)))
- btif_media_cb.tx_counter = 0;
-#endif
-
/* Reset the media feeding state */
btif_media_task_feeding_state_reset();
@@ -1951,35 +1947,26 @@ static UINT8 btif_get_num_aa_frame(void)
result = BTIF_MEDIA_FR_PER_TICKS_48;
break;
case SBC_sf44100:
- if ((btif_media_cb.media_feeding_state.pcm.aa_frame_counter++ % 32) < 7)
- {
- result = BTIF_MEDIA_FR_PER_TICKS_44_1_L;
- }
- else
- {
- result = BTIF_MEDIA_FR_PER_TICKS_44_1_H;
- }
+ result = BTIF_MEDIA_FR_PER_TICKS_44_1;
break;
}
+ /* Frames per tick should be selected to come as close as possible
+ to the ideal framecount. Any residue compared to ideal framecount
+ is compensated here.
+
+ Although we can estimate the frames per tick using modula
+ counters using the rate adapter logic smoothes out the compensation
+ over time and tracks transmitted time vs elapsed time counted from the first
+ frame sent out. Hence regardless of the reason for the drift (gki timer
+ inaccuracies or media tick frame residues) the rate
+ adaptor will compensate as soon as we drift outside the configued
+ threshold
+ */
+
result += ra_adjust();
VERBOSE("WRITE %d FRAMES", result);
-
-#if ((defined(BTIF_MEDIA_OVERFEED_INCLUDED) && (BTIF_MEDIA_OVERFEED_INCLUDED == TRUE)) || \
- (defined(BTIF_MEDIA_UNDERFEED_INCLUDED) && (BTIF_MEDIA_UNDERFEED_INCLUDED == TRUE)))
- btif_media_cb.tx_counter++;
- if (btif_media_cb.tx_counter == 10)
- {
- btif_media_cb.tx_counter = 0;
-#if defined(BTIF_MEDIA_OVERFEED_INCLUDED) && (BTIF_MEDIA_OVERFEED_INCLUDED == TRUE)
- result++;
-#endif
-#if defined(BTIF_MEDIA_UNDERFEED_INCLUDED) && (BTIF_MEDIA_UNDERFEED_INCLUDED == TRUE)
- result--;
-#endif
- }
-#endif
break;
default:
diff --git a/gki/ulinux/gki_ulinux.c b/gki/ulinux/gki_ulinux.c
index fabaea1..e4e0323 100644..100755
--- a/gki/ulinux/gki_ulinux.c
+++ b/gki/ulinux/gki_ulinux.c
@@ -89,6 +89,9 @@ static int shutdown_timer = 0;
#define GKI_SHUTDOWN_EVT APPL_EVT_7
#endif
+#define __likely(cond) __builtin_expect(!!(cond), 1)
+#define __unlikely(cond) __builtin_expect(!!(cond), 0)
+
/*****************************************************************************
** Local type definitions
******************************************************************************/
@@ -538,7 +541,7 @@ void GKI_shutdown(void)
void gki_system_tick_start_stop_cback(BOOLEAN start)
{
tGKI_OS *p_os = &gki_cb.os;
- volatile int *p_run_cond = &p_os->no_timer_suspend;
+ int *p_run_cond = &p_os->no_timer_suspend;
static int wake_lock_count;
if ( FALSE == start )
{
@@ -584,24 +587,104 @@ void gki_system_tick_start_stop_cback(BOOLEAN start)
** one step, If your OS does it in one step, this function
** should be empty.
*********************************************************************************/
-
#ifdef NO_GKI_RUN_RETURN
void* timer_thread(void *arg)
{
- struct timespec delay;
+ int timeout_ns=0;
+ struct timespec timeout;
+ struct timespec previous = {0,0};
+ struct timespec current;
int err;
+ int delta_ns;
+ int restart;
+ tGKI_OS *p_os = &gki_cb.os;
+ int *p_run_cond = &p_os->no_timer_suspend;
+
+ /* Indicate that tick is just starting */
+ restart = 1;
while(!shutdown_timer)
{
- delay.tv_sec = LINUX_SEC / 1000;
- delay.tv_nsec = 1000 * 1000 * (LINUX_SEC%1000);
+ /* If the timer has been stopped (no SW timer running) */
+ if (*p_run_cond == GKI_TIMER_TICK_STOP_COND)
+ {
+ /*
+ * We will lock/wait on GKI_timer_mutex.
+ * This mutex will be unlocked when timer is re-started
+ */
+ GKI_TRACE("GKI_run lock mutex");
+ pthread_mutex_lock(&p_os->gki_timer_mutex);
+
+ /* We are here because the mutex has been released by timer cback */
+ /* Let's release it for future use */
+ GKI_TRACE("GKI_run unlock mutex");
+ pthread_mutex_unlock(&p_os->gki_timer_mutex);
- /* [u]sleep can't be used because it uses SIGALRM */
+ /* Indicate that tick is just starting */
+ restart = 1;
+ }
+
+ /* Get time */
+ clock_gettime(CLOCK_MONOTONIC, &current);
+
+ /* Check if tick was just restarted, indicating to the compiler that this is
+ * unlikely to happen (to help branch prediction) */
+ if (__unlikely(restart))
+ {
+ /* Clear the restart indication */
+ restart = 0;
- do {
- err = nanosleep(&delay, &delay);
- } while (err < 0 && errno ==EINTR);
+ timeout_ns = (GKI_TICKS_TO_MS(1) * 1000000);
+ }
+ else
+ {
+ /* Compute time elapsed since last sleep start */
+ delta_ns = current.tv_nsec - previous.tv_nsec;
+ delta_ns += (current.tv_sec - previous.tv_sec) * 1000000000;
+
+ /* Compute next timeout:
+ * timeout = (next theoretical expiration) - current time
+ * timeout = (previous time + timeout + delay) - current time
+ * timeout = timeout + delay - (current time - previous time)
+ * timeout += delay - delta */
+ timeout_ns += (GKI_TICKS_TO_MS(1) * 1000000) - delta_ns;
+ }
+ /* Save the current time for next iteration */
+ previous = current;
+
+ timeout.tv_sec = 0;
+
+ /* Sleep until next theoretical tick time. In case of excessive
+ elapsed time since last theoretical tick expiration, it is
+ possible that the timeout value is negative. To protect
+ against this error, we set minimum sleep time to 10% of the
+ tick period. We indicate to compiler that this is unlikely to
+ happen (to help branch prediction) */
+
+ if (__unlikely(timeout_ns < ((GKI_TICKS_TO_MS(1) * 1000000) * 0.1)))
+ {
+ timeout.tv_nsec = (GKI_TICKS_TO_MS(1) * 1000000) * 0.1;
+
+ /* Print error message if tick really got delayed
+ (more than 5 ticks) */
+ if (timeout_ns < GKI_TICKS_TO_MS(-5) * 1000000)
+ {
+ GKI_ERROR_LOG("tick delayed > 5 slots (%d,%d) -- cpu overload ? ",
+ timeout_ns, GKI_TICKS_TO_MS(-5) * 1000000);
+ }
+ }
+ else
+ {
+ timeout.tv_nsec = timeout_ns;
+ }
+
+ do
+ {
+ /* [u]sleep can't be used because it uses SIGALRM */
+ err = nanosleep(&timeout, &timeout);
+ } while (err < 0 && errno == EINTR);
+ /* Increment the GKI time value by one tick and update internal timers */
GKI_timer_update(1);
}
GKI_TRACE("gki_ulinux: Exiting timer_thread");