From cbd5caef0e8862dcafd40d80d28f4bca73882f97 Mon Sep 17 00:00:00 2001 From: reimar Date: Sat, 16 Jan 2010 19:59:31 +0000 Subject: Add support for adjustable TV <-> PC level conversion. This could also be done by modifying contrast and brightness, but this seems a bit more flexible and easier to use. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30335 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/csputils.c | 11 +++++++++-- libvo/csputils.h | 8 ++++++++ libvo/vo_gl.c | 15 ++++++++++++++- libvo/vo_gl2.c | 2 +- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/libvo/csputils.c b/libvo/csputils.c index e842592b1f..57362f6725 100644 --- a/libvo/csputils.c +++ b/libvo/csputils.c @@ -60,10 +60,15 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]) { float uvcos = params->saturation * cos(params->hue); float uvsin = params->saturation * sin(params->hue); int format = params->format; + int levelconv = params->levelconv; int i; const float (*uv_coeffs)[3]; const float *level_adjust; - static const float yuv_pc_level_adjust[4] = {-16 / 255.0, -128 / 255.0, -128 / 255.0, 1.164}; + static const float yuv_level_adjust[MP_CSP_LEVELCONV_COUNT][4] = { + {-16 / 255.0, -128 / 255.0, -128 / 255.0, 1.164}, + { 16 / 255.0 * 1.164, -128 / 255.0, -128 / 255.0, 1.0/1.164}, + { 0, -128 / 255.0, -128 / 255.0, 1}, + }; static const float xyz_level_adjust[4] = {0, 0, 0, 0}; static const float uv_coeffs_table[MP_CSP_COUNT][3][3] = { [MP_CSP_DEFAULT] = { @@ -101,7 +106,9 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]) { if (format < 0 || format >= MP_CSP_COUNT) format = MP_CSP_DEFAULT; uv_coeffs = uv_coeffs_table[format]; - level_adjust = yuv_pc_level_adjust; + if (levelconv < 0 || levelconv >= MP_CSP_LEVELCONV_COUNT) + levelconv = MP_CSP_LEVELCONV_TV_TO_PC; + level_adjust = yuv_level_adjust[levelconv]; if (format == MP_CSP_XYZ) level_adjust = xyz_level_adjust; diff --git a/libvo/csputils.h b/libvo/csputils.h index 4723c7006d..54c6926b96 100644 --- a/libvo/csputils.h +++ b/libvo/csputils.h @@ -31,8 +31,16 @@ enum mp_csp_standard { MP_CSP_COUNT }; +enum mp_csp_levelconv { + MP_CSP_LEVELCONV_TV_TO_PC, + MP_CSP_LEVELCONV_PC_TO_TV, + MP_CSP_LEVELCONV_NONE, + MP_CSP_LEVELCONV_COUNT +}; + struct mp_csp_params { enum mp_csp_standard format; + enum mp_csp_levelconv levelconv; float brightness; float contrast; float hue; diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index ab24a65494..16bb1b9328 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -94,6 +94,7 @@ static int use_ycbcr; #define MASK_GAMMA_SUPPORT (MASK_NOT_COMBINERS & ~(1 << YUV_CONVERSION_FRAGMENT)) static int use_yuv; static int colorspace; +static int levelconv; static int is_yuv; static int lscale; static int cscale; @@ -217,7 +218,7 @@ static void update_yuvconv(void) { float ggamma = exp(log(8.0) * eq_ggamma / 100.0); float bgamma = exp(log(8.0) * eq_bgamma / 100.0); gl_conversion_params_t params = {gl_target, yuvconvtype, - {colorspace, bri, cont, hue, sat, rgamma, ggamma, bgamma}, + {colorspace, levelconv, bri, cont, hue, sat, rgamma, ggamma, bgamma}, texture_width, texture_height, 0, 0, filter_strength}; mp_get_chroma_shift(image_format, &xs, &ys); params.chrom_texw = params.texw >> xs; @@ -1007,6 +1008,12 @@ static int valid_csp(void *p) return *csp >= -1 && *csp < MP_CSP_COUNT; } +static int valid_csp_lvl(void *p) +{ + int *lvl = p; + return *lvl >= -1 && *lvl < MP_CSP_LEVELCONV_COUNT; +} + static const opt_t subopts[] = { {"manyfmts", OPT_ARG_BOOL, &many_fmts, NULL}, {"osd", OPT_ARG_BOOL, &use_osd, NULL}, @@ -1017,6 +1024,7 @@ static const opt_t subopts[] = { {"rectangle", OPT_ARG_INT, &use_rectangle,int_non_neg}, {"yuv", OPT_ARG_INT, &use_yuv, int_non_neg}, {"colorspace", OPT_ARG_INT, &colorspace, valid_csp}, + {"levelconv", OPT_ARG_INT, &levelconv, valid_csp_lvl}, {"lscale", OPT_ARG_INT, &lscale, int_non_neg}, {"cscale", OPT_ARG_INT, &cscale, int_non_neg}, {"filter-strength", OPT_ARG_FLOAT, &filter_strength, NULL}, @@ -1048,6 +1056,7 @@ static int preinit(const char *arg) use_ycbcr = 0; use_yuv = 0; colorspace = -1; + levelconv = -1; lscale = 0; cscale = 0; filter_strength = 0.5; @@ -1110,6 +1119,10 @@ static int preinit(const char *arg) " 3: YUV to RGB according to SMPT-240M\n" " 4: YUV to RGB according to EBU\n" " 5: XYZ to RGB\n" + " levelconv=\n" + " 0: YUV to RGB converting TV to PC levels\n" + " 1: YUV to RGB converting PC to TV levels\n" + " 2: YUV to RGB without converting levels\n" " lscale=\n" " 0: use standard bilinear scaling for luma.\n" " 1: use improved bicubic scaling for luma.\n" diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index b65acf589c..9d1bd533d1 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -571,7 +571,7 @@ static int initGl(uint32_t d_width, uint32_t d_height) if (is_yuv) { int xs, ys; gl_conversion_params_t params = {GL_TEXTURE_2D, use_yuv, - {MP_CSP_DEFAULT, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0}, + {-1, -1, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0}, texture_width, texture_height, 0, 0, 0}; switch (use_yuv) { case YUV_CONVERSION_FRAGMENT_LOOKUP: -- cgit v1.2.3