[vlc-commits] [Git][videolan/vlc][master] input: es_out: reset buffering on PCR discontinuity

Steve Lhomme (@robUx4) gitlab at videolan.org
Tue Mar 14 09:50:54 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
07d8bc70 by Alexandre Janniaux at 2023-03-14T09:24:17+00:00
input: es_out: reset buffering on PCR discontinuity

When PCR discontinuities happens, the whole pipeline is reset and it
safely (though after a glitch) reset back to playback on what's visible
after the PCR discontinuities, and restart buffering.

However, this PCR discontinuity currently happens only when **not** in
buffering. When it happens during buffering, then:

 - either the PCR value is much bigger than expected, and buffering will
   stop sooner than expected.

    | Buffer start      Buffer end    New PCR
    | v                          v    v
    | |------.-------------------|    |
    |        ^
    | Old PCR  |----------------------|
    |             Missing buffering
    +-- Resulting buffer after PCR jump to the future.

 - or the PCR value is much smaller than expected, and the buffering is
   completely borked, the computed stream buffer duration is negative
   and it would buffer for the time of the

    | New PCR         Buffer start     Buffer  end
    | v               v                          v
    | |---------------|------.-------------------|
    |                        ^
    |                 Old PCR
    |
    |              Total buffering:
    |
    |  Buffering after the PCR jump
    | |------------------------------------------|
    |                    +
    |                 |------|
    |                 Previous additional buffering
    |
    +-- Resulting buffer after PCR jump to the past.

The second behaviour can be visible when disabling the __MAX for the
caching progress value, leading to logs like:

    [000055df326370e0] main input debug: Buffering 0%
    [000055df326370e0] main input debug: Buffering 1%
    [000055df326370e0] main input debug: Buffering 2%
    [000055df326370e0] main input debug: Buffering 3%
    [000055df326370e0] main input debug: Buffering 4%
    [000055df326370e0] main input debug: Buffering 5%
    [000055df326370e0] main input debug: Buffering 6%
    [000055df326370e0] main input debug: Buffering 7%
    [000055df326370e0] main input debug: Buffering -99%
    [000055df326370e0] main input debug: Buffering -98%
    ...

Such scenario can be created by streaming a .ts file with the option
--ts-trust-pcr on udp://127.0.0.1:1234 for instance, while running
ffmpeg with:

    ffmpeg -re -i input_file.ts -f mpegts udp://127.0.0.1:1234

During buffering, interrupt and restart the ffmpeg streaming command.
The value in --network-caching can also be increase to ensure easier
reproduction of the scenario.

Instead, if PCR is going back to the past, flush the pipeline and reset
the buffering back to zero to avoid waiting for the stream to catch-up
with the old reference, and avoid buffering more than what we requested,
which would shift the playback more from the live.

    | - Step 1:
    | New PCR         Buffer start     Buffer  end
    | v               v                          v
    | |---------------|------.-------------------|
    |                        ^
    |                 Old PCR
    |
    | - Step 2:
    |                 Previous buffering is dropped.
    |                 |------|
    | |--------------------------|
    | ^                          ^
    | New PCR                    New buffer end
    |
    |
    +-- New buffering behaviour when PCR jumps to the past.

- - - - -


1 changed file:

- src/input/es_out.c


Changes:

=====================================
src/input/es_out.c
=====================================
@@ -974,6 +974,17 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
                                   &i_stream_duration, &i_system_duration ))
         return;
 
+    /* If demux signals PCR going back in time while we were buffering,
+     * we want to reset the pipeline, and reset buffering back to zero
+     * so that we don't compare a reference from the future against
+     * values from the past, which could artifically and arbitrarily
+     * increase the buffering duration. */
+    if (i_stream_duration < 0)
+    {
+        EsOutChangePosition(out, true, NULL);
+        return;
+    }
+
     vlc_tick_t i_preroll_duration = 0;
     if( p_sys->i_preroll_end >= 0 )
         i_preroll_duration = __MAX( p_sys->i_preroll_end - i_stream_start, 0 );



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/07d8bc705da7fbb84344340d91504840b3300674

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/07d8bc705da7fbb84344340d91504840b3300674
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