glcolorconvert: add support for ARGB64 conversion
authorMatthew Waters <matthew@centricular.com>
Sat, 5 May 2018 11:21:13 +0000 (21:21 +1000)
committerMatthew Waters <matthew@centricular.com>
Sat, 5 May 2018 11:24:25 +0000 (21:24 +1000)
gst-libs/gst/gl/gstglcolorconvert.c
gst-libs/gst/gl/gstglcolorconvert.h
gst-libs/gst/gl/gstglformat.c
gst-libs/gst/gl/gstglformat.h
gst-libs/gst/gl/gstglmemory.h

index 782dbfd..489a1b2 100644 (file)
@@ -882,18 +882,78 @@ _init_value_string_list (GValue * list, ...)
   va_end (args);
 }
 
+static void
+_append_value_string_list (GValue * list, ...)
+{
+  GValue item = G_VALUE_INIT;
+  gchar *str;
+  va_list args;
+
+  va_start (args, list);
+  while ((str = va_arg (args, gchar *))) {
+    g_value_init (&item, G_TYPE_STRING);
+    g_value_set_string (&item, str);
+
+    gst_value_list_append_value (list, &item);
+    g_value_unset (&item);
+  }
+  va_end (args);
+}
+
+static void
+_init_supported_formats (GstGLContext * context, gboolean output,
+    GValue * supported_formats)
+{
+  /* Assume if context == NULL that we don't have a GL context and can
+   * do the conversion */
+
+  /* Always supported input and output formats */
+  _init_value_string_list (supported_formats, "RGBA", "RGB", "RGBx", "BGR",
+      "BGRx", "BGRA", "xRGB", "xBGR", "ARGB", "ABGR", "GRAY8", "GRAY16_LE",
+      "GRAY16_BE", "AYUV", "YUY2", "UYVY", NULL);
+
+  /* Always supported input formats or output with multiple draw buffers */
+  if (!output || (!context || context->gl_vtable->DrawBuffers))
+    _append_value_string_list (supported_formats, "Y444", "I420", "YV12",
+        "Y42B", "Y41B", "NV12", "NV21", NULL);
+
+  /* Requires reading from a RG/LA framebuffer... */
+  if (!context || (USING_GLES3 (context) || USING_OPENGL (context)))
+    _append_value_string_list (supported_formats, "YUY2", "UYVY", NULL);
+
+  if (!context || gst_gl_format_is_supported (context, GST_GL_RGBA16))
+    _append_value_string_list (supported_formats, "ARGB64", NULL);
+
+  if (!context || gst_gl_format_is_supported (context, GST_GL_RGB565))
+    _append_value_string_list (supported_formats, "RGB16", "BGR16", NULL);
+}
+
 /* copies the given caps */
 static GstCaps *
-gst_gl_color_convert_caps_transform_format_info (GstCaps * caps)
+gst_gl_color_convert_caps_transform_format_info (GstGLContext * context,
+    gboolean output, GstCaps * caps)
 {
   GstStructure *st;
   GstCapsFeatures *f;
   gint i, n;
   GstCaps *res;
+  GValue supported_formats = G_VALUE_INIT;
   GValue rgb_formats = G_VALUE_INIT;
+  GValue supported_rgb_formats = G_VALUE_INIT;
+
+  /* There are effectively two modes here with the RGB/YUV transition:
+   * 1. There is a RGB-like format as input and we can transform to YUV or,
+   * 2. No RGB-like format as input so we can only transform to RGB-like formats
+   *
+   * We also filter down the list of formats depending on what the OpenGL
+   * context supports (when provided).
+   */
 
   _init_value_string_list (&rgb_formats, "RGBA", "ARGB", "BGRA", "ABGR", "RGBx",
-      "xRGB", "BGRx", "xBGR", "RGB", "BGR", NULL);
+      "xRGB", "BGRx", "xBGR", "RGB", "BGR", "ARGB64", NULL);
+  _init_supported_formats (context, output, &supported_formats);
+  gst_value_intersect (&supported_rgb_formats, &rgb_formats,
+      &supported_formats);
 
   res = gst_caps_new_empty ();
 
@@ -933,13 +993,14 @@ gst_gl_color_convert_caps_transform_format_info (GstCaps * caps)
         }
       }
       if (have_rgb_formats) {
-        gst_structure_remove_fields (st, "format", NULL);
+        gst_structure_set_value (st, "format", &supported_formats);
       } else {
+        GValue supported_rgb_formats = G_VALUE_INIT;
         /* add passthrough structure, then the rgb conversion structure */
         gst_structure_set_value (st, "format", &passthrough_formats);
         gst_caps_append_structure_full (res, gst_structure_copy (st),
             gst_caps_features_copy (f));
-        gst_structure_set_value (st, "format", &rgb_formats);
+        gst_structure_set_value (st, "format", &supported_rgb_formats);
       }
       g_value_unset (&passthrough_formats);
     } else if (G_VALUE_HOLDS_STRING (format)) {
@@ -954,7 +1015,7 @@ gst_gl_color_convert_caps_transform_format_info (GstCaps * caps)
             gst_caps_features_copy (f));
         gst_structure_set_value (st, "format", &rgb_formats);
       } else {                  /* RGB */
-        gst_structure_remove_fields (st, "format", NULL);
+        gst_structure_set_value (st, "format", &supported_rgb_formats);
       }
     }
     gst_structure_remove_fields (st, "colorimetry", "chroma-site",
@@ -963,7 +1024,9 @@ gst_gl_color_convert_caps_transform_format_info (GstCaps * caps)
     gst_caps_append_structure_full (res, st, gst_caps_features_copy (f));
   }
 
+  g_value_unset (&supported_formats);
   g_value_unset (&rgb_formats);
+  g_value_unset (&supported_rgb_formats);
 
   return res;
 }
@@ -985,7 +1048,8 @@ GstCaps *
 gst_gl_color_convert_transform_caps (GstGLContext * context,
     GstPadDirection direction, GstCaps * caps, GstCaps * filter)
 {
-  caps = gst_gl_color_convert_caps_transform_format_info (caps);
+  caps = gst_gl_color_convert_caps_transform_format_info (context,
+      direction == GST_PAD_SRC, caps);
 
   if (filter) {
     GstCaps *tmp;
@@ -1430,6 +1494,7 @@ _get_n_textures (GstVideoFormat v_format)
     case GST_VIDEO_FORMAT_UYVY:
     case GST_VIDEO_FORMAT_RGB16:
     case GST_VIDEO_FORMAT_BGR16:
+    case GST_VIDEO_FORMAT_ARGB64:
       return 1;
     case GST_VIDEO_FORMAT_NV12:
     case GST_VIDEO_FORMAT_NV21:
index 40a4829..31e576d 100644 (file)
@@ -90,7 +90,7 @@ struct _GstGLColorConvertClass
 #define GST_GL_COLOR_CONVERT_FORMATS "{ RGBA, RGB, RGBx, BGR, BGRx, BGRA, xRGB, " \
                                "xBGR, ARGB, ABGR, Y444, I420, YV12, Y42B, " \
                                "Y41B, NV12, NV21, YUY2, UYVY, AYUV, " \
-                               "GRAY8, GRAY16_LE, GRAY16_BE, RGB16, BGR16 }"
+                               "GRAY8, GRAY16_LE, GRAY16_BE, RGB16, BGR16, ARGB64 }"
 
 /**
  * GST_GL_COLOR_CONVERT_VIDEO_CAPS:
index 3844d60..bc15743 100644 (file)
@@ -57,11 +57,13 @@ _gl_format_n_components (guint format)
     case GST_VIDEO_GL_TEXTURE_TYPE_RGBA:
     case GST_GL_RGBA:
     case GST_GL_RGBA8:
+    case GST_GL_RGBA16:
       return 4;
     case GST_VIDEO_GL_TEXTURE_TYPE_RGB:
     case GST_VIDEO_GL_TEXTURE_TYPE_RGB16:
     case GST_GL_RGB:
     case GST_GL_RGB8:
+    case GST_GL_RGB16:
     case GST_GL_RGB565:
       return 3;
     case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA:
@@ -87,6 +89,7 @@ _gl_type_n_components (guint type)
 {
   switch (type) {
     case GL_UNSIGNED_BYTE:
+    case GL_UNSIGNED_SHORT:
       return 1;
     case GL_UNSIGNED_SHORT_5_6_5:
       return 3;
@@ -102,6 +105,7 @@ _gl_type_n_bytes (guint type)
   switch (type) {
     case GL_UNSIGNED_BYTE:
       return 1;
+    case GL_UNSIGNED_SHORT:
     case GL_UNSIGNED_SHORT_5_6_5:
       return 2;
     default:
@@ -157,6 +161,8 @@ gst_gl_format_from_video_info (GstGLContext * context, GstVideoInfo * vinfo,
     case GST_VIDEO_FORMAT_AYUV:
       n_plane_components = 4;
       break;
+    case GST_VIDEO_FORMAT_ARGB64:
+      return GST_GL_RGBA16;
     case GST_VIDEO_FORMAT_RGB:
     case GST_VIDEO_FORMAT_BGR:
       n_plane_components = 3;
@@ -229,6 +235,8 @@ gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
           return USING_GLES2 (context)
               && !USING_GLES3 (context) ? GST_GL_RGBA : GST_GL_RGBA8;
           break;
+        case GL_UNSIGNED_SHORT:
+          return GST_GL_RGBA16;
       }
       break;
     case GST_GL_RGB:
@@ -239,7 +247,8 @@ gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
           break;
         case GL_UNSIGNED_SHORT_5_6_5:
           return GST_GL_RGB565;
-          break;
+        case GL_UNSIGNED_SHORT:
+          return GST_GL_RGB16;
       }
       break;
     case GST_GL_RG:
@@ -261,7 +270,9 @@ gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
       }
       break;
     case GST_GL_RGBA8:
+    case GST_GL_RGBA16:
     case GST_GL_RGB8:
+    case GST_GL_RGB16:
     case GST_GL_RGB565:
     case GST_GL_RG8:
     case GST_GL_R8:
@@ -305,6 +316,14 @@ gst_gl_format_type_from_sized_gl_format (GstGLFormat format,
       *unsized_format = GST_GL_RGB;
       *gl_type = GL_UNSIGNED_BYTE;
       break;
+    case GST_GL_RGBA16:
+      *unsized_format = GST_GL_RGBA;
+      *gl_type = GL_UNSIGNED_SHORT;
+      break;
+    case GST_GL_RGB16:
+      *unsized_format = GST_GL_RGB;
+      *gl_type = GL_UNSIGNED_SHORT;
+      break;
     case GST_GL_RGB565:
       *unsized_format = GST_GL_RGB;
       *gl_type = GL_UNSIGNED_SHORT_5_6_5;
index e8daa52..ca7df3a 100644 (file)
@@ -85,10 +85,14 @@ G_BEGIN_DECLS
  *               texture components
  * @GST_GL_RGB565: Three components of bit depth 5, 6 and 5 stored in the R, G,
  *                 and B texture components respectively.
+ * @GST_GL_RGB16: Three 16-bit components stored in the R, G, and B
+ *               texture components
  * @GST_GL_RGBA: Four components stored in the R, G, B, and A texture
  *               components respectively.
  * @GST_GL_RGBA8: Four 8-bit components stored in the R, G, B, and A texture
  *                components respectively.
+ * @GST_GL_RGBA16: Four 16-bit components stored in the R, G, B, and A texture
+ *                components respectively.
  * @GST_GL_DEPTH_COMPONENT16: A single 16-bit component for depth information.
  * @GST_GL_DEPTH24_STENCIL8: A 24-bit component for depth information and
  *                           a 8-bit component for stencil informat.
@@ -111,9 +115,11 @@ typedef enum
   GST_GL_RGB                            = 0x1907,
   GST_GL_RGB8                           = 0x8051,
   GST_GL_RGB565                         = 0x8D62,
+  GST_GL_RGB16                          = 0x8054,
 
   GST_GL_RGBA                           = 0x1908,
   GST_GL_RGBA8                          = 0x8058,
+  GST_GL_RGBA16                         = 0x805B,
 
   GST_GL_DEPTH_COMPONENT16              = 0x81A5,
 
index c8efe9e..e7e14f6 100644 (file)
@@ -53,7 +53,7 @@ GType gst_gl_memory_allocator_get_type(void);
 #define GST_GL_MEMORY_VIDEO_FORMATS_STR \
     "{ RGBA, BGRA, RGBx, BGRx, ARGB, ABGR, xRGB, xBGR, RGB, BGR, RGB16, BGR16, " \
     "AYUV, I420, YV12, NV12, NV21, YUY2, UYVY, Y41B, Y42B, Y444, " \
-    "GRAY8, GRAY16_LE, GRAY16_BE }"
+    "GRAY8, GRAY16_LE, GRAY16_BE, ARGB64 }"
 
 /**
  * GstGLMemory: