gst/videobox/gstvideobox.c: Clean up, port to 0.9, use
authorAndy Wingo <wingo@pobox.com>
Tue, 5 Jul 2005 10:11:24 +0000 (10:11 +0000)
committerAndy Wingo <wingo@pobox.com>
Tue, 5 Jul 2005 10:11:24 +0000 (10:11 +0000)
Original commit message from CVS:
2005-07-05  Andy Wingo  <wingo@pobox.com>

* gst/videobox/gstvideobox.c: Clean up, port to 0.9, use
BaseTransform.

* gst/videobox/Makefile.am: Link to base libs, include
plugins-base cflags, dist the README.

* configure.ac (GST_PLUGIN_ALL, AC_CONFIG_FILES): Add videobox to
the build.

ChangeLog
configure.ac
gst/videobox/Makefile.am
gst/videobox/gstvideobox.c

index b07e938..f200bf1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2005-07-05  Andy Wingo  <wingo@pobox.com>
+
+       * gst/videobox/gstvideobox.c: Clean up, port to 0.9, use
+       BaseTransform.
+
+       * gst/videobox/Makefile.am: Link to base libs, include
+       plugins-base cflags, dist the README.
+
+       * configure.ac (GST_PLUGIN_ALL, AC_CONFIG_FILES): Add videobox to
+       the build.
+
 2005-07-04  Wim Taymans  <wim@fluendo.com>
 
        * gst/realmedia/rmdemux.c:
index 6acad33..c26d3c0 100644 (file)
@@ -306,6 +306,7 @@ GST_PLUGINS_ALL="\
                rtsp    \
                smpte   \
                udp     \
+               videobox \
                videofilter \
                 "
 
@@ -497,6 +498,7 @@ gst/rtp/Makefile
 gst/rtsp/Makefile
 gst/smpte/Makefile
 gst/udp/Makefile
+gst/videobox/Makefile
 gst/videofilter/Makefile
 sys/Makefile
 ext/Makefile
index a857cb5..72b5c23 100644 (file)
@@ -2,8 +2,10 @@
 plugin_LTLIBRARIES = libgstvideobox.la
 
 libgstvideobox_la_SOURCES = gstvideobox.c
-libgstvideobox_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_LIBS_CFLAGS)
-libgstvideobox_la_LIBADD =
+libgstvideobox_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
+libgstvideobox_la_LIBADD = $(GST_BASE_LIBS)
 libgstvideobox_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
 noinst_HEADERS = 
+
+EXTRA_DIST = README
index ea66837..05c9da7 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #endif
 #include <gst/gst.h>
+#include <gst/base/gstbasetransform.h>
 #include <gst/video/video.h>
 
 #include <string.h>
@@ -49,11 +50,7 @@ GstVideoBoxFill;
 
 struct _GstVideoBox
 {
-  GstElement element;
-
-  /* pads */
-  GstPad *sinkpad;
-  GstPad *srcpad;
+  GstBaseTransform element;
 
   /* caps */
   gint in_width, in_height;
@@ -73,7 +70,7 @@ struct _GstVideoBox
 
 struct _GstVideoBoxClass
 {
-  GstElementClass parent_class;
+  GstBaseTransformClass parent_class;
 };
 
 /* elementfactory information */
@@ -94,14 +91,14 @@ GST_ELEMENT_DETAILS ("video box filter",
 
 enum
 {
-  ARG_0,
-  ARG_LEFT,
-  ARG_RIGHT,
-  ARG_TOP,
-  ARG_BOTTOM,
-  ARG_FILL_TYPE,
-  ARG_ALPHA,
-  ARG_BORDER_ALPHA,
+  PROP_0,
+  PROP_LEFT,
+  PROP_RIGHT,
+  PROP_TOP,
+  PROP_BOTTOM,
+  PROP_FILL_TYPE,
+  PROP_ALPHA,
+  PROP_BORDER_ALPHA,
   /* FILL ME */
 };
 
@@ -120,23 +117,22 @@ GST_STATIC_PAD_TEMPLATE ("sink",
     );
 
 
-static void gst_video_box_base_init (gpointer g_class);
-static void gst_video_box_class_init (GstVideoBoxClass * klass);
-static void gst_video_box_init (GstVideoBox * video_box);
+GST_BOILERPLATE (GstVideoBox, gst_video_box, GstBaseTransform,
+    GST_TYPE_BASE_TRANSFORM);
 
 static void gst_video_box_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 static void gst_video_box_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static gboolean gst_video_box_sink_setcaps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_video_box_chain (GstPad * pad, GstBuffer * buffer);
-
-static GstElementStateReturn gst_video_box_change_state (GstElement * element);
+static GstCaps *gst_video_box_transform_caps (GstBaseTransform * trans,
+    GstPad * pad, GstCaps * from);
+static gboolean gst_video_box_set_caps (GstBaseTransform * trans,
+    GstCaps * in, GstCaps * out);
+static GstFlowReturn gst_video_box_transform (GstBaseTransform * trans,
+    GstBuffer * in, GstBuffer ** out);
 
 
-static GstElementClass *parent_class = NULL;
-
 #define GST_TYPE_VIDEO_BOX_FILL (gst_video_box_fill_get_type())
 static GType
 gst_video_box_fill_get_type (void)
@@ -156,32 +152,6 @@ gst_video_box_fill_get_type (void)
   return video_box_fill_type;
 }
 
-/* static guint gst_video_box_signals[LAST_SIGNAL] = { 0 }; */
-
-GType
-gst_video_box_get_type (void)
-{
-  static GType video_box_type = 0;
-
-  if (!video_box_type) {
-    static const GTypeInfo video_box_info = {
-      sizeof (GstVideoBoxClass),
-      gst_video_box_base_init,
-      NULL,
-      (GClassInitFunc) gst_video_box_class_init,
-      NULL,
-      NULL,
-      sizeof (GstVideoBox),
-      0,
-      (GInstanceInitFunc) gst_video_box_init,
-    };
-
-    video_box_type =
-        g_type_register_static (GST_TYPE_ELEMENT, "GstVideoBox",
-        &video_box_info, 0);
-  }
-  return video_box_type;
-}
 
 static void
 gst_video_box_base_init (gpointer g_class)
@@ -195,67 +165,55 @@ gst_video_box_base_init (gpointer g_class)
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&gst_video_box_src_template));
 }
+
 static void
 gst_video_box_class_init (GstVideoBoxClass * klass)
 {
   GObjectClass *gobject_class;
-  GstElementClass *gstelement_class;
+  GstBaseTransformClass *trans_class;
 
   gobject_class = (GObjectClass *) klass;
-  gstelement_class = (GstElementClass *) klass;
-
-  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+  trans_class = (GstBaseTransformClass *) klass;
 
   gobject_class->set_property = gst_video_box_set_property;
   gobject_class->get_property = gst_video_box_get_property;
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILL_TYPE,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FILL_TYPE,
       g_param_spec_enum ("fill", "Fill", "How to fill the borders",
           GST_TYPE_VIDEO_BOX_FILL, DEFAULT_FILL_TYPE,
           (GParamFlags) G_PARAM_READWRITE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LEFT,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LEFT,
       g_param_spec_int ("left", "Left",
           "Pixels to box at left (<0  = add a border)", G_MININT, G_MAXINT,
           DEFAULT_LEFT, G_PARAM_READWRITE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_RIGHT,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_RIGHT,
       g_param_spec_int ("right", "Right",
           "Pixels to box at right (<0 = add a border)", G_MININT, G_MAXINT,
           DEFAULT_RIGHT, G_PARAM_READWRITE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TOP,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TOP,
       g_param_spec_int ("top", "Top",
           "Pixels to box at top (<0 = add a border)", G_MININT, G_MAXINT,
           DEFAULT_TOP, G_PARAM_READWRITE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BOTTOM,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BOTTOM,
       g_param_spec_int ("bottom", "Bottom",
           "Pixels to box at bottom (<0 = add a border)", G_MININT, G_MAXINT,
           DEFAULT_BOTTOM, G_PARAM_READWRITE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ALPHA,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ALPHA,
       g_param_spec_double ("alpha", "Alpha", "Alpha value picture", 0.0, 1.0,
           DEFAULT_ALPHA, G_PARAM_READWRITE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BORDER_ALPHA,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BORDER_ALPHA,
       g_param_spec_double ("border_alpha", "Border Alpha",
           "Alpha value of the border", 0.0, 1.0, DEFAULT_BORDER_ALPHA,
           G_PARAM_READWRITE));
 
-  gstelement_class->change_state = gst_video_box_change_state;
+  trans_class->transform_caps = gst_video_box_transform_caps;
+  trans_class->set_caps = gst_video_box_set_caps;
+  trans_class->transform = gst_video_box_transform;
 }
 
 static void
 gst_video_box_init (GstVideoBox * video_box)
 {
-  /* create the sink and src pads */
-  video_box->sinkpad =
-      gst_pad_new_from_template (gst_static_pad_template_get
-      (&gst_video_box_sink_template), "sink");
-  gst_element_add_pad (GST_ELEMENT (video_box), video_box->sinkpad);
-  gst_pad_set_chain_function (video_box->sinkpad, gst_video_box_chain);
-  gst_pad_set_setcaps_function (video_box->sinkpad, gst_video_box_sink_setcaps);
-
-  video_box->srcpad =
-      gst_pad_new_from_template (gst_static_pad_template_get
-      (&gst_video_box_src_template), "src");
-  gst_element_add_pad (GST_ELEMENT (video_box), video_box->srcpad);
-
   video_box->box_right = DEFAULT_RIGHT;
   video_box->box_left = DEFAULT_LEFT;
   video_box->box_top = DEFAULT_TOP;
@@ -270,15 +228,10 @@ static void
 gst_video_box_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
-  GstVideoBox *video_box;
-
-  /* it's not null if we got it, but it might not be ours */
-  g_return_if_fail (GST_IS_VIDEO_BOX (object));
-
-  video_box = GST_VIDEO_BOX (object);
+  GstVideoBox *video_box = GST_VIDEO_BOX (object);
 
   switch (prop_id) {
-    case ARG_LEFT:
+    case PROP_LEFT:
       video_box->box_left = g_value_get_int (value);
       if (video_box->box_left < 0) {
         video_box->border_left = -video_box->box_left;
@@ -288,7 +241,7 @@ gst_video_box_set_property (GObject * object, guint prop_id,
         video_box->crop_left = video_box->box_left;
       }
       break;
-    case ARG_RIGHT:
+    case PROP_RIGHT:
       video_box->box_right = g_value_get_int (value);
       if (video_box->box_right < 0) {
         video_box->border_right = -video_box->box_right;
@@ -298,7 +251,7 @@ gst_video_box_set_property (GObject * object, guint prop_id,
         video_box->crop_right = video_box->box_right;
       }
       break;
-    case ARG_TOP:
+    case PROP_TOP:
       video_box->box_top = g_value_get_int (value);
       if (video_box->box_top < 0) {
         video_box->border_top = -video_box->box_top;
@@ -308,7 +261,7 @@ gst_video_box_set_property (GObject * object, guint prop_id,
         video_box->crop_top = video_box->box_top;
       }
       break;
-    case ARG_BOTTOM:
+    case PROP_BOTTOM:
       video_box->box_bottom = g_value_get_int (value);
       if (video_box->box_bottom < 0) {
         video_box->border_bottom = -video_box->box_bottom;
@@ -318,13 +271,13 @@ gst_video_box_set_property (GObject * object, guint prop_id,
         video_box->crop_bottom = video_box->box_bottom;
       }
       break;
-    case ARG_FILL_TYPE:
+    case PROP_FILL_TYPE:
       video_box->fill_type = g_value_get_enum (value);
       break;
-    case ARG_ALPHA:
+    case PROP_ALPHA:
       video_box->alpha = g_value_get_double (value);
       break;
-    case ARG_BORDER_ALPHA:
+    case PROP_BORDER_ALPHA:
       video_box->border_alpha = g_value_get_double (value);
       break;
     default:
@@ -336,33 +289,28 @@ static void
 gst_video_box_get_property (GObject * object, guint prop_id, GValue * value,
     GParamSpec * pspec)
 {
-  GstVideoBox *video_box;
-
-  /* it's not null if we got it, but it might not be ours */
-  g_return_if_fail (GST_IS_VIDEO_BOX (object));
-
-  video_box = GST_VIDEO_BOX (object);
+  GstVideoBox *video_box = GST_VIDEO_BOX (object);
 
   switch (prop_id) {
-    case ARG_LEFT:
+    case PROP_LEFT:
       g_value_set_int (value, video_box->box_left);
       break;
-    case ARG_RIGHT:
+    case PROP_RIGHT:
       g_value_set_int (value, video_box->box_right);
       break;
-    case ARG_TOP:
+    case PROP_TOP:
       g_value_set_int (value, video_box->box_top);
       break;
-    case ARG_BOTTOM:
+    case PROP_BOTTOM:
       g_value_set_int (value, video_box->box_bottom);
       break;
-    case ARG_FILL_TYPE:
+    case PROP_FILL_TYPE:
       g_value_set_enum (value, video_box->fill_type);
       break;
-    case ARG_ALPHA:
+    case PROP_ALPHA:
       g_value_set_double (value, video_box->alpha);
       break;
-    case ARG_BORDER_ALPHA:
+    case PROP_BORDER_ALPHA:
       g_value_set_double (value, video_box->border_alpha);
       break;
     default:
@@ -371,19 +319,49 @@ gst_video_box_get_property (GObject * object, guint prop_id, GValue * value,
   }
 }
 
+static GstCaps *
+gst_video_box_transform_caps (GstBaseTransform * trans, GstPad * pad,
+    GstCaps * from)
+{
+  GstVideoBox *video_box;
+  GstCaps *to;
+  GstStructure *structure;
+  gint direction, i, tmp;
+
+  video_box = GST_VIDEO_BOX (trans);
+  to = gst_caps_copy (from);
+  direction = (pad == trans->sinkpad) ? 1 : -1;
+
+  for (i = 0; i < gst_caps_get_size (to); i++) {
+    structure = gst_caps_get_structure (to, i);
+    if (gst_structure_get_int (structure, "width", &tmp))
+      gst_structure_set (structure, "width", G_TYPE_INT,
+          tmp + direction * (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 + direction * (video_box->box_top + video_box->box_bottom), NULL);
+  }
+
+  return to;
+}
+
 static gboolean
-gst_video_box_sink_setcaps (GstPad * pad, GstCaps * caps)
+gst_video_box_set_caps (GstBaseTransform * trans, GstCaps * in, GstCaps * out)
 {
   GstVideoBox *video_box;
   GstStructure *structure;
   gboolean ret;
 
-  video_box = GST_VIDEO_BOX (GST_PAD_PARENT (pad));
-  structure = gst_caps_get_structure (caps, 0);
+  video_box = GST_VIDEO_BOX (trans);
 
+  structure = gst_caps_get_structure (in, 0);
   ret = gst_structure_get_int (structure, "width", &video_box->in_width);
   ret &= gst_structure_get_int (structure, "height", &video_box->in_height);
 
+  structure = gst_caps_get_structure (out, 0);
+  ret &= gst_structure_get_int (structure, "width", &video_box->out_width);
+  ret &= gst_structure_get_int (structure, "height", &video_box->out_height);
+
   return ret;
 }
 
@@ -601,110 +579,43 @@ gst_video_box_ayuv (GstVideoBox * video_box, guint8 * src, guint8 * dest)
 }
 
 static GstFlowReturn
-gst_video_box_chain (GstPad * pad, GstBuffer * buffer)
+gst_video_box_transform (GstBaseTransform * trans, GstBuffer * in,
+    GstBuffer ** out)
 {
   GstVideoBox *video_box;
-  GstBuffer *outbuf;
-  gint new_width, new_height;
   GstFlowReturn ret;
 
-  video_box = GST_VIDEO_BOX (gst_pad_get_parent (pad));
-
-  new_width =
-      video_box->in_width - (video_box->box_left + video_box->box_right);
-  new_height =
-      video_box->in_height - (video_box->box_top + video_box->box_bottom);
-
-  if (new_width != video_box->out_width ||
-      new_height != video_box->out_height ||
-      !GST_PAD_CAPS (video_box->srcpad)) {
-    GstCaps *newcaps;
-
-    newcaps = gst_caps_copy (gst_pad_get_negotiated_caps (video_box->sinkpad));
-
-    video_box->use_alpha = TRUE;
-
-    /* try AYUV first */
-    gst_caps_set_simple (newcaps,
-        "format", GST_TYPE_FOURCC, GST_STR_FOURCC ("AYUV"),
-        "width", G_TYPE_INT, new_width, "height", G_TYPE_INT, new_height, NULL);
-
-    if (GST_PAD_LINK_FAILED (gst_pad_try_set_caps (video_box->srcpad, newcaps))) {
-      video_box->use_alpha = FALSE;
-      newcaps =
-          gst_caps_copy (gst_pad_get_negotiated_caps (video_box->sinkpad));
-      gst_caps_set_simple (newcaps, "format", GST_TYPE_FOURCC,
-          GST_STR_FOURCC ("I420"), "width", G_TYPE_INT, new_width, "height",
-          G_TYPE_INT, new_height, NULL);
-
-      if (GST_PAD_LINK_FAILED (gst_pad_try_set_caps (video_box->srcpad,
-                  newcaps))) {
-        GST_ELEMENT_ERROR (video_box, CORE, NEGOTIATION, (NULL), (NULL));
-        return;
-      }
-    }
-
-    video_box->out_width = new_width;
-    video_box->out_height = new_height;
-  }
+  video_box = GST_VIDEO_BOX (trans);
 
   if (video_box->use_alpha) {
-    ret = gst_pad_alloc_buffer (video_box->srcpad,
-        GST_BUFFER_OFFSET_NONE, new_width * new_height * 4,
-        GST_RPAD_CAPS (video_box->srcpad), &outbuf);
+    ret = gst_pad_alloc_buffer (trans->srcpad,
+        GST_BUFFER_OFFSET_NONE,
+        video_box->out_height * video_box->out_height * 4,
+        GST_PAD_CAPS (trans->srcpad), out);
     if (ret != GST_FLOW_OK)
       goto done;
 
     gst_video_box_ayuv (video_box,
-        GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (outbuf));
+        GST_BUFFER_DATA (in), GST_BUFFER_DATA (*out));
   } else {
-    ret = gst_pad_alloc_buffer (video_box->srcpad,
-        GST_BUFFER_OFFSET_NONE, GST_VIDEO_I420_SIZE (new_width, new_height),
-        GST_RPAD_CAPS (video_box->srcpad), &outbuf);
+    ret = gst_pad_alloc_buffer (trans->srcpad,
+        GST_BUFFER_OFFSET_NONE,
+        GST_VIDEO_I420_SIZE (video_box->out_width, video_box->out_height),
+        GST_PAD_CAPS (trans->srcpad), out);
     if (ret != GST_FLOW_OK)
       goto done;
 
     gst_video_box_i420 (video_box,
-        GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (outbuf));
+        GST_BUFFER_DATA (in), GST_BUFFER_DATA (*out));
   }
-  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
-  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer);
 
-  ret = gst_pad_push (video_box->srcpad, outbuf);
+  gst_buffer_stamp (*out, in);
 
 done:
-  gst_buffer_unref (buffer);
-
+  gst_buffer_unref (in);
   return ret;
 }
 
-static GstElementStateReturn
-gst_video_box_change_state (GstElement * element)
-{
-  GstVideoBox *video_box;
-
-  video_box = GST_VIDEO_BOX (element);
-
-  switch (GST_STATE_TRANSITION (element)) {
-    case GST_STATE_NULL_TO_READY:
-      break;
-    case GST_STATE_READY_TO_PAUSED:
-      break;
-    case GST_STATE_PAUSED_TO_PLAYING:
-      break;
-    case GST_STATE_PLAYING_TO_PAUSED:
-      break;
-    case GST_STATE_PAUSED_TO_READY:
-      break;
-    case GST_STATE_READY_TO_NULL:
-      break;
-  }
-
-  parent_class->change_state (element);
-
-  return GST_STATE_SUCCESS;
-}
-
 static gboolean
 plugin_init (GstPlugin * plugin)
 {