[vlc-devel] [PATCH 3/3] audiotrack: smooth out the AudioTrack position
Thomas Guillem
thomas at gllm.fr
Tue Apr 14 19:44:53 CEST 2015
It improves delay precision for old devices.
---
modules/audio_output/audiotrack.c | 80 +++++++++++++++++++++++++++++++++++----
1 file changed, 73 insertions(+), 7 deletions(-)
diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c
index 8744647..d1821b9 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 30000 // 30ms
+
static int Open( vlc_object_t * );
static void Close( vlc_object_t * );
static void Stop( audio_output_t * );
@@ -63,6 +66,15 @@ struct aout_sys_t {
uint32_t i_last;
} headpos;
+ /* 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;
@@ -438,6 +450,63 @@ AudioTrack_GetPosition( JNIEnv *env, audio_output_t *p_aout )
- p_sys->headpos.i_initial;
}
+static void
+AudioTrack_ResetSmoothPositionUs( JNIEnv *env, audio_output_t *p_aout )
+{
+ aout_sys_t *p_sys = p_aout->sys;
+ VLC_UNUSED( env );
+
+ 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 ) );
+ if( i_audiotrack_us <= 0 )
+ return 0;
+
+ 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++;
+
+ if( p_sys->smoothpos.i_count >= SMOOTHPOS_SAMPLE_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;
+ msg_Err( p_aout, "AudioTrack_GetSmoothPositionUs: %lld", p_sys->smoothpos.i_us + i_now);
+ }
+ }
+ if( p_sys->smoothpos.i_us != 0 )
+ return p_sys->smoothpos.i_us + i_now;
+ else
+ return 0;
+}
+
static mtime_t
AudioTrack_GetTimestampPositionUs( JNIEnv *env, audio_output_t *p_aout )
{
@@ -512,6 +581,7 @@ AudioTrack_InitDelay( JNIEnv *env, audio_output_t *p_aout )
p_sys->i_samples_written = 0;
p_sys->headpos.i_last = 0;
p_sys->headpos.i_wrap_count = 0;
+ AudioTrack_ResetSmoothPositionUs(env, p_aout );
}
static int
@@ -529,13 +599,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 )
{
@@ -1223,6 +1288,7 @@ Pause( audio_output_t *p_aout, bool b_pause, mtime_t i_date )
JNI_AT_CALL_VOID( play );
CHECK_AT_EXCEPTION( "play" );
p_sys->i_play_time = mdate();
+ AudioTrack_ResetSmoothPositionUs( env, p_aout );
}
}
--
2.1.3
More information about the vlc-devel
mailing list