mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
videoscale: Add modified Lanczos scaling method
Adds a Lanczos-derived scaling method, which is rather slow, but very high quality. Adds a few properties that can be used to tune various scaling properties: sharpness, sharpen, envelope, dither. Not currently Orcified, but was designed with that in mind.
This commit is contained in:
parent
924f743981
commit
4e38577b30
5 changed files with 1689 additions and 4 deletions
|
@ -8,7 +8,8 @@ libgstvideoscale_la_SOURCES = \
|
|||
vs_image.c \
|
||||
vs_scanline.c \
|
||||
vs_4tap.c \
|
||||
vs_fill_borders.c
|
||||
vs_fill_borders.c \
|
||||
vs_lanczos.c
|
||||
|
||||
nodist_libgstvideoscale_la_SOURCES = $(ORC_NODIST_SOURCES)
|
||||
|
||||
|
|
|
@ -89,13 +89,22 @@ GST_DEBUG_CATEGORY (video_scale_debug);
|
|||
|
||||
#define DEFAULT_PROP_METHOD GST_VIDEO_SCALE_BILINEAR
|
||||
#define DEFAULT_PROP_ADD_BORDERS FALSE
|
||||
#define DEFAULT_PROP_SHARPNESS 1.0
|
||||
#define DEFAULT_PROP_SHARPEN 0.0
|
||||
#define DEFAULT_PROP_DITHER FALSE
|
||||
#define DEFAULT_PROP_SUBMETHOD 1
|
||||
#define DEFAULT_PROP_ENVELOPE 2.0
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_METHOD,
|
||||
PROP_ADD_BORDERS
|
||||
/* FILL ME */
|
||||
PROP_ADD_BORDERS,
|
||||
PROP_SHARPNESS,
|
||||
PROP_SHARPEN,
|
||||
PROP_DITHER,
|
||||
PROP_SUBMETHOD,
|
||||
PROP_ENVELOPE
|
||||
};
|
||||
|
||||
#undef GST_VIDEO_SIZE_RANGE
|
||||
|
@ -144,6 +153,7 @@ gst_video_scale_method_get_type (void)
|
|||
{GST_VIDEO_SCALE_NEAREST, "Nearest Neighbour", "nearest-neighbour"},
|
||||
{GST_VIDEO_SCALE_BILINEAR, "Bilinear", "bilinear"},
|
||||
{GST_VIDEO_SCALE_4TAP, "4-tap", "4-tap"},
|
||||
{GST_VIDEO_SCALE_LANCZOS, "Lanczos", "lanczos"},
|
||||
{0, NULL, NULL},
|
||||
};
|
||||
|
||||
|
@ -251,6 +261,36 @@ gst_video_scale_class_init (GstVideoScaleClass * klass)
|
|||
DEFAULT_PROP_ADD_BORDERS,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_SHARPNESS,
|
||||
g_param_spec_double ("sharpness", "Sharpness",
|
||||
"Sharpness of filter", 0.0, 2.0, DEFAULT_PROP_SHARPNESS,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_SHARPEN,
|
||||
g_param_spec_double ("sharpen", "Sharpen",
|
||||
"Sharpening", 0.0, 1.0, DEFAULT_PROP_SHARPEN,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_DITHER,
|
||||
g_param_spec_boolean ("dither", "Dither",
|
||||
"Add dither (only used for Lanczos method)",
|
||||
DEFAULT_PROP_DITHER,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
#if 0
|
||||
/* I am hiding submethod for now, since it's poorly named, poorly
|
||||
* documented, and will probably just get people into trouble. */
|
||||
g_object_class_install_property (gobject_class, PROP_SUBMETHOD,
|
||||
g_param_spec_int ("submethod", "submethod",
|
||||
"submethod", 0, 3, DEFAULT_PROP_SUBMETHOD,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
#endif
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_ENVELOPE,
|
||||
g_param_spec_double ("envelope", "Envelope",
|
||||
"Size of filter envelope", 0.0, 5.0, DEFAULT_PROP_ENVELOPE,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
trans_class->transform_caps =
|
||||
GST_DEBUG_FUNCPTR (gst_video_scale_transform_caps);
|
||||
trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_video_scale_set_caps);
|
||||
|
@ -267,6 +307,11 @@ gst_video_scale_init (GstVideoScale * videoscale, GstVideoScaleClass * klass)
|
|||
videoscale->tmp_buf = NULL;
|
||||
videoscale->method = DEFAULT_PROP_METHOD;
|
||||
videoscale->add_borders = DEFAULT_PROP_ADD_BORDERS;
|
||||
videoscale->submethod = DEFAULT_PROP_SUBMETHOD;
|
||||
videoscale->sharpness = DEFAULT_PROP_SHARPNESS;
|
||||
videoscale->sharpen = DEFAULT_PROP_SHARPEN;
|
||||
videoscale->dither = DEFAULT_PROP_DITHER;
|
||||
videoscale->envelope = DEFAULT_PROP_ENVELOPE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -296,6 +341,31 @@ gst_video_scale_set_property (GObject * object, guint prop_id,
|
|||
GST_OBJECT_UNLOCK (vscale);
|
||||
gst_base_transform_reconfigure (GST_BASE_TRANSFORM_CAST (vscale));
|
||||
break;
|
||||
case PROP_SHARPNESS:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
vscale->sharpness = g_value_get_double (value);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
case PROP_SHARPEN:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
vscale->sharpen = g_value_get_double (value);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
case PROP_DITHER:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
vscale->dither = g_value_get_boolean (value);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
case PROP_SUBMETHOD:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
vscale->submethod = g_value_get_int (value);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
case PROP_ENVELOPE:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
vscale->envelope = g_value_get_double (value);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -319,6 +389,31 @@ gst_video_scale_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
g_value_set_boolean (value, vscale->add_borders);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
case PROP_SHARPNESS:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
g_value_set_double (value, vscale->sharpness);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
case PROP_SHARPEN:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
g_value_set_double (value, vscale->sharpen);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
case PROP_DITHER:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
g_value_set_boolean (value, vscale->dither);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
case PROP_SUBMETHOD:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
g_value_set_int (value, vscale->submethod);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
case PROP_ENVELOPE:
|
||||
GST_OBJECT_LOCK (vscale);
|
||||
g_value_set_double (value, vscale->envelope);
|
||||
GST_OBJECT_UNLOCK (vscale);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1078,6 +1173,11 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in,
|
|||
case GST_VIDEO_SCALE_4TAP:
|
||||
vs_image_scale_4tap_RGBA (&dest, &src, videoscale->tmp_buf);
|
||||
break;
|
||||
case GST_VIDEO_SCALE_LANCZOS:
|
||||
vs_image_scale_lanczos_AYUV (&dest, &src, videoscale->tmp_buf,
|
||||
videoscale->sharpness, videoscale->dither, videoscale->submethod,
|
||||
videoscale->envelope, videoscale->sharpen);
|
||||
break;
|
||||
default:
|
||||
goto unknown_mode;
|
||||
}
|
||||
|
@ -1217,6 +1317,17 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in,
|
|||
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_LANCZOS:
|
||||
vs_image_scale_lanczos_Y (&dest, &src, videoscale->tmp_buf,
|
||||
videoscale->sharpness, videoscale->dither, videoscale->submethod,
|
||||
videoscale->envelope, videoscale->sharpen);
|
||||
vs_image_scale_lanczos_Y (&dest_u, &src_u, videoscale->tmp_buf,
|
||||
videoscale->sharpness, videoscale->dither, videoscale->submethod,
|
||||
videoscale->envelope, videoscale->sharpen);
|
||||
vs_image_scale_lanczos_Y (&dest_v, &src_v, videoscale->tmp_buf,
|
||||
videoscale->sharpness, videoscale->dither, videoscale->submethod,
|
||||
videoscale->envelope, videoscale->sharpen);
|
||||
break;
|
||||
default:
|
||||
goto unknown_mode;
|
||||
}
|
||||
|
|
|
@ -47,13 +47,15 @@ GST_DEBUG_CATEGORY_EXTERN (video_scale_debug);
|
|||
* @GST_VIDEO_SCALE_NEAREST: use nearest neighbour scaling (fast and ugly)
|
||||
* @GST_VIDEO_SCALE_BILINEAR: use bilinear scaling (slower but prettier).
|
||||
* @GST_VIDEO_SCALE_4TAP: use a 4-tap filter for scaling (slow).
|
||||
* @GST_VIDEO_SCALE_LANCZOS: use a multitap Lanczos filter for scaling (slow).
|
||||
*
|
||||
* The videoscale method to use.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VIDEO_SCALE_NEAREST,
|
||||
GST_VIDEO_SCALE_BILINEAR,
|
||||
GST_VIDEO_SCALE_4TAP
|
||||
GST_VIDEO_SCALE_4TAP,
|
||||
GST_VIDEO_SCALE_LANCZOS
|
||||
} GstVideoScaleMethod;
|
||||
|
||||
typedef struct _GstVideoScale GstVideoScale;
|
||||
|
@ -67,8 +69,14 @@ typedef struct _GstVideoScaleClass GstVideoScaleClass;
|
|||
struct _GstVideoScale {
|
||||
GstVideoFilter element;
|
||||
|
||||
/* properties */
|
||||
GstVideoScaleMethod method;
|
||||
gboolean add_borders;
|
||||
double sharpness;
|
||||
double sharpen;
|
||||
gboolean dither;
|
||||
int submethod;
|
||||
double envelope;
|
||||
|
||||
/* negotiated stuff */
|
||||
GstVideoFormat format;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#ifndef __VS_IMAGE_H__
|
||||
#define __VS_IMAGE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <_stdint.h>
|
||||
|
||||
typedef struct _VSImage VSImage;
|
||||
|
@ -48,6 +49,9 @@ void vs_image_scale_nearest_RGBA (const VSImage *dest, const VSImage *src,
|
|||
uint8_t *tmpbuf);
|
||||
void vs_image_scale_linear_RGBA (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf);
|
||||
void vs_image_scale_lanczos_AYUV (const VSImage * dest, const VSImage * src,
|
||||
uint8_t * tmpbuf, double sharpness, gboolean dither, int submethod,
|
||||
double a, double sharpen);
|
||||
|
||||
void vs_image_scale_nearest_RGB (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf);
|
||||
|
@ -68,6 +72,9 @@ void vs_image_scale_nearest_Y (const VSImage *dest, const VSImage *src,
|
|||
uint8_t *tmpbuf);
|
||||
void vs_image_scale_linear_Y (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf);
|
||||
void vs_image_scale_lanczos_Y (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf, double sharpness, gboolean dither, int submethod,
|
||||
double a, double sharpen);
|
||||
|
||||
void vs_image_scale_nearest_RGB565 (const VSImage *dest, const VSImage *src,
|
||||
uint8_t *tmpbuf);
|
||||
|
|
1558
gst/videoscale/vs_lanczos.c
Normal file
1558
gst/videoscale/vs_lanczos.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue