qt: Added support for RGB16/BGR16 input format to qmlglsink

This allows input format to be 16-bit RGB565/BGR565, which is
generated by various V4L2 devices. This format can be useful
on hardware which is constrained by memory bandwidth.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7567>
This commit is contained in:
Marek Vasut 2024-09-24 18:23:45 +02:00 committed by GStreamer Marge Bot
parent f5169670bc
commit c1adfb2e1a
3 changed files with 27 additions and 6 deletions

View file

@ -12530,7 +12530,7 @@
"long-name": "Qt Video Sink", "long-name": "Qt Video Sink",
"pad-templates": { "pad-templates": {
"sink": { "sink": {
"caps": "video/x-raw(memory:GLMemory):\n format: { RGB, RGBA, BGRA, YV12, NV12 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n texture-target: { (string)2D, (string)external-oes }\n", "caps": "video/x-raw(memory:GLMemory):\n format: { RGB, RGBA, RGB16, BGRA, BGR16, YV12, NV12 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n texture-target: { (string)2D, (string)external-oes }\n",
"direction": "sink", "direction": "sink",
"presence": "always" "presence": "always"
} }

View file

@ -110,6 +110,8 @@ public:
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_RGBA:
case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_BGRA:
case GST_VIDEO_FORMAT_RGB16:
case GST_VIDEO_FORMAT_BGR16:
tex_names[0] = UNIFORM_TEXTURE0_NAME; tex_names[0] = UNIFORM_TEXTURE0_NAME;
break; break;
case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_YV12:
@ -201,11 +203,13 @@ GstQSGMaterial::new_for_format_and_target(GstVideoFormat format, GstGLTextureTar
switch (format) { switch (format) {
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_RGBA:
case GST_VIDEO_FORMAT_RGB16:
if (target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) if (target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES)
return static_cast<GstQSGMaterial *>(new GstQSGMaterial_RGBA_external()); return static_cast<GstQSGMaterial *>(new GstQSGMaterial_RGBA_external());
return static_cast<GstQSGMaterial *>(new GstQSGMaterial_RGBA()); return static_cast<GstQSGMaterial *>(new GstQSGMaterial_RGBA());
case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_BGRA:
case GST_VIDEO_FORMAT_BGR16:
return static_cast<GstQSGMaterial *>(new GstQSGMaterial_RGBA_SWIZZLE()); return static_cast<GstQSGMaterial *>(new GstQSGMaterial_RGBA_SWIZZLE());
case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_YV12:
return static_cast<GstQSGMaterial *>(new GstQSGMaterial_YUV_TRIPLANAR()); return static_cast<GstQSGMaterial *>(new GstQSGMaterial_YUV_TRIPLANAR());
@ -306,7 +310,8 @@ fragmentShaderForFormatAndTarget(GstVideoFormat v_format, GstGLTextureTarget tex
switch (v_format) { switch (v_format) {
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_RGBA: { case GST_VIDEO_FORMAT_RGBA:
case GST_VIDEO_FORMAT_RGB16: {
char *swizzle = gst_gl_color_convert_swizzle_shader_string (context); char *swizzle = gst_gl_color_convert_swizzle_shader_string (context);
char *ret = NULL; char *ret = NULL;
@ -326,7 +331,8 @@ fragmentShaderForFormatAndTarget(GstVideoFormat v_format, GstGLTextureTarget tex
g_clear_pointer (&swizzle, g_free); g_clear_pointer (&swizzle, g_free);
return ret; return ret;
} }
case GST_VIDEO_FORMAT_BGRA: { case GST_VIDEO_FORMAT_BGRA:
case GST_VIDEO_FORMAT_BGR16: {
char *swizzle = gst_gl_color_convert_swizzle_shader_string (context); char *swizzle = gst_gl_color_convert_swizzle_shader_string (context);
char *ret = g_strdup_printf ("%s" texcoord_input single_texture_input uniform_swizzle uniform_opacity char *ret = g_strdup_printf ("%s" texcoord_input single_texture_input uniform_swizzle uniform_opacity
"%s\n" "%s\n"
@ -564,6 +570,9 @@ out:
funcs->glActiveTexture(GL_TEXTURE0 + i); funcs->glActiveTexture(GL_TEXTURE0 + i);
if (this->dummy_textures[i] == 0) { if (this->dummy_textures[i] == 0) {
/* Default GL formats for most supported input formats. */
guint glformat = GL_RGBA;
guint gltype = GL_UNSIGNED_BYTE;
/* Make this a black 64x64 pixel RGBA texture. /* Make this a black 64x64 pixel RGBA texture.
* This size and format is supported pretty much everywhere, so these * This size and format is supported pretty much everywhere, so these
* are a safe pick. (64 pixel sidelength must be supported according * are a safe pick. (64 pixel sidelength must be supported according
@ -584,6 +593,18 @@ out:
} }
} }
break; break;
case GST_VIDEO_FORMAT_RGB16:
case GST_VIDEO_FORMAT_BGR16:
/* Override GL formats to support RGB565/BGR565 */
glformat = GL_RGB;
gltype = GL_UNSIGNED_SHORT_5_6_5;
for (gsize j = 0; j < tex_sidelength; j++) {
for (gsize k = 0; k < tex_sidelength; k++) {
data[(j * tex_sidelength + k) * 2 + 0] = 0xFF;
data[(j * tex_sidelength + k) * 2 + 1] = 0xFF;
}
}
break;
case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_YV12:
if (i == 1 || i == 2) { if (i == 1 || i == 2) {
for (gsize j = 0; j < tex_sidelength; j++) { for (gsize j = 0; j < tex_sidelength; j++) {
@ -612,8 +633,8 @@ out:
funcs->glBindTexture (GL_TEXTURE_2D, this->dummy_textures[i]); funcs->glBindTexture (GL_TEXTURE_2D, this->dummy_textures[i]);
funcs->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); funcs->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
funcs->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); funcs->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
funcs->glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, tex_sidelength, funcs->glTexImage2D (GL_TEXTURE_2D, 0, glformat, tex_sidelength,
tex_sidelength, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); tex_sidelength, 0, glformat, gltype, data);
} }
g_assert (this->dummy_textures[i] != 0); g_assert (this->dummy_textures[i] != 0);

View file

@ -108,7 +108,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), " GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
"format = (string) { RGB, RGBA, BGRA, YV12, NV12 }, " "format = (string) { RGB, RGBA, RGB16, BGRA, BGR16, YV12, NV12 }, "
"width = " GST_VIDEO_SIZE_RANGE ", " "width = " GST_VIDEO_SIZE_RANGE ", "
"height = " GST_VIDEO_SIZE_RANGE ", " "height = " GST_VIDEO_SIZE_RANGE ", "
"framerate = " GST_VIDEO_FPS_RANGE ", " "framerate = " GST_VIDEO_FPS_RANGE ", "