From d42d60bc1e0a1c3b472b21d3cd203279879f7d95 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 6 Jan 2015 16:49:53 +0100 Subject: csputils: replace float[3][4] with a struct Not being able to use the 3x3 part of the matrix was annoying, so split it into a float[3][3] matrix and a separate float[3] constant vector. --- demux/demux_disc.c | 6 +-- sub/draw_bmp.c | 8 +-- sub/sd_ass.c | 14 +++--- sub/sd_lavc.c | 6 +-- video/csputils.c | 124 ++++++++++++++++++++-------------------------- video/csputils.h | 37 +++++++++----- video/out/gl_video.c | 16 +++--- video/out/vo_opengl_old.c | 13 +++-- video/vdpau_mixer.c | 11 ++-- 9 files changed, 117 insertions(+), 118 deletions(-) diff --git a/demux/demux_disc.c b/demux/demux_disc.c index 751b81281f..69643a0053 100644 --- a/demux/demux_disc.c +++ b/demux/demux_disc.c @@ -95,15 +95,15 @@ static void add_dvd_streams(demuxer_t *demuxer) struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS; csp.int_bits_in = 8; csp.int_bits_out = 8; - float cmatrix[3][4]; - mp_get_yuv2rgb_coeffs(&csp, cmatrix); + struct mp_cmat cmatrix; + mp_get_yuv2rgb_coeffs(&csp, &cmatrix); char *s = talloc_strdup(sh, ""); s = talloc_asprintf_append(s, "palette: "); for (int i = 0; i < 16; i++) { int color = info.palette[i]; int c[3] = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff}; - mp_map_int_color(cmatrix, 8, c); + mp_map_int_color(&cmatrix, 8, c); color = (c[2] << 16) | (c[1] << 8) | c[0]; if (i != 0) diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c index 5e2ed41cd9..c5c0dddd29 100644 --- a/sub/draw_bmp.c +++ b/sub/draw_bmp.c @@ -294,11 +294,11 @@ static void draw_ass(struct mp_draw_sub_cache *cache, struct mp_rect bb, cspar.int_bits_in = bits; cspar.int_bits_out = 8; - float yuv2rgb[3][4], rgb2yuv[3][4]; + struct mp_cmat yuv2rgb, rgb2yuv; bool need_conv = temp->flags & MP_IMGFLAG_YUV; if (need_conv) { - mp_get_yuv2rgb_coeffs(&cspar, yuv2rgb); - mp_invert_yuv2rgb(rgb2yuv, yuv2rgb); + mp_get_yuv2rgb_coeffs(&cspar, &yuv2rgb); + mp_invert_yuv2rgb(&rgb2yuv, &yuv2rgb); } for (int i = 0; i < sbs->num_parts; ++i) { @@ -315,7 +315,7 @@ static void draw_ass(struct mp_draw_sub_cache *cache, struct mp_rect bb, int a = 255 - (sb->libass.color & 0xFF); int color_yuv[3] = {r, g, b}; if (need_conv) { - mp_map_int_color(rgb2yuv, bits, color_yuv); + mp_map_int_color(&rgb2yuv, bits, color_yuv); } else { color_yuv[0] = g; color_yuv[1] = b; diff --git a/sub/sd_ass.c b/sub/sd_ass.c index 8f5b02c842..8bfefb35cb 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -400,9 +400,9 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts) vs_params.levels_in = levels; vs_params.int_bits_in = 8; vs_params.int_bits_out = 8; - float vs_yuv2rgb[3][4], vs_rgb2yuv[3][4]; - mp_get_yuv2rgb_coeffs(&vs_params, vs_yuv2rgb); - mp_invert_yuv2rgb(vs_rgb2yuv, vs_yuv2rgb); + struct mp_cmat vs_yuv2rgb, vs_rgb2yuv; + mp_get_yuv2rgb_coeffs(&vs_params, &vs_yuv2rgb); + mp_invert_yuv2rgb(&vs_rgb2yuv, &vs_yuv2rgb); // Proper conversion to RGB struct mp_csp_params rgb_params = MP_CSP_PARAMS_DEFAULTS; @@ -410,8 +410,8 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts) rgb_params.levels_in = params.colorlevels; rgb_params.int_bits_in = 8; rgb_params.int_bits_out = 8; - float vs2rgb[3][4]; - mp_get_yuv2rgb_coeffs(&rgb_params, vs2rgb); + struct mp_cmat vs2rgb; + mp_get_yuv2rgb_coeffs(&rgb_params, &vs2rgb); for (int n = 0; n < parts->num_parts; n++) { struct sub_bitmap *sb = &parts->parts[n]; @@ -421,8 +421,8 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts) int b = (color >> 8u) & 0xff; int a = 0xff - (color & 0xff); int c[3] = {r, g, b}; - mp_map_int_color(vs_rgb2yuv, 8, c); - mp_map_int_color(vs2rgb, 8, c); + mp_map_int_color(&vs_rgb2yuv, 8, c); + mp_map_int_color(&vs2rgb, 8, c); sb->libass.color = MP_ASS_RGBA(c[0], c[1], c[2], a); } } diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c index 0a969efc41..4bdd6ea548 100644 --- a/sub/sd_lavc.c +++ b/sub/sd_lavc.c @@ -112,10 +112,10 @@ static void set_mp4_vobsub_idx(AVCodecContext *avctx, char *src, int w, int h) struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS; csp.int_bits_in = 8; csp.int_bits_out = 8; - float cmatrix[3][4]; - mp_get_yuv2rgb_coeffs(&csp, cmatrix); + struct mp_cmat cmatrix; + mp_get_yuv2rgb_coeffs(&csp, &cmatrix); int c[3] = {(e >> 16) & 0xff, (e >> 8) & 0xff, e & 0xff}; - mp_map_int_color(cmatrix, 8, c); + mp_map_int_color(&cmatrix, 8, c); e = (c[2] << 16) | (c[1] << 8) | c[0]; snprintf(pal_s + pal_s_pos, sizeof(pal_s) - pal_s_pos, "%06x%s", e, diff --git a/video/csputils.c b/video/csputils.c index 70edbfa6a3..6e8c76f6d8 100644 --- a/video/csputils.c +++ b/video/csputils.c @@ -459,17 +459,17 @@ void mp_get_cms_matrix(struct mp_csp_primaries src, struct mp_csp_primaries dest // intent = the rendering intent used to convert to the target primaries void mp_get_xyz2rgb_coeffs(struct mp_csp_params *params, struct mp_csp_primaries prim, - enum mp_render_intent intent, float m[3][4]) + enum mp_render_intent intent, struct mp_cmat *m) { - float tmp[3][3], brightness = params->brightness; - mp_get_rgb2xyz_matrix(prim, tmp); - mp_invert_matrix3x3(tmp); + float brightness = params->brightness; + mp_get_rgb2xyz_matrix(prim, m->m); + mp_invert_matrix3x3(m->m); // All non-absolute mappings want to map source white to target white if (intent != MP_INTENT_ABSOLUTE_COLORIMETRIC) { // SMPTE 428-1 defines the calibration white point as CIE xy (0.314, 0.351) static const struct mp_csp_col_xy smpte428 = {0.314, 0.351}; - mp_apply_chromatic_adaptation(smpte428, prim.white, tmp); + mp_apply_chromatic_adaptation(smpte428, prim.white, m->m); } // Since this outputs linear RGB rather than companded RGB, we @@ -482,12 +482,8 @@ void mp_get_xyz2rgb_coeffs(struct mp_csp_params *params, brightness *= brightness; } - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) - m[i][j] = tmp[i][j]; - - m[i][COL_C] = brightness; - } + for (int i = 0; i < 3; i++) + m->c[i] = brightness; } /* Fill in the Y, U, V vectors of a yuv2rgb conversion matrix @@ -510,21 +506,19 @@ void mp_get_xyz2rgb_coeffs(struct mp_csp_params *params, * Under these conditions the given parameters lr, lg, lb uniquely * determine the mapping of Y, U, V to R, G, B. */ -static void luma_coeffs(float m[3][4], float lr, float lg, float lb) +static void luma_coeffs(struct mp_cmat *mat, float lr, float lg, float lb) { assert(fabs(lr+lg+lb - 1) < 1e-6); - m[0][0] = m[1][0] = m[2][0] = 1; - m[0][1] = 0; - m[1][1] = -2 * (1-lb) * lb/lg; - m[2][1] = 2 * (1-lb); - m[0][2] = 2 * (1-lr); - m[1][2] = -2 * (1-lr) * lr/lg; - m[2][2] = 0; - // Constant coefficients (m[x][3]) not set here + *mat = (struct mp_cmat) { + { {1, 0, 2 * (1-lr) }, + {1, -2 * (1-lb) * lb/lg, -2 * (1-lr) * lr/lg }, + {1, 2 * (1-lb), 0 } }, + // Constant coefficients (mat->c) not set here + }; } // get the coefficients of the yuv -> rgb conversion matrix -void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4]) +void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, struct mp_cmat *m) { int colorspace = params->colorspace; if (colorspace <= MP_CSP_AUTO || colorspace >= MP_CSP_COUNT) @@ -543,13 +537,11 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4]) // If this clips on any VO, a constant 0.5 coefficient can be added // to the chroma channels to normalize them into [0,1]. This is not // currently needed by anything, though. - static const float ycbcr_to_crycb[3][4] = {{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}; - memcpy(m, ycbcr_to_crycb, sizeof(ycbcr_to_crycb)); + *m = (struct mp_cmat){{{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}}; break; } case MP_CSP_RGB: { - static const float ident[3][4] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; - memcpy(m, ident, sizeof(ident)); + *m = (struct mp_cmat){{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}}; levels_in = -1; break; } @@ -563,12 +555,11 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4]) break; } case MP_CSP_YCGCO: { - static const float ycgco_to_rgb[3][4] = { - {1, -1, 1}, - {1, 1, 0}, - {1, -1, -1}, + *m = (struct mp_cmat) { + {{1, -1, 1}, + {1, 1, 0}, + {1, -1, -1}}, }; - memcpy(m, ycgco_to_rgb, sizeof(ycgco_to_rgb)); break; } default: @@ -580,9 +571,9 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4]) float huecos = params->saturation * cos(params->hue); float huesin = params->saturation * sin(params->hue); for (int i = 0; i < 3; i++) { - float u = m[i][COL_U]; - m[i][COL_U] = huecos * u - huesin * m[i][COL_V]; - m[i][COL_V] = huesin * u + huecos * m[i][COL_V]; + float u = m->m[i][1], v = m->m[i][2]; + m->m[i][1] = huecos * u - huesin * v; + m->m[i][2] = huesin * u + huecos * v; } assert(params->input_bits >= 8); @@ -619,20 +610,20 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4]) double ymul = (rgblev.max - rgblev.min) / (yuvlev.ymax - yuvlev.ymin); double cmul = (rgblev.max - rgblev.min) / (yuvlev.cmid - yuvlev.cmin) / 2; for (int i = 0; i < 3; i++) { - m[i][COL_Y] *= ymul; - m[i][COL_U] *= cmul; - m[i][COL_V] *= cmul; - // Set COL_C so that Y=umin,UV=cmid maps to RGB=min (black to black) - m[i][COL_C] = rgblev.min - m[i][COL_Y] * yuvlev.ymin - -(m[i][COL_U] + m[i][COL_V]) * yuvlev.cmid; + m->m[i][0] *= ymul; + m->m[i][1] *= cmul; + m->m[i][2] *= cmul; + // Set c so that Y=umin,UV=cmid maps to RGB=min (black to black) + m->c[i] = rgblev.min - m->m[i][0] * yuvlev.ymin + -(m->m[i][1] + m->m[i][2]) * yuvlev.cmid; } // Brightness adds a constant to output R,G,B. // Contrast scales Y around 1/2 (not 0 in this implementation). for (int i = 0; i < 3; i++) { - m[i][COL_C] += params->brightness; - m[i][COL_Y] *= params->contrast; - m[i][COL_C] += (rgblev.max-rgblev.min) * (1 - params->contrast)/2; + m->c[i] += params->brightness; + m->m[i][0] *= params->contrast; + m->c[i] += (rgblev.max-rgblev.min) * (1 - params->contrast)/2; } int in_bits = FFMAX(params->int_bits_in, 1); @@ -640,9 +631,9 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4]) double in_scale = (1 << in_bits) - 1.0; double out_scale = (1 << out_bits) - 1.0; for (int i = 0; i < 3; i++) { - m[i][COL_C] *= out_scale; // constant is 1.0 + m->c[i] *= out_scale; // constant is 1.0 for (int x = 0; x < 3; x++) - m[i][x] *= out_scale / in_scale; + m->m[i][x] *= out_scale / in_scale; } } @@ -655,15 +646,17 @@ void mp_gen_yuv2rgb_map(struct mp_csp_params *params, unsigned char *map, int si int i, j, k, l; float step = 1.0 / size; float y, u, v; - float yuv2rgb[3][4]; + struct mp_cmat yuv2rgb; unsigned char gmaps[3][GMAP_SIZE]; mp_gen_gamma_map(gmaps[0], GMAP_SIZE, params->rgamma); mp_gen_gamma_map(gmaps[1], GMAP_SIZE, params->ggamma); mp_gen_gamma_map(gmaps[2], GMAP_SIZE, params->bgamma); - mp_get_yuv2rgb_coeffs(params, yuv2rgb); - for (i = 0; i < 3; i++) - for (j = 0; j < 4; j++) - yuv2rgb[i][j] *= GMAP_SIZE - 1; + mp_get_yuv2rgb_coeffs(params, &yuv2rgb); + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) + yuv2rgb.m[i][j] *= GMAP_SIZE - 1; + yuv2rgb.c[i] *= GMAP_SIZE - 1; + } v = 0; for (i = -1; i <= size; i++) { u = 0; @@ -671,8 +664,8 @@ void mp_gen_yuv2rgb_map(struct mp_csp_params *params, unsigned char *map, int si y = 0; for (k = -1; k <= size; k++) { for (l = 0; l < 3; l++) { - float rgb = yuv2rgb[l][COL_Y] * y + yuv2rgb[l][COL_U] * u + - yuv2rgb[l][COL_V] * v + yuv2rgb[l][COL_C]; + float rgb = yuv2rgb.m[l][0] * y + yuv2rgb.m[l][1] * u + + yuv2rgb.m[l][2] * v + yuv2rgb.c[l]; *map++ = gmaps[l][av_clip(rgb, 0, GMAP_SIZE - 1)]; } y += (k == -1 || k == size - 1) ? step / 2 : step; @@ -741,42 +734,31 @@ int mp_csp_equalizer_set(struct mp_csp_equalizer *eq, const char *property, return 1; } -void mp_invert_yuv2rgb(float out[3][4], float in[3][4]) +void mp_invert_yuv2rgb(struct mp_cmat *out, struct mp_cmat *in) { - float tmp[3][3]; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) - tmp[i][j] = in[i][j]; - } - - mp_invert_matrix3x3(tmp); - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) - out[i][j] = tmp[i][j]; - } + *out = *in; + mp_invert_matrix3x3(out->m); // fix the constant coefficient // rgb = M * yuv + C // M^-1 * rgb = yuv + M^-1 * C // yuv = M^-1 * rgb - M^-1 * C // ^^^^^^^^^^ - out[0][3] = -(out[0][0] * in[0][3] + out[0][1] * in[1][3] + out[0][2] * in[2][3]); - out[1][3] = -(out[1][0] * in[0][3] + out[1][1] * in[1][3] + out[1][2] * in[2][3]); - out[2][3] = -(out[2][0] * in[0][3] + out[2][1] * in[1][3] + out[2][2] * in[2][3]); + out->c[0] = -(out->m[0][0] * in->c[0] + out->m[0][1] * in->c[1] + out->m[0][2] * in->c[2]); + out->c[1] = -(out->m[1][0] * in->c[0] + out->m[1][1] * in->c[1] + out->m[1][2] * in->c[2]); + out->c[2] = -(out->m[2][0] * in->c[0] + out->m[2][1] * in->c[1] + out->m[2][2] * in->c[2]); } // Multiply the color in c with the given matrix. // c is {R, G, B} or {Y, U, V} (depending on input/output and matrix). // Output is clipped to the given number of bits. -void mp_map_int_color(float matrix[3][4], int clip_bits, int c[3]) +void mp_map_int_color(struct mp_cmat *matrix, int clip_bits, int c[3]) { int in[3] = {c[0], c[1], c[2]}; for (int i = 0; i < 3; i++) { - double val = matrix[i][3]; + double val = matrix->c[i]; for (int x = 0; x < 3; x++) - val += matrix[i][x] * in[x]; + val += matrix->m[i][x] * in[x]; int ival = lrint(val); c[i] = av_clip(ival, 0, (1 << clip_bits) - 1); } diff --git a/video/csputils.h b/video/csputils.h index 51de50c4b6..8e8d18e7df 100644 --- a/video/csputils.h +++ b/video/csputils.h @@ -214,28 +214,41 @@ int mp_chroma_location_to_av(enum mp_chroma_location mploc); void mp_get_chroma_location(enum mp_chroma_location loc, int *x, int *y); void mp_gen_gamma_map(unsigned char *map, int size, float gamma); -#define ROW_R 0 -#define ROW_G 1 -#define ROW_B 2 -#define COL_Y 0 -#define COL_U 1 -#define COL_V 2 -#define COL_C 3 + struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim csp); -void mp_apply_chromatic_adaptation(struct mp_csp_col_xy src, struct mp_csp_col_xy dest, float m[3][3]); +/* Color conversion matrix: RGB = m * YUV + c + * m is in row-major matrix, with m[row][col], e.g.: + * [ a11 a12 a13 ] float m[3][3] = { { a11, a12, a13 }, + * [ a21 a22 a23 ] { a21, a22, a23 }, + * [ a31 a32 a33 ] { a31, a32, a33 } }; + * This is accessed as e.g.: m[2-1][1-1] = a21 + * In particular, each row contains all the coefficients for one of R, G, B, + * while each column contains all the coefficients for one of Y, U, V: + * m[r,g,b][y,u,v] = ... + * The matrix could also be viewed as group of 3 vectors, e.g. the 1st column + * is the Y vector (1, 1, 1), the 2nd is the U vector, the 3rd the V vector. + * The matrix might also be used for other conversions and colorspaces. + */ +struct mp_cmat { + float m[3][3]; + float c[3]; +}; + +void mp_apply_chromatic_adaptation(struct mp_csp_col_xy src, + struct mp_csp_col_xy dest, float m[3][3]); void mp_get_cms_matrix(struct mp_csp_primaries src, struct mp_csp_primaries dest, enum mp_render_intent intent, float cms_matrix[3][3]); void mp_get_rgb2xyz_matrix(struct mp_csp_primaries space, float m[3][3]); void mp_get_xyz2rgb_coeffs(struct mp_csp_params *params, struct mp_csp_primaries prim, - enum mp_render_intent intent, float xyz2rgb[3][4]); -void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]); + enum mp_render_intent intent, struct mp_cmat *xyz2rgb); +void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, struct mp_cmat *yuv2rgb); void mp_gen_yuv2rgb_map(struct mp_csp_params *params, uint8_t *map, int size); void mp_mul_matrix3x3(float a[3][3], float b[3][3]); void mp_invert_matrix3x3(float m[3][3]); -void mp_invert_yuv2rgb(float out[3][4], float in[3][4]); -void mp_map_int_color(float matrix[3][4], int clip_bits, int c[3]); +void mp_invert_yuv2rgb(struct mp_cmat *out, struct mp_cmat *in); +void mp_map_int_color(struct mp_cmat *matrix, int clip_bits, int c[3]); #endif /* MPLAYER_CSPUTILS_H */ diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 672fb5dafb..88de5eeffb 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -661,24 +661,20 @@ static void update_uniforms(struct gl_video *p, GLuint program) loc = gl->GetUniformLocation(program, "colormatrix"); if (loc >= 0) { - float m[3][4] = {{0}}; + struct mp_cmat m = {{{0}}}; if (p->image_desc.flags & MP_IMGFLAG_XYZ) { // Hard-coded as relative colorimetric for now, since this transforms // from the source file's D55 material to whatever color space our // projector/display lives in, which should be D55 for a proper // home cinema setup either way. - mp_get_xyz2rgb_coeffs(&cparams, p->csp_src, MP_INTENT_RELATIVE_COLORIMETRIC, m); + mp_get_xyz2rgb_coeffs(&cparams, p->csp_src, + MP_INTENT_RELATIVE_COLORIMETRIC, &m); } else { - mp_get_yuv2rgb_coeffs(&cparams, m); + mp_get_yuv2rgb_coeffs(&cparams, &m); } - float transposed[3][3]; - for (int a = 0; a < 3; a++) { - for (int b = 0; b < 3; b++) - transposed[a][b] = m[b][a]; - } - gl->UniformMatrix3fv(loc, 1, GL_FALSE, &transposed[0][0]); + gl->UniformMatrix3fv(loc, 1, GL_TRUE, &m.m[0][0]); loc = gl->GetUniformLocation(program, "colormatrix_c"); - gl->Uniform3f(loc, m[0][3], m[1][3], m[2][3]); + gl->Uniform3f(loc, m.c[0], m.c[1], m.c[2]); } gl->Uniform1f(gl->GetUniformLocation(program, "input_gamma"), diff --git a/video/out/vo_opengl_old.c b/video/out/vo_opengl_old.c index 6c9bfb62a0..f39f5709cf 100644 --- a/video/out/vo_opengl_old.c +++ b/video/out/vo_opengl_old.c @@ -1070,7 +1070,7 @@ static void glSetupYUVFragprog(struct vo *vo, GL *gl, GLint i; // this is the conversion matrix, with y, u, v factors // for red, green, blue and the constant offsets - float yuv2rgb[3][4]; + struct mp_cmat yuv2rgb; int noise = params->noise_strength != 0; create_conv_textures(vo, gl, params, &cur_texu, conv_texs); create_scaler_textures(vo, gl, YUV_LUM_SCALER(type), &cur_texu, lum_scale_texs); @@ -1102,7 +1102,7 @@ static void glSetupYUVFragprog(struct vo *vo, GL *gl, add_scaler(YUV_CHROM_SCALER(type), prog, chrom_scale_texs, '2', 'b', rect, params->chrom_texw, params->chrom_texh, params->filter_strength); - mp_get_yuv2rgb_coeffs(¶ms->csp_params, yuv2rgb); + mp_get_yuv2rgb_coeffs(¶ms->csp_params, &yuv2rgb); switch (YUV_CONVERSION(type)) { case YUV_CONVERSION_FRAGMENT: append_template(prog, yuv_prog_template); @@ -1121,11 +1121,14 @@ static void glSetupYUVFragprog(struct vo *vo, GL *gl, break; } for (int r = 0; r < 3; r++) { - for (int c = 0; c < 4; c++) { - // "cmRC" + for (int c = 0; c < 3; c++) { + // "mRC" char var[] = { 'c', 'm', '1' + r, '1' + c, '\0' }; - replace_var_float(prog, var, yuv2rgb[r][c]); + replace_var_float(prog, var, yuv2rgb.m[r][c]); } + // "mR4" + char var[] = { 'c', 'm', '1' + r, '4', '\0' }; + replace_var_float(prog, var, yuv2rgb.c[r]); } replace_var_float(prog, "gamma_r", (float)1.0 / params->csp_params.rgamma); replace_var_float(prog, "gamma_g", (float)1.0 / params->csp_params.ggamma); diff --git a/video/vdpau_mixer.c b/video/vdpau_mixer.c index 182e1fd40a..d3a4a02457 100644 --- a/video/vdpau_mixer.c +++ b/video/vdpau_mixer.c @@ -192,14 +192,19 @@ static int create_vdp_mixer(struct mp_vdpau_mixer *mixer) if (!opts->chroma_deint) SET_VIDEO_ATTR(SKIP_CHROMA_DEINTERLACE, uint8_t, 1); - // VdpCSCMatrix happens to be compatible with mpv's CSC matrix type - // both are float[3][4] + struct mp_cmat yuv2rgb; VdpCSCMatrix matrix; struct mp_csp_params cparams = MP_CSP_PARAMS_DEFAULTS; mp_csp_set_image_params(&cparams, &mixer->image_params); mp_csp_copy_equalizer_values(&cparams, &mixer->video_eq); - mp_get_yuv2rgb_coeffs(&cparams, matrix); + mp_get_yuv2rgb_coeffs(&cparams, &yuv2rgb); + + for (int r = 0; r < 3; r++) { + for (int c = 0; c < 3; c++) + matrix[r][c] = yuv2rgb.m[r][c]; + matrix[r][3] = yuv2rgb.c[r]; + } set_video_attribute(mixer, VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX, &matrix, "CSC matrix"); -- cgit v1.2.3