From 3cfff727b19d450898dbe7931c53ea05bc2a9ac3 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Sat, 5 May 2018 21:21:13 +1000 Subject: [PATCH] glcolorconvert: add support for ARGB64 conversion --- gst-libs/gst/gl/gstglcolorconvert.c | 77 ++++++++++++++++++++++++++--- gst-libs/gst/gl/gstglcolorconvert.h | 2 +- gst-libs/gst/gl/gstglformat.c | 21 +++++++- gst-libs/gst/gl/gstglformat.h | 6 +++ gst-libs/gst/gl/gstglmemory.h | 2 +- 5 files changed, 99 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c index 782dbfd5e4..489a1b2d29 100644 --- a/gst-libs/gst/gl/gstglcolorconvert.c +++ b/gst-libs/gst/gl/gstglcolorconvert.c @@ -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: diff --git a/gst-libs/gst/gl/gstglcolorconvert.h b/gst-libs/gst/gl/gstglcolorconvert.h index 40a4829d57..31e576d03f 100644 --- a/gst-libs/gst/gl/gstglcolorconvert.h +++ b/gst-libs/gst/gl/gstglcolorconvert.h @@ -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: diff --git a/gst-libs/gst/gl/gstglformat.c b/gst-libs/gst/gl/gstglformat.c index 3844d60fee..bc1574377d 100644 --- a/gst-libs/gst/gl/gstglformat.c +++ b/gst-libs/gst/gl/gstglformat.c @@ -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; diff --git a/gst-libs/gst/gl/gstglformat.h b/gst-libs/gst/gl/gstglformat.h index e8daa523a7..ca7df3a723 100644 --- a/gst-libs/gst/gl/gstglformat.h +++ b/gst-libs/gst/gl/gstglformat.h @@ -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, diff --git a/gst-libs/gst/gl/gstglmemory.h b/gst-libs/gst/gl/gstglmemory.h index c8efe9e20f..e7e14f6b3e 100644 --- a/gst-libs/gst/gl/gstglmemory.h +++ b/gst-libs/gst/gl/gstglmemory.h @@ -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: