mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
decodebin3: Remove failing stream from selection
If no decoder is present for a given stream, remove it from the requested selection. Fixes #1581 and #1662 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3754>
This commit is contained in:
parent
34ea792881
commit
e2773304a2
1 changed files with 62 additions and 31 deletions
|
@ -499,7 +499,7 @@ static void free_input (GstDecodebin3 * dbin, DecodebinInput * input);
|
||||||
static DecodebinInput *create_new_input (GstDecodebin3 * dbin, gboolean main);
|
static DecodebinInput *create_new_input (GstDecodebin3 * dbin, gboolean main);
|
||||||
static gboolean set_input_group_id (DecodebinInput * input, guint32 * group_id);
|
static gboolean set_input_group_id (DecodebinInput * input, guint32 * group_id);
|
||||||
|
|
||||||
static void reconfigure_output_stream (DecodebinOutputStream * output,
|
static gboolean reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
MultiQueueSlot * slot);
|
MultiQueueSlot * slot);
|
||||||
static void free_output_stream (GstDecodebin3 * dbin,
|
static void free_output_stream (GstDecodebin3 * dbin,
|
||||||
DecodebinOutputStream * output);
|
DecodebinOutputStream * output);
|
||||||
|
@ -1535,6 +1535,21 @@ stream_in_list (GList * list, const gchar * sid)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GList *
|
||||||
|
remove_from_list (GList * list, const gchar * sid)
|
||||||
|
{
|
||||||
|
GList *tmp;
|
||||||
|
|
||||||
|
for (tmp = list; tmp; tmp = tmp->next) {
|
||||||
|
gchar *osid = tmp->data;
|
||||||
|
if (!g_strcmp0 (sid, osid)) {
|
||||||
|
g_free (osid);
|
||||||
|
return g_list_delete_link (list, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
stream_list_equal (GList * lista, GList * listb)
|
stream_list_equal (GList * lista, GList * listb)
|
||||||
{
|
{
|
||||||
|
@ -2282,6 +2297,34 @@ check_all_slot_for_eos (GstDecodebin3 * dbin, GstEvent * ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_slot_reconfiguration (GstDecodebin3 * dbin, MultiQueueSlot * slot)
|
||||||
|
{
|
||||||
|
DecodebinOutputStream *output;
|
||||||
|
|
||||||
|
SELECTION_LOCK (dbin);
|
||||||
|
output = get_output_for_slot (slot);
|
||||||
|
if (!output) {
|
||||||
|
SELECTION_UNLOCK (dbin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reconfigure_output_stream (output, slot)) {
|
||||||
|
GST_DEBUG_OBJECT (dbin, "Removing failing stream from selection: %s ",
|
||||||
|
gst_stream_get_stream_id (slot->active_stream));
|
||||||
|
slot->dbin->requested_selection =
|
||||||
|
remove_from_list (slot->dbin->requested_selection,
|
||||||
|
gst_stream_get_stream_id (slot->active_stream));
|
||||||
|
SELECTION_UNLOCK (dbin);
|
||||||
|
reassign_slot (dbin, slot);
|
||||||
|
} else {
|
||||||
|
GstMessage *msg = is_selection_done (dbin);
|
||||||
|
SELECTION_UNLOCK (dbin);
|
||||||
|
if (msg)
|
||||||
|
gst_element_post_message ((GstElement *) slot->dbin, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstPadProbeReturn
|
static GstPadProbeReturn
|
||||||
multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
|
multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
MultiQueueSlot * slot)
|
MultiQueueSlot * slot)
|
||||||
|
@ -2357,17 +2400,7 @@ multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
case GST_EVENT_CAPS:
|
case GST_EVENT_CAPS:
|
||||||
{
|
{
|
||||||
/* Configure the output slot if needed */
|
/* Configure the output slot if needed */
|
||||||
DecodebinOutputStream *output;
|
check_slot_reconfiguration (dbin, slot);
|
||||||
GstMessage *msg = NULL;
|
|
||||||
SELECTION_LOCK (dbin);
|
|
||||||
output = get_output_for_slot (slot);
|
|
||||||
if (output) {
|
|
||||||
reconfigure_output_stream (output, slot);
|
|
||||||
msg = is_selection_done (dbin);
|
|
||||||
}
|
|
||||||
SELECTION_UNLOCK (dbin);
|
|
||||||
if (msg)
|
|
||||||
gst_element_post_message ((GstElement *) slot->dbin, msg);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
|
@ -2678,13 +2711,16 @@ keyframe_waiter_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
return GST_PAD_PROBE_DROP;
|
return GST_PAD_PROBE_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* Returns FALSE if the output couldn't be properly configured and the
|
||||||
|
* associated GstStreams should be disabled */
|
||||||
|
static gboolean
|
||||||
reconfigure_output_stream (DecodebinOutputStream * output,
|
reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
MultiQueueSlot * slot)
|
MultiQueueSlot * slot)
|
||||||
{
|
{
|
||||||
GstDecodebin3 *dbin = output->dbin;
|
GstDecodebin3 *dbin = output->dbin;
|
||||||
GstCaps *new_caps = (GstCaps *) gst_stream_get_caps (slot->active_stream);
|
GstCaps *new_caps = (GstCaps *) gst_stream_get_caps (slot->active_stream);
|
||||||
gboolean needs_decoder;
|
gboolean needs_decoder;
|
||||||
|
gboolean ret = TRUE;
|
||||||
|
|
||||||
needs_decoder = gst_caps_can_intersect (new_caps, dbin->caps) != TRUE;
|
needs_decoder = gst_caps_can_intersect (new_caps, dbin->caps) != TRUE;
|
||||||
|
|
||||||
|
@ -2697,7 +2733,7 @@ reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
GST_WARNING_OBJECT (dbin,
|
GST_WARNING_OBJECT (dbin,
|
||||||
"Output still linked to another slot (%p)", output->slot);
|
"Output still linked to another slot (%p)", output->slot);
|
||||||
gst_caps_unref (new_caps);
|
gst_caps_unref (new_caps);
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if existing config is reusable as-is by checking if
|
/* Check if existing config is reusable as-is by checking if
|
||||||
|
@ -2726,7 +2762,7 @@ reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
output->linked = TRUE;
|
output->linked = TRUE;
|
||||||
}
|
}
|
||||||
gst_caps_unref (new_caps);
|
gst_caps_unref (new_caps);
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dbin, "Removing old decoder for slot %p", slot);
|
GST_DEBUG_OBJECT (dbin, "Removing old decoder for slot %p", slot);
|
||||||
|
@ -2778,9 +2814,11 @@ reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
output->decoder = gst_element_factory_create ((GstElementFactory *)
|
output->decoder = gst_element_factory_create ((GstElementFactory *)
|
||||||
next_factory->data, NULL);
|
next_factory->data, NULL);
|
||||||
GST_DEBUG ("Created decoder '%s'", GST_ELEMENT_NAME (output->decoder));
|
GST_DEBUG ("Created decoder '%s'", GST_ELEMENT_NAME (output->decoder));
|
||||||
} else
|
} else {
|
||||||
GST_DEBUG ("Could not find an element for caps %" GST_PTR_FORMAT,
|
GST_DEBUG ("Could not find an element for caps %" GST_PTR_FORMAT,
|
||||||
new_caps);
|
new_caps);
|
||||||
|
g_assert (output->decoder == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (output->decoder == NULL) {
|
if (output->decoder == NULL) {
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
@ -2793,10 +2831,12 @@ reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));
|
gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
SELECTION_LOCK (dbin);
|
SELECTION_LOCK (dbin);
|
||||||
|
ret = FALSE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (!gst_bin_add ((GstBin *) dbin, output->decoder)) {
|
if (!gst_bin_add ((GstBin *) dbin, output->decoder)) {
|
||||||
GST_ERROR_OBJECT (dbin, "could not add decoder to pipeline");
|
GST_ERROR_OBJECT (dbin, "could not add decoder to pipeline");
|
||||||
|
ret = FALSE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
output->decoder_sink =
|
output->decoder_sink =
|
||||||
|
@ -2812,6 +2852,7 @@ reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK) {
|
GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK) {
|
||||||
GST_ERROR_OBJECT (dbin, "could not link to %s:%s",
|
GST_ERROR_OBJECT (dbin, "could not link to %s:%s",
|
||||||
GST_DEBUG_PAD_NAME (output->decoder_sink));
|
GST_DEBUG_PAD_NAME (output->decoder_sink));
|
||||||
|
ret = FALSE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (gst_element_set_state (output->decoder,
|
if (gst_element_set_state (output->decoder,
|
||||||
|
@ -2853,6 +2894,7 @@ reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
if (!gst_ghost_pad_set_target ((GstGhostPad *) output->src_pad,
|
if (!gst_ghost_pad_set_target ((GstGhostPad *) output->src_pad,
|
||||||
output->decoder_src)) {
|
output->decoder_src)) {
|
||||||
GST_ERROR_OBJECT (dbin, "Could not expose decoder pad");
|
GST_ERROR_OBJECT (dbin, "Could not expose decoder pad");
|
||||||
|
ret = FALSE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (output->src_exposed == FALSE) {
|
if (output->src_exposed == FALSE) {
|
||||||
|
@ -2878,7 +2920,7 @@ reconfigure_output_stream (DecodebinOutputStream * output,
|
||||||
gst_element_sync_state_with_parent (output->decoder);
|
gst_element_sync_state_with_parent (output->decoder);
|
||||||
|
|
||||||
output->slot = slot;
|
output->slot = slot;
|
||||||
return;
|
return ret;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
{
|
{
|
||||||
|
@ -2896,27 +2938,16 @@ cleanup:
|
||||||
gst_bin_remove ((GstBin *) dbin, output->decoder);
|
gst_bin_remove ((GstBin *) dbin, output->decoder);
|
||||||
output->decoder = NULL;
|
output->decoder = NULL;
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstPadProbeReturn
|
static GstPadProbeReturn
|
||||||
idle_reconfigure (GstPad * pad, GstPadProbeInfo * info, MultiQueueSlot * slot)
|
idle_reconfigure (GstPad * pad, GstPadProbeInfo * info, MultiQueueSlot * slot)
|
||||||
{
|
{
|
||||||
GstMessage *msg = NULL;
|
GstDecodebin3 *dbin = slot->dbin;
|
||||||
DecodebinOutputStream *output;
|
|
||||||
|
|
||||||
SELECTION_LOCK (slot->dbin);
|
check_slot_reconfiguration (dbin, slot);
|
||||||
output = get_output_for_slot (slot);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pad, "output : %p", output);
|
|
||||||
|
|
||||||
if (output) {
|
|
||||||
reconfigure_output_stream (output, slot);
|
|
||||||
msg = is_selection_done (slot->dbin);
|
|
||||||
}
|
|
||||||
SELECTION_UNLOCK (slot->dbin);
|
|
||||||
if (msg)
|
|
||||||
gst_element_post_message ((GstElement *) slot->dbin, msg);
|
|
||||||
|
|
||||||
return GST_PAD_PROBE_REMOVE;
|
return GST_PAD_PROBE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue