mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
decodebin2: Post a element message on the bus with the stream topology
Fixes bug #598533.
This commit is contained in:
parent
50fdbcd9ea
commit
efcca84bac
1 changed files with 133 additions and 2 deletions
|
@ -2447,6 +2447,128 @@ sort_end_pads (GstDecodePad * da, GstDecodePad * db)
|
||||||
return va - vb;
|
return va - vb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstCaps *
|
||||||
|
_gst_element_get_linked_caps (GstElement * src, GstElement * sink)
|
||||||
|
{
|
||||||
|
GstIterator *it;
|
||||||
|
GstElement *parent;
|
||||||
|
GstPad *pad, *peer;
|
||||||
|
gboolean done = FALSE;
|
||||||
|
GstCaps *caps = NULL;
|
||||||
|
|
||||||
|
it = gst_element_iterate_src_pads (src);
|
||||||
|
while (!done) {
|
||||||
|
switch (gst_iterator_next (it, (gpointer) & pad)) {
|
||||||
|
case GST_ITERATOR_OK:
|
||||||
|
peer = gst_pad_get_peer (pad);
|
||||||
|
if (peer) {
|
||||||
|
parent = gst_pad_get_parent_element (peer);
|
||||||
|
if (parent == sink) {
|
||||||
|
caps = gst_pad_get_negotiated_caps (pad);
|
||||||
|
done = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
gst_object_unref (parent);
|
||||||
|
gst_object_unref (peer);
|
||||||
|
}
|
||||||
|
gst_object_unref (pad);
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_RESYNC:
|
||||||
|
gst_iterator_resync (it);
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_ERROR:
|
||||||
|
case GST_ITERATOR_DONE:
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_iterator_free (it);
|
||||||
|
|
||||||
|
return caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GQuark topology_structure_name = 0;
|
||||||
|
static GQuark topology_caps = 0;
|
||||||
|
static GQuark topology_next = 0;
|
||||||
|
static GQuark topology_pad = 0;
|
||||||
|
|
||||||
|
/* FIXME: Invent gst_structure_take_structure() to prevent all the
|
||||||
|
* structure copying for nothing
|
||||||
|
*/
|
||||||
|
static GstStructure *
|
||||||
|
gst_decode_chain_get_topology (GstDecodeChain * chain)
|
||||||
|
{
|
||||||
|
GstStructure *s, *u;
|
||||||
|
GList *l;
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
|
u = gst_structure_id_empty_new (topology_structure_name);
|
||||||
|
|
||||||
|
/* Now at the last element */
|
||||||
|
if (chain->elements && (chain->endpad || chain->deadend)) {
|
||||||
|
s = gst_structure_id_empty_new (topology_structure_name);
|
||||||
|
gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, chain->endcaps,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (chain->endpad)
|
||||||
|
gst_structure_id_set (u, topology_pad, GST_TYPE_PAD, chain->endpad, NULL);
|
||||||
|
gst_structure_id_set (s, topology_next, GST_TYPE_STRUCTURE, u, NULL);
|
||||||
|
gst_structure_free (u);
|
||||||
|
u = s;
|
||||||
|
} else if (chain->active_group) {
|
||||||
|
GValue list = { 0, };
|
||||||
|
GValue item = { 0, };
|
||||||
|
|
||||||
|
g_value_init (&list, GST_TYPE_LIST);
|
||||||
|
g_value_init (&item, GST_TYPE_STRUCTURE);
|
||||||
|
for (l = chain->active_group->children; l; l = l->next) {
|
||||||
|
s = gst_decode_chain_get_topology (l->data);
|
||||||
|
gst_value_set_structure (&item, s);
|
||||||
|
gst_value_list_append_value (&list, &item);
|
||||||
|
g_value_reset (&item);
|
||||||
|
gst_structure_free (s);
|
||||||
|
}
|
||||||
|
gst_structure_id_set_value (u, topology_next, &list);
|
||||||
|
g_value_unset (&list);
|
||||||
|
g_value_unset (&item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get caps between all elements in this chain */
|
||||||
|
l = (chain->elements && chain->elements->next) ? chain->elements->next : NULL;
|
||||||
|
for (; l && l->next; l = l->next) {
|
||||||
|
GstCaps *caps = _gst_element_get_linked_caps (l->next->data, l->data);
|
||||||
|
|
||||||
|
s = gst_structure_id_empty_new (topology_structure_name);
|
||||||
|
gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, caps, NULL);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
gst_structure_id_set (s, topology_next, GST_TYPE_STRUCTURE, u, NULL);
|
||||||
|
gst_structure_free (u);
|
||||||
|
u = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Caps that resulted in this chain */
|
||||||
|
caps = gst_pad_get_negotiated_caps (chain->pad);
|
||||||
|
gst_structure_set (u, "caps", GST_TYPE_CAPS, caps, NULL);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_decode_bin_post_topology_message (GstDecodeBin * dbin)
|
||||||
|
{
|
||||||
|
GstStructure *s;
|
||||||
|
GstMessage *msg;
|
||||||
|
|
||||||
|
s = gst_decode_chain_get_topology (dbin->decode_chain);
|
||||||
|
|
||||||
|
msg = gst_message_new_element (GST_OBJECT (dbin), s);
|
||||||
|
gst_element_post_message (GST_ELEMENT (dbin), msg);
|
||||||
|
}
|
||||||
|
|
||||||
/* Must only be called if the toplevel chain is complete and blocked! */
|
/* Must only be called if the toplevel chain is complete and blocked! */
|
||||||
/* Not MT-safe, call with decodebin expose lock! */
|
/* Not MT-safe, call with decodebin expose lock! */
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -2528,12 +2650,15 @@ gst_decode_bin_expose (GstDecodeBin * dbin)
|
||||||
GST_DEBUG_OBJECT (dbin, "emitted new-decoded-pad");
|
GST_DEBUG_OBJECT (dbin, "emitted new-decoded-pad");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* signal no-more-pads. This allows the application to hook stuff to the
|
/* 4. Signal no-more-pads. This allows the application to hook stuff to the
|
||||||
* exposed pads */
|
* exposed pads */
|
||||||
GST_LOG_OBJECT (dbin, "signalling no-more-pads");
|
GST_LOG_OBJECT (dbin, "signalling no-more-pads");
|
||||||
gst_element_no_more_pads (GST_ELEMENT (dbin));
|
gst_element_no_more_pads (GST_ELEMENT (dbin));
|
||||||
|
|
||||||
/* 4. Unblock internal pads. The application should have connected stuff now
|
/* 5. Send a custom element message with the stream topology */
|
||||||
|
gst_decode_bin_post_topology_message (dbin);
|
||||||
|
|
||||||
|
/* 6. Unblock internal pads. The application should have connected stuff now
|
||||||
* so that streaming can continue. */
|
* so that streaming can continue. */
|
||||||
for (tmp = endpads; tmp; tmp = tmp->next) {
|
for (tmp = endpads; tmp; tmp = tmp->next) {
|
||||||
GstDecodePad *dpad = (GstDecodePad *) tmp->data;
|
GstDecodePad *dpad = (GstDecodePad *) tmp->data;
|
||||||
|
@ -2913,6 +3038,12 @@ gst_decode_bin_plugin_init (GstPlugin * plugin)
|
||||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||||
#endif /* ENABLE_NLS */
|
#endif /* ENABLE_NLS */
|
||||||
|
|
||||||
|
/* Register some quarks here for the stream topology message */
|
||||||
|
topology_structure_name = g_quark_from_static_string ("stream-topology");
|
||||||
|
topology_caps = g_quark_from_static_string ("caps");
|
||||||
|
topology_next = g_quark_from_static_string ("next");
|
||||||
|
topology_pad = g_quark_from_static_string ("pad");
|
||||||
|
|
||||||
return gst_element_register (plugin, "decodebin2", GST_RANK_NONE,
|
return gst_element_register (plugin, "decodebin2", GST_RANK_NONE,
|
||||||
GST_TYPE_DECODE_BIN);
|
GST_TYPE_DECODE_BIN);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue