1 /*
2 * GStreamer
3 * Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 /**
22 * SECTION:element-glcolorscale
23 * @title: glcolorscale
24 *
25 * video frame scaling and colorspace conversion.
26 *
27 * ## Scaling and Color space conversion
28 *
29 * Equivalent to glupload ! gldownload.
30 *
31 * ## Examples
32 * |[
33 * gst-launch-1.0 -v videotestsrc ! video/x-raw ! glcolorscale ! ximagesink
34 * ]| A pipeline to test colorspace conversion.
35 * FBO is required.
36 |[
37 * gst-launch-1.0 -v videotestsrc ! video/x-raw, width=640, height=480, format=AYUV ! glcolorscale ! \
38 * video/x-raw, width=320, height=240, format=YV12 ! videoconvert ! autovideosink
39 * ]| A pipeline to test hardware scaling and colorspace conversion.
40 * FBO and GLSL are required.
41 *
42 */
43
44 #ifdef HAVE_CONFIG_H
45 #include "config.h"
46 #endif
47
48 #include "gstglcolorscale.h"
49
50 #define GST_CAT_DEFAULT gst_gl_colorscale_debug
51 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
52
53 /* Properties */
54 enum
55 {
56 PROP_0
57 };
58
59 #define DEBUG_INIT \
60 GST_DEBUG_CATEGORY_INIT (gst_gl_colorscale_debug, "glcolorscale", 0, "glcolorscale element");
61 #define gst_gl_colorscale_parent_class parent_class
62 G_DEFINE_TYPE_WITH_CODE (GstGLColorscale, gst_gl_colorscale,
63 GST_TYPE_GL_FILTER, DEBUG_INIT);
64
65 static void gst_gl_colorscale_set_property (GObject * object, guint prop_id,
66 const GValue * value, GParamSpec * pspec);
67 static void gst_gl_colorscale_get_property (GObject * object, guint prop_id,
68 GValue * value, GParamSpec * pspec);
69
70 static gboolean gst_gl_colorscale_gl_start (GstGLBaseFilter * base_filter);
71 static void gst_gl_colorscale_gl_stop (GstGLBaseFilter * base_filter);
72
73 static gboolean gst_gl_colorscale_filter_texture (GstGLFilter * filter,
74 GstGLMemory * in_tex, GstGLMemory * out_tex);
75
76 static void
gst_gl_colorscale_class_init(GstGLColorscaleClass * klass)77 gst_gl_colorscale_class_init (GstGLColorscaleClass * klass)
78 {
79 GObjectClass *gobject_class;
80 GstElementClass *element_class;
81 GstBaseTransformClass *basetransform_class;
82 GstGLBaseFilterClass *base_filter_class;
83 GstGLFilterClass *filter_class;
84
85 gobject_class = (GObjectClass *) klass;
86 element_class = GST_ELEMENT_CLASS (klass);
87 basetransform_class = GST_BASE_TRANSFORM_CLASS (klass);
88 base_filter_class = GST_GL_BASE_FILTER_CLASS (klass);
89 filter_class = GST_GL_FILTER_CLASS (klass);
90
91 gst_gl_filter_add_rgba_pad_templates (GST_GL_FILTER_CLASS (klass));
92
93 gobject_class->set_property = gst_gl_colorscale_set_property;
94 gobject_class->get_property = gst_gl_colorscale_get_property;
95
96 gst_element_class_set_metadata (element_class, "OpenGL color scale",
97 "Filter/Effect/Video", "Colorspace converter and video scaler",
98 "Julien Isorce <julien.isorce@gmail.com>\n"
99 "Matthew Waters <matthew@centricular.com>");
100
101 basetransform_class->passthrough_on_same_caps = TRUE;
102
103 base_filter_class->gl_start = GST_DEBUG_FUNCPTR (gst_gl_colorscale_gl_start);
104 base_filter_class->gl_stop = GST_DEBUG_FUNCPTR (gst_gl_colorscale_gl_stop);
105 base_filter_class->supported_gl_api =
106 GST_GL_API_OPENGL | GST_GL_API_OPENGL3 | GST_GL_API_GLES2;
107
108 filter_class->filter_texture = gst_gl_colorscale_filter_texture;
109 }
110
111 static void
gst_gl_colorscale_init(GstGLColorscale * colorscale)112 gst_gl_colorscale_init (GstGLColorscale * colorscale)
113 {
114 }
115
116 static void
gst_gl_colorscale_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)117 gst_gl_colorscale_set_property (GObject * object, guint prop_id,
118 const GValue * value, GParamSpec * pspec)
119 {
120 switch (prop_id) {
121 default:
122 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
123 break;
124 }
125 }
126
127 static void
gst_gl_colorscale_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)128 gst_gl_colorscale_get_property (GObject * object, guint prop_id,
129 GValue * value, GParamSpec * pspec)
130 {
131 switch (prop_id) {
132 default:
133 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
134 break;
135 }
136 }
137
138 static gboolean
gst_gl_colorscale_gl_start(GstGLBaseFilter * base_filter)139 gst_gl_colorscale_gl_start (GstGLBaseFilter * base_filter)
140 {
141 GstGLColorscale *colorscale = GST_GL_COLORSCALE (base_filter);
142 GstGLFilter *filter = GST_GL_FILTER (base_filter);
143 GstGLShader *shader;
144 GError *error = NULL;
145
146 if (!(shader = gst_gl_shader_new_default (base_filter->context, &error))) {
147 GST_ERROR_OBJECT (colorscale, "Failed to initialize shader: %s",
148 error->message);
149 gst_object_unref (shader);
150 return FALSE;
151 }
152
153 filter->draw_attr_position_loc =
154 gst_gl_shader_get_attribute_location (shader, "a_position");
155 filter->draw_attr_texture_loc =
156 gst_gl_shader_get_attribute_location (shader, "a_texcoord");
157
158 colorscale->shader = shader;
159
160 return GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter);
161 }
162
163 static void
gst_gl_colorscale_gl_stop(GstGLBaseFilter * base_filter)164 gst_gl_colorscale_gl_stop (GstGLBaseFilter * base_filter)
165 {
166 GstGLColorscale *colorscale = GST_GL_COLORSCALE (base_filter);
167
168 if (colorscale->shader) {
169 gst_object_unref (colorscale->shader);
170 colorscale->shader = NULL;
171 }
172
173 GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);
174 }
175
176 static gboolean
gst_gl_colorscale_filter_texture(GstGLFilter * filter,GstGLMemory * in_tex,GstGLMemory * out_tex)177 gst_gl_colorscale_filter_texture (GstGLFilter * filter, GstGLMemory * in_tex,
178 GstGLMemory * out_tex)
179 {
180 GstGLColorscale *colorscale = GST_GL_COLORSCALE (filter);
181
182 if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context))
183 gst_gl_filter_render_to_target_with_shader (filter, in_tex, out_tex,
184 colorscale->shader);
185
186 return TRUE;
187 }
188