Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / plugins / elements / gstcapsfilter.c
index 2dde28d..16278dc 100644 (file)
@@ -61,12 +61,12 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
 GST_DEBUG_CATEGORY_STATIC (gst_capsfilter_debug);
 #define GST_CAT_DEFAULT gst_capsfilter_debug
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_capsfilter_debug, "capsfilter", 0, \
     "capsfilter element");
-
-GST_BOILERPLATE_FULL (GstCapsFilter, gst_capsfilter, GstBaseTransform,
-    GST_TYPE_BASE_TRANSFORM, _do_init);
+#define gst_capsfilter_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstCapsFilter, gst_capsfilter, GST_TYPE_BASE_TRANSFORM,
+    _do_init);
 
 
 static void gst_capsfilter_set_property (GObject * object, guint prop_id,
@@ -76,34 +76,19 @@ static void gst_capsfilter_get_property (GObject * object, guint prop_id,
 static void gst_capsfilter_dispose (GObject * object);
 
 static GstCaps *gst_capsfilter_transform_caps (GstBaseTransform * base,
-    GstPadDirection direction, GstCaps * caps);
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter);
 static gboolean gst_capsfilter_accept_caps (GstBaseTransform * base,
     GstPadDirection direction, GstCaps * caps);
 static GstFlowReturn gst_capsfilter_transform_ip (GstBaseTransform * base,
     GstBuffer * buf);
 static GstFlowReturn gst_capsfilter_prepare_buf (GstBaseTransform * trans,
-    GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
-
-static void
-gst_capsfilter_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "CapsFilter",
-      "Generic",
-      "Pass data without modification, limiting formats",
-      "David Schleef <ds@schleef.org>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-}
+    GstBuffer * input, GstBuffer ** buf);
 
 static void
 gst_capsfilter_class_init (GstCapsFilterClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseTransformClass *trans_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
@@ -118,6 +103,17 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass)
               "object."), GST_TYPE_CAPS,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gstelement_class = GST_ELEMENT_CLASS (klass);
+  gst_element_class_set_details_simple (gstelement_class,
+      "CapsFilter",
+      "Generic",
+      "Pass data without modification, limiting formats",
+      "David Schleef <ds@schleef.org>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
   trans_class = GST_BASE_TRANSFORM_CLASS (klass);
   trans_class->transform_caps =
       GST_DEBUG_FUNCPTR (gst_capsfilter_transform_caps);
@@ -128,7 +124,7 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass)
 }
 
 static void
-gst_capsfilter_init (GstCapsFilter * filter, GstCapsFilterClass * g_class)
+gst_capsfilter_init (GstCapsFilter * filter)
 {
   GstBaseTransform *trans = GST_BASE_TRANSFORM (filter);
   gst_base_transform_set_gap_aware (trans, TRUE);
@@ -172,8 +168,7 @@ gst_capsfilter_set_property (GObject * object, guint prop_id,
       GST_DEBUG_OBJECT (capsfilter, "set new caps %" GST_PTR_FORMAT, new_caps);
 
       /* filter the currently negotiated format against the new caps */
-      GST_OBJECT_LOCK (GST_BASE_TRANSFORM_SINK_PAD (object));
-      nego = GST_PAD_CAPS (GST_BASE_TRANSFORM_SINK_PAD (object));
+      nego = gst_pad_get_current_caps (GST_BASE_TRANSFORM_SINK_PAD (object));
       if (nego) {
         GST_DEBUG_OBJECT (capsfilter, "we had negotiated caps %" GST_PTR_FORMAT,
             nego);
@@ -202,6 +197,7 @@ gst_capsfilter_set_property (GObject * object, guint prop_id,
             suggest = gst_caps_copy (new_caps);
           }
         }
+        gst_caps_unref (nego);
       } else {
         GST_DEBUG_OBJECT (capsfilter, "no negotiated caps");
         /* Suggest the new caps, we can't just rely on _get_caps as this may
@@ -209,7 +205,6 @@ gst_capsfilter_set_property (GObject * object, guint prop_id,
          * pushed yet */
         suggest = gst_caps_copy (new_caps);
       }
-      GST_OBJECT_UNLOCK (GST_BASE_TRANSFORM_SINK_PAD (object));
 
       GST_DEBUG_OBJECT (capsfilter, "suggesting new caps %" GST_PTR_FORMAT,
           suggest);
@@ -255,18 +250,28 @@ gst_capsfilter_dispose (GObject * object)
 
 static GstCaps *
 gst_capsfilter_transform_caps (GstBaseTransform * base,
-    GstPadDirection direction, GstCaps * caps)
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
 {
   GstCapsFilter *capsfilter = GST_CAPSFILTER (base);
-  GstCaps *ret, *filter_caps;
+  GstCaps *ret, *filter_caps, *tmp;
 
   GST_OBJECT_LOCK (capsfilter);
   filter_caps = gst_caps_ref (capsfilter->filter_caps);
   GST_OBJECT_UNLOCK (capsfilter);
 
-  ret = gst_caps_intersect (caps, filter_caps);
+  if (filter) {
+    tmp =
+        gst_caps_intersect_full (filter, filter_caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (filter_caps);
+    filter_caps = tmp;
+  }
+
+  ret = gst_caps_intersect_full (filter_caps, caps, GST_CAPS_INTERSECT_FIRST);
+
   GST_DEBUG_OBJECT (capsfilter, "input:     %" GST_PTR_FORMAT, caps);
-  GST_DEBUG_OBJECT (capsfilter, "filter:    %" GST_PTR_FORMAT, filter_caps);
+  GST_DEBUG_OBJECT (capsfilter, "filter:    %" GST_PTR_FORMAT, filter);
+  GST_DEBUG_OBJECT (capsfilter, "caps filter:    %" GST_PTR_FORMAT,
+      filter_caps);
   GST_DEBUG_OBJECT (capsfilter, "intersect: %" GST_PTR_FORMAT, ret);
 
   gst_caps_unref (filter_caps);
@@ -322,43 +327,21 @@ gst_capsfilter_transform_ip (GstBaseTransform * base, GstBuffer * buf)
  */
 static GstFlowReturn
 gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
-    gint size, GstCaps * caps, GstBuffer ** buf)
+    GstBuffer ** buf)
 {
   GstFlowReturn ret = GST_FLOW_OK;
 
-  if (GST_BUFFER_CAPS (input) != NULL) {
-    /* Output buffer already has caps */
-    GST_LOG_OBJECT (trans, "Input buffer already has caps (implicitely fixed)");
-    /* FIXME : Move this behaviour to basetransform. The given caps are the ones
-     * of the source pad, therefore our outgoing buffers should always have
-     * those caps. */
-    if (GST_BUFFER_CAPS (input) != caps) {
-      /* caps are different, make a metadata writable output buffer to set
-       * caps */
-      if (gst_buffer_is_metadata_writable (input)) {
-        /* input is writable, just set caps and use this as the output */
-        *buf = input;
-        gst_buffer_set_caps (*buf, caps);
-        gst_buffer_ref (input);
-      } else {
-        GST_DEBUG_OBJECT (trans, "Creating sub-buffer and setting caps");
-        *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
-        gst_buffer_set_caps (*buf, caps);
-      }
-    } else {
-      /* caps are right, just use a ref of the input as the outbuf */
-      *buf = input;
-      gst_buffer_ref (input);
-    }
-  } else {
+  /* always return the input as output buffer */
+  *buf = input;
+
+  if (!gst_pad_has_current_caps (trans->sinkpad)) {
     /* Buffer has no caps. See if the output pad only supports fixed caps */
     GstCaps *out_caps;
 
-    out_caps = GST_PAD_CAPS (trans->srcpad);
+    GST_LOG_OBJECT (trans, "Input pad does not have caps");
 
-    if (out_caps != NULL) {
-      gst_caps_ref (out_caps);
-    } else {
+    out_caps = gst_pad_get_current_caps (trans->srcpad);
+    if (out_caps == NULL) {
       out_caps = gst_pad_get_allowed_caps (trans->srcpad);
       g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR);
     }
@@ -368,18 +351,10 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
 
     if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) {
       GST_DEBUG_OBJECT (trans, "Have fixed output caps %"
-          GST_PTR_FORMAT " to apply to buffer with no caps", out_caps);
-      if (gst_buffer_is_metadata_writable (input)) {
-        gst_buffer_ref (input);
-        *buf = input;
-      } else {
-        GST_DEBUG_OBJECT (trans, "Creating sub-buffer and setting caps");
-        *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
-      }
-      GST_BUFFER_CAPS (*buf) = out_caps;
+          GST_PTR_FORMAT " to apply to srcpad", out_caps);
 
-      if (GST_PAD_CAPS (trans->srcpad) == NULL)
-        gst_pad_set_caps (trans->srcpad, out_caps);
+      if (!gst_pad_has_current_caps (trans->srcpad))
+        gst_pad_push_event (trans->srcpad, gst_event_new_caps (out_caps));
     } else {
       gchar *caps_str = gst_caps_to_string (out_caps);