OSDN Git Service

Calculate A2DP frames to send based on elapsed time
authorAndre Eisenbach <eisenbach@google.com>
Fri, 11 Jul 2014 23:57:24 +0000 (16:57 -0700)
committerAndre Eisenbach <eisenbach@google.com>
Sat, 12 Jul 2014 00:10:56 +0000 (17:10 -0700)
This patch is aimed at improving A2DP audio quality by sending the
correct number of frames based on the actual time elapes between "ticks"
in order to account for timer drift.

Change-Id: If5b7cde90f5eb10b926ad247f51cff0eb60bbff7

btif/src/btif_media_task.c
utils/src/bt_utils.c

index bc54ece..2128b84 100644 (file)
@@ -302,6 +302,7 @@ typedef struct {
 
 static tBTIF_MEDIA_CB btif_media_cb;
 static int media_task_running = MEDIA_TASK_STATE_OFF;
+static UINT64 last_frame_us = 0;
 
 
 /*****************************************************************************
@@ -363,22 +364,20 @@ BOOLEAN btif_media_task_clear_track(void);
  **  Misc helper functions
  *****************************************************************************/
 
-static void log_tstamps_us(char *comment)
+static UINT64 time_now_us()
 {
-    #define USEC_PER_SEC 1000000L
-    static struct timespec prev = {0, 0};
-    struct timespec now, diff;
-    unsigned int diff_us = 0;
-    unsigned int now_us = 0;
-
-    clock_gettime(CLOCK_MONOTONIC, &now);
-    now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;
-    diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
+    struct timespec ts_now;
+    clock_gettime(CLOCK_BOOTTIME, &ts_now);
+    return (ts_now.tv_sec * USEC_PER_SEC) + (ts_now.tv_nsec / 1000);
+}
 
-    APPL_TRACE_DEBUG("[%s] ts %08d, diff : %08d, queue sz %d", comment, now_us, diff_us,
+static void log_tstamps_us(char *comment)
+{
+    static UINT64 prev_us = 0;
+    const UINT64 now_us = time_now_us();
+    APPL_TRACE_DEBUG("[%s] ts %08llu, diff : %08llu, queue sz %d", comment, now_us, now_us - prev_us,
                 btif_media_cb.TxAaQ.count);
-
-    prev = now;
+    prev_us = now_us;
 }
 
 const char* dump_media_event(UINT16 event)
@@ -2382,6 +2381,7 @@ static void btif_media_task_aa_start_tx(void)
     // UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_CBACK, NULL);
 
     btif_media_cb.is_tx_timer = TRUE;
+    last_frame_us = 0;
 
     /* Reset the media feeding state */
     btif_media_task_feeding_state_reset();
@@ -2413,6 +2413,7 @@ static void btif_media_task_aa_stop_tx(void)
 
     /* audio engine stopped, reset tx suspended flag */
     btif_media_cb.tx_flush = 0;
+    last_frame_us = 0;
 
     /* Reset the media feeding state */
     btif_media_task_feeding_state_reset();
@@ -2440,8 +2441,15 @@ static UINT8 btif_get_num_aa_frame(void)
                              btif_media_cb.media_feeding.cfg.pcm.num_channel *
                              btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
 
+            UINT32 us_this_tick = BTIF_MEDIA_TIME_TICK * 1000;
+            UINT64 now_us = time_now_us();
+            if (last_frame_us != 0)
+                us_this_tick = (now_us - last_frame_us);
+            last_frame_us = now_us;
+
             btif_media_cb.media_feeding_state.pcm.counter +=
-                                btif_media_cb.media_feeding_state.pcm.bytes_per_tick;
+                                btif_media_cb.media_feeding_state.pcm.bytes_per_tick *
+                                us_this_tick / (BTIF_MEDIA_TIME_TICK * 1000);
             if ((!btif_media_cb.media_feeding_state.pcm.overflow) ||
                 (btif_media_cb.TxAaQ.count < A2DP_PACKET_COUNT_LOW_WATERMARK)) {
                 if (btif_media_cb.media_feeding_state.pcm.overflow) {
index 6decacf..df1fd04 100644 (file)
@@ -127,7 +127,7 @@ void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
     pthread_once(&g_DoSchedulingGroupOnce[g_TaskIdx], check_do_scheduling_group);
     if (g_DoSchedulingGroup[g_TaskIdx]) {
         // set_sched_policy does not support tid == 0
-        rc = set_sched_policy(tid, SP_FOREGROUND);
+        rc = set_sched_policy(tid, SP_AUDIO_SYS);
     }
     g_TaskIDs[high_task] = tid;
     pthread_mutex_unlock(&gIdxLock);