<!doctype html><html><head>
<title></title>
<style type="text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style>
</head>
<body>I don't perceive a catch-22 at all. If the dejitter delay is accounted by the clock, which it obviously should, then everything should work as things stand.<br>
<br>
There is the corner case that the dejitter is too short to begin with, and audio is not master, but then I would argue that skipping ahead is the right thing. <br><br><div class="gmail_quote">Le 2 juillet 2018 18:35:14 GMT+03:00, Thomas Guillem <thomas@gllm.fr> a écrit :<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div>On Wed, Jun 27, 2018, at 15:59, Rémi Denis-Courmont wrote:<br></div>
<blockquote type="cite"><div>The patch description makes no sense to me, because it describes the existing state before the patch.<br></div>
</blockquote><div><br></div>
<div>Indeed, the commit message is not that good. I'll try to improve it. In the meantime, here is what I tried to fix:<br></div>
<div><br></div>
<blockquote type="cite"><div><br></div>
<div>Besides, there are no problems with output not starting corked, as long as the output knows its latency immediately. Not all but several outputs can probably start corked (i.e. paused), but they might not need to.<br></div>
<div><br></div>
<div>The issue is PulseAudio has no latency estimate at start, so it needs to postpone start. This is more generic for the users: it can cope with fringe sink sorts. But for our purpose as developers, it is just an inconvenience of PulseAudio.<br></div>
<div><br></div>
<div>But really the assumption is that one of the following is true:<br></div>
<div>1) latency is known immediately (e.g. ALSA),<br></div>
</blockquote><div><br></div>
<div>There is a chicken-egg situation with such modules (e.g ALSA):<br></div>
<div>Before this patch (and in the clock branch), the clock was updated after the first time_get(), so it took only the audio delay into account, not the dejitter value from the output clock. To take into account the dejitter, you need to do (what this patch is doing):<br></div>
<div> <br></div>
<div>- First, and if the delay is OK, convert the pts from now + delay:<br></div>
<div>    vlc_tick_t system_pts = vlc_clock_ConvertToSystem(owner->sync.clock, system_now + delay, block->i_pts);<br></div>
<div><br></div>
<div>- Compare this value with now: if it's positive, you need to silence the aout (so, the dejitter value approximately)<br></div>
<div><br></div>
<div>    vlc_tick_t silence_delay = system_pts - system_now;<br></div>
<div>    if (silence_delay > 0)<br></div>
<div>       aout_DecSilence (aout, silence_delay, block->i_pts);<br></div>
<div><br></div>
<div>- Get the new delay, and do go the original code path (aout_RequestRetiming()):<br></div>
<div><br></div>
<div>    if (aout->time_get(aout, &delay) == 0)<br></div>
<div>        aout_RequestRetiming(aout, system_now + delay, block->i_pts);<br></div>
<div><br></div>
<div>This delay will take into account the audio device latency (if the aout module permits it) and the dejitter value from the clock.<br></div>
<div><br></div>
<blockquote type="cite"><div>2) latency is signaled asynchronously when it becomes available (e.g. PulseAudio), or<br></div>
<div>3) latency is irrelevant (e.g. file).<br></div>
<div><br></div>
<div>And with that, I don't follow what this patch does, other than make the existing code more intricate.<br></div>
<div><br></div>
<div><div>Le 27 juin 2018 15:41:34 GMT+03:00, Thomas Guillem <thomas@gllm.fr> a écrit :<br></div>
<blockquote style="margin-top:0pt;margin-right:0pt;margin-bottom:0pt;margin-left:0.8ex;border-left-color:rgb(204, 204, 204);border-left-style:solid;border-left-width:1px;padding-left:1ex;"><pre><div>The idea here is a play a silence corresponding to the difference between the<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>first system pts and now. This will be used for aouts that can't start corked,<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>so every aout modules except PulseAudio. To reach this new code path, aout<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>modules need to return a valid value from the first pf_get_time callback<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>(already the case of main modules).<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>---<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> src/audio_output/aout_internal.h |  1 +<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> src/audio_output/dec.c           | 54 ++++++++++++++++++++++----------<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> 2 files changed, 38 insertions(+), 17 deletions(-)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div><br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>index 55fab1a7e9..42d0f1ff35 100644<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>--- a/src/audio_output/aout_internal.h<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+++ b/src/audio_output/aout_internal.h<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>@@ -72,6 +72,7 @@ typedef struct<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> <br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     struct<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     {<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+        bool is_first;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>         vlc_tick_t end; /**< Last seen PTS */<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>         struct vlc_clock_t *clock;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>         float rate; /**< Play-out speed rate */<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>index 523682e619..8a2808c5a0 100644<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>--- a/src/audio_output/dec.c<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+++ b/src/audio_output/dec.c<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>@@ -102,6 +102,7 @@ error:<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>         return -1;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     }<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> <br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    owner->sync.is_first = true;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     owner->sync.rate = 1.f;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     owner->sync.end = VLC_TS_INVALID;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     owner->sync.resamp_type = AOUT_RESAMPLING_NONE;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>@@ -229,8 +230,8 @@ static void aout_DecSilence (audio_output_t *aout, vlc_tick_t length, vlc_tick_t<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>                vlc_clock_ConvertToSystem(owner->sync.clock, vlc_tick_now(), pts));<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> }<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> <br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-static void aout_DecSynchronize(audio_output_t *aout, vlc_tick_t system_now,<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-                                vlc_tick_t dec_pts)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+static vlc_tick_t aout_DecSynchronize(audio_output_t *aout, vlc_tick_t system_now,<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+                                   block_t *block)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> {<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     /**<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>      * Depending on the drift between the actual and intended playback times,<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>@@ -248,11 +249,39 @@ static void aout_DecSynchronize(audio_output_t *aout, vlc_tick_t system_now,<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>      * all samples in the buffer will have been played. Then:<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>      *    pts = vlc_tick_now() + delay<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>      */<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    aout_owner_t *owner = aout_owner (aout);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     vlc_tick_t delay;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    if (aout->time_get(aout, &delay) != 0)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-        return; /* nothing can be done if timing is unknown */<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    if (aout->time_get(aout, &delay) == 0)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    {<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+        if (owner->sync.is_first)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+        {<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+            vlc_tick_t system_pts =<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+                vlc_clock_ConvertToSystem(owner->sync.clock, system_now + delay,<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+                                          block->i_pts);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+            vlc_tick_t silence_delay = system_pts - system_now;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+            if (silence_delay > 0)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+                aout_DecSilence (aout, silence_delay, block->i_pts);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+            if (aout->time_get(aout, &delay) == 0)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+                aout_RequestRetiming(aout, system_now + delay, block->i_pts);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+        }<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+        else<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+            aout_RequestRetiming(aout, system_now + delay, block->i_pts);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    }<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    if (owner->sync.delay != 0)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    {<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+        block->i_pts += owner->sync.delay;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+        block->i_dts += owner->sync.delay;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    }<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> <br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    aout_RequestRetiming(aout, system_now, dec_pts - delay);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    vlc_tick_t system_pts = vlc_clock_ConvertToSystem(owner->sync.clock, system_now,<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+                                                   block->i_pts);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    owner->sync.end = block->i_pts + block->i_length + 1;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    owner->sync.discontinuity = false;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    owner->sync.is_first = false;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    return system_pts;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> }<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> <br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> void aout_RequestRetiming(audio_output_t *aout, vlc_tick_t system_ts,<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>@@ -397,20 +426,10 @@ int aout_DecPlay(audio_output_t *aout, block_t *block)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     }<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> <br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     /* Drift correction */<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    vlc_tick_t system_now = vlc_tick_now();<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    aout_DecSynchronize(aout, system_now, block->i_pts);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    if (owner->sync.delay != 0)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    {<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-        block->i_pts += owner->sync.delay;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-        block->i_dts += owner->sync.delay;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    }<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    vlc_tick_t system_pts = aout_DecSynchronize(aout, vlc_tick_now(), block);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> <br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     /* Output */<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    owner->sync.end = block->i_pts + block->i_length + 1;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    owner->sync.discontinuity = false;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-    aout->play(aout, block, vlc_clock_ConvertToSystem(owner->sync.clock, system_now,<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>-                                                      block->i_pts));<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    aout->play(aout, block, system_pts);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     atomic_fetch_add_explicit(&owner->buffers_played, 1, memory_order_relaxed);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     return ret;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> drop:<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>@@ -473,6 +492,7 @@ void aout_DecFlush (audio_output_t *aout, bool wait)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> {<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     aout_owner_t *owner = aout_owner (aout);<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div> <br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>+    owner->sync.is_first = true;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     owner->sync.end = VLC_TS_INVALID;<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     if (owner->mixer_format.i_format)<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
<div>     {<br></div>
<div>
<br></div>
<div>
<br></div>
<div>
<br></div>
</pre></blockquote></div>
<div><br></div>
<div>--<br></div>
<div>Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté. <br></div>
<div><u>_______________________________________________</u><br></div>
<div>vlc-devel mailing list<br></div>
<div>To unsubscribe or modify your subscription options:<br></div>
<div><a href="https://mailman.videolan.org/listinfo/vlc-devel">https://mailman.videolan.org/listinfo/vlc-devel</a><br></div>
</blockquote><div><br></div>


</blockquote></div><br>
-- <br>
Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.</body></html>