mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 03:31:05 +00:00
decodebin3: Handle upstream selection
Detect if upstream handles stream-selection, and if so bypass all stream selection handling (streams are forwarded as-is). Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1905>
This commit is contained in:
parent
e291ad2cbb
commit
7eea928dd0
1 changed files with 64 additions and 10 deletions
|
@ -247,6 +247,7 @@ struct _GstDecodebin3
|
||||||
* it has fully transitioned to active */
|
* it has fully transitioned to active */
|
||||||
gboolean selection_updated;
|
gboolean selection_updated;
|
||||||
/* End of variables protected by selection_lock */
|
/* End of variables protected by selection_lock */
|
||||||
|
gboolean upstream_selected;
|
||||||
|
|
||||||
/* List of pending collections.
|
/* List of pending collections.
|
||||||
* FIXME : Is this really needed ? */
|
* FIXME : Is this really needed ? */
|
||||||
|
@ -288,6 +289,7 @@ struct _DecodebinInput
|
||||||
GstPad *parsebin_sink;
|
GstPad *parsebin_sink;
|
||||||
|
|
||||||
GstStreamCollection *collection; /* Active collection */
|
GstStreamCollection *collection; /* Active collection */
|
||||||
|
gboolean upstream_selected;
|
||||||
|
|
||||||
guint group_id;
|
guint group_id;
|
||||||
|
|
||||||
|
@ -1007,6 +1009,27 @@ sink_event_function (GstPad * sinkpad, GstDecodebin3 * dbin, GstEvent * event)
|
||||||
GST_DEBUG_OBJECT (sinkpad, "event %" GST_PTR_FORMAT, event);
|
GST_DEBUG_OBJECT (sinkpad, "event %" GST_PTR_FORMAT, event);
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_STREAM_START:
|
||||||
|
{
|
||||||
|
GstQuery *q = gst_query_new_selectable ();
|
||||||
|
|
||||||
|
/* Query whether upstream can handle stream selection or not */
|
||||||
|
if (gst_pad_peer_query (sinkpad, q)) {
|
||||||
|
gst_query_parse_selectable (q, &input->upstream_selected);
|
||||||
|
GST_DEBUG_OBJECT (sinkpad, "Upstream is selectable : %d",
|
||||||
|
input->upstream_selected);
|
||||||
|
} else {
|
||||||
|
input->upstream_selected = FALSE;
|
||||||
|
GST_DEBUG_OBJECT (sinkpad, "Upstream does not handle SELECTABLE query");
|
||||||
|
}
|
||||||
|
gst_query_unref (q);
|
||||||
|
|
||||||
|
/* FIXME : We force `decodebin3` to upstream selection mode if *any* of the
|
||||||
|
inputs is. This means things might break if there's a mix */
|
||||||
|
if (input->upstream_selected)
|
||||||
|
dbin->upstream_selected = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GST_EVENT_CAPS:
|
case GST_EVENT_CAPS:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (sinkpad,
|
GST_DEBUG_OBJECT (sinkpad,
|
||||||
|
@ -1057,6 +1080,7 @@ create_new_input (GstDecodebin3 * dbin, gboolean main)
|
||||||
input->ghost_sink = gst_ghost_pad_new_no_target (pad_name, GST_PAD_SINK);
|
input->ghost_sink = gst_ghost_pad_new_no_target (pad_name, GST_PAD_SINK);
|
||||||
g_free (pad_name);
|
g_free (pad_name);
|
||||||
}
|
}
|
||||||
|
input->upstream_selected = FALSE;
|
||||||
g_object_set_data (G_OBJECT (input->ghost_sink), "decodebin.input", input);
|
g_object_set_data (G_OBJECT (input->ghost_sink), "decodebin.input", input);
|
||||||
gst_pad_set_event_function (input->ghost_sink,
|
gst_pad_set_event_function (input->ghost_sink,
|
||||||
(GstPadEventFunction) sink_event_function);
|
(GstPadEventFunction) sink_event_function);
|
||||||
|
@ -1441,14 +1465,12 @@ stream_in_collection (GstDecodebin3 * dbin, gchar * sid)
|
||||||
/* Call with INPUT_LOCK taken */
|
/* Call with INPUT_LOCK taken */
|
||||||
static void
|
static void
|
||||||
handle_stream_collection (GstDecodebin3 * dbin,
|
handle_stream_collection (GstDecodebin3 * dbin,
|
||||||
GstStreamCollection * collection, GstElement * child)
|
GstStreamCollection * collection, DecodebinInput * input)
|
||||||
{
|
{
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
const gchar *upstream_id;
|
const gchar *upstream_id;
|
||||||
guint i;
|
guint i;
|
||||||
#endif
|
#endif
|
||||||
DecodebinInput *input = find_message_parsebin (dbin, child);
|
|
||||||
|
|
||||||
if (!input) {
|
if (!input) {
|
||||||
GST_DEBUG_OBJECT (dbin,
|
GST_DEBUG_OBJECT (dbin,
|
||||||
"Couldn't find corresponding input, most likely shutting down");
|
"Couldn't find corresponding input, most likely shutting down");
|
||||||
|
@ -1558,14 +1580,30 @@ gst_decodebin3_handle_message (GstBin * bin, GstMessage * message)
|
||||||
case GST_MESSAGE_STREAM_COLLECTION:
|
case GST_MESSAGE_STREAM_COLLECTION:
|
||||||
{
|
{
|
||||||
GstStreamCollection *collection = NULL;
|
GstStreamCollection *collection = NULL;
|
||||||
|
DecodebinInput *input;
|
||||||
|
|
||||||
|
INPUT_LOCK (dbin);
|
||||||
|
input =
|
||||||
|
find_message_parsebin (dbin,
|
||||||
|
(GstElement *) GST_MESSAGE_SRC (message));
|
||||||
|
if (input == NULL) {
|
||||||
|
GST_DEBUG_OBJECT (dbin,
|
||||||
|
"Couldn't find corresponding input, most likely shutting down");
|
||||||
|
INPUT_UNLOCK (dbin);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (input->upstream_selected) {
|
||||||
|
GST_DEBUG_OBJECT (dbin,
|
||||||
|
"Upstream handles selection, not using/forwarding collection");
|
||||||
|
INPUT_UNLOCK (dbin);
|
||||||
|
goto drop_message;
|
||||||
|
}
|
||||||
gst_message_parse_stream_collection (message, &collection);
|
gst_message_parse_stream_collection (message, &collection);
|
||||||
if (collection) {
|
if (collection) {
|
||||||
INPUT_LOCK (dbin);
|
handle_stream_collection (dbin, collection, input);
|
||||||
handle_stream_collection (dbin, collection,
|
|
||||||
(GstElement *) GST_MESSAGE_SRC (message));
|
|
||||||
posting_collection = TRUE;
|
posting_collection = TRUE;
|
||||||
INPUT_UNLOCK (dbin);
|
|
||||||
}
|
}
|
||||||
|
INPUT_UNLOCK (dbin);
|
||||||
|
|
||||||
SELECTION_LOCK (dbin);
|
SELECTION_LOCK (dbin);
|
||||||
if (dbin->collection) {
|
if (dbin->collection) {
|
||||||
|
@ -1618,6 +1656,14 @@ gst_decodebin3_handle_message (GstBin * bin, GstMessage * message)
|
||||||
/* Figure out a selection for that collection */
|
/* Figure out a selection for that collection */
|
||||||
update_requested_selection (dbin);
|
update_requested_selection (dbin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
drop_message:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (bin, "dropping message");
|
||||||
|
gst_message_unref (message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DecodebinOutputStream *
|
static DecodebinOutputStream *
|
||||||
|
@ -1702,7 +1748,7 @@ get_output_for_slot (MultiQueueSlot * slot)
|
||||||
|
|
||||||
/* 3. In default mode check if we should expose */
|
/* 3. In default mode check if we should expose */
|
||||||
id_in_list = (gchar *) stream_in_list (dbin->requested_selection, stream_id);
|
id_in_list = (gchar *) stream_in_list (dbin->requested_selection, stream_id);
|
||||||
if (id_in_list) {
|
if (id_in_list || dbin->upstream_selected) {
|
||||||
/* Check if we can steal an existing output stream we could re-use.
|
/* Check if we can steal an existing output stream we could re-use.
|
||||||
* that is:
|
* that is:
|
||||||
* * an output stream whose slot->stream is not in requested
|
* * an output stream whose slot->stream is not in requested
|
||||||
|
@ -2862,6 +2908,11 @@ ghost_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
GList *streams = NULL;
|
GList *streams = NULL;
|
||||||
guint32 seqnum = gst_event_get_seqnum (event);
|
guint32 seqnum = gst_event_get_seqnum (event);
|
||||||
|
|
||||||
|
if (dbin->upstream_selected) {
|
||||||
|
GST_DEBUG_OBJECT (pad, "Letting select-streams event flow upstream");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
SELECTION_LOCK (dbin);
|
SELECTION_LOCK (dbin);
|
||||||
if (seqnum == dbin->select_streams_seqnum) {
|
if (seqnum == dbin->select_streams_seqnum) {
|
||||||
SELECTION_UNLOCK (dbin);
|
SELECTION_UNLOCK (dbin);
|
||||||
|
@ -2906,9 +2957,11 @@ ghost_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_decodebin3_send_event (GstElement * element, GstEvent * event)
|
gst_decodebin3_send_event (GstElement * element, GstEvent * event)
|
||||||
{
|
{
|
||||||
|
GstDecodebin3 *dbin = (GstDecodebin3 *) element;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (element, "event %s", GST_EVENT_TYPE_NAME (event));
|
GST_DEBUG_OBJECT (element, "event %s", GST_EVENT_TYPE_NAME (event));
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_SELECT_STREAMS) {
|
if (!dbin->upstream_selected
|
||||||
GstDecodebin3 *dbin = (GstDecodebin3 *) element;
|
&& GST_EVENT_TYPE (event) == GST_EVENT_SELECT_STREAMS) {
|
||||||
GList *streams = NULL;
|
GList *streams = NULL;
|
||||||
guint32 seqnum = gst_event_get_seqnum (event);
|
guint32 seqnum = gst_event_get_seqnum (event);
|
||||||
|
|
||||||
|
@ -3100,6 +3153,7 @@ gst_decodebin3_change_state (GstElement * element, GstStateChange transition)
|
||||||
g_object_set (dbin->multiqueue, "min-interleave-time",
|
g_object_set (dbin->multiqueue, "min-interleave-time",
|
||||||
dbin->default_mq_min_interleave, NULL);
|
dbin->default_mq_min_interleave, NULL);
|
||||||
dbin->current_mq_min_interleave = dbin->default_mq_min_interleave;
|
dbin->current_mq_min_interleave = dbin->default_mq_min_interleave;
|
||||||
|
dbin->upstream_selected = FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue