move code from videoflip directory. Why? I don't really know.
authorDavid Schleef <ds@schleef.org>
Wed, 2 Jul 2003 06:50:32 +0000 (06:50 +0000)
committerDavid Schleef <ds@schleef.org>
Wed, 2 Jul 2003 06:50:32 +0000 (06:50 +0000)
Original commit message from CVS:
move code from videoflip directory.  Why?  I don't really know.

gst/videofilter/gstvideoflip.c
gst/videofilter/gstvideoflip.h

index 646cc1e..f10040e 100644 (file)
 
 
 /*#define DEBUG_ENABLED */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 #include <gstvideoflip.h>
 
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+
 
 /* elementfactory information */
 static GstElementDetails videoflip_details = {
-  "Video Filter Template",
+  "Video flipper",
   "Filter/Video",
   "LGPL",
-  "Template for a video filter",
+  "Flips and rotates video",
   VERSION,
   "David Schleef <ds@schleef.org>",
   "(C) 2003",
@@ -42,6 +50,7 @@ enum {
 
 enum {
   ARG_0,
+  ARG_METHOD,
   /* FILL ME */
 };
 
@@ -58,6 +67,30 @@ static GstVideoflipClass *this_class = NULL;
 static GstVideofilterClass *parent_class = NULL;
 static GstElementClass *element_class = NULL;
 
+#define GST_TYPE_VIDEOFLIP_METHOD (gst_videoflip_method_get_type())
+
+static GType
+gst_videoflip_method_get_type(void)
+{
+  static GType videoflip_method_type = 0;
+  static GEnumValue videoflip_methods[] = {
+    { GST_VIDEOFLIP_METHOD_IDENTITY,   "0", "Identity (no rotation)" },
+    { GST_VIDEOFLIP_METHOD_90R,                "1", "Rotate clockwise 90 degrees" },
+    { GST_VIDEOFLIP_METHOD_180,                "2", "Rotate 180 degrees" },
+    { GST_VIDEOFLIP_METHOD_90L,                "3", "Rotate counter-clockwise 90 degrees" },
+    { GST_VIDEOFLIP_METHOD_HORIZ,      "4", "Flip horizontally" },
+    { GST_VIDEOFLIP_METHOD_VERT,       "5", "Flip vertically" },
+    { GST_VIDEOFLIP_METHOD_TRANS,      "6", "Flip across upper left/lower right diagonal" },
+    { GST_VIDEOFLIP_METHOD_OTHER,      "7", "Flip across upper right/lower left diagonal" },
+    { 0, NULL, NULL },
+  };
+  if(!videoflip_method_type){
+    videoflip_method_type = g_enum_register_static("GstVideoflipMethod",
+       videoflip_methods);
+  }
+  return videoflip_method_type;
+}
+
 GType
 gst_videoflip_get_type (void)
 {
@@ -80,7 +113,10 @@ gst_videoflip_get_type (void)
 }
 
 static GstVideofilterFormat gst_videoflip_formats[] = {
+  /* planar */
+  { "YV12", 12, gst_videoflip_planar411, },
   { "I420", 12, gst_videoflip_planar411, },
+  { "IYUV", 12, gst_videoflip_planar411, },
 };
 
 static void
@@ -95,12 +131,10 @@ gst_videoflip_class_init (GstVideoflipClass *klass)
   gstelement_class = (GstElementClass*)klass;
   gstvideofilter_class = (GstVideofilterClass *)klass;
 
-#if 0
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_METHOD,
       g_param_spec_enum("method","method","method",
       GST_TYPE_VIDEOFLIP_METHOD, GST_VIDEOFLIP_METHOD_90R,
       G_PARAM_READWRITE));
-#endif
 
   this_class = klass;
   parent_class = g_type_class_ref(GST_TYPE_VIDEOFILTER);
@@ -164,7 +198,7 @@ gst_videoflip_init (GstVideoflip *videoflip)
 {
   GstVideofilter *videofilter;
 
-  GST_DEBUG("gst_videoflip_init");
+  GST_DEBUG ("gst_videoflip_init");
 
   videofilter = GST_VIDEOFILTER(videoflip);
 
@@ -182,19 +216,19 @@ gst_videoflip_init (GstVideoflip *videoflip)
 static void
 gst_videoflip_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
-  GstVideoflip *src;
+  GstVideoflip *videoflip;
 
   /* it's not null if we got it, but it might not be ours */
   g_return_if_fail(GST_IS_VIDEOFLIP(object));
-  src = GST_VIDEOFLIP(object);
+  videoflip = GST_VIDEOFLIP(object);
 
-  GST_DEBUG("gst_videoflip_set_property");
+  GST_DEBUG ("gst_videoflip_set_property");
   switch (prop_id) {
-#if 0
     case ARG_METHOD:
-      src->method = g_value_get_enum (value);
+      videoflip->method = g_value_get_enum (value);
+      /* FIXME is this ok? (threading issues) */
+      gst_videoflip_setup(GST_VIDEOFILTER(videoflip));
       break;
-#endif
     default:
       break;
   }
@@ -203,18 +237,16 @@ gst_videoflip_set_property (GObject *object, guint prop_id, const GValue *value,
 static void
 gst_videoflip_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
 {
-  GstVideoflip *src;
+  GstVideoflip *videoflip;
 
   /* it's not null if we got it, but it might not be ours */
   g_return_if_fail(GST_IS_VIDEOFLIP(object));
-  src = GST_VIDEOFLIP(object);
+  videoflip = GST_VIDEOFLIP(object);
 
   switch (prop_id) {
-#if 0
     case ARG_METHOD:
-      g_value_set_enum (value, src->method);
+      g_value_set_enum (value, videoflip->method);
       break;
-#endif
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -248,25 +280,162 @@ GstPluginDesc plugin_desc = {
   plugin_init
 };
 
-static void gst_videoflip_setup(GstVideofilter *videofilter)
+
+static void gst_videoflip_flip(GstVideoflip *videoflip, unsigned char *dest,
+    unsigned char *src, int sw, int sh, int dw, int dh);
+
+
+static void gst_videoflip_setup (GstVideofilter *videofilter)
 {
+  int from_width, from_height;
   GstVideoflip *videoflip;
 
-  g_return_if_fail(GST_IS_VIDEOFLIP(videofilter));
+  GST_DEBUG("gst_videoflip_setup");
+
   videoflip = GST_VIDEOFLIP(videofilter);
 
-  /* if any setup needs to be done, do it here */
+  from_width = gst_videofilter_get_input_width(videofilter);
+  from_height = gst_videofilter_get_input_height(videofilter);
+
+  if(from_width==0 || from_height==0){
+    return;
+  }
+
+  switch(videoflip->method){
+    case GST_VIDEOFLIP_METHOD_90R:
+    case GST_VIDEOFLIP_METHOD_90L:
+    case GST_VIDEOFLIP_METHOD_TRANS:
+    case GST_VIDEOFLIP_METHOD_OTHER:
+      gst_videofilter_set_output_size(videofilter, from_height, from_width);
+      break;
+    case GST_VIDEOFLIP_METHOD_IDENTITY:
+    case GST_VIDEOFLIP_METHOD_180:
+    case GST_VIDEOFLIP_METHOD_HORIZ:
+    case GST_VIDEOFLIP_METHOD_VERT:
+      gst_videofilter_set_output_size(videofilter, from_width, from_height);
+      break;
+    default:
+      g_assert_not_reached();
+      break;
+  }
+
+  GST_DEBUG ("format=%p \"%s\" from %dx%d to %dx%d",
+               videofilter->format, videofilter->format->fourcc,
+               from_width, from_height,
+               videofilter->to_width, videofilter->to_height);
+
+  if(videoflip->method == GST_VIDEOFLIP_METHOD_IDENTITY){
+    GST_DEBUG ("videoflip: using passthru");
+    videofilter->passthru = TRUE;
+  }else{
+    videofilter->passthru = FALSE;
+  }
+
+  videofilter->from_buf_size = (videofilter->from_width * videofilter->from_height
+                 * videofilter->format->depth) / 8;
+  videofilter->to_buf_size = (videofilter->to_width * videofilter->to_height
+                 * videofilter->format->depth) / 8;
 
+  videofilter->inited = TRUE;
 }
 
 static void gst_videoflip_planar411(GstVideofilter *videofilter,
     void *dest, void *src)
 {
   GstVideoflip *videoflip;
+  int sw;
+  int sh;
+  int dw;
+  int dh;
 
   g_return_if_fail(GST_IS_VIDEOFLIP(videofilter));
   videoflip = GST_VIDEOFLIP(videofilter);
 
-  /* do something interesting here */
+  sw = videofilter->from_width;
+  sh = videofilter->from_height;
+  dw = videofilter->to_width;
+  dh = videofilter->to_height;
+
+  GST_DEBUG ("videoflip: scaling planar 4:1:1 %dx%d to %dx%d", sw, sh, dw, dh);
+
+  gst_videoflip_flip(videoflip, dest, src, sw, sh, dw, dh);
+
+  src += sw*sh;
+  dest += dw*dh;
+
+  dh = dh>>1;
+  dw = dw>>1;
+  sh = sh>>1;
+  sw = sw>>1;
+
+  gst_videoflip_flip(videoflip, dest, src, sw, sh, dw, dh);
+
+  src += sw*sh;
+  dest += dw*dh;
+
+  gst_videoflip_flip(videoflip, dest, src, sw, sh, dw, dh);
+}
+
+static void
+gst_videoflip_flip(GstVideoflip *videoflip, unsigned char *dest,
+    unsigned char *src, int sw, int sh, int dw, int dh)
+{
+  int x,y;
+
+  switch(videoflip->method){
+    case GST_VIDEOFLIP_METHOD_90R:
+      for(y=0;y<dh;y++){
+        for(x=0;x<dw;x++){
+         dest[y*dw + x] = src[(sh - 1 - x)*sw + y];
+       }
+      }
+      break;
+    case GST_VIDEOFLIP_METHOD_90L:
+      for(y=0;y<dh;y++){
+        for(x=0;x<dw;x++){
+         dest[y*dw + x] = src[x*sw + (sw - 1 - y)];
+       }
+      }
+      break;
+    case GST_VIDEOFLIP_METHOD_180:
+      for(y=0;y<dh;y++){
+        for(x=0;x<dw;x++){
+         dest[y*dw + x] = src[(sh - 1 - y)*sw + (sw - 1 - x)];
+       }
+      }
+      break;
+    case GST_VIDEOFLIP_METHOD_HORIZ:
+      for(y=0;y<dh;y++){
+        for(x=0;x<dw;x++){
+         dest[y*dw + x] = src[y*sw + (sw - 1 - x)];
+       }
+      }
+      break;
+    case GST_VIDEOFLIP_METHOD_VERT:
+      for(y=0;y<dh;y++){
+        for(x=0;x<dw;x++){
+         dest[y*dw + x] = src[(sh - 1 - y)*sw + x];
+       }
+      }
+      break;
+    case GST_VIDEOFLIP_METHOD_TRANS:
+      for(y=0;y<dh;y++){
+        for(x=0;x<dw;x++){
+         dest[y*dw + x] = src[x*sw + y];
+       }
+      }
+      break;
+    case GST_VIDEOFLIP_METHOD_OTHER:
+      for(y=0;y<dh;y++){
+        for(x=0;x<dw;x++){
+         dest[y*dw + x] = src[(sh - 1 - x)*sw + (sw - 1 - y)];
+       }
+      }
+      break;
+    default:
+      /* FIXME */
+      break;
+  }
 }
 
+
index ae5d1fd..9260a8c 100644 (file)
 
 G_BEGIN_DECLS
 
+typedef enum {
+  GST_VIDEOFLIP_METHOD_IDENTITY,
+  GST_VIDEOFLIP_METHOD_90R,
+  GST_VIDEOFLIP_METHOD_180,
+  GST_VIDEOFLIP_METHOD_90L,
+  GST_VIDEOFLIP_METHOD_HORIZ,
+  GST_VIDEOFLIP_METHOD_VERT,
+  GST_VIDEOFLIP_METHOD_TRANS,
+  GST_VIDEOFLIP_METHOD_OTHER,
+} GstVideoflipMethod;
+
+
 #define GST_TYPE_VIDEOFLIP \
   (gst_videoflip_get_type())
 #define GST_VIDEOFLIP(obj) \
@@ -47,6 +59,7 @@ typedef struct _GstVideoflipClass GstVideoflipClass;
 struct _GstVideoflip {
   GstVideofilter videofilter;
 
+  GstVideoflipMethod method;
 };
 
 struct _GstVideoflipClass {