We need to take into account the base_ts to compute next_ts and it needs
to be updated on rate change.
This introduces `pending_rate` so that change rate is properly handled
in the streaming thread in a safe way.
Added tests
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/679>
Stop comparing all timestamps from buffers that are before the segment
with the segment.stop and compare with the actual end times.
Comparing to segment.stop for all the buffers that where before
the segment.stop was incorrect and leading to consuming wrong buffers
and not respecting segment.stop, this is now properly tested.
Expectations for `reverse.10_to_1fps.validatetest` have been fixed to
take that into account and comparing the checksums of the sinkpad and
srcpad expectations makes pretty clear how wrong that was.
(we can see in the expectations that videotestsrc outputs an extra
buffer with pts == segment.stop and this one is now properly dropped
by videorate as bec7f4ad5e aimed at
doing)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/668>
And fix reverse playback buffer duration computation as in reverse
playback, buffer duration is prev_buffer.pts - buffer.pts not pts -
next_pts (buffers are displayed from buffer.pts + buffer.duration for
a duration of buffers.duration).
This is now tested with the `validate.test.clock_sync.videorate.*`
tests in the default integration testsuite where we check the exact
data flow and the synchronization on the clock behaviour with a
TestClock.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/646>
Previously configured bufferpool can be expired/inactivate by the
updated caps. Therefore new reconfigure event should be signalled in order to
do allocation query dancing between upstream and downstream again.
Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/730
Previously this would've only set discont=TRUE and then for all future
buffers simply returned immediately.
Instead we also need to
a) drain previous input until its buffer time
b) update next_ts and base_ts accordingly for the gap
c) actually store the new buffer after the gap so it can be used in
the future and so the old buffer before the gap is gone
Also update the unit test accordingly so that it actually tests for this
behaviour. Previously it only tested that after the gap we got no output
at all.
This will only duplicate buffers if the gap between two consecutive
buffers is up to fill-until nsec. If it's larger, it will only output
the new buffer and mark it as discont.
Instead go backwards before segment.stop based on the framerate or the
next buffers end timestamp. Otherwise the first buffer will usually be
dropped because outside the segment.
https://bugzilla.gnome.org/show_bug.cgi?id=781899
gst_video_rate_flush_prev() ensures that the pushed buffer is writable
by calling gst_buffer_make_writable() on videorate->prevbuf.
In drop-only mode we always push buffers directly when they are received
from GstBaseTransform (gst_video_rate_transform_ip()) and do not keep them
around. GstBaseTransform already ensures that those buffers are
writable so there is no need to do it twice.
This change saves us from copying buffers in drop-only mode as we no longer
calls gst_buffer_make_writable() with a buffer having a refcount of 2
(one ref owned by GstBaseTransform and one in videorate->prevbuf).
https://bugzilla.gnome.org/show_bug.cgi?id=780767
Instead go backwards before segment.stop based on the framerate or the
next buffers end timestamp. Otherwise the first buffer will usually be
dropped because outside the segment.
https://bugzilla.gnome.org/show_bug.cgi?id=781899
The latency query originally had a fallthrough to the default
label at the end as fallback, but that got messed up when the
DURATION and POSITION queries were added, so it then fell through
to the duration query handler instead. Restore original behaviour.
https://bugzilla.gnome.org/show_bug.cgi?id=699077
Duration query would return TRUE and duration=-1. This
worked in the unit test because the unit test implementation
was a bit broken.
Both queries need to access rate with a lock.
Fix broken duration query test as well. It relied on broken
behaviour by the videorate query handler, and also it was
implemented as a downstream query rather than an upstream
query. And we must return HANDLED from the probe so that the
query we intercept actually returns TRUE.
https://bugzilla.gnome.org/show_bug.cgi?id=699077
This is enough for making it work in GES, but it's unclear if all the various
property combinations are working correctly. It's an improvement over what was
there before in any case, which was to just drop all buffers if rate < 0.0.
https://bugzilla.gnome.org/show_bug.cgi?id=769624
Make writable the buffer before pushing it lead to a buffer copy. It's
because a reference is keep for the previous buffer.
The previous buffer reference is only need to duplicate the buffer. In
drop-only mode, the previous buffer is release just after pushing the
buffer so a copy is done but it's useless.
https://bugzilla.gnome.org/show_bug.cgi?id=764319
Since the loops increasing count from 0 are always run at least
once (if count < 1), count will always be at least one when
compared to the drop/dup conditions.
Coverity 1139674
Since the videorate element just duplicates or drops frames
to achieve the desired framerate, it can accept video/x-bayer media
(in any format), which are not present in the current caps.
Just add "video/x-bayer(ANY);" to the caps of the static pad template
(fixing line style to pass the indent commit hook).
https://bugzilla.gnome.org/show_bug.cgi?id=753483
When a stream has a variable framerate, videorate calculates it and
forces it on the output caps. However, the code in _transform_caps()
currently also does that if the transform is going in the opposite
direction (GST_PAD_SRC), so during a renegotiation it tries to force
upstream to use the calculated framerate and it fails.
https://bugzilla.gnome.org/show_bug.cgi?id=750032
In case upstream does not provide videorate with framerate information,
it will detect the current framerate from the buffer it received,
but if downstream forces the use of variable framerate (most probably
through the use of a caps filter with framerate = 0 / 1), videorate will
respect that.
And add some unit tests
https://bugzilla.gnome.org/show_bug.cgi?id=734424
In the case the framerate is variable (represented by framerate=0/1),
we currently end up loop pushing the first buffer and then recompute
diff1 and diff2 without updating the videorate->next_ts at all
leading to infinitely looping pushing that first buffer.
In the case of variable framerate, we should just compute the next_ts
as previous_pts + previous_duration.
https://bugzilla.gnome.org/show_bug.cgi?id=734424
VideRate keeps 1 buffer in order to duplicate base on closest buffer
relative to targeted time. This extra buffer need to be request
otherwise the pipeline may stall when fixed size buffer pool is used.
https://bugzilla.gnome.org/show_bug.cgi?id=738302
There's no reason why we would have to wait for the next buffer to decide
whether to output the current one or not. We just have to check if the
current one is earlier than our expected next time, which is the previous
frame timestamp plus the expected frame duration.
https://bugzilla.gnome.org/show_bug.cgi?id=740018
They are very confusing for people, and more often than not
also just not very accurate. Seeing 'last reviewed: 2005' in
your docs is not very confidence-inspiring. Let's just remove
those comments.