GstElement *decoder = GST_ELEMENT_CAST (walk->data);
GST_DEBUG_OBJECT (bin, "removing old decoder element");
+
+ /* Even if we reuse this decodebin, the previous topology will
+ * be irrelevant */
+ g_object_set_data (G_OBJECT (decoder), "uridecodebin-topology", NULL);
+
if (force) {
gst_element_set_state (decoder, GST_STATE_NULL);
gst_bin_remove (GST_BIN_CAST (bin), decoder);
return new_msg;
}
+static GstMessage *
+make_topology_message (GstURIDecodeBin * dec)
+{
+ GSList *tmp;
+ GstStructure *aggregated_topology = NULL;
+ GValue list = G_VALUE_INIT;
+ GstCaps *caps = NULL;
+ gchar *name, *proto;
+
+ aggregated_topology = gst_structure_new_empty ("stream-topology");
+ g_value_init (&list, GST_TYPE_LIST);
+
+ for (tmp = dec->decodebins; tmp; tmp = tmp->next) {
+ GValue item = G_VALUE_INIT;
+ GstStructure *dec_topology =
+ g_object_get_data (G_OBJECT (tmp->data), "uridecodebin-topology");
+
+ g_value_init (&item, GST_TYPE_STRUCTURE);
+ gst_value_set_structure (&item, dec_topology);
+ gst_value_list_append_and_take_value (&list, &item);
+ }
+
+ gst_structure_take_value (aggregated_topology, "next", &list);
+
+ /* This is a bit wacky, but that's the best way I can find to express
+ * uridecodebin 'caps' as subsequently shown by gst-discoverer */
+ proto = gst_uri_get_protocol (dec->uri);
+ name = g_strdup_printf ("application/%s", proto);
+ g_free (proto);
+
+ caps = gst_caps_new_empty_simple (name);
+ g_free (name);
+
+ gst_structure_set (aggregated_topology, "caps", GST_TYPE_CAPS, caps, NULL);
+ gst_caps_unref (caps);
+
+ return gst_message_new_element (GST_OBJECT (dec), aggregated_topology);
+}
+
+static void
+check_topology (gpointer data, gpointer user_data)
+{
+ gboolean *has_topo = user_data;
+
+ if (g_object_get_data (data, "uridecodebin-topology") == NULL)
+ *has_topo = FALSE;
+}
+
static void
handle_message (GstBin * bin, GstMessage * msg)
{
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ELEMENT:{
- if (gst_message_has_name (msg, "redirect")) {
+
+ if (gst_message_has_name (msg, "stream-topology")) {
+ GstElement *element = GST_ELEMENT (GST_MESSAGE_SRC (msg));
+ gboolean has_all_topo = TRUE;
+
+ if (dec->pending || (dec->decodebins && dec->decodebins->next != NULL)) {
+ const GstStructure *structure;
+
+ /* If there is only one, just let it through, so this case is if
+ * there is more than one.
+ */
+
+ structure = gst_message_get_structure (msg);
+
+ g_object_set_data_full (G_OBJECT (element), "uridecodebin-topology",
+ gst_structure_copy (structure),
+ (GDestroyNotify) gst_structure_free);
+
+ gst_message_unref (msg);
+ msg = NULL;
+
+ g_slist_foreach (dec->decodebins, check_topology, &has_all_topo);
+ if (has_all_topo)
+ msg = make_topology_message (dec);
+ }
+ } else if (gst_message_has_name (msg, "redirect")) {
/* sort redirect messages based on the connection speed. This simplifies
* the user of this element as it can in most cases just pick the first item
* of the sorted list as a good redirection candidate. It can of course