6 #include <gstglbuffer.h>
7 #include <gstgldisplay.h>
10 #include "glextensions.h"
14 static GObjectClass *gst_gl_buffer_parent_class;
17 gst_gl_buffer_finalize (GstGLBuffer * buffer)
19 gst_gl_display_lock (buffer->display);
21 glDeleteTextures (1, &buffer->texture);
22 if (buffer->texture_u) {
23 glDeleteTextures (1, &buffer->texture_u);
25 if (buffer->texture_v) {
26 glDeleteTextures (1, &buffer->texture_v);
29 gst_gl_display_unlock (buffer->display);
30 g_object_unref (buffer->display);
32 GST_MINI_OBJECT_CLASS (gst_gl_buffer_parent_class)->
33 finalize (GST_MINI_OBJECT (buffer));
37 gst_gl_buffer_init (GstGLBuffer * buffer, gpointer g_class)
43 gst_gl_buffer_class_init (gpointer g_class, gpointer class_data)
45 GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
47 gst_gl_buffer_parent_class = g_type_class_peek_parent (g_class);
49 mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
50 gst_gl_buffer_finalize;
55 gst_gl_buffer_get_type (void)
57 static GType _gst_gl_buffer_type;
59 if (G_UNLIKELY (_gst_gl_buffer_type == 0)) {
60 static const GTypeInfo info = {
61 sizeof (GstBufferClass),
64 gst_gl_buffer_class_init,
69 (GInstanceInitFunc) gst_gl_buffer_init,
72 _gst_gl_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
73 "GstGLBuffer", &info, 0);
75 return _gst_gl_buffer_type;
80 gst_gl_buffer_new (GstGLDisplay * display, GstGLBufferFormat format,
81 int width, int height)
85 g_return_val_if_fail (width > 0, NULL);
86 g_return_val_if_fail (height > 0, NULL);
88 buffer = (GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER);
90 buffer->display = g_object_ref (display);
91 buffer->width = width;
92 buffer->height = height;
93 /* this is not strictly true, but it's used for compatibility with
94 * queue and BaseTransform */
95 GST_BUFFER_SIZE (buffer) = width * height * 4;
97 gst_gl_display_lock (buffer->display);
98 glGenTextures (1, &buffer->texture);
99 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture);
101 case GST_GL_BUFFER_FORMAT_RGBA:
102 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
103 buffer->width, buffer->height, 0, GL_RGBA, GL_FLOAT, NULL);
105 case GST_GL_BUFFER_FORMAT_RGB:
106 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
107 buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
110 g_warning ("GL buffer format not handled");
113 gst_gl_display_unlock (buffer->display);
119 gst_gl_buffer_new_from_data (GstGLDisplay * display, GstVideoFormat format,
120 int width, int height, void *data)
125 g_return_val_if_fail (width > 0, NULL);
126 g_return_val_if_fail (height > 0, NULL);
127 g_return_val_if_fail (data != NULL, NULL);
129 GST_DEBUG ("uploading %p %dx%d", data, width, height);
131 buffer = (GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER);
132 buffer->display = g_object_ref (display);
133 buffer->width = width;
134 buffer->height = height;
135 /* this is not strictly true, but it's used for compatibility with
136 * queue and BaseTransform */
137 GST_BUFFER_SIZE (buffer) = width * height * 4;
139 gst_gl_display_lock (buffer->display);
140 glGenTextures (1, &buffer->texture);
141 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture);
144 case GST_VIDEO_FORMAT_RGBx:
145 buffer->format = GST_GL_BUFFER_FORMAT_RGB;
146 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
147 buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
148 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
149 GL_RGBA, GL_UNSIGNED_BYTE, data);
151 case GST_VIDEO_FORMAT_BGRx:
152 buffer->format = GST_GL_BUFFER_FORMAT_RGB;
153 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
154 buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
155 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
156 GL_BGRA, GL_UNSIGNED_BYTE, data);
158 case GST_VIDEO_FORMAT_xRGB:
159 buffer->format = GST_GL_BUFFER_FORMAT_RGB;
160 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
161 buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
162 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
163 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
165 case GST_VIDEO_FORMAT_xBGR:
166 buffer->format = GST_GL_BUFFER_FORMAT_RGB;
167 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
168 buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
169 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
170 GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data);
172 case GST_VIDEO_FORMAT_YUY2:
173 buffer->format = GST_GL_BUFFER_FORMAT_YUYV;
174 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height,
175 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
176 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
177 GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data);
179 case GST_VIDEO_FORMAT_UYVY:
180 buffer->format = GST_GL_BUFFER_FORMAT_YUYV;
181 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height,
182 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
183 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
184 GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data);
186 case GST_VIDEO_FORMAT_AYUV:
187 buffer->format = GST_GL_BUFFER_FORMAT_RGB;
188 buffer->is_yuv = TRUE;
189 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
190 buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
191 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
192 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
194 case GST_VIDEO_FORMAT_I420:
195 case GST_VIDEO_FORMAT_YV12:
196 buffer->format = GST_GL_BUFFER_FORMAT_PLANAR420;
197 buffer->is_yuv = TRUE;
198 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
199 buffer->width, buffer->height,
200 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
201 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
202 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
204 glGenTextures (1, &buffer->texture_u);
205 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_u);
206 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
207 GST_ROUND_UP_2 (buffer->width) / 2,
208 GST_ROUND_UP_2 (buffer->height) / 2,
209 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
210 comp = (format == GST_VIDEO_FORMAT_I420) ? 1 : 2;
211 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
212 GST_ROUND_UP_2 (buffer->width) / 2,
213 GST_ROUND_UP_2 (buffer->height) / 2,
214 GL_LUMINANCE, GL_UNSIGNED_BYTE,
216 gst_video_format_get_component_offset (format, comp, width, height));
218 glGenTextures (1, &buffer->texture_v);
219 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_v);
220 glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
221 GST_ROUND_UP_2 (buffer->width) / 2,
222 GST_ROUND_UP_2 (buffer->height) / 2,
223 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
224 comp = (format == GST_VIDEO_FORMAT_I420) ? 2 : 1;
225 glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
226 GST_ROUND_UP_2 (buffer->width) / 2,
227 GST_ROUND_UP_2 (buffer->height) / 2,
228 GL_LUMINANCE, GL_UNSIGNED_BYTE,
230 gst_video_format_get_component_offset (format, comp, width, height));
233 g_assert_not_reached ();
236 gst_gl_display_unlock (buffer->display);
243 gst_gl_buffer_download (GstGLBuffer * buffer, GstVideoFormat format, void *data)
247 GST_DEBUG ("downloading");
249 gst_gl_display_lock (buffer->display);
251 glGenFramebuffersEXT (1, &fbo);
252 glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
254 glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
255 GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, buffer->texture, 0);
257 glDrawBuffer (GL_COLOR_ATTACHMENT1_EXT);
258 glReadBuffer (GL_COLOR_ATTACHMENT1_EXT);
260 g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
261 GL_FRAMEBUFFER_COMPLETE_EXT);
263 /* we need a reset function */
264 glMatrixMode (GL_COLOR);
266 glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, 0);
267 glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0);
268 glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, 0);
271 case GST_VIDEO_FORMAT_RGBx:
272 glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA,
273 GL_UNSIGNED_BYTE, data);
275 case GST_VIDEO_FORMAT_BGRx:
276 glReadPixels (0, 0, buffer->width, buffer->height, GL_BGRA,
277 GL_UNSIGNED_BYTE, data);
279 case GST_VIDEO_FORMAT_xBGR:
280 glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA,
281 GL_UNSIGNED_INT_8_8_8_8, data);
283 case GST_VIDEO_FORMAT_xRGB:
284 glReadPixels (0, 0, buffer->width, buffer->height, GL_BGRA,
285 GL_UNSIGNED_INT_8_8_8_8, data);
288 g_assert_not_reached ();
291 glDeleteFramebuffersEXT (1, &fbo);
293 gst_gl_display_unlock (buffer->display);