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

@ -117,8 +117,8 @@ static const gfloat from_rgb_bt709_ucoeff[] = {-0.100640f, -0.338688f, 0.439327f
static const gfloat from_rgb_bt709_vcoeff[] = {0.440654f, -0.400285f, -0.040370f}; static const gfloat from_rgb_bt709_vcoeff[] = {0.440654f, -0.400285f, -0.040370f};
/* GRAY16 to RGB conversion /* GRAY16 to RGB conversion
* data transferred as GL_LUMINANCE_ALPHA then convert back to GRAY16 * data transferred as GL_LUMINANCE_ALPHA then convert back to GRAY16
* high byte weight as : 255*256/65535 * high byte weight as : 255*256/65535
* ([0~1] denormalize to [0~255],shift to high byte,normalize to [0~1]) * ([0~1] denormalize to [0~255],shift to high byte,normalize to [0~1])
* low byte weight as : 255/65535 (similar) * low byte weight as : 255/65535 (similar)
* */ * */
@ -181,8 +181,8 @@ static const struct shader_templ templ_REORDER =
}; };
/* GRAY16 to RGB conversion /* GRAY16 to RGB conversion
* data transferred as GL_LUMINANCE_ALPHA then convert back to GRAY16 * data transferred as GL_LUMINANCE_ALPHA then convert back to GRAY16
* high byte weight as : 255*256/65535 * high byte weight as : 255*256/65535
* ([0~1] denormalize to [0~255],shift to high byte,normalize to [0~1]) * ([0~1] denormalize to [0~255],shift to high byte,normalize to [0~1])
* low byte weight as : 255/65535 (similar) * low byte weight as : 255/65535 (similar)
* */ * */
@ -310,22 +310,23 @@ static const struct shader_templ templ_SEMI_PLANAR_to_RGB =
GST_GL_TEXTURE_TARGET_2D GST_GL_TEXTURE_TARGET_2D
}; };
/* RGB to NV12/NV21 conversion */ /* RGB to NV12/NV21/NV16/NV61 conversion */
/* NV12: u, v /* NV12/NV16: u, v
NV21: v, u */ NV21/NV61: v, u */
static const gchar templ_RGB_to_NV12_NV21_BODY[] = static const gchar templ_RGB_to_SEMI_PLANAR_YUV_BODY[] =
"vec4 texel, uv_texel;\n" "vec4 texel, uv_texel;\n"
"vec3 yuv;\n" "vec3 yuv;\n"
"texel = texture2D(tex, texcoord).%c%c%c%c;\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.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" "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[0] = vec4(yuv.x, 0.0, 0.0, 1.0);\n"
"gl_FragData[1] = vec4(yuv.%c, yuv.%c, 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, { 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, }, { glsl_func_rgb_to_yuv, NULL, },
GST_GL_TEXTURE_TARGET_2D 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 */ /* Always supported input formats or output with multiple draw buffers */
if (!output || (!context || context->gl_vtable->DrawBuffers)) if (!output || (!context || context->gl_vtable->DrawBuffers))
_append_value_string_list (supported_formats, "Y444", "I420", "YV12", _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... */ /* Requires reading from a RG/LA framebuffer... */
if (!context || (USING_GLES3 (context) || USING_OPENGL (context))) if (!context || (USING_GLES3 (context) || USING_OPENGL (context)))
@ -1532,6 +1533,8 @@ _get_n_textures (GstVideoFormat v_format)
return 1; return 1;
case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV12:
case GST_VIDEO_FORMAT_NV21: 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_10LE:
case GST_VIDEO_FORMAT_P010_10BE: case GST_VIDEO_FORMAT_P010_10BE:
case GST_VIDEO_FORMAT_P016_LE: case GST_VIDEO_FORMAT_P016_LE:
@ -1679,6 +1682,7 @@ _YUV_to_RGB (GstGLColorConvert * convert)
break; break;
} }
case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV12:
case GST_VIDEO_FORMAT_NV16:
{ {
char val2 = convert->priv->in_tex_formats[1] == GST_GL_RG ? 'g' : 'a'; char val2 = convert->priv->in_tex_formats[1] == GST_GL_RG ? 'g' : 'a';
info->templ = &templ_SEMI_PLANAR_to_RGB; info->templ = &templ_SEMI_PLANAR_to_RGB;
@ -1690,6 +1694,7 @@ _YUV_to_RGB (GstGLColorConvert * convert)
break; break;
} }
case GST_VIDEO_FORMAT_NV21: case GST_VIDEO_FORMAT_NV21:
case GST_VIDEO_FORMAT_NV61:
{ {
char val2 = convert->priv->in_tex_formats[1] == GST_GL_RG ? 'g' : 'a'; char val2 = convert->priv->in_tex_formats[1] == GST_GL_RG ? 'g' : 'a';
info->templ = &templ_SEMI_PLANAR_to_RGB; info->templ = &templ_SEMI_PLANAR_to_RGB;
@ -1810,20 +1815,34 @@ _RGB_to_YUV (GstGLColorConvert * convert)
info->out_n_textures = 1; info->out_n_textures = 1;
break; break;
case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV12:
info->templ = &templ_RGB_to_NV12_NV21, case GST_VIDEO_FORMAT_NV16:
info->frag_body = g_strdup_printf (templ_RGB_to_NV12_NV21_BODY, 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],
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'); 'y', 'z');
info->out_n_textures = 2; 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; break;
case GST_VIDEO_FORMAT_NV21: case GST_VIDEO_FORMAT_NV21:
info->templ = &templ_RGB_to_NV12_NV21, case GST_VIDEO_FORMAT_NV61:
info->frag_body = g_strdup_printf (templ_RGB_to_NV12_NV21_BODY, 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],
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'); 'z', 'y');
info->out_n_textures = 2; 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; break;
default: default:
break; break;

View file

@ -95,9 +95,9 @@ struct _GstGLColorConvertClass
#define GST_GL_COLOR_CONVERT_FORMATS "{ RGBA, RGB, RGBx, BGR, BGRx, BGRA, xRGB, " \ #define GST_GL_COLOR_CONVERT_FORMATS "{ RGBA, RGB, RGBx, BGR, BGRx, BGRA, xRGB, " \
"xBGR, ARGB, ABGR, Y444, I420, YV12, Y42B, " \ "xBGR, ARGB, ABGR, Y444, I420, YV12, Y42B, " \
"Y41B, NV12, NV21, YUY2, UYVY, AYUV, VUYA, Y410, " \ "Y41B, NV12, NV21, NV16, NV61, YUY2, UYVY, AYUV, " \
"GRAY8, GRAY16_LE, GRAY16_BE, RGB16, BGR16, ARGB64 " \ "VUYA, Y410, GRAY8, GRAY16_LE, GRAY16_BE, " \
COLOR_CONVERT_EXT_FORMATS "}" "RGB16, BGR16, ARGB64 " COLOR_CONVERT_EXT_FORMATS "}"
/** /**
* GST_GL_COLOR_CONVERT_VIDEO_CAPS: * GST_GL_COLOR_CONVERT_VIDEO_CAPS:

View file

@ -190,6 +190,8 @@ gst_gl_format_from_video_info (GstGLContext * context, GstVideoInfo * vinfo,
break; break;
case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV12:
case GST_VIDEO_FORMAT_NV21: case GST_VIDEO_FORMAT_NV21:
case GST_VIDEO_FORMAT_NV16:
case GST_VIDEO_FORMAT_NV61:
n_plane_components = plane == 0 ? 1 : 2; n_plane_components = plane == 0 ? 1 : 2;
break; break;
case GST_VIDEO_FORMAT_GRAY8: 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 \ #define GST_GL_MEMORY_VIDEO_FORMATS_STR \
"{ RGBA, BGRA, RGBx, BGRx, ARGB, ABGR, xRGB, xBGR, RGB, BGR, RGB16, BGR16, " \ "{ RGBA, BGRA, RGBx, BGRx, ARGB, ABGR, xRGB, xBGR, RGB, BGR, RGB16, BGR16, " \
"AYUV, VUYA, Y410, I420, YV12, NV12, NV21, YUY2, UYVY, Y41B, Y42B, Y444, " \ "AYUV, VUYA, Y410, I420, YV12, NV12, NV21, NV16, NV61, YUY2, UYVY, Y41B, " \
"GRAY8, GRAY16_LE, GRAY16_BE, ARGB64" MEMORY_VIDEO_EXT_FORMATS "}" "Y42B, Y444, GRAY8, GRAY16_LE, GRAY16_BE, ARGB64" MEMORY_VIDEO_EXT_FORMATS "}"
/** /**
* GstGLMemory: * GstGLMemory: