decodebin3: Refactor GST_EVENT_SELECT_STREAMS handling

* The same code is used for the event, regardless of whether it's coming from
via a pad or directly on the element
* The pending_select_streams list content was never used, switch it to a boolean

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7002>
This commit is contained in:
Edward Hervey 2024-03-14 10:06:54 +01:00 committed by Backport Bot
parent dd01275e00
commit 18fbe14ac8

View file

@ -248,8 +248,8 @@ struct _GstDecodebin3
GList *to_activate; GList *to_activate;
/* Pending select streams event */ /* Pending select streams event */
guint32 select_streams_seqnum; guint32 select_streams_seqnum;
/* pending list of streams to select (from downstream) */ /* There is a pending GST_EVENT_SELECT_STREAMS being handled */
GList *pending_select_streams; gboolean pending_select_streams;
/* TRUE if requested_selection was updated, will become FALSE once /* TRUE if requested_selection was updated, will become FALSE once
* it has fully transitioned to active */ * it has fully transitioned to active */
gboolean selection_updated; gboolean selection_updated;
@ -694,8 +694,7 @@ gst_decodebin3_reset (GstDecodebin3 * dbin)
dbin->select_streams_seqnum = GST_SEQNUM_INVALID; dbin->select_streams_seqnum = GST_SEQNUM_INVALID;
g_list_free (dbin->pending_select_streams); dbin->pending_select_streams = FALSE;
dbin->pending_select_streams = NULL;
dbin->selection_updated = FALSE; dbin->selection_updated = FALSE;
} }
@ -3324,8 +3323,7 @@ handle_stream_switch (GstDecodebin3 * dbin, GList * select_streams,
return TRUE; return TRUE;
} }
/* Remove pending select_streams */ /* Remove pending select_streams */
g_list_free (dbin->pending_select_streams); dbin->pending_select_streams = FALSE;
dbin->pending_select_streams = NULL;
/* COMPARE the requested streams to the active and requested streams /* COMPARE the requested streams to the active and requested streams
* on multiqueue. */ * on multiqueue. */
@ -3515,6 +3513,51 @@ handle_stream_switch (GstDecodebin3 * dbin, GList * select_streams,
return ret; return ret;
} }
/*
* * event : (transfer full): The select streams event
*
* Handles a GST_EVENT_SELECT_STREAMS (from application or downstream)
*
* Returns: TRUE if the event was handled, or FALSE if it should be forwarded to
* the default handler.
*/
static gboolean
handle_select_streams (GstDecodebin3 * dbin, GstEvent * event)
{
GList *streams = NULL;
guint32 seqnum = gst_event_get_seqnum (event);
if (dbin->upstream_selected) {
GST_DEBUG_OBJECT (dbin, "Letting select-streams event flow upstream");
return FALSE;
}
SELECTION_LOCK (dbin);
if (seqnum == dbin->select_streams_seqnum) {
SELECTION_UNLOCK (dbin);
GST_DEBUG_OBJECT (dbin,
"Already handled/handling that SELECT_STREAMS event");
gst_event_unref (event);
return TRUE;
}
dbin->select_streams_seqnum = seqnum;
if (dbin->pending_select_streams)
GST_LOG_OBJECT (dbin, "Replacing pending select streams");
dbin->pending_select_streams = TRUE;
gst_event_parse_select_streams (event, &streams);
SELECTION_UNLOCK (dbin);
/* Finally handle the switch */
if (streams) {
handle_stream_switch (dbin, streams, seqnum);
g_list_free_full (streams, g_free);
}
gst_event_unref (event);
return TRUE;
}
static GstPadProbeReturn static GstPadProbeReturn
ghost_pad_event_probe (GstPad * pad, GstPadProbeInfo * info, ghost_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
DecodebinOutputStream * output) DecodebinOutputStream * output)
@ -3528,41 +3571,8 @@ ghost_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SELECT_STREAMS: case GST_EVENT_SELECT_STREAMS:
{ {
GList *streams = NULL; if (handle_select_streams (dbin, 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);
if (seqnum == dbin->select_streams_seqnum) {
SELECTION_UNLOCK (dbin);
GST_DEBUG_OBJECT (pad,
"Already handled/handling that SELECT_STREAMS event");
gst_event_unref (event);
ret = GST_PAD_PROBE_HANDLED; ret = GST_PAD_PROBE_HANDLED;
break;
}
dbin->select_streams_seqnum = seqnum;
if (dbin->pending_select_streams != NULL) {
GST_LOG_OBJECT (dbin, "Replacing pending select streams");
g_list_free (dbin->pending_select_streams);
dbin->pending_select_streams = NULL;
}
gst_event_parse_select_streams (event, &streams);
dbin->pending_select_streams = g_list_copy (streams);
SELECTION_UNLOCK (dbin);
/* Finally handle the switch */
if (streams) {
handle_stream_switch (dbin, streams, seqnum);
g_list_free_full (streams, g_free);
}
gst_event_unref (event);
ret = GST_PAD_PROBE_HANDLED;
} }
break; break;
default: default:
@ -3578,37 +3588,12 @@ gst_decodebin3_send_event (GstElement * element, GstEvent * event)
GstDecodebin3 *dbin = (GstDecodebin3 *) element; 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 (!dbin->upstream_selected
&& GST_EVENT_TYPE (event) == GST_EVENT_SELECT_STREAMS) {
GList *streams = NULL;
guint32 seqnum = gst_event_get_seqnum (event);
SELECTION_LOCK (dbin); if (GST_EVENT_TYPE (event) == GST_EVENT_SELECT_STREAMS
if (seqnum == dbin->select_streams_seqnum) { && handle_select_streams (dbin, event)) {
SELECTION_UNLOCK (dbin);
GST_DEBUG_OBJECT (dbin,
"Already handled/handling that SELECT_STREAMS event");
return TRUE;
}
dbin->select_streams_seqnum = seqnum;
if (dbin->pending_select_streams != NULL) {
GST_LOG_OBJECT (dbin, "Replacing pending select streams");
g_list_free (dbin->pending_select_streams);
dbin->pending_select_streams = NULL;
}
gst_event_parse_select_streams (event, &streams);
dbin->pending_select_streams = g_list_copy (streams);
SELECTION_UNLOCK (dbin);
/* Finally handle the switch */
if (streams) {
handle_stream_switch (dbin, streams, seqnum);
g_list_free_full (streams, g_free);
}
gst_event_unref (event);
return TRUE; return TRUE;
} }
return GST_ELEMENT_CLASS (parent_class)->send_event (element, event); return GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
} }