videofilter: avoid holding object lock when calling basetransform function
[platform/upstream/gstreamer.git] / gst / videofilter / gstgamma.c
index eaa0dc8..481f404 100644 (file)
@@ -55,7 +55,6 @@
 #include <math.h>
 
 #include <gst/video/video.h>
-#include <gst/controller/gstcontroller.h>
 
 GST_DEBUG_CATEGORY_STATIC (gamma_debug);
 #define GST_CAT_DEFAULT gamma_debug
@@ -71,49 +70,23 @@ enum
 #define DEFAULT_PROP_GAMMA  1
 
 static GstStaticPadTemplate gst_gamma_src_template =
-    GST_STATIC_PAD_TEMPLATE ("src",
+GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";"
-        GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_BGRA ";"
-        GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_RGBA ";"
-        GST_VIDEO_CAPS_YUV ("Y444") ";"
-        GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_RGBx ";"
-        GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_BGRx ";"
-        GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
-        GST_VIDEO_CAPS_YUV ("Y42B") ";"
-        GST_VIDEO_CAPS_YUV ("NV12") ";"
-        GST_VIDEO_CAPS_YUV ("NV21") ";"
-        GST_VIDEO_CAPS_YUV ("YUY2") ";"
-        GST_VIDEO_CAPS_YUV ("UYVY") ";"
-        GST_VIDEO_CAPS_YUV ("YVYU") ";"
-        GST_VIDEO_CAPS_YUV ("I420") ";"
-        GST_VIDEO_CAPS_YUV ("YV12") ";"
-        GST_VIDEO_CAPS_YUV ("IYUV") ";" GST_VIDEO_CAPS_YUV ("Y41B")
-    )
+    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
+            "ARGB, BGRA, ABGR, RGBA, ABGR, RGBA, Y444, "
+            "xRGB, RGBx, xBGR, BGRx, RGB, BGR, Y42B, NV12, "
+            "NV21, YUY2, UYVY, YVYU, I420, YV12, IYUV, Y41B }"))
     );
 
 static GstStaticPadTemplate gst_gamma_sink_template =
-    GST_STATIC_PAD_TEMPLATE ("sink",
+GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";"
-        GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_BGRA ";"
-        GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_RGBA ";"
-        GST_VIDEO_CAPS_YUV ("Y444") ";"
-        GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_RGBx ";"
-        GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_BGRx ";"
-        GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
-        GST_VIDEO_CAPS_YUV ("Y42B") ";"
-        GST_VIDEO_CAPS_YUV ("NV12") ";"
-        GST_VIDEO_CAPS_YUV ("NV21") ";"
-        GST_VIDEO_CAPS_YUV ("YUY2") ";"
-        GST_VIDEO_CAPS_YUV ("UYVY") ";"
-        GST_VIDEO_CAPS_YUV ("YVYU") ";"
-        GST_VIDEO_CAPS_YUV ("I420") ";"
-        GST_VIDEO_CAPS_YUV ("YV12") ";"
-        GST_VIDEO_CAPS_YUV ("IYUV") ";" GST_VIDEO_CAPS_YUV ("Y41B")
-    )
+    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
+            "ARGB, BGRA, ABGR, RGBA, ABGR, RGBA, Y444, "
+            "xRGB, RGBx, xBGR, BGRx, RGB, BGR, Y42B, NV12, "
+            "NV21, YUY2, UYVY, YVYU, I420, YV12, IYUV, Y41B }"))
     );
 
 static void gst_gamma_set_property (GObject * object, guint prop_id,
@@ -121,10 +94,10 @@ static void gst_gamma_set_property (GObject * object, guint prop_id,
 static void gst_gamma_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static gboolean gst_gamma_set_caps (GstBaseTransform * base, GstCaps * incaps,
-    GstCaps * outcaps);
-static GstFlowReturn gst_gamma_transform_ip (GstBaseTransform * transform,
-    GstBuffer * buf);
+static gboolean gst_gamma_set_info (GstVideoFilter * vfilter, GstCaps * incaps,
+    GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info);
+static GstFlowReturn gst_gamma_transform_frame_ip (GstVideoFilter * vfilter,
+    GstVideoFrame * frame);
 static void gst_gamma_before_transform (GstBaseTransform * transform,
     GstBuffer * buf);
 
@@ -138,6 +111,7 @@ gst_gamma_class_init (GstGammaClass * g_class)
   GObjectClass *gobject_class = (GObjectClass *) g_class;
   GstElementClass *gstelement_class = (GstElementClass *) g_class;
   GstBaseTransformClass *trans_class = (GstBaseTransformClass *) g_class;
+  GstVideoFilterClass *vfilter_class = (GstVideoFilterClass *) g_class;
 
   GST_DEBUG_CATEGORY_INIT (gamma_debug, "gamma", 0, "gamma");
 
@@ -158,10 +132,12 @@ gst_gamma_class_init (GstGammaClass * g_class)
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&gst_gamma_src_template));
 
-  trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_gamma_set_caps);
-  trans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_gamma_transform_ip);
   trans_class->before_transform =
       GST_DEBUG_FUNCPTR (gst_gamma_before_transform);
+
+  vfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_gamma_set_info);
+  vfilter_class->transform_frame_ip =
+      GST_DEBUG_FUNCPTR (gst_gamma_transform_frame_ip);
 }
 
 static void
@@ -186,8 +162,8 @@ gst_gamma_set_property (GObject * object, guint prop_id, const GValue * value,
           val);
       GST_OBJECT_LOCK (gamma);
       gamma->gamma = val;
-      gst_gamma_calculate_tables (gamma);
       GST_OBJECT_UNLOCK (gamma);
+      gst_gamma_calculate_tables (gamma);
       break;
     }
     default:
@@ -218,38 +194,38 @@ gst_gamma_calculate_tables (GstGamma * gamma)
   gint n;
   gdouble val;
   gdouble exp;
+  gboolean passthrough = FALSE;
 
+  GST_OBJECT_LOCK (gamma);
   if (gamma->gamma == 1.0) {
-    GST_BASE_TRANSFORM (gamma)->passthrough = TRUE;
-    return;
-  }
-  GST_BASE_TRANSFORM (gamma)->passthrough = FALSE;
-
-  exp = 1.0 / gamma->gamma;
-  for (n = 0; n < 256; n++) {
-    val = n / 255.0;
-    val = pow (val, exp);
-    val = 255.0 * val;
-    gamma->gamma_table[n] = (guint8) floor (val + 0.5);
+    passthrough = TRUE;
+  } else {
+    exp = 1.0 / gamma->gamma;
+    for (n = 0; n < 256; n++) {
+      val = n / 255.0;
+      val = pow (val, exp);
+      val = 255.0 * val;
+      gamma->gamma_table[n] = (guint8) floor (val + 0.5);
+    }
   }
+  GST_OBJECT_UNLOCK (gamma);
+
+  gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (gamma), passthrough);
 }
 
 static void
-gst_gamma_planar_yuv_ip (GstGamma * gamma, guint8 * data)
+gst_gamma_planar_yuv_ip (GstGamma * gamma, GstVideoFrame * frame)
 {
   gint i, j, height;
-  gint width, row_stride, row_wrap;
+  gint width, stride, row_wrap;
   const guint8 *table = gamma->gamma_table;
+  guint8 *data;
 
-  data =
-      data + gst_video_format_get_component_offset (gamma->format, 0,
-      gamma->width, gamma->height);
-
-  width = gst_video_format_get_component_width (gamma->format, 0, gamma->width);
-  height = gst_video_format_get_component_height (gamma->format, 0,
-      gamma->height);
-  row_stride = gst_video_format_get_row_stride (gamma->format, 0, gamma->width);
-  row_wrap = row_stride - width;
+  data = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
+  stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
+  width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0);
+  height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0);
+  row_wrap = stride - width;
 
   for (i = 0; i < height; i++) {
     for (j = 0; j < width; j++) {
@@ -261,22 +237,20 @@ gst_gamma_planar_yuv_ip (GstGamma * gamma, guint8 * data)
 }
 
 static void
-gst_gamma_packed_yuv_ip (GstGamma * gamma, guint8 * data)
+gst_gamma_packed_yuv_ip (GstGamma * gamma, GstVideoFrame * frame)
 {
   gint i, j, height;
-  gint width, row_stride, row_wrap;
+  gint width, stride, row_wrap;
   gint pixel_stride;
   const guint8 *table = gamma->gamma_table;
+  guint8 *data;
 
-  data = data + gst_video_format_get_component_offset (gamma->format, 0,
-      gamma->width, gamma->height);
-
-  width = gst_video_format_get_component_width (gamma->format, 0, gamma->width);
-  height = gst_video_format_get_component_height (gamma->format, 0,
-      gamma->height);
-  row_stride = gst_video_format_get_row_stride (gamma->format, 0, gamma->width);
-  pixel_stride = gst_video_format_get_pixel_stride (gamma->format, 0);
-  row_wrap = row_stride - pixel_stride * width;
+  data = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
+  stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
+  width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0);
+  height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0);
+  pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
+  row_wrap = stride - pixel_stride * width;
 
   for (i = 0; i < height; i++) {
     for (j = 0; j < width; j++) {
@@ -302,29 +276,28 @@ static const gint cog_rgb_to_ycbcr_matrix_8bit_sdtv[] = {
 #define APPLY_MATRIX(m,o,v1,v2,v3) ((m[o*4] * v1 + m[o*4+1] * v2 + m[o*4+2] * v3 + m[o*4+3]) >> 8)
 
 static void
-gst_gamma_packed_rgb_ip (GstGamma * gamma, guint8 * data)
+gst_gamma_packed_rgb_ip (GstGamma * gamma, GstVideoFrame * frame)
 {
   gint i, j, height;
-  gint width, row_stride, row_wrap;
+  gint width, stride, row_wrap;
   gint pixel_stride;
   const guint8 *table = gamma->gamma_table;
   gint offsets[3];
   gint r, g, b;
   gint y, u, v;
+  guint8 *data;
+
+  data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
+  stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
+  width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0);
+  height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0);
 
-  offsets[0] = gst_video_format_get_component_offset (gamma->format, 0,
-      gamma->width, gamma->height);
-  offsets[1] = gst_video_format_get_component_offset (gamma->format, 1,
-      gamma->width, gamma->height);
-  offsets[2] = gst_video_format_get_component_offset (gamma->format, 2,
-      gamma->width, gamma->height);
+  offsets[0] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 0);
+  offsets[1] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 1);
+  offsets[2] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 2);
 
-  width = gst_video_format_get_component_width (gamma->format, 0, gamma->width);
-  height = gst_video_format_get_component_height (gamma->format, 0,
-      gamma->height);
-  row_stride = gst_video_format_get_row_stride (gamma->format, 0, gamma->width);
-  pixel_stride = gst_video_format_get_pixel_stride (gamma->format, 0);
-  row_wrap = row_stride - pixel_stride * width;
+  pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
+  row_wrap = stride - pixel_stride * width;
 
   for (i = 0; i < height; i++) {
     for (j = 0; j < width; j++) {
@@ -351,23 +324,16 @@ gst_gamma_packed_rgb_ip (GstGamma * gamma, guint8 * data)
 }
 
 static gboolean
-gst_gamma_set_caps (GstBaseTransform * base, GstCaps * incaps,
-    GstCaps * outcaps)
+gst_gamma_set_info (GstVideoFilter * vfilter, GstCaps * incaps,
+    GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info)
 {
-  GstGamma *gamma = GST_GAMMA (base);
+  GstGamma *gamma = GST_GAMMA (vfilter);
 
   GST_DEBUG_OBJECT (gamma,
       "setting caps: in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps,
       outcaps);
 
-  if (!gst_video_format_parse_caps (incaps, &gamma->format, &gamma->width,
-          &gamma->height))
-    goto invalid_caps;
-
-  gamma->size =
-      gst_video_format_get_size (gamma->format, gamma->width, gamma->height);
-
-  switch (gamma->format) {
+  switch (GST_VIDEO_INFO_FORMAT (in_info)) {
     case GST_VIDEO_FORMAT_I420:
     case GST_VIDEO_FORMAT_YV12:
     case GST_VIDEO_FORMAT_Y41B:
@@ -399,12 +365,14 @@ gst_gamma_set_caps (GstBaseTransform * base, GstCaps * incaps,
       goto invalid_caps;
       break;
   }
-
   return TRUE;
 
+  /* ERRORS */
 invalid_caps:
-  GST_ERROR_OBJECT (gamma, "Invalid caps: %" GST_PTR_FORMAT, incaps);
-  return FALSE;
+  {
+    GST_ERROR_OBJECT (gamma, "Invalid caps: %" GST_PTR_FORMAT, incaps);
+    return FALSE;
+  }
 }
 
 static void
@@ -421,44 +389,28 @@ gst_gamma_before_transform (GstBaseTransform * base, GstBuffer * outbuf)
       GST_TIME_ARGS (timestamp));
 
   if (GST_CLOCK_TIME_IS_VALID (stream_time))
-    gst_object_sync_values (G_OBJECT (gamma), stream_time);
+    gst_object_sync_values (GST_OBJECT (gamma), stream_time);
 }
 
 static GstFlowReturn
-gst_gamma_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
+gst_gamma_transform_frame_ip (GstVideoFilter * vfilter, GstVideoFrame * frame)
 {
-  GstGamma *gamma = GST_GAMMA (base);
-  guint8 *data;
-  gsize size;
+  GstGamma *gamma = GST_GAMMA (vfilter);
 
   if (!gamma->process)
     goto not_negotiated;
 
-  if (base->passthrough)
+  if (gst_base_transform_is_passthrough (GST_BASE_TRANSFORM (vfilter)))
     goto done;
 
-  data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_READWRITE);
-
-  if (size != gamma->size)
-    goto wrong_size;
-
   GST_OBJECT_LOCK (gamma);
-  gamma->process (gamma, data);
+  gamma->process (gamma, frame);
   GST_OBJECT_UNLOCK (gamma);
 
-  gst_buffer_unmap (outbuf, data, size);
-
 done:
   return GST_FLOW_OK;
 
   /* ERRORS */
-wrong_size:
-  {
-    GST_ELEMENT_ERROR (gamma, STREAM, FORMAT,
-        (NULL), ("Invalid buffer size %d, expected %d", size, gamma->size));
-    gst_buffer_unmap (outbuf, data, size);
-    return GST_FLOW_ERROR;
-  }
 not_negotiated:
   {
     GST_ERROR_OBJECT (gamma, "Not negotiated yet");