capsfilter: optimisation: avoid unnecessary gst_pad_has_current_caps() checks
authorTim-Philipp Müller <tim@centricular.com>
Tue, 8 Mar 2016 19:08:16 +0000 (19:08 +0000)
committerSebastian Dröge <sebastian@centricular.com>
Thu, 24 Mar 2016 12:48:40 +0000 (14:48 +0200)
No need to do this for every input buffer, since it involves
locking and iterating of the sticky events array and such.

https://bugzilla.gnome.org/show_bug.cgi?id=763337

plugins/elements/gstcapsfilter.c
plugins/elements/gstcapsfilter.h

index 26ae121..30b6b99 100644 (file)
@@ -167,6 +167,7 @@ gst_capsfilter_init (GstCapsFilter * filter)
   gst_base_transform_set_prefer_passthrough (trans, FALSE);
   filter->filter_caps = gst_caps_new_any ();
   filter->filter_caps_used = FALSE;
   gst_base_transform_set_prefer_passthrough (trans, FALSE);
   filter->filter_caps = gst_caps_new_any ();
   filter->filter_caps_used = FALSE;
+  filter->got_sink_caps = FALSE;
   filter->caps_change_mode = DEFAULT_CAPS_CHANGE_MODE;
 }
 
   filter->caps_change_mode = DEFAULT_CAPS_CHANGE_MODE;
 }
 
@@ -404,7 +405,7 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
   *buf = input;
 
   if (GST_PAD_MODE (trans->srcpad) == GST_PAD_MODE_PUSH
   *buf = input;
 
   if (GST_PAD_MODE (trans->srcpad) == GST_PAD_MODE_PUSH
-      && !gst_pad_has_current_caps (trans->sinkpad)) {
+      && !filter->got_sink_caps) {
 
     /* No caps. See if the output pad only supports fixed caps */
     GstCaps *out_caps;
 
     /* No caps. See if the output pad only supports fixed caps */
     GstCaps *out_caps;
@@ -505,7 +506,7 @@ gst_capsfilter_sink_event (GstBaseTransform * trans, GstEvent * event)
     }
     g_list_free (filter->pending_events);
     filter->pending_events = NULL;
     }
     g_list_free (filter->pending_events);
     filter->pending_events = NULL;
-  } else if (!gst_pad_has_current_caps (trans->sinkpad)) {
+  } else if (!filter->got_sink_caps) {
     GST_LOG_OBJECT (trans, "Got %s event before caps, queueing",
         GST_EVENT_TYPE_NAME (event));
 
     GST_LOG_OBJECT (trans, "Got %s event before caps, queueing",
         GST_EVENT_TYPE_NAME (event));
 
@@ -521,32 +522,35 @@ done:
       GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans,
       gst_event_ref (event));
 
       GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans,
       gst_event_ref (event));
 
-  if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS
-      && filter->caps_change_mode == GST_CAPS_FILTER_CAPS_CHANGE_MODE_DELAYED) {
-    GList *l;
-    GstCaps *caps;
-
-    gst_event_parse_caps (event, &caps);
-
-    /* Remove all previous caps up to one that works.
-     * Note that this might keep some leftover caps if there
-     * are multiple compatible caps */
-    GST_OBJECT_LOCK (filter);
-    for (l = g_list_last (filter->previous_caps); l; l = l->prev) {
-      if (gst_caps_can_intersect (caps, l->data)) {
-        while (l->next) {
-          gst_caps_unref (l->next->data);
-          l = g_list_delete_link (l, l->next);
+  if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS) {
+    filter->got_sink_caps = TRUE;
+    if (filter->caps_change_mode == GST_CAPS_FILTER_CAPS_CHANGE_MODE_DELAYED) {
+      GList *l;
+      GstCaps *caps;
+
+      gst_event_parse_caps (event, &caps);
+
+      /* Remove all previous caps up to one that works.
+       * Note that this might keep some leftover caps if there
+       * are multiple compatible caps */
+      GST_OBJECT_LOCK (filter);
+      for (l = g_list_last (filter->previous_caps); l; l = l->prev) {
+        if (gst_caps_can_intersect (caps, l->data)) {
+          while (l->next) {
+            gst_caps_unref (l->next->data);
+            l = g_list_delete_link (l, l->next);
+          }
+          break;
         }
         }
-        break;
       }
       }
+      if (!l && gst_caps_can_intersect (caps, filter->filter_caps)) {
+        g_list_free_full (filter->previous_caps,
+            (GDestroyNotify) gst_caps_unref);
+        filter->previous_caps = NULL;
+        filter->filter_caps_used = TRUE;
+      }
+      GST_OBJECT_UNLOCK (filter);
     }
     }
-    if (!l && gst_caps_can_intersect (caps, filter->filter_caps)) {
-      g_list_free_full (filter->previous_caps, (GDestroyNotify) gst_caps_unref);
-      filter->previous_caps = NULL;
-      filter->filter_caps_used = TRUE;
-    }
-    GST_OBJECT_UNLOCK (filter);
   }
   gst_event_unref (event);
 
   }
   gst_event_unref (event);
 
@@ -566,5 +570,7 @@ gst_capsfilter_stop (GstBaseTransform * trans)
   filter->previous_caps = NULL;
   GST_OBJECT_UNLOCK (filter);
 
   filter->previous_caps = NULL;
   GST_OBJECT_UNLOCK (filter);
 
+  filter->got_sink_caps = FALSE;
+
   return TRUE;
 }
   return TRUE;
 }
index 652ec34..8a57bc4 100644 (file)
@@ -67,6 +67,7 @@ struct _GstCapsFilter {
   GstCaps *filter_caps;
   gboolean filter_caps_used;
   GstCapsFilterCapsChangeMode caps_change_mode;
   GstCaps *filter_caps;
   gboolean filter_caps_used;
   GstCapsFilterCapsChangeMode caps_change_mode;
+  gboolean got_sink_caps;
 
   GList *pending_events;
   GList *previous_caps;
 
   GList *pending_events;
   GList *previous_caps;