3 * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
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.
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.
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.
24 * @short_description: utilities for dealing with OpenGL formats
25 * @see_also: #GstGLBaseMemory, #GstGLMemory, #GstGLFramebuffer, #GstGLBuffer
27 * Some useful utilities for converting between various formats and OpenGL
35 #include "gstglformat.h"
37 #include "gstglcontext.h"
38 #include "gstglfuncs.h"
40 #define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
41 #define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
42 #define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
43 #define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
44 #define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
46 #ifndef GL_TEXTURE_RECTANGLE
47 #define GL_TEXTURE_RECTANGLE 0x84F5
49 #ifndef GL_TEXTURE_EXTERNAL_OES
50 #define GL_TEXTURE_EXTERNAL_OES 0x8D65
52 #ifndef GL_UNSIGNED_INT_2_10_10_10_REV
53 #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
57 _gl_format_n_components (guint format)
60 case GST_VIDEO_GL_TEXTURE_TYPE_RGBA:
66 case GST_VIDEO_GL_TEXTURE_TYPE_RGB:
67 case GST_VIDEO_GL_TEXTURE_TYPE_RGB16:
73 case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA:
74 case GST_VIDEO_GL_TEXTURE_TYPE_RG:
75 case GST_GL_LUMINANCE_ALPHA:
80 case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE:
81 case GST_VIDEO_GL_TEXTURE_TYPE_R:
82 case GST_GL_LUMINANCE:
94 _gl_type_n_components (guint type)
97 case GL_UNSIGNED_BYTE:
98 case GL_UNSIGNED_SHORT:
100 case GL_UNSIGNED_SHORT_5_6_5:
102 case GL_UNSIGNED_INT_2_10_10_10_REV:
105 g_assert_not_reached ();
111 _gl_type_n_bytes (guint type)
114 case GL_UNSIGNED_BYTE:
116 case GL_UNSIGNED_SHORT:
117 case GL_UNSIGNED_SHORT_5_6_5:
119 case GL_UNSIGNED_INT_2_10_10_10_REV:
122 g_assert_not_reached ();
128 * gst_gl_format_type_n_bytes:
129 * @format: the OpenGL format, `GL_RGBA`, `GL_LUMINANCE`, etc
130 * @type: the OpenGL type, `GL_UNSIGNED_BYTE`, `GL_FLOAT`, etc
132 * Returns: the number of bytes the specified @format, @type combination takes
136 gst_gl_format_type_n_bytes (guint format, guint type)
138 return _gl_format_n_components (format) / _gl_type_n_components (type) *
139 _gl_type_n_bytes (type);
143 * gst_gl_format_from_video_info:
144 * @context: a #GstGLContext
145 * @vinfo: a #GstVideoInfo
146 * @plane: the plane number in @vinfo
148 * Returns: the #GstGLFormat necessary for holding the data in @plane of @vinfo
151 gst_gl_format_from_video_info (GstGLContext * context, GstVideoInfo * vinfo,
154 gboolean texture_rg =
155 gst_gl_context_check_feature (context, "GL_EXT_texture_rg")
156 || gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0)
157 || gst_gl_context_check_feature (context, "GL_ARB_texture_rg")
158 || gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 0);
159 GstVideoFormat v_format = GST_VIDEO_INFO_FORMAT (vinfo);
160 guint n_plane_components;
163 case GST_VIDEO_FORMAT_RGBx:
164 case GST_VIDEO_FORMAT_BGRx:
165 case GST_VIDEO_FORMAT_xRGB:
166 case GST_VIDEO_FORMAT_xBGR:
167 case GST_VIDEO_FORMAT_RGBA:
168 case GST_VIDEO_FORMAT_BGRA:
169 case GST_VIDEO_FORMAT_ARGB:
170 case GST_VIDEO_FORMAT_ABGR:
171 case GST_VIDEO_FORMAT_AYUV:
172 case GST_VIDEO_FORMAT_VUYA:
173 n_plane_components = 4;
175 case GST_VIDEO_FORMAT_ARGB64:
176 return GST_GL_RGBA16;
177 case GST_VIDEO_FORMAT_RGB:
178 case GST_VIDEO_FORMAT_BGR:
179 n_plane_components = 3;
181 case GST_VIDEO_FORMAT_RGB16:
182 case GST_VIDEO_FORMAT_BGR16:
183 return GST_GL_RGB565;
185 case GST_VIDEO_FORMAT_GRAY16_BE:
186 case GST_VIDEO_FORMAT_GRAY16_LE:
187 case GST_VIDEO_FORMAT_YUY2:
188 case GST_VIDEO_FORMAT_UYVY:
189 n_plane_components = 2;
191 case GST_VIDEO_FORMAT_NV12:
192 case GST_VIDEO_FORMAT_NV21:
193 n_plane_components = plane == 0 ? 1 : 2;
195 case GST_VIDEO_FORMAT_GRAY8:
196 case GST_VIDEO_FORMAT_Y444:
197 case GST_VIDEO_FORMAT_Y42B:
198 case GST_VIDEO_FORMAT_Y41B:
199 case GST_VIDEO_FORMAT_I420:
200 case GST_VIDEO_FORMAT_YV12:
201 n_plane_components = 1;
203 case GST_VIDEO_FORMAT_BGR10A2_LE:
204 case GST_VIDEO_FORMAT_RGB10A2_LE:
205 case GST_VIDEO_FORMAT_Y410:
206 return GST_GL_RGB10_A2;
207 case GST_VIDEO_FORMAT_P010_10LE:
208 case GST_VIDEO_FORMAT_P010_10BE:
209 case GST_VIDEO_FORMAT_P016_LE:
210 case GST_VIDEO_FORMAT_P016_BE:
211 return plane == 0 ? GST_GL_R16 : GST_GL_RG16;
213 n_plane_components = 4;
214 g_assert_not_reached ();
218 switch (n_plane_components) {
224 return texture_rg ? GST_GL_RG : GST_GL_LUMINANCE_ALPHA;
226 return texture_rg ? GST_GL_RED : GST_GL_LUMINANCE;
231 g_critical ("Unknown video format 0x%x provided", v_format);
236 * gst_gl_sized_gl_format_from_gl_format_type:
237 * @context: a #GstGLContext
238 * @format: an OpenGL format, `GL_RGBA`, `GL_LUMINANCE`, etc
239 * @type: an OpenGL type, `GL_UNSIGNED_BYTE`, `GL_FLOAT`, etc
241 * Returns: the sized internal format specified by @format and @type that can
242 * be used in @context
245 gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
246 guint format, guint type)
248 gboolean ext_texture_rg =
249 gst_gl_context_check_feature (context, "GL_EXT_texture_rg");
254 case GL_UNSIGNED_BYTE:
255 return USING_GLES2 (context)
256 && !USING_GLES3 (context) ? GST_GL_RGBA : GST_GL_RGBA8;
257 case GL_UNSIGNED_SHORT:
258 return GST_GL_RGBA16;
259 case GL_UNSIGNED_INT_2_10_10_10_REV:
260 return GST_GL_RGB10_A2;
265 case GL_UNSIGNED_BYTE:
266 return USING_GLES2 (context)
267 && !USING_GLES3 (context) ? GST_GL_RGB : GST_GL_RGB8;
268 case GL_UNSIGNED_SHORT_5_6_5:
269 return GST_GL_RGB565;
270 case GL_UNSIGNED_SHORT:
276 case GL_UNSIGNED_BYTE:
277 if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
280 case GL_UNSIGNED_SHORT:
286 case GL_UNSIGNED_BYTE:
287 if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
290 case GL_UNSIGNED_SHORT:
301 case GST_GL_LUMINANCE:
302 case GST_GL_LUMINANCE_ALPHA:
304 case GST_GL_DEPTH_COMPONENT16:
305 case GST_GL_DEPTH24_STENCIL8:
306 case GST_GL_RGB10_A2:
311 g_critical ("Unknown GL format 0x%x type 0x%x provided", format, type);
315 g_assert_not_reached ();
320 * gst_gl_format_type_from_sized_gl_format:
321 * @format: the sized internal #GstGLFormat
322 * @unsized_format: (out): location for the resulting unsized #GstGLFormat
323 * @gl_type: (out): location for the resulting GL type
325 * Get the unsized format and type from @format for usage in glReadPixels,
326 * glTex{Sub}Image*, glTexImage* and similar functions.
331 gst_gl_format_type_from_sized_gl_format (GstGLFormat format,
332 GstGLFormat * unsized_format, guint * gl_type)
334 g_return_if_fail (unsized_format != NULL);
335 g_return_if_fail (gl_type != NULL);
339 *unsized_format = GST_GL_RGBA;
340 *gl_type = GL_UNSIGNED_BYTE;
343 *unsized_format = GST_GL_RGB;
344 *gl_type = GL_UNSIGNED_BYTE;
347 *unsized_format = GST_GL_RGBA;
348 *gl_type = GL_UNSIGNED_SHORT;
351 *unsized_format = GST_GL_RGB;
352 *gl_type = GL_UNSIGNED_SHORT;
355 *unsized_format = GST_GL_RGB;
356 *gl_type = GL_UNSIGNED_SHORT_5_6_5;
359 *unsized_format = GST_GL_RG;
360 *gl_type = GL_UNSIGNED_BYTE;
363 *unsized_format = GST_GL_RED;
364 *gl_type = GL_UNSIGNED_BYTE;
370 case GST_GL_LUMINANCE:
371 case GST_GL_LUMINANCE_ALPHA:
373 *unsized_format = format;
374 *gl_type = GL_UNSIGNED_BYTE;
376 case GST_GL_RGB10_A2:
377 *unsized_format = GST_GL_RGBA;
378 *gl_type = GL_UNSIGNED_INT_2_10_10_10_REV;
381 *unsized_format = GST_GL_RED;
382 *gl_type = GL_UNSIGNED_SHORT;
385 *unsized_format = GST_GL_RG;
386 *gl_type = GL_UNSIGNED_SHORT;
389 g_critical ("Unknown GL format 0x%x provided", format);
390 *unsized_format = format;
391 *gl_type = GL_UNSIGNED_BYTE;
397 * gst_gl_format_is_supported:
398 * @context: a #GstGLContext
399 * @format: the #GstGLFormat to check is supported by @context
401 * Returns: Whether @format is supported by @context based on the OpenGL API,
402 * version, or available OpenGL extension/s.
407 gst_gl_format_is_supported (GstGLContext * context, GstGLFormat format)
409 g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
415 case GST_GL_LUMINANCE:
417 case GST_GL_LUMINANCE_ALPHA:
418 /* deprecated/removed in core GL3 contexts */
419 return USING_OPENGL (context) || USING_GLES2 (context);
422 return gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0)
423 || gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 0)
424 || gst_gl_context_check_feature (context, "GL_EXT_texture_rg")
425 || gst_gl_context_check_feature (context, "GL_ARB_texture_rg");
428 return USING_GLES3 (context)
429 || gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 0)
430 || gst_gl_context_check_feature (context, "GL_ARB_texture_rg");
433 return (USING_GLES3 (context) && !USING_GLES2 (context))
434 || USING_OPENGL (context) || USING_OPENGL3 (context);
437 return USING_OPENGL (context) || USING_OPENGL3 (context)
438 || USING_GLES3 (context);
440 return USING_GLES2 (context) || (USING_OPENGL3 (context)
441 && gst_gl_context_check_feature (context,
442 "GL_ARB_ES2_compatibility"));
443 case GST_GL_DEPTH_COMPONENT16:
444 return gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 4)
445 || USING_GLES2 (context)
446 || gst_gl_context_check_feature (context, "GL_ARB_depth_texture")
447 || gst_gl_context_check_feature (context, "GL_OES_depth_texture");
448 case GST_GL_DEPTH24_STENCIL8:
449 return gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 3, 0)
450 || USING_GLES3 (context)
451 || gst_gl_context_check_feature (context,
452 "GL_OES_packed_depth_stencil")
453 || gst_gl_context_check_feature (context,
454 "GL_EXT_packed_depth_stencil");
455 case GST_GL_RGB10_A2:
456 return USING_OPENGL (context) || USING_OPENGL3 (context)
457 || USING_GLES3 (context)
458 || gst_gl_context_check_feature (context,
459 "GL_OES_required_internalformat");
462 return gst_gl_context_check_gl_version (context,
463 GST_GL_API_OPENGL | GST_GL_API_OPENGL3, 3, 0)
464 || (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 1)
465 && gst_gl_context_check_feature (context, "GL_EXT_texture_norm16"));
467 g_assert_not_reached ();
473 * gst_gl_texture_target_to_string:
474 * @target: a #GstGLTextureTarget
476 * Returns: the stringified version of @target or %NULL
479 gst_gl_texture_target_to_string (GstGLTextureTarget target)
482 case GST_GL_TEXTURE_TARGET_2D:
483 return GST_GL_TEXTURE_TARGET_2D_STR;
484 case GST_GL_TEXTURE_TARGET_RECTANGLE:
485 return GST_GL_TEXTURE_TARGET_RECTANGLE_STR;
486 case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
487 return GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR;
494 * gst_gl_texture_target_from_string:
495 * @str: a string equivalent to one of the GST_GL_TEXTURE_TARGET_*_STR values
497 * Returns: the #GstGLTextureTarget represented by @str or
498 * %GST_GL_TEXTURE_TARGET_NONE
501 gst_gl_texture_target_from_string (const gchar * str)
504 return GST_GL_TEXTURE_TARGET_NONE;
506 if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_2D_STR) == 0)
507 return GST_GL_TEXTURE_TARGET_2D;
508 if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_RECTANGLE_STR) == 0)
509 return GST_GL_TEXTURE_TARGET_RECTANGLE;
510 if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR) == 0)
511 return GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
513 return GST_GL_TEXTURE_TARGET_NONE;
517 * gst_gl_texture_target_to_gl:
518 * @target: a #GstGLTextureTarget
520 * Returns: the OpenGL value for binding the @target with glBindTexture() and
521 * similar functions or 0
524 gst_gl_texture_target_to_gl (GstGLTextureTarget target)
527 case GST_GL_TEXTURE_TARGET_2D:
528 return GL_TEXTURE_2D;
529 case GST_GL_TEXTURE_TARGET_RECTANGLE:
530 return GL_TEXTURE_RECTANGLE;
531 case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
532 return GL_TEXTURE_EXTERNAL_OES;
539 * gst_gl_texture_target_from_gl:
540 * @target: an OpenGL texture binding target
542 * Returns: the #GstGLTextureTarget that's equiavalant to @target or
543 * %GST_GL_TEXTURE_TARGET_NONE
546 gst_gl_texture_target_from_gl (guint target)
550 return GST_GL_TEXTURE_TARGET_2D;
551 case GL_TEXTURE_RECTANGLE:
552 return GST_GL_TEXTURE_TARGET_RECTANGLE;
553 case GL_TEXTURE_EXTERNAL_OES:
554 return GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
556 return GST_GL_TEXTURE_TARGET_NONE;
561 * gst_gl_texture_target_to_buffer_pool_option:
562 * @target: a #GstGLTextureTarget
564 * Returns: a string representing the @GstBufferPoolOption specified by @target
567 gst_gl_texture_target_to_buffer_pool_option (GstGLTextureTarget target)
570 case GST_GL_TEXTURE_TARGET_2D:
571 return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_2D;
572 case GST_GL_TEXTURE_TARGET_RECTANGLE:
573 return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_RECTANGLE;
574 case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
575 return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_EXTERNAL_OES;