From: Wim Taymans Date: Sun, 26 Oct 2014 04:58:56 +0000 (+0100) Subject: resampler: add parameters to cubic filter X-Git-Tag: 1.6.0~915 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=716b91d86e5b736786b69847d7d56d455479fdd5;p=platform%2Fupstream%2Fgst-plugins-base.git resampler: add parameters to cubic filter Improve cubic filter and add parameters. Switch to mitchell filter by default. --- diff --git a/gst-libs/gst/video/resampler.c b/gst-libs/gst/video/resampler.c index 54cbde4..2fdf295 100644 --- a/gst-libs/gst/video/resampler.c +++ b/gst-libs/gst/video/resampler.c @@ -38,6 +38,8 @@ struct _ResamplerParams gdouble (*get_tap) (ResamplerParams * params, gint l, gint xi, gdouble x); + /* for cubic */ + gdouble b, c; /* used by lanczos */ gdouble ex, fx, dx; /* extra params */ @@ -91,33 +93,43 @@ get_linear_tap (ResamplerParams * params, gint l, gint xi, gdouble x) } static gdouble -bicubic (gdouble s) +bicubic (gdouble s, gdouble b, gdouble c) { + gdouble s2, s3; + s = fabs (s); + s2 = s * s; + s3 = s2 * s; if (s <= 1.0) - return 3.0 * (s * s * s) / 2.0 - 5.0 * (s * s) / 2.0 + 1.0; + return ((12.0 - 9.0 * b - 6.0 * c) * s3 + + (-18.0 + 12.0 * b + 6.0 * c) * s2 + (6.0 - 2.0 * b)) / 6.0; else if (s <= 2.0) - return -1.0 * (s * s * s) / 2.0 + 5.0 * (s * s) / 2.0 - 4.0 * s + 2.0; + return ((-b - 6.0 * c) * s3 + + (6.0 * b + 30.0 * c) * s2 + + (-12.0 * b - 48.0 * c) * s + (8.0 * b + 24.0 * c)) / 6.0; else return 0.0; } static gdouble -get_bicubic_tap (ResamplerParams * params, gint l, gint xi, gdouble x) +get_cubic_tap (ResamplerParams * params, gint l, gint xi, gdouble x) { - gdouble a, res; + gdouble a, b, c, res; a = x - (xi + 1); + b = params->b; + c = params->c; + if (l == 0) - res = bicubic (1.0 + a); + res = bicubic (1.0 + a, b, c); else if (l == 1) - res = bicubic (a); + res = bicubic (a, b, c); else if (l == 2) - res = bicubic (1.0 - a); + res = bicubic (1.0 - a, b, c); else - res = bicubic (2.0 - a); + res = bicubic (2.0 - a, b, c); return res; } @@ -277,9 +289,17 @@ gst_resampler_init (GstResampler * resampler, if (n_taps == 0) n_taps = 2; break; - case GST_RESAMPLER_METHOD_BICUBIC: + case GST_RESAMPLER_METHOD_CUBIC: + if (!options + || !gst_structure_get_double (options, GST_RESAMPLER_OPT_CUBIC_B, + ¶ms.b)) + params.b = 1.0 / 3.0; + if (!options + || !gst_structure_get_double (options, GST_RESAMPLER_OPT_CUBIC_C, + ¶ms.c)) + params.c = 1.0 / 3.0; n_taps = 4; - params.get_tap = get_bicubic_tap; + params.get_tap = get_cubic_tap; break; case GST_RESAMPLER_METHOD_SINC: params.get_tap = get_sinc_tap; diff --git a/gst-libs/gst/video/resampler.h b/gst-libs/gst/video/resampler.h index e11096e..1d525d2 100644 --- a/gst-libs/gst/video/resampler.h +++ b/gst-libs/gst/video/resampler.h @@ -32,7 +32,7 @@ typedef struct _GstResampler GstResampler; * upsampling and drops when downsampling * @GST_RESAMPLER_METHOD_LINEAR: Uses linear interpolation to reconstruct * missing samples and averaging to downsample - * @GST_RESAMPLER_METHOD_BICUBIC: Uses bicubic interpolation + * @GST_RESAMPLER_METHOD_CUBIC: Uses cubic interpolation * @GST_RESAMPLER_METHOD_SINC: Uses sinc interpolation * @GST_RESAMPLER_METHOD_LANCZOS: Uses lanczos interpolation * @@ -43,12 +43,43 @@ typedef struct _GstResampler GstResampler; typedef enum { GST_RESAMPLER_METHOD_NEAREST, GST_RESAMPLER_METHOD_LINEAR, - GST_RESAMPLER_METHOD_BICUBIC, + GST_RESAMPLER_METHOD_CUBIC, GST_RESAMPLER_METHOD_SINC, GST_RESAMPLER_METHOD_LANCZOS, } GstResamplerMethod; /** + * GST_RESAMPLER_OPT_CUBIC_B: + * + * G_TYPE_DOUBLE, B parameter of the cubic filter. The B + * parameter controls the bluriness. Values between 0.0 and + * 2.0 are accepted. 1/3 is the default. + * + * Below are some values of popular filters: + * B C + * Hermite 0.0 0.0 + * Spline 1.0 0.0 + * Catmull-Rom 0.0 1/2 + * Mitchell 1/3 1/3 + * Robidoux 0.3782 0.3109 + * Robidoux + * Sharp 0.2620 0.3690 + * Robidoux + * Soft 0.6796 0.1602 + */ +#define GST_RESAMPLER_OPT_CUBIC_B "GstResampler.cubic-b" +/** + * GST_RESAMPLER_OPT_CUBIC_C: + * + * G_TYPE_DOUBLE, C parameter of the cubic filter. The C + * parameter controls the Keys alpha value. Values between 0.0 and + * 2.0 are accepted. 1/3 is the default. + * + * See #GST_RESAMPLER_OPT_CUBIC_B for some more common values + */ +#define GST_RESAMPLER_OPT_CUBIC_C "GstResampler.cubic-c" + +/** * GST_RESAMPLER_OPT_ENVELOPE: * * G_TYPE_DOUBLE, specifies the size of filter envelope for diff --git a/gst-libs/gst/video/video-converter.c b/gst-libs/gst/video/video-converter.c index 87158c7..2728a79 100644 --- a/gst-libs/gst/video/video-converter.c +++ b/gst-libs/gst/video/video-converter.c @@ -312,7 +312,7 @@ chain_hscale (GstVideoConverter * convert, GstLineCacheNeedLineFunc need_line) if (!gst_structure_get_enum (convert->config, GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, GST_TYPE_RESAMPLER_METHOD, &method)) - method = GST_RESAMPLER_METHOD_LINEAR; + method = GST_RESAMPLER_METHOD_CUBIC; if (!gst_structure_get_uint (convert->config, GST_VIDEO_CONVERTER_OPT_RESAMPLER_TAPS, &taps)) taps = 0; @@ -341,7 +341,7 @@ chain_vscale (GstVideoConverter * convert, GstLineCacheNeedLineFunc need_line) if (!gst_structure_get_enum (convert->config, GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD, GST_TYPE_RESAMPLER_METHOD, &method)) - method = GST_RESAMPLER_METHOD_LINEAR; + method = GST_RESAMPLER_METHOD_CUBIC; if (!gst_structure_get_uint (convert->config, GST_VIDEO_CONVERTER_OPT_RESAMPLER_TAPS, &taps)) taps = 0;