From e22a782729f1abd7e3ad98c1929ea51620918618 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 2 Jul 2003 06:50:32 +0000 Subject: move code from videoflip directory. Why? I don't really know. Original commit message from CVS: move code from videoflip directory. Why? I don't really know. --- gst/videofilter/gstvideoflip.c | 209 +++++++++++++++++++++++++++++++++++++---- gst/videofilter/gstvideoflip.h | 13 +++ 2 files changed, 202 insertions(+), 20 deletions(-) (limited to 'gst/videofilter') diff --git a/gst/videofilter/gstvideoflip.c b/gst/videofilter/gstvideoflip.c index 646cc1e2..f10040e9 100644 --- a/gst/videofilter/gstvideoflip.c +++ b/gst/videofilter/gstvideoflip.c @@ -20,15 +20,23 @@ /*#define DEBUG_ENABLED */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include +#include +#include +#include + + /* 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 ", "(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