glcolorconvert: add support for the NV16 and NV61 formats

NV16/NV61 is basically the same as NV12/NV21 with a higher chroma resolution.
Since only the size of the UV plane/texture is different, the same shaders are used as for NV12/NV21.
This commit is contained in:
David Trussel 2019-10-11 10:14:49 +02:00 committed by Matthew Waters
parent 7ef84fb757
commit 0b362e5a4b
4 changed files with 42 additions and 21 deletions

View file

@ -310,22 +310,23 @@ static const struct shader_templ templ_SEMI_PLANAR_to_RGB =
GST_GL_TEXTURE_TARGET_2D
};
/* RGB to NV12/NV21 conversion */
/* NV12: u, v
NV21: v, u */
static const gchar templ_RGB_to_NV12_NV21_BODY[] =
/* RGB to NV12/NV21/NV16/NV61 conversion */
/* NV12/NV16: u, v
NV21/NV61: v, u */
static const gchar templ_RGB_to_SEMI_PLANAR_YUV_BODY[] =
"vec4 texel, uv_texel;\n"
"vec3 yuv;\n"
"texel = texture2D(tex, texcoord).%c%c%c%c;\n"
"uv_texel = texture2D(tex, texcoord * tex_scale0 * 2.0).%c%c%c%c;\n"
"uv_texel = texture2D(tex, texcoord * tex_scale0 * chroma_sampling).%c%c%c%c;\n"
"yuv.x = rgb_to_yuv (texel.rgb, offset, coeff1, coeff2, coeff3).x;\n"
"yuv.yz = rgb_to_yuv (uv_texel.rgb, offset, coeff1, coeff2, coeff3).yz;\n"
"gl_FragData[0] = vec4(yuv.x, 0.0, 0.0, 1.0);\n"
"gl_FragData[1] = vec4(yuv.%c, yuv.%c, 0.0, 1.0);\n";
static const struct shader_templ templ_RGB_to_NV12_NV21 =
static const struct shader_templ templ_RGB_to_SEMI_PLANAR_YUV =
{ NULL,
DEFAULT_UNIFORMS RGB_TO_YUV_COEFFICIENTS "uniform sampler2D tex;\n",
DEFAULT_UNIFORMS RGB_TO_YUV_COEFFICIENTS "uniform sampler2D tex;\n"
"uniform vec2 chroma_sampling;\n",
{ glsl_func_rgb_to_yuv, NULL, },
GST_GL_TEXTURE_TARGET_2D
};
@ -912,7 +913,7 @@ _init_supported_formats (GstGLContext * context, gboolean output,
/* 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);
"Y42B", "Y41B", "NV12", "NV21", "NV16", "NV61", NULL);
/* Requires reading from a RG/LA framebuffer... */
if (!context || (USING_GLES3 (context) || USING_OPENGL (context)))
@ -1532,6 +1533,8 @@ _get_n_textures (GstVideoFormat v_format)
return 1;
case GST_VIDEO_FORMAT_NV12:
case GST_VIDEO_FORMAT_NV21:
case GST_VIDEO_FORMAT_NV16:
case GST_VIDEO_FORMAT_NV61:
case GST_VIDEO_FORMAT_P010_10LE:
case GST_VIDEO_FORMAT_P010_10BE:
case GST_VIDEO_FORMAT_P016_LE:
@ -1679,6 +1682,7 @@ _YUV_to_RGB (GstGLColorConvert * convert)
break;
}
case GST_VIDEO_FORMAT_NV12:
case GST_VIDEO_FORMAT_NV16:
{
char val2 = convert->priv->in_tex_formats[1] == GST_GL_RG ? 'g' : 'a';
info->templ = &templ_SEMI_PLANAR_to_RGB;
@ -1690,6 +1694,7 @@ _YUV_to_RGB (GstGLColorConvert * convert)
break;
}
case GST_VIDEO_FORMAT_NV21:
case GST_VIDEO_FORMAT_NV61:
{
char val2 = convert->priv->in_tex_formats[1] == GST_GL_RG ? 'g' : 'a';
info->templ = &templ_SEMI_PLANAR_to_RGB;
@ -1810,20 +1815,34 @@ _RGB_to_YUV (GstGLColorConvert * convert)
info->out_n_textures = 1;
break;
case GST_VIDEO_FORMAT_NV12:
info->templ = &templ_RGB_to_NV12_NV21,
info->frag_body = g_strdup_printf (templ_RGB_to_NV12_NV21_BODY,
case GST_VIDEO_FORMAT_NV16:
info->templ = &templ_RGB_to_SEMI_PLANAR_YUV,
info->frag_body = g_strdup_printf (templ_RGB_to_SEMI_PLANAR_YUV_BODY,
pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3],
pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3],
'y', 'z');
info->out_n_textures = 2;
if (out_format == GST_VIDEO_FORMAT_NV16) {
info->chroma_sampling[0] = 2.0f;
info->chroma_sampling[1] = 1.0f;
} else {
info->chroma_sampling[0] = info->chroma_sampling[1] = 2.0f;
}
break;
case GST_VIDEO_FORMAT_NV21:
info->templ = &templ_RGB_to_NV12_NV21,
info->frag_body = g_strdup_printf (templ_RGB_to_NV12_NV21_BODY,
case GST_VIDEO_FORMAT_NV61:
info->templ = &templ_RGB_to_SEMI_PLANAR_YUV,
info->frag_body = g_strdup_printf (templ_RGB_to_SEMI_PLANAR_YUV_BODY,
pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3],
pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3],
'z', 'y');
info->out_n_textures = 2;
if (out_format == GST_VIDEO_FORMAT_NV61) {
info->chroma_sampling[0] = 2.0f;
info->chroma_sampling[1] = 1.0f;
} else {
info->chroma_sampling[0] = info->chroma_sampling[1] = 2.0f;
}
break;
default:
break;

View file

@ -95,9 +95,9 @@ 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, VUYA, Y410, " \
"GRAY8, GRAY16_LE, GRAY16_BE, RGB16, BGR16, ARGB64 " \
COLOR_CONVERT_EXT_FORMATS "}"
"Y41B, NV12, NV21, NV16, NV61, YUY2, UYVY, AYUV, " \
"VUYA, Y410, GRAY8, GRAY16_LE, GRAY16_BE, " \
"RGB16, BGR16, ARGB64 " COLOR_CONVERT_EXT_FORMATS "}"
/**
* GST_GL_COLOR_CONVERT_VIDEO_CAPS:

View file

@ -190,6 +190,8 @@ gst_gl_format_from_video_info (GstGLContext * context, GstVideoInfo * vinfo,
break;
case GST_VIDEO_FORMAT_NV12:
case GST_VIDEO_FORMAT_NV21:
case GST_VIDEO_FORMAT_NV16:
case GST_VIDEO_FORMAT_NV61:
n_plane_components = plane == 0 ? 1 : 2;
break;
case GST_VIDEO_FORMAT_GRAY8:

View file

@ -58,8 +58,8 @@ 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, VUYA, Y410, I420, YV12, NV12, NV21, YUY2, UYVY, Y41B, Y42B, Y444, " \
"GRAY8, GRAY16_LE, GRAY16_BE, ARGB64" MEMORY_VIDEO_EXT_FORMATS "}"
"AYUV, VUYA, Y410, I420, YV12, NV12, NV21, NV16, NV61, YUY2, UYVY, Y41B, " \
"Y42B, Y444, GRAY8, GRAY16_LE, GRAY16_BE, ARGB64" MEMORY_VIDEO_EXT_FORMATS "}"
/**
* GstGLMemory: