diff -r 9b2c3c7a1a9c -r 567bb019e3e3 gst_plugins_base/gst/videoscale/gstvideoscale.c --- a/gst_plugins_base/gst/videoscale/gstvideoscale.c Wed Mar 31 22:03:18 2010 +0300 +++ b/gst_plugins_base/gst/videoscale/gstvideoscale.c Tue Aug 31 15:30:33 2010 +0300 @@ -22,35 +22,27 @@ * SECTION:element-videoscale * @see_also: videorate, ffmpegcolorspace * - * - * * This element resizes video frames. By default the element will try to * negotiate to the same size on the source and sinkpad so that no scaling * is needed. It is therefore safe to insert this element in a pipeline to * get more robust behaviour without any cost if no scaling is needed. - * - * + * * This element supports a wide range of color spaces including various YUV and * RGB formats and is therefore generally able to operate anywhere in a * pipeline. - * + * + * * Example pipelines - * - * + * |[ * gst-launch -v filesrc location=videotestsrc.ogg ! oggdemux ! theoradec ! ffmpegcolorspace ! videoscale ! ximagesink - * - * Decode an Ogg/Theora and display the video using ximagesink. Since + * ]| Decode an Ogg/Theora and display the video using ximagesink. Since * ximagesink cannot perform scaling, the video scaling will be performed by * videoscale when you resize the video window. * To create the test Ogg/Theora file refer to the documentation of theoraenc. - * - * - * + * |[ * gst-launch -v filesrc location=videotestsrc.ogg ! oggdemux ! theoradec ! videoscale ! video/x-raw-yuv, width=50 ! xvimagesink - * - * Decode an Ogg/Theora and display the video using xvimagesink with a width of - * 50. - * + * ]| Decode an Ogg/Theora and display the video using xvimagesink with a width + * of 50. * * * Last reviewed on 2006-03-02 (0.10.4) @@ -63,15 +55,16 @@ #include #include -#include +#include +#ifdef __SYMBIAN32__ +#include +#endif #include "gstvideoscale.h" #include "vs_image.h" #include "vs_4tap.h" -#include - /* debug variable definition */ GST_DEBUG_CATEGORY (video_scale_debug); @@ -83,7 +76,7 @@ "Resizes video", "Wim Taymans "); -#define DEFAULT_PROP_METHOD GST_VIDEO_SCALE_NEAREST +#define DEFAULT_PROP_METHOD GST_VIDEO_SCALE_BILINEAR enum { @@ -92,10 +85,6 @@ /* FILL ME */ }; -/* can't handle width/height of 1 yet, since we divide a lot by (n-1) */ -#undef GST_VIDEO_SIZE_RANGE -#define GST_VIDEO_SIZE_RANGE "(int) [ 2, MAX ]" - static GstStaticCaps gst_video_scale_format_caps[] = { GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx), GST_STATIC_CAPS (GST_VIDEO_CAPS_xRGB), @@ -107,6 +96,7 @@ GST_STATIC_CAPS (GST_VIDEO_CAPS_ABGR), GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB), GST_STATIC_CAPS (GST_VIDEO_CAPS_BGR), + GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("v308")), GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV")), GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("YUY2")), GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("YVYU")), @@ -115,7 +105,18 @@ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")), GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("YV12")), GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB_16), - GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB_15) + GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB_15), + GST_STATIC_CAPS ("video/x-raw-gray, " + "bpp = 8, " + "depth = 8, " + "width = " GST_VIDEO_SIZE_RANGE ", " + "height = " GST_VIDEO_SIZE_RANGE ", " "framerate = " GST_VIDEO_FPS_RANGE), + GST_STATIC_CAPS ("video/x-raw-gray, " + "bpp = 16, " + "depth = 16, " + "endianness = BYTE_ORDER, " + "width = " GST_VIDEO_SIZE_RANGE ", " + "height = " GST_VIDEO_SIZE_RANGE ", " "framerate = " GST_VIDEO_FPS_RANGE) }; enum @@ -130,6 +131,7 @@ GST_VIDEO_SCALE_ABGR, GST_VIDEO_SCALE_RGB, GST_VIDEO_SCALE_BGR, + GST_VIDEO_SCALE_v308, GST_VIDEO_SCALE_AYUV, GST_VIDEO_SCALE_YUY2, GST_VIDEO_SCALE_YVYU, @@ -138,7 +140,9 @@ GST_VIDEO_SCALE_I420, GST_VIDEO_SCALE_YV12, GST_VIDEO_SCALE_RGB565, - GST_VIDEO_SCALE_RGB555 + GST_VIDEO_SCALE_RGB555, + GST_VIDEO_SCALE_GRAY8, + GST_VIDEO_SCALE_GRAY16 }; #define GST_TYPE_VIDEO_SCALE_METHOD (gst_video_scale_method_get_type()) @@ -146,6 +150,7 @@ gst_video_scale_method_get_type (void) { static GType video_scale_method_type = 0; + static const GEnumValue video_scale_methods[] = { {GST_VIDEO_SCALE_NEAREST, "Nearest Neighbour", "nearest-neighbour"}, {GST_VIDEO_SCALE_BILINEAR, "Bilinear", "bilinear"}, @@ -194,9 +199,13 @@ static void gst_video_scale_base_init (gpointer g_class); + static void gst_video_scale_class_init (GstVideoScaleClass * klass); + static void gst_video_scale_init (GstVideoScale * videoscale); + static void gst_video_scale_finalize (GstVideoScale * videoscale); + static gboolean gst_video_scale_src_event (GstBaseTransform * trans, GstEvent * event); @@ -277,7 +286,8 @@ g_object_class_install_property (gobject_class, PROP_METHOD, g_param_spec_enum ("method", "method", "method", - GST_TYPE_VIDEO_SCALE_METHOD, DEFAULT_PROP_METHOD, G_PARAM_READWRITE)); + GST_TYPE_VIDEO_SCALE_METHOD, DEFAULT_PROP_METHOD, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); trans_class->transform_caps = GST_DEBUG_FUNCPTR (gst_video_scale_transform_caps); @@ -367,54 +377,28 @@ structure = gst_caps_get_structure (caps, 0); - /* check compatibility of format and method before we copy the input caps */ - if (method == GST_VIDEO_SCALE_4TAP) { - guint32 fourcc; - - if (!gst_structure_has_name (structure, "video/x-raw-yuv")) - goto method_not_implemented_for_format; - if (!gst_structure_get_fourcc (structure, "format", &fourcc)) - goto method_not_implemented_for_format; - if (fourcc != GST_MAKE_FOURCC ('I', '4', '2', '0') && - fourcc != GST_MAKE_FOURCC ('Y', 'V', '1', '2')) - goto method_not_implemented_for_format; - } - ret = gst_caps_copy (caps); - structure = gst_caps_get_structure (ret, 0); + structure = gst_structure_copy (gst_caps_get_structure (ret, 0)); gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + gst_caps_merge_structure (ret, gst_structure_copy (structure)); + /* if pixel aspect ratio, make a range of it */ if ((par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) { - GstCaps *copy; - GstStructure *cstruct; - - /* copy input PAR first, this is the prefered PAR */ - gst_structure_set_value (structure, "pixel-aspect-ratio", par); - - /* then make a copy with a fraction range as a second choice */ - copy = gst_caps_copy (ret); - cstruct = gst_caps_get_structure (copy, 0); - gst_structure_set (cstruct, + gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); - /* and append */ - gst_caps_append (ret, copy); + gst_caps_merge_structure (ret, structure); + } else { + gst_structure_free (structure); } GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret); return ret; - -method_not_implemented_for_format: - { - GST_DEBUG_OBJECT (trans, "method %d not implemented for format %" - GST_PTR_FORMAT ", returning empty caps", method, caps); - return gst_caps_new_empty (); - } } static int @@ -461,6 +445,7 @@ break; case GST_VIDEO_SCALE_RGB: case GST_VIDEO_SCALE_BGR: + case GST_VIDEO_SCALE_v308: img->stride = GST_ROUND_UP_4 (img->width * 3); *size = img->stride * img->height; break; @@ -471,9 +456,14 @@ *size = img->stride * img->height; break; case GST_VIDEO_SCALE_Y: + case GST_VIDEO_SCALE_GRAY8: img->stride = GST_ROUND_UP_4 (img->width); *size = img->stride * img->height; break; + case GST_VIDEO_SCALE_GRAY16: + img->stride = GST_ROUND_UP_4 (img->width * 2); + *size = img->stride * img->height; + break; case GST_VIDEO_SCALE_I420: case GST_VIDEO_SCALE_YV12: { @@ -610,7 +600,9 @@ /* we have both PAR but they might not be fixated */ if (from_par && to_par) { gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d; + gint count = 0, w = 0, h = 0; + guint num, den; /* from_par should be fixed */ @@ -761,8 +753,12 @@ gst_video_scale_prepare_image (videoscale->format, out, dest, &dest_u, &dest_v); + if (src->height < 4 && method == GST_VIDEO_SCALE_4TAP) + method = GST_VIDEO_SCALE_BILINEAR; + switch (method) { case GST_VIDEO_SCALE_NEAREST: + GST_LOG_OBJECT (videoscale, "doing nearest scaling"); switch (videoscale->format) { case GST_VIDEO_SCALE_RGBx: case GST_VIDEO_SCALE_xRGB: @@ -777,6 +773,7 @@ break; case GST_VIDEO_SCALE_RGB: case GST_VIDEO_SCALE_BGR: + case GST_VIDEO_SCALE_v308: vs_image_scale_nearest_RGB (dest, src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_YUY2: @@ -787,8 +784,12 @@ vs_image_scale_nearest_UYVY (dest, src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_Y: + case GST_VIDEO_SCALE_GRAY8: vs_image_scale_nearest_Y (dest, src, videoscale->tmp_buf); break; + case GST_VIDEO_SCALE_GRAY16: + vs_image_scale_nearest_Y16 (dest, src, videoscale->tmp_buf); + break; case GST_VIDEO_SCALE_I420: case GST_VIDEO_SCALE_YV12: vs_image_scale_nearest_Y (dest, src, videoscale->tmp_buf); @@ -806,6 +807,7 @@ } break; case GST_VIDEO_SCALE_BILINEAR: + GST_LOG_OBJECT (videoscale, "doing bilinear scaling"); switch (videoscale->format) { case GST_VIDEO_SCALE_RGBx: case GST_VIDEO_SCALE_xRGB: @@ -820,6 +822,7 @@ break; case GST_VIDEO_SCALE_RGB: case GST_VIDEO_SCALE_BGR: + case GST_VIDEO_SCALE_v308: vs_image_scale_linear_RGB (dest, src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_YUY2: @@ -830,8 +833,12 @@ vs_image_scale_linear_UYVY (dest, src, videoscale->tmp_buf); break; case GST_VIDEO_SCALE_Y: + case GST_VIDEO_SCALE_GRAY8: vs_image_scale_linear_Y (dest, src, videoscale->tmp_buf); break; + case GST_VIDEO_SCALE_GRAY16: + vs_image_scale_linear_Y16 (dest, src, videoscale->tmp_buf); + break; case GST_VIDEO_SCALE_I420: case GST_VIDEO_SCALE_YV12: vs_image_scale_linear_Y (dest, src, videoscale->tmp_buf); @@ -849,16 +856,51 @@ } break; case GST_VIDEO_SCALE_4TAP: + GST_LOG_OBJECT (videoscale, "doing 4tap scaling"); switch (videoscale->format) { + case GST_VIDEO_SCALE_RGBx: + case GST_VIDEO_SCALE_xRGB: + case GST_VIDEO_SCALE_BGRx: + case GST_VIDEO_SCALE_xBGR: + case GST_VIDEO_SCALE_RGBA: + case GST_VIDEO_SCALE_ARGB: + case GST_VIDEO_SCALE_BGRA: + case GST_VIDEO_SCALE_ABGR: + case GST_VIDEO_SCALE_AYUV: + vs_image_scale_4tap_RGBA (dest, src, videoscale->tmp_buf); + break; + case GST_VIDEO_SCALE_RGB: + case GST_VIDEO_SCALE_BGR: + case GST_VIDEO_SCALE_v308: + vs_image_scale_4tap_RGB (dest, src, videoscale->tmp_buf); + break; + case GST_VIDEO_SCALE_YUY2: + case GST_VIDEO_SCALE_YVYU: + vs_image_scale_4tap_YUYV (dest, src, videoscale->tmp_buf); + break; + case GST_VIDEO_SCALE_UYVY: + vs_image_scale_4tap_UYVY (dest, src, videoscale->tmp_buf); + break; + case GST_VIDEO_SCALE_Y: + case GST_VIDEO_SCALE_GRAY8: + vs_image_scale_4tap_Y (dest, src, videoscale->tmp_buf); + break; + case GST_VIDEO_SCALE_GRAY16: + vs_image_scale_4tap_Y16 (dest, src, videoscale->tmp_buf); + break; case GST_VIDEO_SCALE_I420: case GST_VIDEO_SCALE_YV12: vs_image_scale_4tap_Y (dest, src, videoscale->tmp_buf); vs_image_scale_4tap_Y (&dest_u, &src_u, videoscale->tmp_buf); vs_image_scale_4tap_Y (&dest_v, &src_v, videoscale->tmp_buf); break; + case GST_VIDEO_SCALE_RGB565: + vs_image_scale_4tap_RGB565 (dest, src, videoscale->tmp_buf); + break; + case GST_VIDEO_SCALE_RGB555: + vs_image_scale_4tap_RGB555 (dest, src, videoscale->tmp_buf); + break; default: - /* FIXME: update gst_video_scale_transform_caps once RGB and/or - * other YUV formats work too */ goto unsupported; } break; @@ -929,9 +971,8 @@ static gboolean plugin_init (GstPlugin * plugin) { - #ifndef __SYMBIAN32__ oil_init (); - #endif + if (!gst_element_register (plugin, "videoscale", GST_RANK_NONE, GST_TYPE_VIDEO_SCALE)) return FALSE;