Blame gst-libs/gst/gl/gstglformat.c

Packit 971217
/*
Packit 971217
 * GStreamer
Packit 971217
 * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
Packit 971217
 *
Packit 971217
 * This library is free software; you can redistribute it and/or
Packit 971217
 * modify it under the terms of the GNU Library General Public
Packit 971217
 * License as published by the Free Software Foundation; either
Packit 971217
 * version 2 of the License, or (at your option) any later version.
Packit 971217
 *
Packit 971217
 * This library is distributed in the hope that it will be useful,
Packit 971217
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 971217
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 971217
 * Library General Public License for more details.
Packit 971217
 *
Packit 971217
 * You should have received a copy of the GNU Library General Public
Packit 971217
 * License along with this library; if not, write to the
Packit 971217
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 971217
 * Boston, MA 02110-1301, USA.
Packit 971217
 */
Packit 971217
Packit 971217
/**
Packit 971217
 * SECTION:gstglformat
Packit 971217
 * @title: GstGLFormat
Packit 971217
 * @short_description: utilities for dealing with OpenGL formats
Packit 971217
 * @see_also: #GstGLBaseMemory, #GstGLMemory, #GstGLFramebuffer, #GstGLBuffer
Packit 971217
 *
Packit 971217
 * Some useful utilities for converting between various formats and OpenGL
Packit 971217
 * formats.
Packit 971217
 */
Packit 971217
Packit 971217
#ifdef HAVE_CONFIG_H
Packit 971217
#include "config.h"
Packit 971217
#endif
Packit 971217
Packit 971217
#include "gstglformat.h"
Packit 971217
Packit 971217
#include "gstglcontext.h"
Packit 971217
#include "gstglfuncs.h"
Packit 971217
Packit 971217
#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
Packit 971217
#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
Packit 971217
#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
Packit 971217
#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
Packit 971217
#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
Packit 971217
Packit 971217
#ifndef GL_TEXTURE_RECTANGLE
Packit 971217
#define GL_TEXTURE_RECTANGLE 0x84F5
Packit 971217
#endif
Packit 971217
#ifndef GL_TEXTURE_EXTERNAL_OES
Packit 971217
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
Packit 971217
#endif
Packit 971217
Packit 971217
static inline guint
Packit 971217
_gl_format_n_components (guint format)
Packit 971217
{
Packit 971217
  switch (format) {
Packit 971217
    case GST_VIDEO_GL_TEXTURE_TYPE_RGBA:
Packit 971217
    case GST_GL_RGBA:
Packit 971217
      return 4;
Packit 971217
    case GST_VIDEO_GL_TEXTURE_TYPE_RGB:
Packit 971217
    case GST_VIDEO_GL_TEXTURE_TYPE_RGB16:
Packit 971217
    case GST_GL_RGB:
Packit 971217
    case GST_GL_RGB565:
Packit 971217
      return 3;
Packit 971217
    case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA:
Packit 971217
    case GST_VIDEO_GL_TEXTURE_TYPE_RG:
Packit 971217
    case GST_GL_LUMINANCE_ALPHA:
Packit 971217
    case GST_GL_RG:
Packit 971217
      return 2;
Packit 971217
    case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE:
Packit 971217
    case GST_VIDEO_GL_TEXTURE_TYPE_R:
Packit 971217
    case GST_GL_LUMINANCE:
Packit 971217
    case GST_GL_RED:
Packit 971217
      return 1;
Packit 971217
    default:
Packit 971217
      return 0;
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static inline guint
Packit 971217
_gl_type_n_components (guint type)
Packit 971217
{
Packit 971217
  switch (type) {
Packit 971217
    case GL_UNSIGNED_BYTE:
Packit 971217
      return 1;
Packit 971217
    case GL_UNSIGNED_SHORT_5_6_5:
Packit 971217
      return 3;
Packit 971217
    default:
Packit 971217
      g_assert_not_reached ();
Packit 971217
      return 0;
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static inline guint
Packit 971217
_gl_type_n_bytes (guint type)
Packit 971217
{
Packit 971217
  switch (type) {
Packit 971217
    case GL_UNSIGNED_BYTE:
Packit 971217
      return 1;
Packit 971217
    case GL_UNSIGNED_SHORT_5_6_5:
Packit 971217
      return 2;
Packit 971217
    default:
Packit 971217
      g_assert_not_reached ();
Packit 971217
      return 0;
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_gl_format_type_n_bytes:
Packit 971217
 * @format: the OpenGL format, %GL_RGBA, %GL_LUMINANCE, etc
Packit 971217
 * @type: the OpenGL type, %GL_UNSIGNED_BYTE, %GL_FLOAT, etc
Packit 971217
 *
Packit 971217
 * Returns: the number of bytes the specified @format, @type combination takes
Packit 971217
 * per pixel
Packit 971217
 */
Packit 971217
guint
Packit 971217
gst_gl_format_type_n_bytes (guint format, guint type)
Packit 971217
{
Packit 971217
  return _gl_format_n_components (format) / _gl_type_n_components (type) *
Packit 971217
      _gl_type_n_bytes (type);
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_gl_format_from_video_info:
Packit 971217
 * @context: a #GstGLContext
Packit 971217
 * @vinfo: a #GstVideoInfo
Packit 971217
 * @plane: the plane number in @vinfo
Packit 971217
 *
Packit 971217
 * Returns: the #GstGLFormat necessary for holding the data in @plane of @vinfo
Packit 971217
 */
Packit 971217
GstGLFormat
Packit 971217
gst_gl_format_from_video_info (GstGLContext * context, GstVideoInfo * vinfo,
Packit 971217
    guint plane)
Packit 971217
{
Packit 971217
  gboolean texture_rg =
Packit 971217
      gst_gl_context_check_feature (context, "GL_EXT_texture_rg")
Packit 971217
      || gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0)
Packit 971217
      || gst_gl_context_check_feature (context, "GL_ARB_texture_rg")
Packit 971217
      || gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 0);
Packit 971217
  GstVideoFormat v_format = GST_VIDEO_INFO_FORMAT (vinfo);
Packit 971217
  guint n_plane_components;
Packit 971217
Packit 971217
  switch (v_format) {
Packit 971217
    case GST_VIDEO_FORMAT_RGBx:
Packit 971217
    case GST_VIDEO_FORMAT_BGRx:
Packit 971217
    case GST_VIDEO_FORMAT_xRGB:
Packit 971217
    case GST_VIDEO_FORMAT_xBGR:
Packit 971217
    case GST_VIDEO_FORMAT_RGBA:
Packit 971217
    case GST_VIDEO_FORMAT_BGRA:
Packit 971217
    case GST_VIDEO_FORMAT_ARGB:
Packit 971217
    case GST_VIDEO_FORMAT_ABGR:
Packit 971217
    case GST_VIDEO_FORMAT_AYUV:
Packit 971217
      n_plane_components = 4;
Packit 971217
      break;
Packit 971217
    case GST_VIDEO_FORMAT_RGB:
Packit 971217
    case GST_VIDEO_FORMAT_BGR:
Packit 971217
      n_plane_components = 3;
Packit 971217
      break;
Packit 971217
    case GST_VIDEO_FORMAT_RGB16:
Packit 971217
    case GST_VIDEO_FORMAT_BGR16:
Packit 971217
      return GST_GL_RGB565;
Packit 971217
    case GST_VIDEO_FORMAT_GRAY16_BE:
Packit 971217
    case GST_VIDEO_FORMAT_GRAY16_LE:
Packit 971217
    case GST_VIDEO_FORMAT_YUY2:
Packit 971217
    case GST_VIDEO_FORMAT_UYVY:
Packit 971217
      n_plane_components = 2;
Packit 971217
      break;
Packit 971217
    case GST_VIDEO_FORMAT_NV12:
Packit 971217
    case GST_VIDEO_FORMAT_NV21:
Packit 971217
      n_plane_components = plane == 0 ? 1 : 2;
Packit 971217
      break;
Packit 971217
    case GST_VIDEO_FORMAT_GRAY8:
Packit 971217
    case GST_VIDEO_FORMAT_Y444:
Packit 971217
    case GST_VIDEO_FORMAT_Y42B:
Packit 971217
    case GST_VIDEO_FORMAT_Y41B:
Packit 971217
    case GST_VIDEO_FORMAT_I420:
Packit 971217
    case GST_VIDEO_FORMAT_YV12:
Packit 971217
      n_plane_components = 1;
Packit 971217
      break;
Packit 971217
    default:
Packit 971217
      n_plane_components = 4;
Packit 971217
      g_assert_not_reached ();
Packit 971217
      break;
Packit 971217
  }
Packit 971217
Packit 971217
  switch (n_plane_components) {
Packit 971217
    case 4:
Packit 971217
      return GST_GL_RGBA;
Packit 971217
      break;
Packit 971217
    case 3:
Packit 971217
      return GST_GL_RGB;
Packit 971217
      break;
Packit 971217
    case 2:
Packit 971217
      return texture_rg ? GST_GL_RG : GST_GL_LUMINANCE_ALPHA;
Packit 971217
      break;
Packit 971217
    case 1:
Packit 971217
      return texture_rg ? GST_GL_RED : GST_GL_LUMINANCE;
Packit 971217
      break;
Packit 971217
    default:
Packit 971217
      g_assert_not_reached ();
Packit 971217
      break;
Packit 971217
  }
Packit 971217
Packit 971217
  return GST_GL_RGBA;
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_gl_sized_gl_format_from_gl_format_type:
Packit 971217
 * @context: a #GstGLContext
Packit 971217
 * @format: an OpenGL format, %GL_RGBA, %GL_LUMINANCE, etc
Packit 971217
 * @type: an OpenGL type, %GL_UNSIGNED_BYTE, %GL_FLOAT, etc
Packit 971217
 *
Packit 971217
 * Returns: the sized internal format specified by @format and @type that can
Packit 971217
 *          be used in @context
Packit 971217
 */
Packit 971217
guint
Packit 971217
gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
Packit 971217
    guint format, guint type)
Packit 971217
{
Packit 971217
  gboolean ext_texture_rg =
Packit 971217
      gst_gl_context_check_feature (context, "GL_EXT_texture_rg");
Packit 971217
Packit 971217
  switch (format) {
Packit 971217
    case GST_GL_RGBA:
Packit 971217
      switch (type) {
Packit 971217
        case GL_UNSIGNED_BYTE:
Packit 971217
          return USING_GLES2 (context)
Packit 971217
              && !USING_GLES3 (context) ? GST_GL_RGBA : GST_GL_RGBA8;
Packit 971217
          break;
Packit 971217
      }
Packit 971217
      break;
Packit 971217
    case GST_GL_RGB:
Packit 971217
      switch (type) {
Packit 971217
        case GL_UNSIGNED_BYTE:
Packit 971217
          return USING_GLES2 (context)
Packit 971217
              && !USING_GLES3 (context) ? GST_GL_RGB : GST_GL_RGB8;
Packit 971217
          break;
Packit 971217
        case GL_UNSIGNED_SHORT_5_6_5:
Packit 971217
          return GST_GL_RGB565;
Packit 971217
          break;
Packit 971217
      }
Packit 971217
      break;
Packit 971217
    case GST_GL_RG:
Packit 971217
      switch (type) {
Packit 971217
        case GL_UNSIGNED_BYTE:
Packit 971217
          if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
Packit 971217
            return GST_GL_RG;
Packit 971217
          return GST_GL_RG8;
Packit 971217
          break;
Packit 971217
      }
Packit 971217
      break;
Packit 971217
    case GST_GL_RED:
Packit 971217
      switch (type) {
Packit 971217
        case GL_UNSIGNED_BYTE:
Packit 971217
          if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
Packit 971217
            return GST_GL_RED;
Packit 971217
          return GST_GL_R8;
Packit 971217
          break;
Packit 971217
      }
Packit 971217
      break;
Packit 971217
    case GST_GL_RGBA8:
Packit 971217
    case GST_GL_RGB8:
Packit 971217
    case GST_GL_RGB565:
Packit 971217
    case GST_GL_RG8:
Packit 971217
    case GST_GL_R8:
Packit 971217
    case GST_GL_LUMINANCE:
Packit 971217
    case GST_GL_LUMINANCE_ALPHA:
Packit 971217
    case GST_GL_ALPHA:
Packit 971217
    case GST_GL_DEPTH_COMPONENT16:
Packit 971217
    case GST_GL_DEPTH24_STENCIL8:
Packit 971217
      return format;
Packit 971217
    default:
Packit 971217
      break;
Packit 971217
  }
Packit 971217
Packit 971217
  g_assert_not_reached ();
Packit 971217
  return 0;
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_gl_texture_target_to_string:
Packit 971217
 * @target: a #GstGLTextureTarget
Packit 971217
 *
Packit 971217
 * Returns: the stringified version of @target or %NULL
Packit 971217
 */
Packit 971217
const gchar *
Packit 971217
gst_gl_texture_target_to_string (GstGLTextureTarget target)
Packit 971217
{
Packit 971217
  switch (target) {
Packit 971217
    case GST_GL_TEXTURE_TARGET_2D:
Packit 971217
      return GST_GL_TEXTURE_TARGET_2D_STR;
Packit 971217
    case GST_GL_TEXTURE_TARGET_RECTANGLE:
Packit 971217
      return GST_GL_TEXTURE_TARGET_RECTANGLE_STR;
Packit 971217
    case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
Packit 971217
      return GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR;
Packit 971217
    default:
Packit 971217
      return NULL;
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_gl_texture_target_from_string:
Packit 971217
 * @str: a string equivalant to one of the GST_GL_TEXTURE_TARGET_*_STR values
Packit 971217
 *
Packit 971217
 * Returns: the #GstGLTextureTarget represented by @str or
Packit 971217
 *          %GST_GL_TEXTURE_TARGET_NONE
Packit 971217
 */
Packit 971217
GstGLTextureTarget
Packit 971217
gst_gl_texture_target_from_string (const gchar * str)
Packit 971217
{
Packit 971217
  if (!str)
Packit 971217
    return GST_GL_TEXTURE_TARGET_NONE;
Packit 971217
Packit 971217
  if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_2D_STR) == 0)
Packit 971217
    return GST_GL_TEXTURE_TARGET_2D;
Packit 971217
  if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_RECTANGLE_STR) == 0)
Packit 971217
    return GST_GL_TEXTURE_TARGET_RECTANGLE;
Packit 971217
  if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR) == 0)
Packit 971217
    return GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
Packit 971217
Packit 971217
  return GST_GL_TEXTURE_TARGET_NONE;
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_gl_texture_target_to_gl:
Packit 971217
 * @target: a #GstGLTextureTarget
Packit 971217
 *
Packit 971217
 * Returns: the OpenGL value for binding the @target with glBindTexture() and
Packit 971217
 *          similar functions or 0
Packit 971217
 */
Packit 971217
guint
Packit 971217
gst_gl_texture_target_to_gl (GstGLTextureTarget target)
Packit 971217
{
Packit 971217
  switch (target) {
Packit 971217
    case GST_GL_TEXTURE_TARGET_2D:
Packit 971217
      return GL_TEXTURE_2D;
Packit 971217
    case GST_GL_TEXTURE_TARGET_RECTANGLE:
Packit 971217
      return GL_TEXTURE_RECTANGLE;
Packit 971217
    case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
Packit 971217
      return GL_TEXTURE_EXTERNAL_OES;
Packit 971217
    default:
Packit 971217
      return 0;
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_gl_texture_target_from_gl:
Packit 971217
 * @target: an OpenGL texture binding target
Packit 971217
 *
Packit 971217
 * Returns: the #GstGLTextureTarget that's equiavalant to @target or
Packit 971217
 *          %GST_GL_TEXTURE_TARGET_NONE
Packit 971217
 */
Packit 971217
GstGLTextureTarget
Packit 971217
gst_gl_texture_target_from_gl (guint target)
Packit 971217
{
Packit 971217
  switch (target) {
Packit 971217
    case GL_TEXTURE_2D:
Packit 971217
      return GST_GL_TEXTURE_TARGET_2D;
Packit 971217
    case GL_TEXTURE_RECTANGLE:
Packit 971217
      return GST_GL_TEXTURE_TARGET_RECTANGLE;
Packit 971217
    case GL_TEXTURE_EXTERNAL_OES:
Packit 971217
      return GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
Packit 971217
    default:
Packit 971217
      return GST_GL_TEXTURE_TARGET_NONE;
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_gl_texture_target_to_buffer_pool_option:
Packit 971217
 * @target: a #GstGLTextureTarget
Packit 971217
 *
Packit 971217
 * Returns: a string representing the @GstBufferPoolOption specified by @target
Packit 971217
 */
Packit 971217
const gchar *
Packit 971217
gst_gl_texture_target_to_buffer_pool_option (GstGLTextureTarget target)
Packit 971217
{
Packit 971217
  switch (target) {
Packit 971217
    case GST_GL_TEXTURE_TARGET_2D:
Packit 971217
      return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_2D;
Packit 971217
    case GST_GL_TEXTURE_TARGET_RECTANGLE:
Packit 971217
      return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_RECTANGLE;
Packit 971217
    case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
Packit 971217
      return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_EXTERNAL_OES;
Packit 971217
    default:
Packit 971217
      return NULL;
Packit 971217
  }
Packit 971217
}