gamma: Use libgstvideo for format specific values and make gamma processing more...
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Sat, 17 Apr 2010 16:13:46 +0000 (18:13 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 29 Apr 2010 17:28:18 +0000 (19:28 +0200)
Allows us to easily add support for new color formats later.

gst/videofilter/gstgamma.c
gst/videofilter/gstgamma.h

index 44b4a09..5446014 100644 (file)
@@ -89,7 +89,6 @@ static gboolean gst_gamma_set_caps (GstBaseTransform * base, GstCaps * incaps,
 static GstFlowReturn gst_gamma_transform_ip (GstBaseTransform * transform,
     GstBuffer * buf);
 
-static void gst_gamma_planar411_ip (GstGamma * gamma, guint8 * data, gint size);
 static void gst_gamma_calculate_tables (GstGamma * gamma);
 
 GST_BOILERPLATE (GstGamma, gst_gamma, GstVideoFilter, GST_TYPE_VIDEO_FILTER);
@@ -197,45 +196,54 @@ gst_gamma_calculate_tables (GstGamma * gamma)
   }
 }
 
-/* Useful macros */
-#define GST_VIDEO_I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
-#define GST_VIDEO_I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
-#define GST_VIDEO_I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(GST_VIDEO_I420_Y_ROWSTRIDE(width)))/2)
+static void
+gst_gamma_planar_ip (GstGamma * gamma, guint8 * data)
+{
+  gint size;
+
+  data =
+      data + gst_video_format_get_component_offset (gamma->format, 0,
+      gamma->width, gamma->height);
+  size =
+      gst_video_format_get_row_stride (gamma->format, 0,
+      gamma->width) * gst_video_format_get_component_height (gamma->format, 0,
+      gamma->height);
 
-#define GST_VIDEO_I420_Y_OFFSET(w,h) (0)
-#define GST_VIDEO_I420_U_OFFSET(w,h) (GST_VIDEO_I420_Y_OFFSET(w,h)+(GST_VIDEO_I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
-#define GST_VIDEO_I420_V_OFFSET(w,h) (GST_VIDEO_I420_U_OFFSET(w,h)+(GST_VIDEO_I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
-#define GST_VIDEO_I420_SIZE(w,h)     (GST_VIDEO_I420_V_OFFSET(w,h)+(GST_VIDEO_I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
+  oil_tablelookup_u8 (data, 1, data, 1, gamma->gamma_table, 1, size);
+}
 
 static gboolean
 gst_gamma_set_caps (GstBaseTransform * base, GstCaps * incaps,
     GstCaps * outcaps)
 {
   GstGamma *gamma = GST_GAMMA (base);
-  GstStructure *structure;
-  gboolean res;
 
   GST_DEBUG_OBJECT (gamma,
       "setting caps: in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps,
       outcaps);
 
-  structure = gst_caps_get_structure (incaps, 0);
+  if (!gst_video_format_parse_caps (incaps, &gamma->format, &gamma->width,
+          &gamma->height))
+    goto invalid_caps;
 
-  res = gst_structure_get_int (structure, "width", &gamma->width);
-  res &= gst_structure_get_int (structure, "height", &gamma->height);
-  if (!res)
-    goto done;
+  gamma->size =
+      gst_video_format_get_size (gamma->format, gamma->width, gamma->height);
 
-  gamma->size = GST_VIDEO_I420_SIZE (gamma->width, gamma->height);
+  switch (gamma->format) {
+    case GST_VIDEO_FORMAT_I420:
+    case GST_VIDEO_FORMAT_YV12:
+      gamma->process = gst_gamma_planar_ip;
+      break;
+    default:
+      goto invalid_caps;
+      break;
+  }
 
-done:
-  return res;
-}
+  return TRUE;
 
-static void
-gst_gamma_planar411_ip (GstGamma * gamma, guint8 * data, gint size)
-{
-  oil_tablelookup_u8 (data, 1, data, 1, gamma->gamma_table, 1, size);
+invalid_caps:
+  GST_ERROR_OBJECT (gamma, "Invalid caps: %" GST_PTR_FORMAT, incaps);
+  return FALSE;
 }
 
 static GstFlowReturn
@@ -246,6 +254,9 @@ gst_gamma_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
   guint size;
   GstClockTime timestamp, stream_time;
 
+  if (!gamma->process)
+    goto not_negotiated;
+
   timestamp = GST_BUFFER_TIMESTAMP (outbuf);
   stream_time =
       gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);
@@ -266,8 +277,7 @@ gst_gamma_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
     goto wrong_size;
 
   GST_OBJECT_LOCK (gamma);
-  gst_gamma_planar411_ip (gamma, data,
-      gamma->height * GST_VIDEO_I420_Y_ROWSTRIDE (gamma->width));
+  gamma->process (gamma, data);
   GST_OBJECT_UNLOCK (gamma);
 
 done:
@@ -280,6 +290,11 @@ wrong_size:
         (NULL), ("Invalid buffer size %d, expected %d", size, gamma->size));
     return GST_FLOW_ERROR;
   }
+not_negotiated:
+  {
+    GST_ERROR_OBJECT (gamma, "Not negotiated yet");
+    return GST_FLOW_NOT_NEGOTIATED;
+  }
 }
 
 static gboolean
index 099c15f..8680dba 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef __GST_VIDEO_GAMMA_H__
 #define __GST_VIDEO_GAMMA_H__
 
+#include <gst/gst.h>
+#include <gst/video/video.h>
 #include <gst/video/gstvideofilter.h>
 
 G_BEGIN_DECLS
@@ -52,15 +54,18 @@ struct _GstGamma
   GstVideoFilter videofilter;
 
   /* format */
+  GstVideoFormat format;
   gint width;
   gint height;
   gint size;
 
   /* properties */
-  double gamma;
+  gdouble gamma;
 
   /* tables */
   guint8 gamma_table[256];
+
+  void (*process) (GstGamma *gamma, guint8 *data);
 };
 
 struct _GstGammaClass