mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-18 05:16:05 +00:00
xsharpen video filter from Virtualdub
Original commit message from CVS: xsharpen video filter from Virtualdub
This commit is contained in:
parent
2b60d60286
commit
b821822691
5 changed files with 633 additions and 1 deletions
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit 1a826743b023d38a14e16cf1b3fb85eabdbb65d6
|
||||
Subproject commit 4ed4b888250d1081585717504b571ebf2de72c60
|
11
gst/virtualdub/Makefile.am
Normal file
11
gst/virtualdub/Makefile.am
Normal file
|
@ -0,0 +1,11 @@
|
|||
plugindir = $(libdir)/gst
|
||||
|
||||
plugin_LTLIBRARIES = libgstvirtualdub.la
|
||||
|
||||
libgstvirtualdub_la_SOURCES = gstvirtualdub.c gstxsharpen.c
|
||||
libgstvirtualdub_la_CFLAGS = $(GST_CFLAGS)
|
||||
libgstvirtualdub_la_LIBADD =
|
||||
libgstvirtualdub_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
||||
noinst_HEADERS = gstvirtualdub.h
|
||||
|
122
gst/virtualdub/gstvirtualdub.c
Normal file
122
gst/virtualdub/gstvirtualdub.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* EffecTV:
|
||||
* Copyright (C) 2001 FUKUCHI Kentarou
|
||||
*
|
||||
* EffecTV is free software. We release this product under the terms of the
|
||||
* GNU General Public License version 2. The license is included in the file
|
||||
* COPYING.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst.h>
|
||||
#include "gstvirtualdub.h"
|
||||
|
||||
|
||||
struct _elements_entry {
|
||||
gchar *name;
|
||||
GType (*type) (void);
|
||||
GstElementDetails *details;
|
||||
gboolean (*factoryinit) (GstElementFactory *factory);
|
||||
};
|
||||
|
||||
static struct _elements_entry _elements[] = {
|
||||
{ "xsharpen", gst_xsharpen_get_type, &gst_xsharpen_details, NULL },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
|
||||
GstPadTemplate*
|
||||
gst_virtualdub_src_factory (void)
|
||||
{
|
||||
static GstPadTemplate *templ = NULL;
|
||||
if (!templ) {
|
||||
templ = GST_PAD_TEMPLATE_NEW (
|
||||
"src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_CAPS_NEW (
|
||||
"virtualdub_src",
|
||||
"video/raw",
|
||||
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")),
|
||||
"bpp", GST_PROPS_INT (32),
|
||||
"depth", GST_PROPS_INT (32),
|
||||
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
|
||||
"red_mask", GST_PROPS_INT (0xff0000),
|
||||
"green_mask", GST_PROPS_INT (0xff00),
|
||||
"blue_mask", GST_PROPS_INT (0xff),
|
||||
"width", GST_PROPS_INT_RANGE (16, 4096),
|
||||
"height", GST_PROPS_INT_RANGE (16, 4096)
|
||||
)
|
||||
);
|
||||
}
|
||||
return templ;
|
||||
}
|
||||
|
||||
GstPadTemplate*
|
||||
gst_virtualdub_sink_factory (void)
|
||||
{
|
||||
static GstPadTemplate *templ = NULL;
|
||||
if (!templ) {
|
||||
templ = GST_PAD_TEMPLATE_NEW (
|
||||
"sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_CAPS_NEW (
|
||||
"virtualdub_sink",
|
||||
"video/raw",
|
||||
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")),
|
||||
"bpp", GST_PROPS_INT (32),
|
||||
"depth", GST_PROPS_INT (32),
|
||||
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
|
||||
"red_mask", GST_PROPS_INT (0xff0000),
|
||||
"green_mask", GST_PROPS_INT (0xff00),
|
||||
"blue_mask", GST_PROPS_INT (0xff),
|
||||
"width", GST_PROPS_INT_RANGE (16, 4096),
|
||||
"height", GST_PROPS_INT_RANGE (16, 4096)
|
||||
)
|
||||
);
|
||||
}
|
||||
return templ;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GModule * module, GstPlugin * plugin)
|
||||
{
|
||||
GstElementFactory *factory;
|
||||
gint i = 0;
|
||||
|
||||
while (_elements[i].name) {
|
||||
factory = gst_element_factory_new (_elements[i].name,
|
||||
(_elements[i].type) (),
|
||||
_elements[i].details);
|
||||
|
||||
if (!factory) {
|
||||
g_warning ("gst_virtualdub_new failed for `%s'",
|
||||
_elements[i].name);
|
||||
continue;
|
||||
}
|
||||
gst_element_factory_add_pad_template (factory, gst_virtualdub_src_factory ());
|
||||
gst_element_factory_add_pad_template (factory, gst_virtualdub_sink_factory ());
|
||||
|
||||
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
|
||||
if (_elements[i].factoryinit) {
|
||||
_elements[i].factoryinit (factory);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstPluginDesc plugin_desc = {
|
||||
GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"virtualdub",
|
||||
plugin_init
|
||||
};
|
38
gst/virtualdub/gstvirtualdub.h
Normal file
38
gst/virtualdub/gstvirtualdub.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* Filter:
|
||||
* Copyright (C) 2000 Donald A. Graft
|
||||
*
|
||||
* EffecTV is free software. We release this product under the terms of the
|
||||
* GNU General Public License version 2. The license is included in the file
|
||||
* COPYING.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
typedef unsigned int Pixel;
|
||||
typedef unsigned int Pixel32;
|
||||
typedef unsigned char Pixel8;
|
||||
typedef int PixCoord;
|
||||
typedef int PixDim;
|
||||
typedef int PixOffset;
|
||||
|
||||
|
||||
#define R_MASK (0x00ff0000)
|
||||
#define G_MASK (0x0000ff00)
|
||||
#define B_MASK (0x000000ff)
|
||||
#define R_SHIFT (16)
|
||||
#define G_SHIFT (8)
|
||||
#define B_SHIFT (0)
|
||||
|
||||
|
||||
GType gst_xsharpen_get_type (void);
|
||||
extern GstElementDetails gst_xsharpen_details;
|
||||
|
||||
extern GstPadTemplate *gst_virtualdub_sink_factory ();
|
||||
extern GstPadTemplate *gst_virtualdub_src_factory ();
|
461
gst/virtualdub/gstxsharpen.c
Normal file
461
gst/virtualdub/gstxsharpen.c
Normal file
|
@ -0,0 +1,461 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* Filter:
|
||||
* Copyright (C) 2000 Donald A. Graft
|
||||
*
|
||||
* Port done with help of transcode xsharpen filter by Tilmann Bitterberg
|
||||
*
|
||||
* EffecTV is free software. We release this product under the terms of the
|
||||
* GNU General Public License version 2. The license is included in the file
|
||||
* COPYING.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst.h>
|
||||
#include "gstvirtualdub.h"
|
||||
|
||||
#define GST_TYPE_XSHARPEN \
|
||||
(gst_xsharpen_get_type())
|
||||
#define GST_XSHARPEN(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_XSHARPEN,GstXsharpen))
|
||||
#define GST_XSHARPEN_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstXsharpen))
|
||||
#define GST_IS_XSHARPEN(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_XSHARPEN))
|
||||
#define GST_IS_XSHARPEN_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XSHARPEN))
|
||||
|
||||
typedef struct _GstXsharpen GstXsharpen;
|
||||
typedef struct _GstXsharpenClass GstXsharpenClass;
|
||||
|
||||
struct _GstXsharpen
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad, *srcpad;
|
||||
|
||||
gint width, height;
|
||||
gint strength, strengthinv, threshold;
|
||||
gint srcpitch, dstpitch;
|
||||
};
|
||||
|
||||
struct _GstXsharpenClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
GstElementDetails gst_xsharpen_details = {
|
||||
"",
|
||||
"Filter/Video/Effect",
|
||||
"Apply a sharpen effect on video"
|
||||
VERSION,
|
||||
"Jeremy SIMON <jsimon13@yahoo.fr>",
|
||||
"(C) 2000 Donald Graft",
|
||||
};
|
||||
|
||||
|
||||
/* Filter signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
ARG_STRENGTH,
|
||||
ARG_THRESHOLD,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
};
|
||||
|
||||
static void gst_xsharpen_class_init (GstXsharpenClass * klass);
|
||||
static void gst_xsharpen_init (GstXsharpen * sharpen);
|
||||
|
||||
static void gst_xsharpen_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_xsharpen_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static void gst_xsharpen_chain (GstPad * pad, GstBuffer * buf);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
GType gst_xsharpen_get_type (void)
|
||||
{
|
||||
static GType xsharpen_type = 0;
|
||||
|
||||
if (!xsharpen_type) {
|
||||
static const GTypeInfo xsharpen_info = {
|
||||
sizeof (GstXsharpenClass), NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_xsharpen_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstXsharpen),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_xsharpen_init,
|
||||
};
|
||||
|
||||
xsharpen_type = g_type_register_static (GST_TYPE_ELEMENT, "GstXsharpen", &xsharpen_info, 0);
|
||||
}
|
||||
return xsharpen_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_xsharpen_class_init (GstXsharpenClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_STRENGTH,
|
||||
g_param_spec_int("strength", "strength", "strength",
|
||||
0, 255, 255, (GParamFlags)G_PARAM_READWRITE ));
|
||||
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_THRESHOLD,
|
||||
g_param_spec_int("threshold", "threshold", "threshold",
|
||||
0, 255, 255, (GParamFlags)G_PARAM_READWRITE ));
|
||||
|
||||
gobject_class->set_property = gst_xsharpen_set_property;
|
||||
gobject_class->get_property = gst_xsharpen_get_property;
|
||||
}
|
||||
|
||||
static GstPadConnectReturn
|
||||
gst_xsharpen_sinkconnect (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstXsharpen *sharpen;
|
||||
|
||||
sharpen = GST_XSHARPEN (gst_pad_get_parent (pad));
|
||||
|
||||
if (!GST_CAPS_IS_FIXED (caps))
|
||||
return GST_PAD_CONNECT_DELAYED;
|
||||
|
||||
gst_caps_get_int (caps, "width", &sharpen->width);
|
||||
gst_caps_get_int (caps, "height", &sharpen->height);
|
||||
|
||||
sharpen->strengthinv = 255 - sharpen->strength;
|
||||
|
||||
sharpen->dstpitch = sharpen->srcpitch = sharpen->width * sizeof (Pixel32);
|
||||
|
||||
if (gst_pad_try_set_caps (sharpen->srcpad, caps)) {
|
||||
return GST_PAD_CONNECT_OK;
|
||||
}
|
||||
|
||||
return GST_PAD_CONNECT_REFUSED;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_xsharpen_init (GstXsharpen * sharpen)
|
||||
{
|
||||
sharpen->sinkpad = gst_pad_new_from_template (gst_virtualdub_sink_factory (), "sink");
|
||||
gst_pad_set_chain_function (sharpen->sinkpad, gst_xsharpen_chain);
|
||||
gst_pad_set_connect_function (sharpen->sinkpad, gst_xsharpen_sinkconnect);
|
||||
gst_element_add_pad (GST_ELEMENT (sharpen), sharpen->sinkpad);
|
||||
|
||||
sharpen->srcpad = gst_pad_new_from_template (gst_virtualdub_src_factory (), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (sharpen), sharpen->srcpad);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_xsharpen_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstXsharpen *xsharpen;
|
||||
GstBuffer *outbuf;
|
||||
gint x, y;
|
||||
gint r, g, b, R, G, B;
|
||||
Pixel32 p, min, max;
|
||||
gint luma, lumac, lumamax, lumamin, mindiff, maxdiff;
|
||||
Pixel32 *src_buf, *dst_buf, *src, *dst;
|
||||
|
||||
xsharpen = GST_XSHARPEN (gst_pad_get_parent (pad));
|
||||
|
||||
outbuf = gst_buffer_new ();
|
||||
GST_BUFFER_SIZE (outbuf) = ( xsharpen->width * xsharpen->height * sizeof (Pixel32));
|
||||
GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
|
||||
|
||||
src_buf = (Pixel32 *)GST_BUFFER_DATA (buf);
|
||||
dst_buf = (Pixel32 *)GST_BUFFER_DATA (outbuf);
|
||||
min = max = 0;
|
||||
|
||||
/* First copy through the four border lines. */
|
||||
src = src_buf;
|
||||
dst = dst_buf;
|
||||
for (x = 0; x < xsharpen->width; x++)
|
||||
{
|
||||
dst[x] = src[x];
|
||||
}
|
||||
|
||||
src = (Pixel *)((char *)src_buf + (xsharpen->height - 1) * xsharpen->srcpitch);
|
||||
dst = (Pixel *)((char *)dst_buf + (xsharpen->height - 1) * xsharpen->dstpitch);
|
||||
|
||||
for (x = 0; x < xsharpen->width; x++)
|
||||
{
|
||||
dst[x] = src[x];
|
||||
}
|
||||
|
||||
src = src_buf;
|
||||
dst = dst_buf;
|
||||
|
||||
for (y = 0; y < xsharpen->height; y++)
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[xsharpen->width-1] = src[xsharpen->width-1];
|
||||
src = (Pixel *)((char *)src + xsharpen->srcpitch);
|
||||
dst = (Pixel *)((char *)dst + xsharpen->dstpitch);
|
||||
}
|
||||
|
||||
/* Now calculate and store the pixel luminances for the remaining pixels. */
|
||||
src = src_buf;
|
||||
for (y = 0; y < xsharpen->height; y++)
|
||||
{
|
||||
for (x = 0; x < xsharpen->width; x++)
|
||||
{
|
||||
r = (src[x] >> 16) & 0xff;
|
||||
g = (src[x] >> 8) & 0xff;
|
||||
b = src[x] & 0xff;
|
||||
luma = (55 * r + 182 * g + 19 * b) >> 8;
|
||||
src[x] &= 0x00ffffff;
|
||||
src[x] |= (luma << 24);
|
||||
}
|
||||
src = (Pixel *)((char *)src + xsharpen->srcpitch);
|
||||
}
|
||||
|
||||
/* Finally run the 3x3 rank-order sharpening kernel over the pixels. */
|
||||
src = (Pixel *)((char *)src_buf + xsharpen->srcpitch);
|
||||
dst = (Pixel *)((char *)dst_buf + xsharpen->dstpitch);
|
||||
|
||||
for (y = 1; y < xsharpen->height - 1; y++)
|
||||
{
|
||||
for (x = 1; x < xsharpen->width - 1; x++)
|
||||
{
|
||||
/* Find the brightest and dimmest pixels in the 3x3 window
|
||||
surrounding the current pixel. */
|
||||
|
||||
lumamax = -1;
|
||||
lumamin = 1000;
|
||||
|
||||
p = ((Pixel32 *)((char *)src - xsharpen->srcpitch))[x-1];
|
||||
luma = p >> 24;
|
||||
if (luma > lumamax)
|
||||
{
|
||||
lumamax = luma;
|
||||
max = p;
|
||||
}
|
||||
if (luma < lumamin)
|
||||
{
|
||||
lumamin = luma;
|
||||
min = p;
|
||||
}
|
||||
|
||||
p = ((Pixel32 *)((char *)src - xsharpen->srcpitch))[x];
|
||||
luma = p >> 24;
|
||||
if (luma > lumamax)
|
||||
{
|
||||
lumamax = luma;
|
||||
max = p;
|
||||
}
|
||||
if (luma < lumamin)
|
||||
{
|
||||
lumamin = luma;
|
||||
min = p;
|
||||
}
|
||||
|
||||
p = ((Pixel32 *)((char *)src - xsharpen->srcpitch))[x+1];
|
||||
luma = p >> 24;
|
||||
if (luma > lumamax)
|
||||
{
|
||||
lumamax = luma;
|
||||
max = p;
|
||||
}
|
||||
if (luma < lumamin)
|
||||
{
|
||||
lumamin = luma;
|
||||
min = p;
|
||||
}
|
||||
|
||||
p = src[x-1];
|
||||
luma = p >> 24;
|
||||
if (luma > lumamax)
|
||||
{
|
||||
lumamax = luma;
|
||||
max = p;
|
||||
}
|
||||
if (luma < lumamin)
|
||||
{
|
||||
lumamin = luma;
|
||||
min = p;
|
||||
}
|
||||
|
||||
p = src[x];
|
||||
lumac = luma = p >> 24;
|
||||
if (luma > lumamax)
|
||||
{
|
||||
lumamax = luma;
|
||||
max = p;
|
||||
}
|
||||
if (luma < lumamin)
|
||||
{
|
||||
lumamin = luma;
|
||||
min = p;
|
||||
}
|
||||
|
||||
p = src[x+1];
|
||||
luma = p >> 24;
|
||||
if (luma > lumamax)
|
||||
{
|
||||
lumamax = luma;
|
||||
max = p;
|
||||
}
|
||||
if (luma < lumamin)
|
||||
{
|
||||
lumamin = luma;
|
||||
min = p;
|
||||
}
|
||||
|
||||
p = ((Pixel32 *)((char *)src + xsharpen->srcpitch))[x-1];
|
||||
luma = p >> 24;
|
||||
if (luma > lumamax)
|
||||
{
|
||||
lumamax = luma;
|
||||
max = p;
|
||||
}
|
||||
if (luma < lumamin)
|
||||
{
|
||||
lumamin = luma;
|
||||
min = p;
|
||||
}
|
||||
|
||||
p = ((Pixel32 *)((char *)src + xsharpen->srcpitch))[x];
|
||||
luma = p >> 24;
|
||||
if (luma > lumamax)
|
||||
{
|
||||
lumamax = luma;
|
||||
max = p;
|
||||
}
|
||||
if (luma < lumamin)
|
||||
{
|
||||
lumamin = luma;
|
||||
min = p;
|
||||
}
|
||||
|
||||
p = ((Pixel32 *)((char *)src + xsharpen->srcpitch))[x+1];
|
||||
luma = p >> 24;
|
||||
if (luma > lumamax)
|
||||
{
|
||||
lumamax = luma;
|
||||
max = p;
|
||||
}
|
||||
if (luma < lumamin)
|
||||
{
|
||||
lumamin = luma;
|
||||
min = p;
|
||||
}
|
||||
|
||||
/* Determine whether the current pixel is closer to the
|
||||
brightest or the dimmest pixel. Then compare the current
|
||||
pixel to that closest pixel. If the difference is within
|
||||
threshold, map the current pixel to the closest pixel;
|
||||
otherwise pass it through. */
|
||||
|
||||
p = -1;
|
||||
if (xsharpen->strength != 0)
|
||||
{
|
||||
mindiff = lumac - lumamin;
|
||||
maxdiff = lumamax - lumac;
|
||||
if (mindiff > maxdiff)
|
||||
{
|
||||
if (maxdiff < xsharpen->threshold)
|
||||
{
|
||||
p = max;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mindiff < xsharpen->threshold)
|
||||
{
|
||||
p = min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p == -1)
|
||||
{
|
||||
dst[x] = src[x];
|
||||
}
|
||||
else
|
||||
{
|
||||
R = (src[x] >> 16) & 0xff;
|
||||
G = (src[x] >> 8) & 0xff;
|
||||
B = src[x] & 0xff;
|
||||
r = (p >> 16) & 0xff;
|
||||
g = (p >> 8) & 0xff;
|
||||
b = p & 0xff;
|
||||
r = (xsharpen->strength * r + xsharpen->strengthinv * R) / 255;
|
||||
g = (xsharpen->strength * g + xsharpen->strengthinv * G) / 255;
|
||||
b = (xsharpen->strength * b + xsharpen->strengthinv * B) / 255;
|
||||
dst[x] = (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
src = (Pixel *)((char *)src + xsharpen->srcpitch);
|
||||
dst = (Pixel *)((char *)dst + xsharpen->dstpitch);
|
||||
}
|
||||
|
||||
gst_buffer_unref (buf);
|
||||
|
||||
gst_pad_push (xsharpen->srcpad, outbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_xsharpen_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstXsharpen *xsharpen;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_XSHARPEN (object));
|
||||
|
||||
xsharpen = GST_XSHARPEN (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_STRENGTH:
|
||||
xsharpen->strength = g_value_get_int (value);
|
||||
xsharpen->strengthinv = 255 - xsharpen->strength;
|
||||
case ARG_THRESHOLD:
|
||||
xsharpen->threshold = g_value_get_int (value);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_xsharpen_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstXsharpen *xsharpen;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_XSHARPEN (object));
|
||||
|
||||
xsharpen = GST_XSHARPEN (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_STRENGTH:
|
||||
g_value_set_int (value, xsharpen->strength );
|
||||
break;
|
||||
case ARG_THRESHOLD:
|
||||
g_value_set_int (value, xsharpen->threshold );
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue