[vlc-devel] workaround audio drops on openbsd

Alexandre Ratchov alex at caoua.org
Mon Apr 15 22:11:22 CEST 2013


On OpenBSD audio DMA starts slightly after samples to play are
submitted by VLC to the audio layer. It may take up to ~150ms in
the worst cases, depending on user setup, and can't be avoided.

The initial delay makes VLC think that audio plays way too slow and
triggers up-sampling. In certain cases, VLC may call the
aout->flush() method to resync, but it takes some time (to drain)
which introduces additional delay and makes things yet worse.

I've tried various aproaches to solve the problem but neither is
100% satisfying:

(1) dropping the first audio chunk to compensate the delay hurts
    playback of music starting immediately

(2) cheating in aout->time_get() and reporting a slightly smaller
    time position just works, but video ends up slightly ahead of
    audio. In most cases, this is hardly perceptible though, hence
    the proposed diff.

Is there a way to "shift" VLC time reference, or to make it use
aout->time_get() as clock reference? Other suggestions?

If not, the diff below implements (2), which is the least worst
option in my opinion.


-- Alexandre

diff --git a/modules/audio_output/sndio.c b/modules/audio_output/sndio.c
index a60c309..7139e25 100644
--- a/modules/audio_output/sndio.c
+++ b/modules/audio_output/sndio.c
@@ -59,6 +59,7 @@ struct aout_sys_t
     unsigned rate;
     unsigned volume;
     bool mute;
+    mtime_t init_time, start_time;
 /** Initializes an sndio playback stream */
@@ -193,6 +194,7 @@ static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt)
     sys->delay = 0;
     sio_onmove (sys->hdl, PositionChanged, aout);
     sio_start (sys->hdl);
+    sys->init_time = mdate ();
     return VLC_SUCCESS;
@@ -212,6 +214,8 @@ static void PositionChanged (void *arg, int delta)
     audio_output_t *aout = arg;
     aout_sys_t *sys = aout->sys;
+    if (!sys->started)
+	sys->start_time = mdate ();
     sys->delay -= delta;
     sys->started = 1;
@@ -222,7 +226,8 @@ static int TimeGet (audio_output_t *aout, mtime_t *restrict delay)
     if (!sys->started)
 	return -1;
-    *delay = (mtime_t)sys->delay * CLOCK_FREQ / sys->rate;
+    *delay = (mtime_t)sys->delay * CLOCK_FREQ / sys->rate +
+	sys->init_time - sys->start_time;
     return 0;
@@ -242,6 +247,7 @@ static void Flush (audio_output_t *aout, bool wait)
     sio_stop (sys->hdl);
     sys->started = 0;
     sys->delay = 0;
+    sys->init_time = mdate ();
     sio_start (sys->hdl);

More information about the vlc-devel mailing list