[vlc-devel] [PATCH] aout: play the silence buffer on most modules

Thomas Guillem thomas at gllm.fr
Thu Aug 15 13:01:46 CEST 2019


Add a new capability: aout->module_info.can_play_at_date, only set by Pulse
(for now) since it is the only module that can handle a play_date != system_now.

This capability is checked by the aout core in order to tell if it should first
play a silence buffer (that has the same length than the jitter delay).

Before this commit, I assumed that a module could need a silence buffer only if
it returned a valid delay before the first play. This assumption is now false,
cf. the coreaudio case here: bdd96900164739b72220334bdbda511aff708caa. I plan
do to the same for the Android aout module: return a delay only when it is
really known but don't handle play_date.

For info: returning a delay before the first play could trigger frame drops (or
audio flush/resampling if audio is not the master) once the delay is really
known (and too far from the first returned delay).
---
 include/vlc_aout.h           |  9 ++++++++-
 modules/audio_output/pulse.c |  1 +
 src/audio_output/dec.c       | 18 +++++++++++++-----
 src/audio_output/output.c    |  1 +
 4 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index 43fbf2f120..74d51c2335 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -190,7 +190,8 @@ struct audio_output
     /**< Queues a block of samples for playback (mandatory, cannot be NULL).
       *
       * \param block block of audio samples
-      * \param date intended system time to render the first sample
+      * \param date intended system time to render the first sample. Should be
+      * used only if module_info.can_play_at_date is true
       *
       * \note This callback cannot be called in stopped state.
       */
@@ -257,6 +258,12 @@ struct audio_output
       * \warning The same constraints apply as with volume_set().
       */
 
+    struct {
+        bool can_play_at_date;
+        /**< Default to false, set it to true if the module can play an audio
+         * buffer at a given date (in the future) */
+    } module_info;
+
     struct {
         bool headphones; /**< Default to false, set it to true if the current
                               sink is using headphones */
diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c
index fba8fd6840..e7f95fd5da 100644
--- a/modules/audio_output/pulse.c
+++ b/modules/audio_output/pulse.c
@@ -1038,6 +1038,7 @@ static int Open(vlc_object_t *obj)
     aout->volume_set = VolumeSet;
     aout->mute_set = MuteSet;
     aout->device_select = StreamMove;
+    aout->module_info.can_play_at_date = true;
 
     pa_threaded_mainloop_lock(sys->mainloop);
     /* Sinks (output devices) list */
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
index e0c9f32b7e..7ebfedb746 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -268,12 +268,18 @@ static void aout_DecSynchronize(audio_output_t *aout, vlc_tick_t system_now,
      *    pts = vlc_tick_now() + delay
      */
     aout_owner_t *owner = aout_owner (aout);
+    bool delay_valid;
     vlc_tick_t delay;
 
-    if (aout->time_get(aout, &delay) != 0)
-        return; /* nothing can be done if timing is unknown */
+    if (aout->time_get(aout, &delay) == 0)
+        delay_valid = true;
+    else
+    {
+        delay_valid = false;
+        delay = 0;
+    }
 
-    if (owner->sync.discontinuity)
+    if (owner->sync.discontinuity && !aout->module_info.can_play_at_date)
     {
         /* Chicken-egg situation for most aout modules that can't be started
          * deferred (all except PulseAudio). These modules will start to play
@@ -291,11 +297,13 @@ static void aout_DecSynchronize(audio_output_t *aout, vlc_tick_t system_now,
         if (jitter > 0)
         {
             aout_DecSilence (aout, jitter, dec_pts - delay);
-            if (aout->time_get(aout, &delay) != 0)
-                return;
+            delay_valid = aout->time_get(aout, &delay) == 0;
         }
     }
 
+    if (!delay_valid)
+        return; /* nothing can be done if timing is unknown */
+
     aout_RequestRetiming(aout, system_now + delay, dec_pts);
 }
 
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index 5c378dbb31..212164f7bf 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -242,6 +242,7 @@ audio_output_t *aout_New (vlc_object_t *parent)
     aout->volume_set = NULL;
     aout->mute_set = NULL;
     aout->device_select = NULL;
+    aout->module_info.can_play_at_date = false;
     owner->module = module_need_var(aout, "audio output", "aout");
     if (owner->module == NULL)
     {
-- 
2.20.1



More information about the vlc-devel mailing list