mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
uridecodebin: aggregate topology messages
This makes it possible for GstDiscoverer to work with sources that have multiple source pads and hence will trigger the creation of multiple decodebin instances such as rtspsrc. Based on the work of Vineeth TM <vineeth.tm@samsung.com> https://bugzilla.gnome.org/show_bug.cgi?id=754178
This commit is contained in:
parent
20705f01fc
commit
bfba213437
1 changed files with 79 additions and 1 deletions
|
@ -1640,6 +1640,11 @@ remove_decoders (GstURIDecodeBin * bin, gboolean force)
|
|||
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);
|
||||
|
@ -2392,6 +2397,54 @@ handle_redirect_message (GstURIDecodeBin * dec, GstMessage * msg)
|
|||
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)
|
||||
{
|
||||
|
@ -2399,7 +2452,32 @@ 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
|
||||
|
|
Loading…
Reference in a new issue