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 case GST_VIDEO_FORMAT_NV16:
194 case GST_VIDEO_FORMAT_NV61:
195 n_plane_components = plane == 0 ? 1 : 2;
197 case GST_VIDEO_FORMAT_GRAY8:
198 case GST_VIDEO_FORMAT_Y444:
199 case GST_VIDEO_FORMAT_Y42B:
200 case GST_VIDEO_FORMAT_Y41B:
201 case GST_VIDEO_FORMAT_I420:
202 case GST_VIDEO_FORMAT_YV12:
203 n_plane_components = 1;
205 case GST_VIDEO_FORMAT_BGR10A2_LE:
206 case GST_VIDEO_FORMAT_RGB10A2_LE:
207 case GST_VIDEO_FORMAT_Y410:
208 return GST_GL_RGB10_A2;
209 case GST_VIDEO_FORMAT_P010_10LE:
210 case GST_VIDEO_FORMAT_P010_10BE:
211 case GST_VIDEO_FORMAT_P016_LE:
212 case GST_VIDEO_FORMAT_P016_BE:
213 return plane == 0 ? GST_GL_R16 : GST_GL_RG16;
215 n_plane_components = 4;
216 g_assert_not_reached ();
220 switch (n_plane_components) {
226 return texture_rg ? GST_GL_RG : GST_GL_LUMINANCE_ALPHA;
228 return texture_rg ? GST_GL_RED : GST_GL_LUMINANCE;
233 g_critical ("Unknown video format 0x%x provided", v_format);
238 * gst_gl_sized_gl_format_from_gl_format_type:
239 * @context: a #GstGLContext
240 * @format: an OpenGL format, `GL_RGBA`, `GL_LUMINANCE`, etc
241 * @type: an OpenGL type, `GL_UNSIGNED_BYTE`, `GL_FLOAT`, etc
243 * Returns: the sized internal format specified by @format and @type that can
244 * be used in @context
247 gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
248 guint format, guint type)
250 gboolean ext_texture_rg =
251 gst_gl_context_check_feature (context, "GL_EXT_texture_rg");
256 case GL_UNSIGNED_BYTE:
257 return USING_GLES2 (context)
258 && !USING_GLES3 (context) ? GST_GL_RGBA : GST_GL_RGBA8;
259 case GL_UNSIGNED_SHORT:
260 return GST_GL_RGBA16;
261 case GL_UNSIGNED_INT_2_10_10_10_REV:
262 return GST_GL_RGB10_A2;
267 case GL_UNSIGNED_BYTE:
268 return USING_GLES2 (context)
269 && !USING_GLES3 (context) ? GST_GL_RGB : GST_GL_RGB8;
270 case GL_UNSIGNED_SHORT_5_6_5:
271 return GST_GL_RGB565;
272 case GL_UNSIGNED_SHORT:
278 case GL_UNSIGNED_BYTE:
279 if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
282 case GL_UNSIGNED_SHORT:
288 case GL_UNSIGNED_BYTE:
289 if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
292 case GL_UNSIGNED_SHORT:
303 case GST_GL_LUMINANCE:
304 case GST_GL_LUMINANCE_ALPHA:
306 case GST_GL_DEPTH_COMPONENT16:
307 case GST_GL_DEPTH24_STENCIL8:
308 case GST_GL_RGB10_A2:
313 g_critical ("Unknown GL format 0x%x type 0x%x provided", format, type);
317 g_assert_not_reached ();
322 * gst_gl_format_type_from_sized_gl_format:
323 * @format: the sized internal #GstGLFormat
324 * @unsized_format: (out): location for the resulting unsized #GstGLFormat
325 * @gl_type: (out): location for the resulting GL type
327 * Get the unsized format and type from @format for usage in glReadPixels,
328 * glTex{Sub}Image*, glTexImage* and similar functions.
333 gst_gl_format_type_from_sized_gl_format (GstGLFormat format,
334 GstGLFormat * unsized_format, guint * gl_type)
336 g_return_if_fail (unsized_format != NULL);
337 g_return_if_fail (gl_type != NULL);
341 *unsized_format = GST_GL_RGBA;
342 *gl_type = GL_UNSIGNED_BYTE;
345 *unsized_format = GST_GL_RGB;
346 *gl_type = GL_UNSIGNED_BYTE;
349 *unsized_format = GST_GL_RGBA;
350 *gl_type = GL_UNSIGNED_SHORT;
353 *unsized_format = GST_GL_RGB;
354 *gl_type = GL_UNSIGNED_SHORT;
357 *unsized_format = GST_GL_RGB;
358 *gl_type = GL_UNSIGNED_SHORT_5_6_5;
361 *unsized_format = GST_GL_RG;
362 *gl_type = GL_UNSIGNED_BYTE;
365 *unsized_format = GST_GL_RED;
366 *gl_type = GL_UNSIGNED_BYTE;
372 case GST_GL_LUMINANCE:
373 case GST_GL_LUMINANCE_ALPHA:
375 *unsized_format = format;
376 *gl_type = GL_UNSIGNED_BYTE;
378 case GST_GL_RGB10_A2:
379 *unsized_format = GST_GL_RGBA;
380 *gl_type = GL_UNSIGNED_INT_2_10_10_10_REV;
383 *unsized_format = GST_GL_RED;
384 *gl_type = GL_UNSIGNED_SHORT;
387 *unsized_format = GST_GL_RG;
388 *gl_type = GL_UNSIGNED_SHORT;
391 g_critical ("Unknown GL format 0x%x provided", format);
392 *unsized_format = format;
393 *gl_type = GL_UNSIGNED_BYTE;
399 * gst_gl_format_is_supported:
400 * @context: a #GstGLContext
401 * @format: the #GstGLFormat to check is supported by @context
403 * Returns: Whether @format is supported by @context based on the OpenGL API,
404 * version, or available OpenGL extension/s.
409 gst_gl_format_is_supported (GstGLContext * context, GstGLFormat format)
411 g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
417 case GST_GL_LUMINANCE:
419 case GST_GL_LUMINANCE_ALPHA:
420 /* deprecated/removed in core GL3 contexts */
421 return USING_OPENGL (context) || USING_GLES2 (context);
424 return gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0)
425 || gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 0)
426 || gst_gl_context_check_feature (context, "GL_EXT_texture_rg")
427 || gst_gl_context_check_feature (context, "GL_ARB_texture_rg");
430 return USING_GLES3 (context)
431 || gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 0)
432 || gst_gl_context_check_feature (context, "GL_ARB_texture_rg");
435 return (USING_GLES3 (context) && !USING_GLES2 (context))
436 || USING_OPENGL (context) || USING_OPENGL3 (context);
439 return USING_OPENGL (context) || USING_OPENGL3 (context)
440 || USING_GLES3 (context);
442 return USING_GLES2 (context) || (USING_OPENGL3 (context)
443 && gst_gl_context_check_feature (context,
444 "GL_ARB_ES2_compatibility"));
445 case GST_GL_DEPTH_COMPONENT16:
446 return gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 4)
447 || USING_GLES2 (context)
448 || gst_gl_context_check_feature (context, "GL_ARB_depth_texture")
449 || gst_gl_context_check_feature (context, "GL_OES_depth_texture");
450 case GST_GL_DEPTH24_STENCIL8:
451 return gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 3, 0)
452 || USING_GLES3 (context)
453 || gst_gl_context_check_feature (context,
454 "GL_OES_packed_depth_stencil")
455 || gst_gl_context_check_feature (context,
456 "GL_EXT_packed_depth_stencil");
457 case GST_GL_RGB10_A2:
458 return USING_OPENGL (context) || USING_OPENGL3 (context)
459 || USING_GLES3 (context)
460 || gst_gl_context_check_feature (context,
461 "GL_OES_required_internalformat");
464 return gst_gl_context_check_gl_version (context,
465 GST_GL_API_OPENGL | GST_GL_API_OPENGL3, 3, 0)
466 || (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 1)
467 && gst_gl_context_check_feature (context, "GL_EXT_texture_norm16"));
469 g_assert_not_reached ();
475 * gst_gl_texture_target_to_string:
476 * @target: a #GstGLTextureTarget
478 * Returns: the stringified version of @target or %NULL
481 gst_gl_texture_target_to_string (GstGLTextureTarget target)
484 case GST_GL_TEXTURE_TARGET_2D:
485 return GST_GL_TEXTURE_TARGET_2D_STR;
486 case GST_GL_TEXTURE_TARGET_RECTANGLE:
487 return GST_GL_TEXTURE_TARGET_RECTANGLE_STR;
488 case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
489 return GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR;
496 * gst_gl_texture_target_from_string:
497 * @str: a string equivalent to one of the GST_GL_TEXTURE_TARGET_*_STR values
499 * Returns: the #GstGLTextureTarget represented by @str or
500 * %GST_GL_TEXTURE_TARGET_NONE
503 gst_gl_texture_target_from_string (const gchar * str)
506 return GST_GL_TEXTURE_TARGET_NONE;
508 if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_2D_STR) == 0)
509 return GST_GL_TEXTURE_TARGET_2D;
510 if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_RECTANGLE_STR) == 0)
511 return GST_GL_TEXTURE_TARGET_RECTANGLE;
512 if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR) == 0)
513 return GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
515 return GST_GL_TEXTURE_TARGET_NONE;
519 * gst_gl_texture_target_to_gl:
520 * @target: a #GstGLTextureTarget
522 * Returns: the OpenGL value for binding the @target with glBindTexture() and
523 * similar functions or 0
526 gst_gl_texture_target_to_gl (GstGLTextureTarget target)
529 case GST_GL_TEXTURE_TARGET_2D:
530 return GL_TEXTURE_2D;
531 case GST_GL_TEXTURE_TARGET_RECTANGLE:
532 return GL_TEXTURE_RECTANGLE;
533 case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
534 return GL_TEXTURE_EXTERNAL_OES;
541 * gst_gl_texture_target_from_gl:
542 * @target: an OpenGL texture binding target
544 * Returns: the #GstGLTextureTarget that's equiavalant to @target or
545 * %GST_GL_TEXTURE_TARGET_NONE
548 gst_gl_texture_target_from_gl (guint target)
552 return GST_GL_TEXTURE_TARGET_2D;
553 case GL_TEXTURE_RECTANGLE:
554 return GST_GL_TEXTURE_TARGET_RECTANGLE;
555 case GL_TEXTURE_EXTERNAL_OES:
556 return GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
558 return GST_GL_TEXTURE_TARGET_NONE;
563 * gst_gl_texture_target_to_buffer_pool_option:
564 * @target: a #GstGLTextureTarget
566 * Returns: a string representing the @GstBufferPoolOption specified by @target
569 gst_gl_texture_target_to_buffer_pool_option (GstGLTextureTarget target)
572 case GST_GL_TEXTURE_TARGET_2D:
573 return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_2D;
574 case GST_GL_TEXTURE_TARGET_RECTANGLE:
575 return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_RECTANGLE;
576 case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
577 return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_EXTERNAL_OES;