[vlc-commits] [Git][videolan/vlc][master] 5 commits: pulse: use vlc_pa_get_latency() directly when draining

Thomas Guillem (@tguillem) gitlab at videolan.org
Wed Apr 6 08:17:33 UTC 2022



Thomas Guillem pushed to branch master at VideoLAN / VLC


Commits:
0ee0dcf3 by Thomas Guillem at 2022-04-06T07:39:59+00:00
pulse: use vlc_pa_get_latency() directly when draining

TimeGet() check the corked state, but the stream is always uncorked here.

- - - - -
f3e0be3a by Thomas Guillem at 2022-04-06T07:39:59+00:00
pulse: move drain_trigger_cb up

To avoid forward declaration in a future commit.

- - - - -
bfde0977 by Thomas Guillem at 2022-04-06T07:39:59+00:00
pulse: add TriggerDrain()

- - - - -
08486a0b by Thomas Guillem at 2022-04-06T07:39:59+00:00
pulse: fix drain with small samples

vlc_pa_get_latency() might return an invalid tick ("no timing info")
when the stream was just uncorked from the Drain callback.

To fix this issue, setup the drain timer from the latency callback when
the stream is draining.

- - - - -
da102673 by Thomas Guillem at 2022-04-06T07:39:59+00:00
pulse: fix drain report if no samples

Report that the stream is drained if play was never called or in case of
overflow.

- - - - -


1 changed file:

- modules/audio_output/pulse.c


Changes:

=====================================
modules/audio_output/pulse.c
=====================================
@@ -67,6 +67,7 @@ typedef struct
     pa_threaded_mainloop *mainloop; /**< PulseAudio thread */
     pa_time_event *trigger; /**< Deferred stream trigger */
     pa_time_event *drain_trigger; /**< Drain stream trigger */
+    bool draining;
     pa_cvolume cvolume; /**< actual sink input volume */
     vlc_tick_t last_date; /**< Play system timestamp of last buffer */
 
@@ -85,6 +86,37 @@ static void VolumeReport(audio_output_t *aout)
     aout_VolumeReport(aout, (float)volume / PA_VOLUME_NORM);
 }
 
+static void drain_trigger_cb(pa_mainloop_api *api, pa_time_event *e,
+                              const struct timeval *tv, void *userdata)
+{
+    audio_output_t *aout = userdata;
+    aout_sys_t *sys = aout->sys;
+
+    assert(sys->drain_trigger == e);
+
+    vlc_pa_rttime_free(sys->mainloop, sys->drain_trigger);
+    sys->drain_trigger = NULL;
+    sys->draining = false;
+
+    aout_DrainedReport(aout);
+    (void) api; (void) e; (void) tv;
+}
+
+static int TriggerDrain(audio_output_t *aout)
+{
+    aout_sys_t *sys = aout->sys;
+    assert(sys->drain_trigger == NULL);
+
+    vlc_tick_t delay = vlc_pa_get_latency(aout, sys->context, sys->stream);
+    if (delay == VLC_TICK_INVALID)
+        return VLC_EGENERIC;
+
+    delay += pa_rtclock_now();
+    sys->drain_trigger = pa_context_rttime_new(sys->context, delay,
+                                               drain_trigger_cb, aout);
+    return sys->drain_trigger ? VLC_SUCCESS : VLC_ENOMEM;
+}
+
 /*** Sink ***/
 static void sink_add_cb(pa_context *ctx, const pa_sink_info *i, int eol,
                         void *userdata)
@@ -258,7 +290,11 @@ static void stream_latency_cb(pa_stream *s, void *userdata)
 
     /* This callback is _never_ called while paused. */
     if (sys->last_date == VLC_TICK_INVALID)
+    {
+        if (sys->draining && sys->drain_trigger == NULL)
+            TriggerDrain(aout);
         return; /* nothing to do if buffers are (still) empty */
+    }
     if (pa_stream_is_corked(s) > 0)
         stream_start(s, aout, sys->last_date);
 }
@@ -561,6 +597,7 @@ static void Flush(audio_output_t *aout)
     {
         vlc_pa_rttime_free(sys->mainloop, sys->drain_trigger);
         sys->drain_trigger = NULL;
+        sys->draining = false;
     }
 
     pa_operation *op = pa_stream_flush(s, NULL, NULL);
@@ -572,21 +609,6 @@ static void Flush(audio_output_t *aout)
     pa_threaded_mainloop_unlock(sys->mainloop);
 }
 
-static void drain_trigger_cb(pa_mainloop_api *api, pa_time_event *e,
-                              const struct timeval *tv, void *userdata)
-{
-    audio_output_t *aout = userdata;
-    aout_sys_t *sys = aout->sys;
-
-    assert(sys->drain_trigger == e);
-
-    vlc_pa_rttime_free(sys->mainloop, sys->drain_trigger);
-    sys->drain_trigger = NULL;
-
-    aout_DrainedReport(aout);
-    (void) api; (void) e; (void) tv;
-}
-
 static void Drain(audio_output_t *aout)
 {
     aout_sys_t *sys = aout->sys;
@@ -611,21 +633,18 @@ static void Drain(audio_output_t *aout)
     pa_operation *op = pa_stream_drain(s, NULL, NULL);
     if (op != NULL)
         pa_operation_unref(op);
-    sys->last_date = VLC_TICK_INVALID;
 
-    /* XXX: Loosy drain emulation.
-     * See #18141: drain callback is never received */
-    assert(sys->drain_trigger == NULL);
-    vlc_tick_t delay;
-    if (TimeGet(aout, &delay) == 0)
+    if (sys->last_date == VLC_TICK_INVALID)
+        aout_DrainedReport(aout);
+    else
     {
-        delay += pa_rtclock_now();
-        sys->drain_trigger = pa_context_rttime_new(sys->context, delay,
-                                                   drain_trigger_cb, aout);
-    }
+        sys->last_date = VLC_TICK_INVALID;
 
-    if (sys->drain_trigger == NULL)
-        aout_DrainedReport(aout);
+        /* XXX: Loosy drain emulation.
+         * See #18141: drain callback is never received */
+        sys->draining = true;
+        TriggerDrain(aout);
+    }
 
     pa_threaded_mainloop_unlock(sys->mainloop);
 }
@@ -854,6 +873,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
     }
 
     sys->trigger = sys->drain_trigger = NULL;
+    sys->draining = false;
     pa_cvolume_init(&sys->cvolume);
     sys->last_date = VLC_TICK_INVALID;
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ff5e2f7b8846d80b588fb649b22eccf7269dd179...da10267380f046c6af34bdd8f586fedfd24fd4d5

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ff5e2f7b8846d80b588fb649b22eccf7269dd179...da10267380f046c6af34bdd8f586fedfd24fd4d5
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list