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 ();
}
}
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)) {
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",
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;
}
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;
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:
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:
{
switch (type) {
case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT:
return 1;
case GL_UNSIGNED_SHORT_5_6_5:
return 3;
switch (type) {
case GL_UNSIGNED_BYTE:
return 1;
+ case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_SHORT_5_6_5:
return 2;
default:
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;
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:
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:
}
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:
*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;