Skip to content

Fix timestamping and clock synchronization in reverse playback

Thibault Saunier requested to merge thiblahute/gstreamer:reverse_playback into master

See individual commit messages.

Tests were added in gst-integration-testsuites!71 (closed)

commit 74a962d591f178774ee4203d9c5b3ae4d32782bb (HEAD -> reverse_playback, thiblahute/reverse_playback)
Author: Thibault Saunier <tsaunier@igalia.com>
Date:   Tue Apr 28 13:28:32 2020 -0400

    identity: Fix timestamping inside single segment in reverse playback
    
    In reverse playback, buffers are played back from buffer.stop
    (buffer.pts + buffer.duration) to buffer.pts running times which
    mean that we need to use the buffer end running time as a buffer
    timestsamp, not the buffer pts when using a single segment in reverse
    playback.
    
    This is now being tested in
    `validate.test.identity.reverse_single_segment`

commit 076be71578da281a6c6a1a6bc9d3e63ec95ff6ad (HEAD -> reverse_playback, thiblahute/reverse_playback)
Author: Thibault Saunier <tsaunier@igalia.com>
Date:   Thu Apr 23 16:24:15 2020 -0400

    basesink: Fix clock synchronization running time in reverse playback
    
    In reverse playback, buffers have to be displayed at buffer.stop running
    time, otherwise a same set of buffer can't be displayed in the exact opposite
    order to forward playback.
    
    For example, seeking a video stream at 1fps with start=0, stop=5s, rate=1.0
    
    will display the following buffers:
    
      b0.pts = 0s, b0.duration = 1s - at running time = 0s
      b1.pts = 1s, b1.duration = 1s - at running time = 1s
      b2.pts = 2s, b2.duration = 1s - at running time = 2s
      b3.pts = 3s, b3.duration = 1s - at running time = 3s
      b4.pts = 4s, b4.duration = 1s - at running time = 4s
      <wait at EOS for 1second>
    
    Now, playing that reverse with start=0, stop=5s, rate=1.0 has to display
    the following buffers:
    
      b0.pts = 4s, b0.duration = 1s - at running time = 0s
      b1.pts = 3s, b1.duration = 1s - at running time = 1s
      b2.pts = 2s, b2.duration = 1s - at running time = 2s
      b3.pts = 1s, b3.duration = 1s - at running time = 3s
      b4.pts = 0s, b4.duration = 1s - at running time = 4s
      <wait at EOS for 1second>
    
    With the previous code, it reproduced the following:
    
      b0.pts = 4s, b0.duration = 1s - at running time = 1s
      b1.pts = 3s, b1.duration = 1s - at running time = 2s
      b2.pts = 2s, b2.duration = 1s - at running time = 3s
      b3.pts = 1s, b3.duration = 1s - at running time = 4s
      b4.pts = 0s, b4.duration = 1s - at running time = 5s
      <NO WAIT AT EOS AND POST EOS RIGHT AWAY>
    
    This is being tested with the `validate.launch_pipeline.sink.reverse_playback_clock_waits.*`
    set of tests

commit 41f5042c9518e42bbf386f5ca4a80e20098ae9f9
Author: Thibault Saunier <tsaunier@igalia.com>
Date:   Thu Apr 23 16:10:24 2020 -0400

    basesrc: Fix the way position is computed in reverse playback
    
    In reverse playback, buffers are played back from buffer.stop
    (buffer.pts + buffer.duration) to buffer.pts, which means that the
    position after the buffer is consumed is buffer.pts, not buffer.pts -
    buffer.duration.
    
    Without that change, and when `automatic_eos` feature is on,
    we were dropping the last buffers as marking the stream EOS one buffer
    too soon.
    
    This is now being tested extensively by GstValidate in the
    `validate.test.clock_sync.*` set of tests.
Edited by Thibault Saunier

Merge request reports