[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