mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
gl: implement a colorbalance element
It performs the exact same operation as videobalance but with opengl shaders and was tested with glvideomixer by comparing frames from videobalance and glcolorbalance.
This commit is contained in:
parent
ceec4ad873
commit
1bb2985777
4 changed files with 624 additions and 0 deletions
|
@ -32,6 +32,7 @@ libgstopengl_la_SOURCES = \
|
|||
effects/gstgleffectsobel.c \
|
||||
effects/gstgleffectlaplacian.c \
|
||||
gstglcolorscale.c \
|
||||
gstglcolorbalance.c \
|
||||
gstglmixer.c \
|
||||
gstglvideomixer.c \
|
||||
gstglfiltershader.c \
|
||||
|
@ -54,6 +55,7 @@ noinst_HEADERS = \
|
|||
gstgleffects.h \
|
||||
effects/gstgleffectssources.h \
|
||||
gstglcolorscale.h \
|
||||
gstglcolorbalance.h \
|
||||
gstglmixer.h \
|
||||
gstglvideomixer.h \
|
||||
gstglfiltershader.h \
|
||||
|
|
543
ext/gl/gstglcolorbalance.c
Normal file
543
ext/gl/gstglcolorbalance.c
Normal file
|
@ -0,0 +1,543 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2016> Matthew Waters <matthew@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
/*
|
||||
* This file was modified from videobalance and converted to OpenGL
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:element-glcolorbalance
|
||||
*
|
||||
* Adjusts brightness, contrast, hue, saturation on a video stream.
|
||||
*
|
||||
* <refsect2>
|
||||
* <title>Example launch line</title>
|
||||
* |[
|
||||
* gst-launch-1.0 videotestsrc ! glupload ! glcolorbalance saturation=0.0 ! glcolorconvert ! gldownload ! ximagesink
|
||||
* ]| This pipeline converts the image to black and white by setting the
|
||||
* saturation to 0.0.
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/math-compat.h>
|
||||
|
||||
#include "gstglcolorbalance.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/video/colorbalance.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (glcolorbalance_debug);
|
||||
#define GST_CAT_DEFAULT glcolorbalance_debug
|
||||
|
||||
/* GstGLColorBalance properties */
|
||||
#define DEFAULT_PROP_CONTRAST 1.0
|
||||
#define DEFAULT_PROP_BRIGHTNESS 0.0
|
||||
#define DEFAULT_PROP_HUE 0.0
|
||||
#define DEFAULT_PROP_SATURATION 1.0
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
static const gchar *color_balance_frag =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision mediump float;\n"
|
||||
"#endif\n"
|
||||
"uniform float brightness;\n"
|
||||
"uniform float contrast;\n"
|
||||
"uniform float saturation;\n"
|
||||
"uniform float hue;\n"
|
||||
"varying vec2 v_texcoord;\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
"#define from_yuv_bt601_offset vec3(-0.0625, -0.5, -0.5)\n"
|
||||
"#define from_yuv_bt601_rcoeff vec3(1.164, 0.000, 1.596)\n"
|
||||
"#define from_yuv_bt601_gcoeff vec3(1.164,-0.391,-0.813)\n"
|
||||
"#define from_yuv_bt601_bcoeff vec3(1.164, 2.018, 0.000)\n"
|
||||
"#define from_rgb_bt601_offset vec3(0.0625, 0.5, 0.5)\n"
|
||||
"#define from_rgb_bt601_ycoeff vec3(0.256816, 0.504154, 0.0979137)\n"
|
||||
"#define from_rgb_bt601_ucoeff vec3(-0.148246, -0.29102, 0.439266)\n"
|
||||
"#define from_rgb_bt601_vcoeff vec3(0.439271, -0.367833, -0.071438)\n"
|
||||
"#define PI 3.14159265\n"
|
||||
"\n"
|
||||
"vec3 yuv_to_rgb (vec3 val) {\n"
|
||||
" vec3 rgb;\n"
|
||||
" val += from_yuv_bt601_offset;\n"
|
||||
" rgb.r = dot(val, from_yuv_bt601_rcoeff);\n"
|
||||
" rgb.g = dot(val, from_yuv_bt601_gcoeff);\n"
|
||||
" rgb.b = dot(val, from_yuv_bt601_bcoeff);\n"
|
||||
" return rgb;\n"
|
||||
"}\n"
|
||||
"vec3 rgb_to_yuv (vec3 val) {\n"
|
||||
" vec3 yuv;\n"
|
||||
" yuv.r = dot(val.rgb, from_rgb_bt601_ycoeff);\n"
|
||||
" yuv.g = dot(val.rgb, from_rgb_bt601_ucoeff);\n"
|
||||
" yuv.b = dot(val.rgb, from_rgb_bt601_vcoeff);\n"
|
||||
" yuv += from_rgb_bt601_offset;\n"
|
||||
" return yuv;\n"
|
||||
"}\n"
|
||||
/* 224 = 256 - (256 - 240) - 16*/
|
||||
"float luma_to_narrow (float luma) {\n"
|
||||
" return (luma + 16.0 / 256.0) * 219.0 / 256.0;"
|
||||
"}\n"
|
||||
"float luma_to_full (float luma) {\n"
|
||||
" return (luma * 256.0 / 219.0) - 16.0 / 256.0;"
|
||||
"}\n"
|
||||
"void main () {\n"
|
||||
" vec3 yuv;\n"
|
||||
/* operations translated from videobalanceand tested with glvideomixer
|
||||
* with one pad's paremeters blend-equation-rgb={subtract,reverse-subtract},
|
||||
* blend-function-src-rgb=src-color and blend-function-dst-rgb=dst-color */
|
||||
" float hue_cos = cos (PI * hue);\n"
|
||||
" float hue_sin = sin (PI * hue);\n"
|
||||
" vec4 rgba = texture2D (tex, v_texcoord);\n"
|
||||
" yuv = rgb_to_yuv (rgba.rgb);\n"
|
||||
" yuv.x = clamp (luma_to_narrow (luma_to_full(yuv.x) * contrast) + brightness, 0.0, 1.0);\n"
|
||||
" vec2 uv = yuv.yz;\n"
|
||||
" yuv.y = clamp (0.5 + (((uv.x - 0.5) * hue_cos + (uv.y - 0.5) * hue_sin) * saturation), 0.0, 1.0);\n"
|
||||
" yuv.z = clamp (0.5 + (((0.5 - uv.x) * hue_sin + (uv.y - 0.5) * hue_cos) * saturation), 0.0, 1.0);\n"
|
||||
" rgba.rgb = yuv_to_rgb (yuv);\n"
|
||||
" gl_FragColor = rgba;\n"
|
||||
"}\n";
|
||||
/* *INDENT-ON* */
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CONTRAST,
|
||||
PROP_BRIGHTNESS,
|
||||
PROP_HUE,
|
||||
PROP_SATURATION
|
||||
};
|
||||
|
||||
static void gst_gl_color_balance_colorbalance_init (GstColorBalanceInterface *
|
||||
iface);
|
||||
|
||||
static void gst_gl_color_balance_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_gl_color_balance_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
#define gst_gl_color_balance_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstGLColorBalance, gst_gl_color_balance,
|
||||
GST_TYPE_GL_FILTER,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE,
|
||||
gst_gl_color_balance_colorbalance_init));
|
||||
|
||||
static gboolean
|
||||
gst_gl_color_balance_is_passthrough (GstGLColorBalance * glcolorbalance)
|
||||
{
|
||||
return glcolorbalance->contrast == 1.0 &&
|
||||
glcolorbalance->brightness == 0.0 &&
|
||||
glcolorbalance->hue == 0.0 && glcolorbalance->saturation == 1.0;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_update_properties (GstGLColorBalance * glcolorbalance)
|
||||
{
|
||||
gboolean passthrough;
|
||||
GstBaseTransform *base = GST_BASE_TRANSFORM (glcolorbalance);
|
||||
|
||||
GST_OBJECT_LOCK (glcolorbalance);
|
||||
passthrough = gst_gl_color_balance_is_passthrough (glcolorbalance);
|
||||
GST_OBJECT_UNLOCK (glcolorbalance);
|
||||
|
||||
gst_base_transform_set_passthrough (base, passthrough);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_color_balance_gl_start (GstGLBaseFilter * base_filter)
|
||||
{
|
||||
GstGLColorBalance *balance = GST_GL_COLOR_BALANCE (base_filter);
|
||||
GstGLFilter *filter = GST_GL_FILTER (base_filter);
|
||||
GError *error = NULL;
|
||||
|
||||
if (balance->shader)
|
||||
gst_object_unref (balance->shader);
|
||||
|
||||
if (!(balance->shader =
|
||||
gst_gl_shader_new_link_with_stages (base_filter->context, &error,
|
||||
gst_glsl_stage_new_default_vertex (base_filter->context),
|
||||
gst_glsl_stage_new_with_string (base_filter->context,
|
||||
GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE,
|
||||
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
|
||||
color_balance_frag), NULL))) {
|
||||
GST_ELEMENT_ERROR (balance, RESOURCE, NOT_FOUND, ("%s",
|
||||
"Failed to initialize colorbalance shader"), ("%s",
|
||||
error ? error->message : "Unknown error"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
filter->draw_attr_position_loc =
|
||||
gst_gl_shader_get_attribute_location (balance->shader, "a_position");
|
||||
filter->draw_attr_texture_loc =
|
||||
gst_gl_shader_get_attribute_location (balance->shader, "a_texcoord");
|
||||
|
||||
return GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_gl_stop (GstGLBaseFilter * base_filter)
|
||||
{
|
||||
GstGLColorBalance *balance = GST_GL_COLOR_BALANCE (base_filter);
|
||||
|
||||
if (balance->shader)
|
||||
gst_object_unref (balance->shader);
|
||||
balance->shader = NULL;
|
||||
|
||||
GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_before_transform (GstBaseTransform * base, GstBuffer * buf)
|
||||
{
|
||||
GstGLColorBalance *balance = GST_GL_COLOR_BALANCE (base);
|
||||
GstClockTime timestamp, stream_time;
|
||||
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buf);
|
||||
stream_time =
|
||||
gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);
|
||||
|
||||
GST_DEBUG_OBJECT (balance, "sync to %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (timestamp));
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (stream_time))
|
||||
gst_object_sync_values (GST_OBJECT (balance), stream_time);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_callback (gint width, gint height, guint tex_id,
|
||||
gpointer data)
|
||||
{
|
||||
GstGLColorBalance *balance = GST_GL_COLOR_BALANCE (data);
|
||||
GstGLFilter *filter = GST_GL_FILTER (data);
|
||||
const GstGLFuncs *gl = GST_GL_BASE_FILTER (data)->context->gl_vtable;
|
||||
|
||||
gst_gl_shader_use (balance->shader);
|
||||
GST_OBJECT_LOCK (balance);
|
||||
gst_gl_shader_set_uniform_1f (balance->shader, "brightness",
|
||||
balance->brightness);
|
||||
gst_gl_shader_set_uniform_1f (balance->shader, "contrast", balance->contrast);
|
||||
gst_gl_shader_set_uniform_1f (balance->shader, "saturation",
|
||||
balance->saturation);
|
||||
gst_gl_shader_set_uniform_1f (balance->shader, "hue", balance->hue);
|
||||
GST_OBJECT_UNLOCK (balance);
|
||||
|
||||
gl->BindTexture (GL_TEXTURE_2D, tex_id);
|
||||
|
||||
gst_gl_filter_draw_texture (filter, tex_id, width, height);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_color_balance_filter_texture (GstGLFilter * filter, guint in_tex,
|
||||
guint out_tex)
|
||||
{
|
||||
gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex,
|
||||
(GLCB) gst_gl_color_balance_callback, filter);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_finalize (GObject * object)
|
||||
{
|
||||
GstGLColorBalance *balance = GST_GL_COLOR_BALANCE (object);
|
||||
GList *channels = NULL;
|
||||
|
||||
channels = balance->channels;
|
||||
while (channels) {
|
||||
GstColorBalanceChannel *channel = channels->data;
|
||||
|
||||
g_object_unref (channel);
|
||||
channels->data = NULL;
|
||||
channels = g_list_next (channels);
|
||||
}
|
||||
|
||||
if (balance->channels)
|
||||
g_list_free (balance->channels);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_class_init (GstGLColorBalanceClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||
GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
|
||||
GstGLBaseFilterClass *base_filter_class = (GstGLBaseFilterClass *) klass;
|
||||
GstGLFilterClass *filter_class = (GstGLFilterClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (glcolorbalance_debug, "glcolorbalance", 0,
|
||||
"glcolorbalance");
|
||||
|
||||
gobject_class->finalize = gst_gl_color_balance_finalize;
|
||||
gobject_class->set_property = gst_gl_color_balance_set_property;
|
||||
gobject_class->get_property = gst_gl_color_balance_get_property;
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_CONTRAST,
|
||||
g_param_spec_double ("contrast", "Contrast", "contrast",
|
||||
0.0, 2.0, DEFAULT_PROP_CONTRAST,
|
||||
GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_BRIGHTNESS,
|
||||
g_param_spec_double ("brightness", "Brightness", "brightness", -1.0, 1.0,
|
||||
DEFAULT_PROP_BRIGHTNESS,
|
||||
GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_HUE,
|
||||
g_param_spec_double ("hue", "Hue", "hue", -1.0, 1.0, DEFAULT_PROP_HUE,
|
||||
GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_SATURATION,
|
||||
g_param_spec_double ("saturation", "Saturation", "saturation", 0.0, 2.0,
|
||||
DEFAULT_PROP_SATURATION,
|
||||
GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_set_static_metadata (gstelement_class, "Video balance",
|
||||
"Filter/Effect/Video",
|
||||
"Adjusts brightness, contrast, hue, saturation on a video stream",
|
||||
"Matthew Waters <matthew@centricular.com>");
|
||||
|
||||
trans_class->before_transform =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_color_balance_before_transform);
|
||||
trans_class->transform_ip_on_passthrough = FALSE;
|
||||
|
||||
base_filter_class->gl_start =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_color_balance_gl_start);
|
||||
base_filter_class->gl_stop = GST_DEBUG_FUNCPTR (gst_gl_color_balance_gl_stop);
|
||||
|
||||
filter_class->filter_texture =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_color_balance_filter_texture);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_init (GstGLColorBalance * glcolorbalance)
|
||||
{
|
||||
const gchar *channels[4] = { "HUE", "SATURATION",
|
||||
"BRIGHTNESS", "CONTRAST"
|
||||
};
|
||||
gint i;
|
||||
|
||||
/* Initialize propertiews */
|
||||
glcolorbalance->contrast = DEFAULT_PROP_CONTRAST;
|
||||
glcolorbalance->brightness = DEFAULT_PROP_BRIGHTNESS;
|
||||
glcolorbalance->hue = DEFAULT_PROP_HUE;
|
||||
glcolorbalance->saturation = DEFAULT_PROP_SATURATION;
|
||||
|
||||
gst_gl_color_balance_update_properties (glcolorbalance);
|
||||
|
||||
/* Generate the channels list */
|
||||
for (i = 0; i < G_N_ELEMENTS (channels); i++) {
|
||||
GstColorBalanceChannel *channel;
|
||||
|
||||
channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL);
|
||||
channel->label = g_strdup (channels[i]);
|
||||
channel->min_value = -1000;
|
||||
channel->max_value = 1000;
|
||||
|
||||
glcolorbalance->channels =
|
||||
g_list_append (glcolorbalance->channels, channel);
|
||||
}
|
||||
}
|
||||
|
||||
static const GList *
|
||||
gst_gl_color_balance_colorbalance_list_channels (GstColorBalance * balance)
|
||||
{
|
||||
GstGLColorBalance *glcolorbalance = GST_GL_COLOR_BALANCE (balance);
|
||||
|
||||
g_return_val_if_fail (glcolorbalance != NULL, NULL);
|
||||
g_return_val_if_fail (GST_IS_GL_COLOR_BALANCE (glcolorbalance), NULL);
|
||||
|
||||
return glcolorbalance->channels;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_colorbalance_set_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value)
|
||||
{
|
||||
GstGLColorBalance *vb = GST_GL_COLOR_BALANCE (balance);
|
||||
gdouble new_val;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_if_fail (vb != NULL);
|
||||
g_return_if_fail (GST_IS_GL_COLOR_BALANCE (vb));
|
||||
g_return_if_fail (channel->label != NULL);
|
||||
|
||||
GST_OBJECT_LOCK (vb);
|
||||
if (!g_ascii_strcasecmp (channel->label, "HUE")) {
|
||||
new_val = (value + 1000.0) * 2.0 / 2000.0 - 1.0;
|
||||
changed = new_val != vb->hue;
|
||||
vb->hue = new_val;
|
||||
} else if (!g_ascii_strcasecmp (channel->label, "SATURATION")) {
|
||||
new_val = (value + 1000.0) * 2.0 / 2000.0;
|
||||
changed = new_val != vb->saturation;
|
||||
vb->saturation = new_val;
|
||||
} else if (!g_ascii_strcasecmp (channel->label, "BRIGHTNESS")) {
|
||||
new_val = (value + 1000.0) * 2.0 / 2000.0 - 1.0;
|
||||
changed = new_val != vb->brightness;
|
||||
vb->brightness = new_val;
|
||||
} else if (!g_ascii_strcasecmp (channel->label, "CONTRAST")) {
|
||||
new_val = (value + 1000.0) * 2.0 / 2000.0;
|
||||
changed = new_val != vb->contrast;
|
||||
vb->contrast = new_val;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (vb);
|
||||
|
||||
if (changed)
|
||||
gst_gl_color_balance_update_properties (vb);
|
||||
|
||||
if (changed) {
|
||||
gst_color_balance_value_changed (balance, channel,
|
||||
gst_color_balance_get_value (balance, channel));
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_gl_color_balance_colorbalance_get_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel)
|
||||
{
|
||||
GstGLColorBalance *vb = GST_GL_COLOR_BALANCE (balance);
|
||||
gint value = 0;
|
||||
|
||||
g_return_val_if_fail (vb != NULL, 0);
|
||||
g_return_val_if_fail (GST_IS_GL_COLOR_BALANCE (vb), 0);
|
||||
g_return_val_if_fail (channel->label != NULL, 0);
|
||||
|
||||
if (!g_ascii_strcasecmp (channel->label, "HUE")) {
|
||||
value = (vb->hue + 1) * 2000.0 / 2.0 - 1000.0;
|
||||
} else if (!g_ascii_strcasecmp (channel->label, "SATURATION")) {
|
||||
value = vb->saturation * 2000.0 / 2.0 - 1000.0;
|
||||
} else if (!g_ascii_strcasecmp (channel->label, "BRIGHTNESS")) {
|
||||
value = (vb->brightness + 1) * 2000.0 / 2.0 - 1000.0;
|
||||
} else if (!g_ascii_strcasecmp (channel->label, "CONTRAST")) {
|
||||
value = vb->contrast * 2000.0 / 2.0 - 1000.0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static GstColorBalanceType
|
||||
gst_gl_color_balance_colorbalance_get_balance_type (GstColorBalance * balance)
|
||||
{
|
||||
return GST_COLOR_BALANCE_SOFTWARE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_colorbalance_init (GstColorBalanceInterface * iface)
|
||||
{
|
||||
iface->list_channels = gst_gl_color_balance_colorbalance_list_channels;
|
||||
iface->set_value = gst_gl_color_balance_colorbalance_set_value;
|
||||
iface->get_value = gst_gl_color_balance_colorbalance_get_value;
|
||||
iface->get_balance_type = gst_gl_color_balance_colorbalance_get_balance_type;
|
||||
}
|
||||
|
||||
static GstColorBalanceChannel *
|
||||
gst_gl_color_balance_find_channel (GstGLColorBalance * balance,
|
||||
const gchar * label)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = balance->channels; l; l = l->next) {
|
||||
GstColorBalanceChannel *channel = l->data;
|
||||
|
||||
if (g_ascii_strcasecmp (channel->label, label) == 0)
|
||||
return channel;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstGLColorBalance *balance = GST_GL_COLOR_BALANCE (object);
|
||||
gdouble d;
|
||||
const gchar *label = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (balance);
|
||||
switch (prop_id) {
|
||||
case PROP_CONTRAST:
|
||||
d = g_value_get_double (value);
|
||||
GST_DEBUG_OBJECT (balance, "Changing contrast from %lf to %lf",
|
||||
balance->contrast, d);
|
||||
if (d != balance->contrast)
|
||||
label = "CONTRAST";
|
||||
balance->contrast = d;
|
||||
break;
|
||||
case PROP_BRIGHTNESS:
|
||||
d = g_value_get_double (value);
|
||||
GST_DEBUG_OBJECT (balance, "Changing brightness from %lf to %lf",
|
||||
balance->brightness, d);
|
||||
if (d != balance->brightness)
|
||||
label = "BRIGHTNESS";
|
||||
balance->brightness = d;
|
||||
break;
|
||||
case PROP_HUE:
|
||||
d = g_value_get_double (value);
|
||||
GST_DEBUG_OBJECT (balance, "Changing hue from %lf to %lf", balance->hue,
|
||||
d);
|
||||
if (d != balance->hue)
|
||||
label = "HUE";
|
||||
balance->hue = d;
|
||||
break;
|
||||
case PROP_SATURATION:
|
||||
d = g_value_get_double (value);
|
||||
GST_DEBUG_OBJECT (balance, "Changing saturation from %lf to %lf",
|
||||
balance->saturation, d);
|
||||
if (d != balance->saturation)
|
||||
label = "SATURATION";
|
||||
balance->saturation = d;
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK (balance);
|
||||
gst_gl_color_balance_update_properties (balance);
|
||||
|
||||
if (label) {
|
||||
GstColorBalanceChannel *channel =
|
||||
gst_gl_color_balance_find_channel (balance, label);
|
||||
gst_color_balance_value_changed (GST_COLOR_BALANCE (balance), channel,
|
||||
gst_color_balance_get_value (GST_COLOR_BALANCE (balance), channel));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_color_balance_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstGLColorBalance *balance = GST_GL_COLOR_BALANCE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CONTRAST:
|
||||
g_value_set_double (value, balance->contrast);
|
||||
break;
|
||||
case PROP_BRIGHTNESS:
|
||||
g_value_set_double (value, balance->brightness);
|
||||
break;
|
||||
case PROP_HUE:
|
||||
g_value_set_double (value, balance->hue);
|
||||
break;
|
||||
case PROP_SATURATION:
|
||||
g_value_set_double (value, balance->saturation);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
73
ext/gl/gstglcolorbalance.h
Normal file
73
ext/gl/gstglcolorbalance.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_GL_COLOR_BALANCE_H__
|
||||
#define __GST_GL_COLOR_BALANCE_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/gl/gl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_GL_COLOR_BALANCE \
|
||||
(gst_gl_color_balance_get_type())
|
||||
#define GST_GL_COLOR_BALANCE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_COLOR_BALANCE,GstGLColorBalance))
|
||||
#define GST_GL_COLOR_BALANCE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GL_COLOR_BALANCE,GstGLColorBalanceClass))
|
||||
#define GST_IS_GL_COLOR_BALANCE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_COLOR_BALANCE))
|
||||
#define GST_IS_GL_COLOR_BALANCE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_COLOR_BALANCE))
|
||||
|
||||
typedef struct _GstGLColorBalance GstGLColorBalance;
|
||||
typedef struct _GstGLColorBalanceClass GstGLColorBalanceClass;
|
||||
|
||||
/**
|
||||
* GstGLColorBalance:
|
||||
*
|
||||
* Opaque data structure.
|
||||
*/
|
||||
struct _GstGLColorBalance {
|
||||
GstGLFilter videofilter;
|
||||
|
||||
/* < private > */
|
||||
GstGLShader *shader;
|
||||
|
||||
/* channels for interface */
|
||||
GList *channels;
|
||||
|
||||
/* properties */
|
||||
gdouble contrast;
|
||||
gdouble brightness;
|
||||
gdouble hue;
|
||||
gdouble saturation;
|
||||
};
|
||||
|
||||
struct _GstGLColorBalanceClass {
|
||||
GstGLFilterClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_gl_color_balance_get_type(void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_COLOR_BALANCE_H__ */
|
|
@ -47,6 +47,7 @@
|
|||
#include "gstgluploadelement.h"
|
||||
#include "gstgldownloadelement.h"
|
||||
#include "gstglcolorconvertelement.h"
|
||||
#include "gstglcolorbalance.h"
|
||||
#include "gstglfilterbin.h"
|
||||
#include "gstglsinkbin.h"
|
||||
#include "gstglsrcbin.h"
|
||||
|
@ -140,6 +141,11 @@ plugin_init (GstPlugin * plugin)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_element_register (plugin, "glcolorbalance",
|
||||
GST_RANK_NONE, GST_TYPE_GL_COLOR_BALANCE)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_element_register (plugin, "glfilterbin",
|
||||
GST_RANK_NONE, GST_TYPE_GL_FILTER_BIN)) {
|
||||
return FALSE;
|
||||
|
|
Loading…
Reference in a new issue