static DecodebinInput *create_new_input (GstDecodebin3 * dbin, gboolean main);
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);
static void free_output_stream (GstDecodebin3 * dbin,
DecodebinOutputStream * output);
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
stream_list_equal (GList * lista, GList * listb)
{
}
}
+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
multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
MultiQueueSlot * slot)
case GST_EVENT_CAPS:
{
/* Configure the output slot if needed */
- DecodebinOutputStream *output;
- 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);
+ check_slot_reconfiguration (dbin, slot);
}
break;
case GST_EVENT_EOS:
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,
MultiQueueSlot * slot)
{
GstDecodebin3 *dbin = output->dbin;
GstCaps *new_caps = (GstCaps *) gst_stream_get_caps (slot->active_stream);
gboolean needs_decoder;
+ gboolean ret = TRUE;
needs_decoder = gst_caps_can_intersect (new_caps, dbin->caps) != TRUE;
GST_WARNING_OBJECT (dbin,
"Output still linked to another slot (%p)", output->slot);
gst_caps_unref (new_caps);
- return;
+ return ret;
}
/* Check if existing config is reusable as-is by checking if
output->linked = TRUE;
}
gst_caps_unref (new_caps);
- return;
+ return ret;
}
GST_DEBUG_OBJECT (dbin, "Removing old decoder for slot %p", slot);
output->decoder = gst_element_factory_create ((GstElementFactory *)
next_factory->data, NULL);
GST_DEBUG ("Created decoder '%s'", GST_ELEMENT_NAME (output->decoder));
- } else
+ } else {
GST_DEBUG ("Could not find an element for caps %" GST_PTR_FORMAT,
new_caps);
+ g_assert (output->decoder == NULL);
+ }
if (output->decoder == NULL) {
GstCaps *caps;
gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));
gst_caps_unref (caps);
SELECTION_LOCK (dbin);
+ ret = FALSE;
goto cleanup;
}
if (!gst_bin_add ((GstBin *) dbin, output->decoder)) {
GST_ERROR_OBJECT (dbin, "could not add decoder to pipeline");
+ ret = FALSE;
goto cleanup;
}
output->decoder_sink =
GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK) {
GST_ERROR_OBJECT (dbin, "could not link to %s:%s",
GST_DEBUG_PAD_NAME (output->decoder_sink));
+ ret = FALSE;
goto cleanup;
}
if (gst_element_set_state (output->decoder,
if (!gst_ghost_pad_set_target ((GstGhostPad *) output->src_pad,
output->decoder_src)) {
GST_ERROR_OBJECT (dbin, "Could not expose decoder pad");
+ ret = FALSE;
goto cleanup;
}
if (output->src_exposed == FALSE) {
gst_element_sync_state_with_parent (output->decoder);
output->slot = slot;
- return;
+ return ret;
cleanup:
{
gst_bin_remove ((GstBin *) dbin, output->decoder);
output->decoder = NULL;
}
+ return ret;
}
}
static GstPadProbeReturn
idle_reconfigure (GstPad * pad, GstPadProbeInfo * info, MultiQueueSlot * slot)
{
- GstMessage *msg = NULL;
- DecodebinOutputStream *output;
-
- SELECTION_LOCK (slot->dbin);
- output = get_output_for_slot (slot);
-
- GST_DEBUG_OBJECT (pad, "output : %p", output);
+ GstDecodebin3 *dbin = slot->dbin;
- 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);
+ check_slot_reconfiguration (dbin, slot);
return GST_PAD_PROBE_REMOVE;
}