[vlc-commits] audiotrack: smooth out the AudioTrack position

Thomas Guillem git at videolan.org
Wed Apr 15 17:27:07 CEST 2015


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Tue Apr 14 19:49:56 2015 +0200| [b50b9c35a75fcef1549e55607ef1c0044d2e1fb1] | committer: Thomas Guillem

audiotrack: smooth out the AudioTrack position

It improves delay precision for old devices.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b50b9c35a75fcef1549e55607ef1c0044d2e1fb1
---

 modules/audio_output/audiotrack.c |   67 ++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 8 deletions(-)

diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c
index 3c5f1ae..c2c06c3 100644
--- a/modules/audio_output/audiotrack.c
+++ b/modules/audio_output/audiotrack.c
@@ -37,6 +37,9 @@
 #define MIN_AUDIOTRACK_BUFFER_US INT64_C(250000)  // 250ms
 #define MAX_AUDIOTRACK_BUFFER_US INT64_C(1000000) // 1000ms
 
+#define SMOOTHPOS_SAMPLE_COUNT 10
+#define SMOOTHPOS_INTERVAL_US INT64_C(30000) // 30ms
+
 #define AUDIOTIMESTAMP_INTERVAL_US INT64_C(500000) // 500ms
 
 static int  Open( vlc_object_t * );
@@ -73,6 +76,15 @@ struct aout_sys_t {
         mtime_t i_last_time;
     } timestamp;
 
+    /* Used by AudioTrack_GetSmoothPositionUs */
+    struct {
+        uint32_t i_idx;
+        uint32_t i_count;
+        mtime_t p_us[SMOOTHPOS_SAMPLE_COUNT];
+        mtime_t i_us;
+        mtime_t i_last_time;
+    } smoothpos;
+
     uint64_t i_samples_written; /* number of samples written since last flush */
     uint32_t i_bytes_per_frame; /* byte per frame */
     uint32_t i_max_audiotrack_samples;
@@ -478,7 +490,7 @@ AudioTrack_ResetPlaybackHeadPosition( JNIEnv *env, audio_output_t *p_aout )
 }
 
 /**
- * Reset AudioTrack Position
+ * Reset AudioTrack SmoothPosition and TimestampPosition
  */
 static void
 AudioTrack_ResetPositions( JNIEnv *env, audio_output_t *p_aout )
@@ -490,6 +502,50 @@ AudioTrack_ResetPositions( JNIEnv *env, audio_output_t *p_aout )
     p_sys->timestamp.i_last_time = 0;
     p_sys->timestamp.i_frame_us = 0;
     p_sys->timestamp.i_frame_pos = 0;
+
+    p_sys->smoothpos.i_count = 0;
+    p_sys->smoothpos.i_idx = 0;
+    p_sys->smoothpos.i_last_time = 0;
+    p_sys->smoothpos.i_us = 0;
+}
+
+/**
+ * Get a smooth AudioTrack position
+ *
+ * This function smooth out the AudioTrack position since it has a very bad
+ * precision (+/- 20ms on old devices).
+ */
+static mtime_t
+AudioTrack_GetSmoothPositionUs( JNIEnv *env, audio_output_t *p_aout )
+{
+    aout_sys_t *p_sys = p_aout->sys;
+    uint64_t i_audiotrack_us;
+    mtime_t i_now = mdate();
+
+    /* Fetch an AudioTrack position every SMOOTHPOS_INTERVAL_US (30ms) */
+    if( i_now - p_sys->smoothpos.i_last_time >= SMOOTHPOS_INTERVAL_US )
+    {
+        i_audiotrack_us = FRAMES_TO_US( AudioTrack_GetPosition( env, p_aout ) );
+
+        p_sys->smoothpos.i_last_time = i_now;
+
+        /* Base the position off the current time */
+        p_sys->smoothpos.p_us[p_sys->smoothpos.i_idx] = i_audiotrack_us - i_now;
+        p_sys->smoothpos.i_idx = (p_sys->smoothpos.i_idx + 1)
+                                 % SMOOTHPOS_SAMPLE_COUNT;
+        if( p_sys->smoothpos.i_count < SMOOTHPOS_SAMPLE_COUNT )
+            p_sys->smoothpos.i_count++;
+
+        /* Calculate the average position based off the current time */
+        p_sys->smoothpos.i_us = 0;
+        for( uint32_t i = 0; i < p_sys->smoothpos.i_count; ++i )
+            p_sys->smoothpos.i_us += p_sys->smoothpos.p_us[i];
+        p_sys->smoothpos.i_us /= p_sys->smoothpos.i_count;
+    }
+    if( p_sys->smoothpos.i_us != 0 )
+        return p_sys->smoothpos.i_us + i_now;
+    else
+        return 0;
 }
 
 static mtime_t
@@ -566,13 +622,8 @@ TimeGet( audio_output_t *p_aout, mtime_t *restrict p_delay )
 
     i_audiotrack_us = AudioTrack_GetTimestampPositionUs( env, p_aout );
 
-    if( i_audiotrack_us == 0 )
-    {
-        uint64_t i_audiotrack_pos = AudioTrack_GetPosition( env, p_aout );
-
-        if( p_sys->i_samples_written > i_audiotrack_pos )
-            i_audiotrack_us = FRAMES_TO_US( i_audiotrack_pos );
-    }
+    if( i_audiotrack_us <= 0 )
+        i_audiotrack_us = AudioTrack_GetSmoothPositionUs(env, p_aout );
 
     if( i_audiotrack_us > 0 )
     {



More information about the vlc-commits mailing list