If we switch to the fallback stream but the last buffering activity was
less than $timeout ago, we shouldn't restart the source yet but wait a
bit longer. However for that we actually need to schedule another
timeout, which was not happening before.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/116
It will take a moment for the fallbackswitch to actually switch to the
main stream. So instead take into account the time since the last
buffering update even when we reached 100%, and don't reset that time
when reaching 100%.
It might be a second stream collection that we receive at a later time,
and the previous pads would already be unblocked at that point. So block
all currently unblocked pads again and then adjust the offset
according to the new situation.
This fixes playback of various RTMP streams where usually we first get a
stream collection with only one of the two streams, and shortly
afterwards with both streams.
This works as an alternative to the "uri" property, which would use an
`uridecodebin3` element.
The provided source element can have static audio/video pads or provide
them as sometimes pad while signalling no-more-pads or a stream
collection message once all pads are available.
They were already converted to the running time a few lines above and
updated inside the buffer. Converting another time for the timeout
causes the timeout to happen at the wrong time, usually much later than
it should.
Test was relying on 'blocksize' property on the source which can
only be used in push mode.
This change in baseparse broke it:
e906197c62
so ensure we are actually in push mode by using pushfilesrc.
When initializing Pad functions in `Pad{Src,Sink}`, we downgrade the
`Pad{Src,Sink}` and upgrade it when necessary. This was implemented
to avoid reference cycles:
`gst::Pad` -> pad function -> `Pad{Src,Sink}` -> `gst::Pad`.
Since `Pad{Src,Sink}` reset the pad functions when dropping, there is
no cycles, so we can use an `Arc<Pad{Src,Sink}>` in the pad functions,
thus saving an `upgrade`.
This is a wrapper around uridecodebin3 and fallbackswitch that allows to
switch to a still frame on errors and automatically retries the source
in the background on errors until a given retry timeout is reached.
- Report a latency:
By design, tttocea608 will output buffers in the "past" when
receiving an input buffer: we want the second to last buffer
in the buffer list that we output to have the same pts as the
input buffer, as it contains the end_of_caption control code
which determines when the current closed caption actually gets
displayed in pop_on mode. The previous buffers have timestamps
decreasing as a function of the framerate, for up to potentially
74 byte pairs (the breakdown is detailed in a comment).
The element thus has to report a latency, at 30 frames per second
it represents around 2.5 seconds.
- Refactor timestamping:
Stop using a frame duration, but rather base our timestamps on
a scaled frame index. This is to avoid rounding errors, and
allow for exactly one byte pair per buffer if the proper framerate
is set on the closed caption branch, and the video branch has
perfect timestamps, eg videorate. In practice, that one byte
pair per frame requirement should only matter for line 21 encoding,
but we have to think about this use case too.
- Splice in erase_display_memory:
When there is a gap between the end of a buffer and the start
of the next one, we want to erase the display memory (this
is unnecessary otherwise, as the end_of_caption control code
will in effect ensure that the display is erased when the
new caption is displayed). The previous implementation only
supported this imperfectly, as it could cause timestamps to
go backwards.
- Output last erase_display_memory:
The previous implementation was missing the final
erase_display_memory on EOS
- Output gaps
- Write more tests
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/314>
This is similar to what the standard jitterbuffer does, and
is necessary to avoid deadlocks with the rtpbin session lock,
if the user calls onto any API that requires us to take the
state lock at the wrong time (eg setting the latency property,
clearing the pt map)
They're actually used as a hackish intrusive list around GQueue so using
a different allocator is rather dangerous. Or rather, this is generally
dangerous and shouldn't be done but ...
Also make sure to free items manually in finalize() so that any
contained buffers can also be unreffed.