When switching from a raw stream to an encoded stream we need to make sure the
slot is unlinked, there is code in place for this but it wasn't triggered
because the slot being reconfigured wasn't advertised as linked beforehand.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5126>
Do not attempt to send a streams-selected message when reassigning
an output slot in case upstream signalled that it is handling stream selection.
In this case decodebin3 doesn't keep track of stream
collections (`dbin->collection` is NULL).
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5059>
Setting the input field on the empty slot prevents future linking of it and will
result in flow errors later on.
This was observed in WebKit's MediaStream source element, when it changes the
caps on one of its associated streams, from an encoded format to a raw video
format. The associated stream-id on the sticky stream-start event doesn´t
change, but the element creates a new GstStream with a different ID and sets it
on the stream-start event. Stream parsing is disabled in urisourcebin, so
decodebin3 handles the parsing. Without this patch we would end-up with unlinked
pads in decodebin3 after switching to the raw video format.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5048>
If the GST_MESSAGE_SRC of error message belongs to candidate decoders,
filter the error message and don't forward it as there might be a
following candidate decoder that can be used.
If the GST_MESSAGE_SRC of error message belongs to candidate decoders,
store the latency message and handle it after decoder is accepted.
This is to avoid the selection lock failure if decodebin3 needs to
handle latency message for candidate decoders when sending sticky event.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4677>
Send sticky events to the new created decoder after it switches
to PAUSED state. It it fails, just skip this decoder and try the
next one until finding one that works. Otherwise remove this
failing stream after trying all decoders and no one can work.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4677>
Generating the source element is done when urisourcebin is doing the READY to
PAUSED state change, so it is reasonable to set the new source element to that
state.
This also allows detecting early failures with backing libraries or
hardware (checks done in NULL->READY).
Finally it makes more sense to have an element in READY when attempting to query
information from it (such as SCHEDULING queries or probing live-ness).
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3856>
self->eos was never reset after streamsynchronizer has sent EOS
(except on explicit flush or switching back to PAUSED).
As a result, synchronization was broken if new streams were pushed later
as gst_stream_synchronizer_wait() does not wait if self->eos is set.
Fix this by reseting self->eos on STREAM_START as that means a new
stream is being sent upstream and so a new EOS will follow later on.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4749>
While decodebin3 could handle changes in inputs (ex: changing codecs), there was
still one limitation which was when changing between sources which had
non-intersecting stream types (ex: switching from a video-only source to a
audio-only source). While the decoder *could* change to the proper codec ... it
would carry on using a `DecodebinOutputStream` associated to that stream
type (and therefore with pads with the wrong name).
In order to handle this:
* We notify the `MultiQueueSlot` of the change in `GstStreamType` if it already
had an associated inputstream (ex: the one associated with the static sink
pad)
* We detect such changes on the output of multiqueue as soon as
possible (i.e. when we get the GST_EVENT_STREAM_START for the new stream type)
by discarding the associated output.
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1669
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4703>
When reconfigure_output_stream entry missing decoder path,
requested_selection should been update with what is really
active/selected immdiately with SELECTION_LOCK hold. So
use an optional message return from reconfigure_output_stream
and post it after release SELECTION_LOCK. This can make sure
other thread call to check_slot_reconfiguration will got
a correct requested_selection.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4599>
decodebin3 will do its best to figure out whether a parsebin is required to
process the incoming stream.
The problem is that for push-based stream it could happen that the stream would
not provide any caps, resulting in nothing being linked internally.
Furthermore, there is the possibility that a stream *with* caps would not be
using a TIME segment, which is required for multiqueue to properly work.
In order to fix those two issues, we force the usage of parsebin on push-based
streams:
* When the pad is linked, if upstream can't provide any caps
* When we get a non-TIME segment
Fixes#2521
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4492>
This is a follow-up of the previous commit that enabled support for redirection.
The problem is that the urisourcebin that emitted the error redirection never
produced any pads, and therefore was never linked to decodebin3. This resulted
in the code waiting for that (output) item to finally switch over ... which will
never happen.
The fix is done by removing it early if it was never connected to decodebin3.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4252>
The goal of parsebin is to figure out which elements to link together in order
to provide elementary streams given any random input.
The problem is that deciding whether a given stream should still have more
elements plugged in or not was dependent on ... the presence of compatible
decoders (sic).
Instead of that, if we can't plug anymore elements on a given stream *and* it is
detected as being an elementary stream, expose it.
Fixes#2118
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4231>
If sticky events are present on parsebin source pads, we propagate them to the
multiqueue source pads. Those will be propagated on the new urisourcebin source
pads like in the other code paths.
This ensures that STREAM_START event are present on new source pads. If CAPS
event are also present (not guaranteed), they will also be available.
Fixes#2384
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4203>
Generating the source element is done when uridecodebin is doing the
READY to PAUSED state change, so it is reasonable to set the new source
element to that state.
This also allows detecting early failures with backing libraries or
hardware (checks done in NULL->READY).
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3857>
The goal of the "global" group-id is to fix new inputs that do not come from the
same "source" as others. In order to ensure all "current" streams have the same
group-id we distribute the first valid group-id to all streams.
This commit fixes two issues with that:
* When inputs are unlinked they weren't always properly resetted (it would only
work if parsebin is used, which is no longer the default in
uridecodebin3/playbin3).
* When computing the global group-id, take into account unset
group-id (i.e. GST_GROUP_ID_INVALID).
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1698
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3712>
The number of expected pads was:
* Defaulting to 1
* Or being overriden by GST_MESSAGE_STREAMS_SELECTED
This fails if upstream isn't a selectable source and has multiple streams, and
would therefore cause failures with multi-stream gapless playback
Fixes#1672
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3658>
It is quite possible to have the blocking probe called from different streaming
threads when all expected pads are present.
* Notify all waiters by using g_cond_broadcast instead of g_cond_signal
* Properly remove the probe after waiting
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3658>
Using the "GstBin" flags to check if an adaptive demuxer is streams-aware isn't
a good idea since it prevents using elements which aren't bins.
Instead we see if a collection was posted by the demuxer by the time a pad is
added.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3601>
Make sure that group-id of a given play item are made consistent from the
start (sources) and all the way through the output.
This ensures that we can reliably detect that we have switched to the next play
item on the output of decodebin3 (and we can therefore properly free/release it)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3457>
When shutting down, we want to remove the urisourcebin blocking probes ... but
we also want to propagate a GST_FLOW_FLUSHING upstream (and not
GST_FLOW_NOT_LINKED) to make the upstream task gracefully stop instead of
posting an error message.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3457>
When `is_selection_done` is called, it checks that all the requested streams are
present in the active stream list ...
... except there could very well be a (about to be removed) stream from the
previous selection present.
Therefore filter the list of streams we add to the message by the streams which
are actually requested.
Fixes issues when switching between different stream types (ex: video-only to
audio-only).
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3457>
This was the intention from the start, just took me a few years *cough* to
actually implement it properly.
Gapless is handled by re-using as much as possible the same decoders and sinks
if present, and only pre-rolling switching at the sources level (with buffering
if/when needed).
In order to enable "gapless" playback, the "next" uri should be set at any time
between the moment the `about-to-finish` signal is emitted and the moment the
current play item is done. Previously this could only be done with the signal
emission.
This new implementation also allows "Instantaneous URI switching". This allows a
much faster way of switching playback entries while re-using as many elements as
possible. To enable this set `instant-uri` property to TRUE, the default being
FALSE.
API: instant-uri properties
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2784>
DecodebinInput (and their backing parsebin or identity) are no longer released
when the corresponding sinkpad is unlinked, but when it's released.
The parsebin element will be resetted:
* If incoming caps are incompatible (was the case before)
* Or when unlinking and it was previously pull-based
This opens the way to use decodebin3 with changing inputs (i.e. gapless)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2784>
Introduce the option to have the streams be parsed with `parsebin` for
compatible sources (i.e. which are eligible for buffering in the same way as
before this commit).
By parsing the inputs directly, this allows more accurate buffering control:
* Instead of relying on potential bitrate information coming from somewhere
* and *without* being linked downstream
If `parse-streams` is activated and the stream is eligible for buffering, then a
`multiqueue` will be used on the output of `parsebin` in order to handle the
buffering.
API: `parse-streams`
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2784>
If the incoming streams are already parsed, there is no need to add yet-another
parsebin to process it *IF* that stream is compatible with a decoder or the
decodebin3 output caps.
This only applies if all the following conditions are met:
* The incoming stream can *NOT* do pull-based scheduling
* The incoming stream provides a `GstStream` and `GstStreamCollection`
* The caps are compatible with either the decodebin3 output caps or a decoder
input
If all those conditions are met, a identity element is used instead of a
parsebin element and the same code paths are taken.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2784>
* Instead of creating temporary `PendingPad` structures, always create a
DecodebinInputStream for every pad of parsebin
* Remove never used `pending_stream` field from DecodebinInputStream
* When unblocking a given DecodebinInput (i.e. wrapping a parsebin), also make
sure that other parsebins from the same GstStreamCollection are unblocked
since they come from the same source
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2784>
Make an explicit topology/tree of structures:
* ChildSrcPadInfo is created for each source element source pad
* ChildSrcPadInfo contains the chain of optional elements specific to that
pad (ex: typefind)
* A ChildSrcPadInfo links to one or more OutputSlot, which contain what is
specific to the output (i.e. optional buffering and ghostpad)
* No longer use GObject {set|get}_data() functions to store those structures and
instead make them explicit
* Pass those structures around explicitely in each function/callback
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2784>
The following problem could happen:
* Thread 1 : urisourcebin gets activated from READY->PAUSED
* Thread 2 : some element causes a pad to be added to urisourcebin , which gets
linked downstream, which decides to activate upstream to pull-based.
* That requires "activating" the pads from PUSH to NONE, and then from NONE to PULL
* Thread 1 : the base class state change handlers checks if all pads are
activated
The issue is that since going form PUSH to PULL requires going through NONE,
there is a window during which:
* Thread 1 : The pad was set to NONE (before being set to PULL)
* Thread 2 : The base class activates that pad (to PUSH)
* Thread 1 : The attempt to "activate" to PULL fails (silently or not)
This is very racy, so in order to avoid that, we make sure that we only add pads
once the transition from READY->PAUSED in the parent classes is done.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2784>
GST_TRACERS="leaks" GST_DEBUG="GST_TRACER:7,leaks:6" gst-play-1.0 --use-playbin3 test.mkv
When running a pipeline like above, leaks are observed.
0:00:56.882419132 240637 0x5562c528ccc0 TRACE GST_TRACER :0:: object-alive, type-name=(string)GstConcatPad, address=(gpointer)0x7efd7c0d20a0, description=(string)<'':sink_0>, ref-count=(uint)1, trace=(string);
0:00:56.882429131 240637 0x5562c528ccc0 TRACE GST_TRACER :0:: object-alive, type-name=(string)GstConcatPad, address=(gpointer)0x7efd7c0d2be0, description=(string)<'':sink_0>, ref-count=(uint)1, trace=(string);
0:00:56.882437056 240637 0x5562c528ccc0 TRACE GST_TRACER :0:: object-alive, type-name=(string)GstConcatPad, address=(gpointer)0x7efd7c0d3720, description=(string)<'':sink_0>, ref-count=(uint)1, trace=(string);
gst_element_release_request_pad does not unref the pad. It needs to
be followed by gst_object_unref. Doing that fixes the above leaks.
Use g_ptr_array_new_with_free_func with gst_object_unref as the free
function to unref the pad after release.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3177>
Always hold a reference to the soft volume element
provided by the playsinkaudioconvert bin helper, the
same as when volume is provided by a sink element,
or the soft volume element gets unreffed too soon.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3108>
when expose-all=False
When trying to find an decoder in that case, we loop over the different
decoder factories, and check that it outputs a format that matches the
requested one (through the :caps property), but if we find a decoder
that do match but later on some other don't we end up failing
autopluging. This patch ensures that we still plug the decoder that can
work.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3011>
We are supposed to guarantee that pads that are exposed have the caps
set, but for sources that have pad with "all raw caps" templates, we end
up exposing pads that don't have caps set yet, which can break code (in
GES for example).
To avoid that we let uridecodebin plug a `decodebin` after such pads and
let decodebin to handle that for us. In the end the only thing that
decodebin does in those cases is to wait for pads to be ready and expose
them, after that `uridecodebin` will expose those pads.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3009>
This can be important for instance when a container holds multiple
tracks with the same media type, with no indication (eg tags) of
which track is the default one.
In that case, players usually pick the first track by default.
This is especially useful when using smart editing with GES, as
it will result in the same ordering as the input file that was
used as a template.
For reference, this yields the same order as ffprobe.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1549>
When collection is updated, decodebin3 exposes pad first and then
streams-selected message is posted.
The condition can cause a situation where playbin3 links non-existing
combiner/playsink pads (since streams-selected is not posted yet) with
new decodebin output pad. This commit will re-check selected/active
streams condition on pad-added and reconfigure output if needed.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2482>
* Remove fields no longer used, or that can be replaced by smaller code
* Rename "channels" to a more meaningful "input pads"
* Directly handle/use combiner pads in the combiners instead of on the playbin3
main structure
Remove the corresponding combiner sinkpad whenever a uridecodebin3 source pad
goes away
* If used, store the corresponding combiner sink pad in the SourcePad helper
structure
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2384>
GLib guarantees libintl is always present, using proxy-libintl as
last resort. There is no need to mock gettex API any more.
This fix static build on Windows because G_INTL_STATIC_COMPILATION must
be defined before including libintl.h, and glib does it for us as part
as including glib.h.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2028>
get_merged_collection() returns an owned stream collection and was
leaked in the else block.
Fix leak when running:
GST_TRACERS=leaks GST_DEBUG="GST_TRACER:7,leaks:6" gst-play-1.0 --use-playbin3 test.mkv
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/954>
Make sure that the requested stream selection isn't identical to the current
one. If that's the case, just carry on as usual.
This avoids multiple `streams-selected` posting ... when the selection didn't
change.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2185>
Configure playsink tried element with the bus of the main pipeline.
That tried element can be a gl video sink, which would benefit from being
able to propagate context messages to the main pipeline and have other
internal pipeline elements configured with it. Having different elements
configured with the same GL context allows them to share buffers with
video/x-raw(memory:GLMemory) caps and achieving zero-copy.
Thanks to Alicia Boya García <aboya@igalia.com> for her work co-debugging
the issue and contributing to find a solution.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2056>
Sources that can internally handle buffering shouldn't have yet-another
buffering element after it. This can be simply detected by checking if it can
answer a TIME BUFFERING query just after creation.
If that is the case, we can expose the element source pads directly
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1905>
The default query handler would go through typefind, which by default accepts
any CAPS. But once configured, parsebin can't reconfigure itself, it should
therefore pass through the ACCEPT_CAPS query to the first element after
typefind (if any).
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1900>
Don't reconfigure outputs when the select-streams
event is sent from the app, as the selection may
not take effect for some time. Instead, wait
for the pipeline to confirm the new set of
selected streams when it sends the message.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1900>
If we previously had subtitles coming in, the video
may be chained through a text overlay block. Before,
the code would end up trying to link pads that were
already linked and video would not get reconnected
properly.
To fix that, make sure that the candidate
pads are actually unlinked first. If a textoverlay
is present and no longer needed, it will be cleaned
up later in the reconfiguration sequence.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1900>
Requesting a new pad can start a reconfiguration cycle, where
playsink will block all input pads and wait for data on them
before doing internal reconfiguration. If a pad is released,
that reconfiguration might never trigger because it's now waiting
for a pad that doesn't exist any more.
In that case, complete the reconfiguration on pad release.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1180>
Fix a small race where a group can receive stream-start
and post a pending buffering message just as another
thread posts a different buffering message, causing them
to be received by the application out of order. In the
worst case, this leads the application receiving a
stale 99% buffering message and going back to buffering
right after the 100% buffering message.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1840>