Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/GStreamer/gstreamer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-03-11 15:17:13 +0300
committerTim-Philipp Müller <tim@centricular.com>2016-04-06 11:58:57 +0300
commit24b7a8fe1876c1ea092375e29990138e4d5f73be (patch)
tree7ac7289358157c412b8c92ad47a28b6dc3f325a5
parentc5ad081b92ad2008f35f666734084d4639ba5aaa (diff)
typefind: Store caps on the pad before emitting have-type but send it downstream only in the default signal handler
https://bugzilla.gnome.org/show_bug.cgi?id=763491
-rw-r--r--plugins/elements/gsttypefindelement.c55
1 files changed, 48 insertions, 7 deletions
diff --git a/plugins/elements/gsttypefindelement.c b/plugins/elements/gsttypefindelement.c
index f9d3e378e7..adf32ecb7a 100644
--- a/plugins/elements/gsttypefindelement.c
+++ b/plugins/elements/gsttypefindelement.c
@@ -172,18 +172,62 @@ static void
gst_type_find_element_have_type (GstTypeFindElement * typefind,
guint probability, GstCaps * caps)
{
+ GstEvent *event;
+
g_assert (caps != NULL);
GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT ", probability=%u",
caps, probability);
GST_OBJECT_LOCK (typefind);
+
+ /* Now actually send the CAPS event downstream.
+ *
+ * Try to directly send the CAPS event downstream that we created in
+ * gst_type_find_element_emit_have_type() if it is still there, instead
+ * of creating a new one. No need to create an equivalent one, replacing
+ * it in the sticky event list and possibly causing renegotiation
+ */
+ event = gst_pad_get_sticky_event (typefind->src, GST_EVENT_CAPS, 0);
+ if (event) {
+ GstCaps *event_caps;
+
+ gst_event_parse_caps (event, &event_caps);
+ if (caps == event_caps) {
+ event = event;
+ } else {
+ gst_event_unref (event);
+ event = gst_event_new_caps (caps);
+ }
+ } else {
+ event = gst_event_new_caps (caps);
+ }
+
if (typefind->caps)
gst_caps_unref (typefind->caps);
typefind->caps = gst_caps_ref (caps);
GST_OBJECT_UNLOCK (typefind);
- gst_pad_set_caps (typefind->src, caps);
+ gst_pad_push_event (typefind->src, event);
+}
+
+static void
+gst_type_find_element_emit_have_type (GstTypeFindElement * typefind,
+ guint probability, GstCaps * caps)
+{
+ GstEvent *event;
+
+ /* Only store the caps event at this point. We give signal handlers
+ * the chance to look at the caps before they are sent downstream.
+ * They are only forwarded downstream later in the default signal
+ * handler after all application signal handlers
+ */
+ event = gst_event_new_caps (caps);
+ gst_pad_store_sticky_event (typefind->src, event);
+ gst_event_unref (event);
+
+ g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
+ probability, caps);
}
static void
@@ -729,8 +773,7 @@ gst_type_find_element_setcaps (GstTypeFindElement * typefind, GstCaps * caps)
if (gst_caps_is_any (caps))
return TRUE;
- g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
- GST_TYPE_FIND_MAXIMUM, caps);
+ gst_type_find_element_emit_have_type (typefind, GST_TYPE_FIND_MAXIMUM, caps);
/* Shortcircuit typefinding if we get caps */
GST_DEBUG_OBJECT (typefind, "Skipping typefinding, using caps from "
@@ -914,8 +957,7 @@ gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind,
/* probability is good enough too, so let's make it known ... emiting this
* signal calls our object handler which sets the caps. */
- g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
- probability, caps);
+ gst_type_find_element_emit_have_type (typefind, probability, caps);
/* .. and send out the accumulated data */
stop_typefinding (typefind);
@@ -1104,8 +1146,7 @@ gst_type_find_element_loop (GstPad * pad)
}
GST_DEBUG ("Emiting found caps %" GST_PTR_FORMAT, found_caps);
- g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE],
- 0, probability, found_caps);
+ gst_type_find_element_emit_have_type (typefind, probability, found_caps);
typefind->mode = MODE_NORMAL;
gst_caps_unref (found_caps);
} else if (typefind->mode == MODE_NORMAL) {