mirror of
https://github.com/mpv-player/mpv
synced 2025-02-16 20:27:23 +00:00
vo_opengl: handle grayscale input better, add YA16 support
Simply clamp off the U/V components in the colormatrix, instead of doing something special in the shader. Also, since YA8/YA16 gave a plane_bits value of 16/32, and a colormatrix calculation overflowed with 32, add a component_bits field to the image format descriptor, which for YA8/YA16 returns 8/16 (the wrong value had no bad consequences otherwise).
This commit is contained in:
parent
30ca30c0a1
commit
a0caadd512
@ -564,8 +564,8 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, struct mp_cmat *m)
|
||||
|
||||
// Hue is equivalent to rotating input [U, V] subvector around the origin.
|
||||
// Saturation scales [U, V].
|
||||
float huecos = params->saturation * cos(params->hue);
|
||||
float huesin = params->saturation * sin(params->hue);
|
||||
float huecos = params->gray ? 0 : params->saturation * cos(params->hue);
|
||||
float huesin = params->gray ? 0 : params->saturation * sin(params->hue);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float u = m->m[i][1], v = m->m[i][2];
|
||||
m->m[i][1] = huecos * u - huesin * v;
|
||||
|
@ -116,6 +116,8 @@ struct mp_csp_params {
|
||||
float rgamma;
|
||||
float ggamma;
|
||||
float bgamma;
|
||||
// discard U/V components
|
||||
bool gray;
|
||||
// texture_bits/input_bits is for rescaling fixed point input to range [0,1]
|
||||
int texture_bits;
|
||||
int input_bits;
|
||||
|
@ -113,6 +113,10 @@ static const struct {
|
||||
{IMGFMT_BGR0, AV_PIX_FMT_BGRA},
|
||||
#endif
|
||||
|
||||
#ifdef AV_PIX_FMT_YA16
|
||||
{IMGFMT_YA16, AV_PIX_FMT_YA16},
|
||||
#endif
|
||||
|
||||
{IMGFMT_VDPAU, AV_PIX_FMT_VDPAU},
|
||||
#if HAVE_VDA_HWACCEL
|
||||
{IMGFMT_VDA, AV_PIX_FMT_VDA},
|
||||
|
@ -142,6 +142,7 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
|
||||
.avformat = fmt,
|
||||
.chroma_xs = pd->log2_chroma_w,
|
||||
.chroma_ys = pd->log2_chroma_h,
|
||||
.component_bits = pd->comp[0].depth_minus1 + 1,
|
||||
};
|
||||
|
||||
int planedepth[4] = {0};
|
||||
@ -154,6 +155,8 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
|
||||
desc.bpp[d.plane] = (d.step_minus1 + 1) * el_size;
|
||||
planedepth[d.plane] += d.depth_minus1 + 1;
|
||||
need_endian |= (d.depth_minus1 + 1 + d.shift) > 8;
|
||||
if (d.depth_minus1 + 1 != desc.component_bits)
|
||||
desc.component_bits = 0;
|
||||
}
|
||||
|
||||
for (int p = 0; p < 4; p++) {
|
||||
@ -315,8 +318,9 @@ int main(int argc, char **argv)
|
||||
FLAG(MP_IMGFLAG_PAL, "pal")
|
||||
FLAG(MP_IMGFLAG_HWACCEL, "hw")
|
||||
printf("\n");
|
||||
printf(" planes=%d, chroma=%d:%d align=%d:%d bits=%d\n", d.num_planes,
|
||||
d.chroma_xs, d.chroma_ys, d.align_x, d.align_y, d.plane_bits);
|
||||
printf(" planes=%d, chroma=%d:%d align=%d:%d bits=%d cbits=%d\n",
|
||||
d.num_planes, d.chroma_xs, d.chroma_ys, d.align_x, d.align_y,
|
||||
d.plane_bits, d.component_bits);
|
||||
printf(" {");
|
||||
for (int n = 0; n < MP_MAX_PLANES; n++)
|
||||
printf("%d/%d/[%d:%d] ", d.bytes[n], d.bpp[n], d.xs[n], d.ys[n]);
|
||||
|
@ -82,6 +82,7 @@ struct mp_imgfmt_desc {
|
||||
int8_t bytes[MP_MAX_PLANES]; // bytes per pixel (MP_IMGFLAG_BYTE_ALIGNED)
|
||||
int8_t bpp[MP_MAX_PLANES]; // bits per pixel
|
||||
int8_t plane_bits; // number of bits in use for plane 0
|
||||
int8_t component_bits; // number of bits per component (0 if uneven)
|
||||
// chroma shifts per plane (provided for convenience with planar formats)
|
||||
int8_t xs[MP_MAX_PLANES];
|
||||
int8_t ys[MP_MAX_PLANES];
|
||||
@ -135,6 +136,7 @@ enum mp_imgfmt {
|
||||
|
||||
// Gray with alpha (packed)
|
||||
IMGFMT_YA8,
|
||||
IMGFMT_YA16,
|
||||
|
||||
// Packed YUV formats (components are byte-accessed)
|
||||
IMGFMT_YUYV, // Y0 U Y1 V
|
||||
|
@ -168,8 +168,7 @@ struct gl_video {
|
||||
|
||||
float input_gamma, conv_gamma;
|
||||
|
||||
// per pixel (full pixel when packed, each component when planar)
|
||||
int plane_bits;
|
||||
int component_bits; // color bit depth for all components; 0 if unknown
|
||||
int plane_count;
|
||||
|
||||
struct video_image image;
|
||||
@ -291,10 +290,11 @@ struct packed_fmt_entry {
|
||||
};
|
||||
|
||||
static const struct packed_fmt_entry mp_packed_formats[] = {
|
||||
// R G B A
|
||||
// w R G B A
|
||||
{IMGFMT_Y8, 1, {1, 0, 0, 0}},
|
||||
{IMGFMT_Y16, 2, {1, 0, 0, 0}},
|
||||
{IMGFMT_YA8, 1, {1, 0, 0, 2}},
|
||||
{IMGFMT_YA16, 2, {1, 0, 0, 2}},
|
||||
{IMGFMT_ARGB, 1, {2, 3, 4, 1}},
|
||||
{IMGFMT_0RGB, 1, {2, 3, 4, 0}},
|
||||
{IMGFMT_BGRA, 1, {3, 2, 1, 4}},
|
||||
@ -652,8 +652,9 @@ static void update_uniforms(struct gl_video *p, GLuint program)
|
||||
gl->UseProgram(program);
|
||||
|
||||
struct mp_csp_params cparams = MP_CSP_PARAMS_DEFAULTS;
|
||||
cparams.input_bits = p->plane_bits;
|
||||
cparams.texture_bits = (p->plane_bits + 7) & ~7;
|
||||
cparams.gray = p->is_yuv && !p->is_packed_yuv && p->plane_count == 1;
|
||||
cparams.input_bits = p->component_bits;
|
||||
cparams.texture_bits = (cparams.input_bits + 7) & ~7;
|
||||
mp_csp_set_image_params(&cparams, &p->image_params);
|
||||
mp_csp_copy_equalizer_values(&cparams, &p->video_eq);
|
||||
if (p->image_desc.flags & MP_IMGFLAG_XYZ) {
|
||||
@ -1132,8 +1133,6 @@ static void compile_shaders(struct gl_video *p)
|
||||
|
||||
if (p->color_swizzle[0])
|
||||
shader_def(&header_conv, "USE_COLOR_SWIZZLE", p->color_swizzle);
|
||||
shader_def_opt(&header_conv, "USE_YGRAY", p->is_yuv && !p->is_packed_yuv
|
||||
&& p->plane_count == 1);
|
||||
shader_def_opt(&header_conv, "USE_INPUT_GAMMA", use_input_gamma);
|
||||
shader_def_opt(&header_conv, "USE_COLORMATRIX", !p->is_rgb);
|
||||
shader_def_opt(&header_conv, "USE_CONV_GAMMA", use_conv_gamma);
|
||||
@ -2413,15 +2412,14 @@ static bool init_format(int fmt, struct gl_video *init)
|
||||
const struct fmt_entry *plane_format[4] = {0};
|
||||
|
||||
init->image_format = fmt;
|
||||
init->plane_bits = desc.bpp[0];
|
||||
init->component_bits = desc.component_bits;
|
||||
init->color_swizzle[0] = '\0';
|
||||
init->has_alpha = false;
|
||||
|
||||
// YUV/planar formats
|
||||
if (desc.flags & MP_IMGFLAG_YUV_P) {
|
||||
int bits = desc.plane_bits;
|
||||
int bits = desc.component_bits;
|
||||
if ((desc.flags & MP_IMGFLAG_NE) && bits >= 8 && bits <= 16) {
|
||||
init->plane_bits = bits;
|
||||
init->has_alpha = desc.num_planes > 3;
|
||||
plane_format[0] = find_tex_format(gl, (bits + 7) / 8, 1);
|
||||
for (int p = 1; p < desc.num_planes; p++)
|
||||
@ -2494,10 +2492,10 @@ static bool init_format(int fmt, struct gl_video *init)
|
||||
supported:
|
||||
|
||||
// Stuff like IMGFMT_420AP10. Untested, most likely insane.
|
||||
if (desc.num_planes == 4 && (init->plane_bits % 8) != 0)
|
||||
if (desc.num_planes == 4 && (init->component_bits % 8) != 0)
|
||||
return false;
|
||||
|
||||
if (init->plane_bits > 8 && init->plane_bits < 16) {
|
||||
if (init->component_bits > 8 && init->component_bits < 16) {
|
||||
if (init->texture_16bit_depth < 16)
|
||||
return false;
|
||||
}
|
||||
|
@ -381,11 +381,6 @@ void main() {
|
||||
#endif
|
||||
vec3 color = acolor.rgb;
|
||||
float alpha = acolor.a;
|
||||
#ifdef USE_YGRAY
|
||||
// NOTE: actually slightly wrong for 16 bit input video, and completely
|
||||
// wrong for 9/10 bit input
|
||||
color.gb = vec2(128.0/255.0);
|
||||
#endif
|
||||
#ifdef USE_INPUT_GAMMA
|
||||
// Pre-colormatrix input gamma correction (eg. for MP_IMGFLAG_XYZ)
|
||||
color = pow(color, vec3(input_gamma));
|
||||
|
Loading…
Reference in New Issue
Block a user