fix up more enums
[platform/upstream/gst-plugins-good.git] / gst / videobox / gstvideobox.c
index 4d4de61..87a72e8 100644 (file)
 #include <gst/base/gstbasetransform.h>
 #include <gst/video/video.h>
 
+#include <liboil/liboil.h>
 #include <string.h>
 
+GST_DEBUG_CATEGORY (videobox_debug);
+#define GST_CAT_DEFAULT videobox_debug
+
 #define GST_TYPE_VIDEO_BOX \
   (gst_video_box_get_type())
 #define GST_VIDEO_BOX(obj) \
@@ -141,9 +145,9 @@ gst_video_box_fill_get_type (void)
 {
   static GType video_box_fill_type = 0;
   static GEnumValue video_box_fill[] = {
-    {VIDEO_BOX_FILL_BLACK, "0", "Black"},
-    {VIDEO_BOX_FILL_GREEN, "1", "Colorkey green"},
-    {VIDEO_BOX_FILL_BLUE, "2", "Colorkey blue"},
+    {VIDEO_BOX_FILL_BLACK, "Black", "black"},
+    {VIDEO_BOX_FILL_GREEN, "Colorkey green", "green"},
+    {VIDEO_BOX_FILL_BLUE, "Colorkey blue", "blue"},
     {0, NULL, NULL},
   };
 
@@ -212,6 +216,9 @@ gst_video_box_class_init (GstVideoBoxClass * klass)
   trans_class->set_caps = gst_video_box_set_caps;
   trans_class->get_unit_size = gst_video_box_get_unit_size;
   trans_class->transform = gst_video_box_transform;
+
+  GST_DEBUG_CATEGORY_INIT (videobox_debug, "videobox", 0,
+      "Resizes a video by adding borders or cropping");
 }
 
 static void
@@ -290,13 +297,8 @@ gst_video_box_set_property (GObject * object, guint prop_id,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
-
-  if (video_box->box_left == 0 && video_box->box_right == 0 &&
-      video_box->box_top == 0 && video_box->box_bottom == 0)
-    gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (video_box), TRUE);
-  else
-    gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (video_box), FALSE);
 }
+
 static void
 gst_video_box_get_property (GObject * object, guint prop_id, GValue * value,
     GParamSpec * pspec)
@@ -337,48 +339,46 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
 {
   GstVideoBox *video_box;
   GstCaps *to;
+  GstStructure *structure;
+  GValue list_value = { 0 }, value = {
+  0};
+  gint dir, i, tmp;
 
   video_box = GST_VIDEO_BOX (trans);
 
-  if (gst_caps_is_fixed (from)) {
-    GstCaps *to_ayuv, *to_i420;
-    GstStructure *structure;
-    gint width, height, dir;
-    gdouble fps;
-
-    dir = (direction == GST_PAD_SINK) ? -1 : 1;
-
-    structure = gst_caps_get_structure (from, 0);
-
-    gst_structure_get_int (structure, "width", &width);
-    gst_structure_get_int (structure, "height", &height);
-    gst_structure_get_double (structure, "framerate", &fps);
-
-    width += dir * (video_box->box_left + video_box->box_right);
-    height += dir * (video_box->box_top + video_box->box_bottom);
-
-    to_i420 = gst_caps_new_simple ("video/x-raw-yuv",
-        "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
-        "width", G_TYPE_INT, width,
-        "height", G_TYPE_INT, height, "framerate", G_TYPE_DOUBLE, fps, NULL);
-
-    to_ayuv = gst_caps_new_simple ("video/x-raw-yuv",
-        "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'),
-        "width", G_TYPE_INT, width,
-        "height", G_TYPE_INT, height, "framerate", G_TYPE_DOUBLE, fps, NULL);
-    to = to_i420;
-    gst_caps_append (to, to_ayuv);
-  } else {
-    GstPadTemplate *tmpl;
-
-    if (direction == GST_PAD_SINK) {
-      tmpl = gst_static_pad_template_get (&gst_video_box_src_template);
-    } else {
-      tmpl = gst_static_pad_template_get (&gst_video_box_sink_template);
+  g_value_init (&list_value, GST_TYPE_LIST);
+  g_value_init (&value, GST_TYPE_FOURCC);
+  gst_value_set_fourcc (&value, GST_MAKE_FOURCC ('I', '4', '2', '0'));
+  gst_value_list_append_value (&list_value, &value);
+  g_value_unset (&value);
+
+  to = gst_caps_copy (from);
+  dir = (direction == GST_PAD_SINK) ? -1 : 1;
+
+  for (i = 0; i < gst_caps_get_size (to); i++) {
+    structure = gst_caps_get_structure (to, i);
+    if (direction == GST_PAD_SINK) {    /* I420 to { I420, AYUV } */
+      g_value_init (&value, GST_TYPE_FOURCC);
+      gst_value_set_fourcc (&value, GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'));
+      gst_value_list_append_value (&list_value, &value);
+      g_value_unset (&value);
+      gst_structure_set_value (structure, "format", &list_value);
+    } else if (direction == GST_PAD_SRC) {
+      gst_structure_set_value (structure, "format", &list_value);
     }
-    to = gst_caps_copy (gst_pad_template_get_caps (tmpl));
+    if (gst_structure_get_int (structure, "width", &tmp))
+      gst_structure_set (structure, "width", G_TYPE_INT,
+          tmp + dir * (video_box->box_left + video_box->box_right), NULL);
+    if (gst_structure_get_int (structure, "height", &tmp))
+      gst_structure_set (structure, "height", G_TYPE_INT,
+          tmp + dir * (video_box->box_top + video_box->box_bottom), NULL);
   }
 
+  g_value_unset (&list_value);
+
+  GST_DEBUG_OBJECT (video_box, "direction %d, transformed %" GST_PTR_FORMAT
+      " to %" GST_PTR_FORMAT, direction, from, to);
+
   return to;
 }
 
@@ -401,7 +401,19 @@ gst_video_box_set_caps (GstBaseTransform * trans, GstCaps * in, GstCaps * out)
   ret &= gst_structure_get_int (structure, "height", &video_box->out_height);
   ret &= gst_structure_get_fourcc (structure, "format", &fourcc);
 
-  video_box->use_alpha = fourcc == GST_STR_FOURCC ("AYUV");
+  if (fourcc == GST_STR_FOURCC ("AYUV")) {
+    video_box->use_alpha = TRUE;
+  } else {
+    if (video_box->box_left == 0 && video_box->box_right == 0 &&
+        video_box->box_top == 0 && video_box->box_bottom == 0) {
+      gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (video_box), TRUE);
+      GST_LOG ("we are using passthrough");
+    } else {
+      gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (video_box),
+          FALSE);
+      GST_LOG ("we are not using passthrough");
+    }
+  }
 
   return ret;
 }
@@ -463,22 +475,22 @@ gst_video_box_copy_plane_i420 (GstVideoBox * video_box, guint8 * src,
 
   /* top border */
   for (j = 0; j < bt; j++) {
-    memset (dest, fill_color, dest_width);
+    oil_splat_u8_ns (dest, &fill_color, dest_width);
     dest += dest_stride;
   }
 
   /* copy and add left and right border */
   for (j = 0; j < src_crop_height; j++) {
-    memset (dest, fill_color, bl);
-    memcpy (dest + bl, src, src_crop_width);
-    memset (dest + bl + src_crop_width, fill_color, br);
+    oil_splat_u8_ns (dest, &fill_color, bl);
+    oil_memcpy (dest + bl, src, src_crop_width);
+    oil_splat_u8_ns (dest + bl + src_crop_width, &fill_color, br);
     dest += dest_stride;
     src += src_stride;
   }
 
   /* bottom border */
   for (j = 0; j < bb; j++) {
-    memset (dest, fill_color, dest_width);
+    oil_splat_u8_ns (dest, &fill_color, dest_width);
     dest += dest_stride;
   }
 }
@@ -550,14 +562,13 @@ gst_video_box_i420 (GstVideoBox * video_box, guint8 * src, guint8 * dest)
 
 /* Note the source image is always I420, we
  * are converting to AYUV on the fly here */
-
 static void
 gst_video_box_ayuv (GstVideoBox * video_box, guint8 * src, guint8 * dest)
 {
   guint8 *srcY, *srcU, *srcV;
   gint crop_width, crop_width2, crop_height;
   gint out_width, out_height;
-  gint src_stride, src_stride2;
+  gint src_stridey, src_strideu, src_stridev;
   gint br, bl, bt, bb;
   gint colorY, colorU, colorV;
   gint i, j;
@@ -574,8 +585,9 @@ gst_video_box_ayuv (GstVideoBox * video_box, guint8 * src, guint8 * dest)
   out_width = video_box->out_width;
   out_height = video_box->out_height;
 
-  src_stride = GST_VIDEO_I420_Y_ROWSTRIDE (video_box->in_width);
-  src_stride2 = src_stride / 2;
+  src_stridey = GST_VIDEO_I420_Y_ROWSTRIDE (video_box->in_width);
+  src_strideu = GST_VIDEO_I420_U_ROWSTRIDE (video_box->in_width);
+  src_stridev = GST_VIDEO_I420_V_ROWSTRIDE (video_box->in_width);
 
   crop_width =
       video_box->in_width - (video_box->crop_left + video_box->crop_right);
@@ -585,13 +597,13 @@ gst_video_box_ayuv (GstVideoBox * video_box, guint8 * src, guint8 * dest)
 
   srcY =
       src + GST_VIDEO_I420_Y_OFFSET (video_box->in_width, video_box->in_height);
-  srcY += src_stride * video_box->crop_top + video_box->crop_left;
+  srcY += src_stridey * video_box->crop_top + video_box->crop_left;
   srcU =
       src + GST_VIDEO_I420_U_OFFSET (video_box->in_width, video_box->in_height);
-  srcU += src_stride2 * (video_box->crop_top / 2) + (video_box->crop_left / 2);
+  srcU += src_strideu * (video_box->crop_top / 2) + (video_box->crop_left / 2);
   srcV =
       src + GST_VIDEO_I420_V_OFFSET (video_box->in_width, video_box->in_height);
-  srcV += src_stride2 * (video_box->crop_top / 2) + (video_box->crop_left / 2);
+  srcV += src_stridev * (video_box->crop_top / 2) + (video_box->crop_left / 2);
 
   colorY = yuv_colors_Y[video_box->fill_type];
   colorU = yuv_colors_U[video_box->fill_type];
@@ -602,24 +614,28 @@ gst_video_box_ayuv (GstVideoBox * video_box, guint8 * src, guint8 * dest)
       colorV);
 
   /* top border */
-  for (i = 0; i < bt; i++) {
-    for (j = 0; j < out_width; j++) {
-      *destp++ = ayuv;
-    }
+  if (bt) {
+    size_t nb_pixels = bt * out_width;
+
+    oil_splat_u32_ns (destp, &ayuv, nb_pixels);
+    destp += nb_pixels;
   }
   for (i = 0; i < crop_height; i++) {
     /* left border */
-    for (j = 0; j < bl; j++) {
-      *destp++ = ayuv;
+    if (bl) {
+      oil_splat_u32_ns (destp, &ayuv, bl);
+      destp += bl;
     }
     dest = (guint8 *) destp;
     /* center */
+    /* We can splat the alpha channel for the whole line */
+    oil_splat_u8 (dest, 4, &i_alpha, crop_width);
     for (j = 0; j < crop_width2; j++) {
-      *dest++ = i_alpha;
+      dest++;
       *dest++ = *srcY++;
       *dest++ = *srcU;
       *dest++ = *srcV;
-      *dest++ = i_alpha;
+      dest++;
       *dest++ = *srcY++;
       *dest++ = *srcU++;
       *dest++ = *srcV++;
@@ -628,22 +644,24 @@ gst_video_box_ayuv (GstVideoBox * video_box, guint8 * src, guint8 * dest)
       srcU -= crop_width2;
       srcV -= crop_width2;
     } else {
-      srcU += src_stride2 - crop_width2;
-      srcV += src_stride2 - crop_width2;
+      srcU += src_strideu - crop_width2;
+      srcV += src_stridev - crop_width2;
     }
-    srcY += src_stride - crop_width;
+    srcY += src_stridey - crop_width;
 
     destp = (guint32 *) dest;
     /* right border */
-    for (j = 0; j < br; j++) {
-      *destp++ = ayuv;
+    if (br) {
+      oil_splat_u32_ns (destp, &ayuv, br);
+      destp += br;
     }
   }
   /* bottom border */
-  for (i = 0; i < bb; i++) {
-    for (j = 0; j < out_width; j++) {
-      *destp++ = ayuv;
-    }
+  if (bb) {
+    size_t nb_pixels = bb * out_width;
+
+    oil_splat_u32_ns (destp, &ayuv, nb_pixels);
+    destp += nb_pixels;
   }
 }
 
@@ -675,4 +693,4 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
     GST_VERSION_MINOR,
     "videobox",
     "resizes a video by adding borders or cropping",
-    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
+    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)