diff options
author | Torsten Jager <t.jager@gmx.de> | 2012-07-06 21:58:29 +0300 |
---|---|---|
committer | Torsten Jager <t.jager@gmx.de> | 2012-07-06 21:58:29 +0300 |
commit | b31054e542aaacc2c4c83a5e6d398121793d1a37 (patch) | |
tree | d434e18f8279fa7a43c27b13108c08ed2a1a864f | |
parent | 97841e0e129d0708750789a28fbaf8cb67b9ce26 (diff) | |
download | xine-lib-b31054e542aaacc2c4c83a5e6d398121793d1a37.tar.gz xine-lib-b31054e542aaacc2c4c83a5e6d398121793d1a37.tar.bz2 |
yuv2rgb: added color matrix and fullrange support
-rw-r--r-- | src/video_out/video_out_caca.c | 2 | ||||
-rw-r--r-- | src/video_out/video_out_fb.c | 12 | ||||
-rw-r--r-- | src/video_out/video_out_opengl.c | 12 | ||||
-rw-r--r-- | src/video_out/video_out_xcbshm.c | 12 | ||||
-rw-r--r-- | src/video_out/video_out_xshm.c | 12 | ||||
-rw-r--r-- | src/video_out/yuv2rgb.c | 47 | ||||
-rw-r--r-- | src/video_out/yuv2rgb.h | 15 | ||||
-rw-r--r-- | src/video_out/yuv2rgb_mmx.c | 26 | ||||
-rw-r--r-- | src/xine-engine/video_out.c | 8 |
9 files changed, 103 insertions, 43 deletions
diff --git a/src/video_out/video_out_caca.c b/src/video_out/video_out_caca.c index f50a39779..074829192 100644 --- a/src/video_out/video_out_caca.c +++ b/src/video_out/video_out_caca.c @@ -285,7 +285,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi this->vo_driver.dispose = caca_dispose_driver; this->yuv2rgb_factory = yuv2rgb_factory_init(MODE_32_RGB, 0, NULL); - this->yuv2rgb_factory->set_csc_levels(this->yuv2rgb_factory, 0, 128, 128); + this->yuv2rgb_factory->set_csc_levels(this->yuv2rgb_factory, 0, 128, 128, CM_DEFAULT); if (dp) { this->cv = caca_get_canvas(dp); diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c index 0d4376336..8669eca65 100644 --- a/src/video_out/video_out_fb.c +++ b/src/video_out/video_out_fb.c @@ -622,7 +622,8 @@ static int fb_set_property(vo_driver_t *this_gen, int property, int value) this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); break; case VO_PROP_CONTRAST: @@ -630,7 +631,8 @@ static int fb_set_property(vo_driver_t *this_gen, int property, int value) this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); break; case VO_PROP_SATURATION: @@ -638,7 +640,8 @@ static int fb_set_property(vo_driver_t *this_gen, int property, int value) this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); break; default: @@ -894,7 +897,8 @@ static int setup_yuv2rgb(fb_driver_t *this, config_values_t *config, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); return 1; } diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c index 570afa2fd..e6108f0db 100644 --- a/src/video_out/video_out_opengl.c +++ b/src/video_out/video_out_opengl.c @@ -1640,7 +1640,8 @@ static int opengl_set_property (vo_driver_t *this_gen, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->sc.force_redraw = 1; break; case VO_PROP_CONTRAST: @@ -1648,7 +1649,8 @@ static int opengl_set_property (vo_driver_t *this_gen, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->sc.force_redraw = 1; break; case VO_PROP_SATURATION: @@ -1656,7 +1658,8 @@ static int opengl_set_property (vo_driver_t *this_gen, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->sc.force_redraw = 1; break; default: @@ -1889,7 +1892,8 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); XLockDisplay (this->display); this->xoverlay = x11osd_create (this->xine, this->display, this->screen, diff --git a/src/video_out/video_out_xcbshm.c b/src/video_out/video_out_xcbshm.c index 7f2e45fca..76e4a79e3 100644 --- a/src/video_out/video_out_xcbshm.c +++ b/src/video_out/video_out_xcbshm.c @@ -863,7 +863,8 @@ static int xshm_set_property (vo_driver_t *this_gen, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->sc.force_redraw = 1; break; @@ -872,7 +873,8 @@ static int xshm_set_property (vo_driver_t *this_gen, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->sc.force_redraw = 1; break; @@ -881,7 +883,8 @@ static int xshm_set_property (vo_driver_t *this_gen, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->sc.force_redraw = 1; break; @@ -1323,7 +1326,8 @@ static vo_driver_t *xshm_open_plugin(video_driver_class_t *class_gen, const void this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->xoverlay = xcbosd_create(this->xine, this->connection, this->screen, this->window, XCBOSD_SHAPED); diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index 8c4b5f2d8..2c443bb7d 100644 --- a/src/video_out/video_out_xshm.c +++ b/src/video_out/video_out_xshm.c @@ -951,7 +951,8 @@ static int xshm_set_property (vo_driver_t *this_gen, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->sc.force_redraw = 1; break; @@ -960,7 +961,8 @@ static int xshm_set_property (vo_driver_t *this_gen, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->sc.force_redraw = 1; break; @@ -969,7 +971,8 @@ static int xshm_set_property (vo_driver_t *this_gen, this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); this->sc.force_redraw = 1; break; @@ -1364,7 +1367,8 @@ static vo_driver_t *xshm_open_plugin_2 (video_driver_class_t *class_gen, const v this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, - this->yuv2rgb_saturation); + this->yuv2rgb_saturation, + CM_DEFAULT); LOCK_DISPLAY(this); this->xoverlay = x11osd_create (this->xine, this->display, this->screen, diff --git a/src/video_out/yuv2rgb.c b/src/video_out/yuv2rgb.c index cb5a990a1..27a74620a 100644 --- a/src/video_out/yuv2rgb.c +++ b/src/video_out/yuv2rgb.c @@ -2289,7 +2289,7 @@ static int div_round (int dividend, int divisor) } static void yuv2rgb_set_csc_levels (yuv2rgb_factory_t *this, - int brightness, int contrast, int saturation) + int brightness, int contrast, int saturation, int colormatrix) { int i; uint8_t table_Y[1024]; @@ -2300,18 +2300,40 @@ static void yuv2rgb_set_csc_levels (yuv2rgb_factory_t *this, void *table_r = 0, *table_g = 0, *table_b = 0; int shift_r = 0, shift_g = 0, shift_b = 0; - int crv = Inverse_Table_6_9[this->matrix_coefficients][0]; - int cbu = Inverse_Table_6_9[this->matrix_coefficients][1]; - int cgu = -Inverse_Table_6_9[this->matrix_coefficients][2]; - int cgv = -Inverse_Table_6_9[this->matrix_coefficients][3]; + int yoffset = -16; + int ygain = (1 << 16) * 255 / 219; + + int cm = (colormatrix >> 1) & 7; + int crv = Inverse_Table_6_9[cm][0]; + int cbu = Inverse_Table_6_9[cm][1]; + int cgu = -Inverse_Table_6_9[cm][2]; + int cgv = -Inverse_Table_6_9[cm][3]; int mode = this->mode; int swapped = this->swapped; + /* nasty workaround for xine-ui not sending exact defaults */ + if (brightness == -1) brightness = 0; + if (contrast == 127) contrast = 128; + if (saturation == 127) saturation = 128; + + /* full range mode */ + if (colormatrix & 1) { + yoffset = 0; + ygain = (1 << 16); + + crv = (crv * 112 + 63) / 127; + cbu = (cbu * 112 + 63) / 127; + cgu = (cgu * 112 + 63) / 127; + cgv = (cgv * 112 + 63) / 127; + } + + yoffset += brightness; + for (i = 0; i < 1024; i++) { int j; - j = (76309 * (i - 384 - 16 + brightness) + 32768) >> 16; + j = (ygain * (i - 384 + yoffset) + 32768) >> 16; j = (j < 0) ? 0 : ((j > 255) ? 255 : j); table_Y[i] = j; } @@ -2470,16 +2492,16 @@ static void yuv2rgb_set_csc_levels (yuv2rgb_factory_t *this, for (i = 0; i < 256; i++) { this->table_rV[i] = (((uint8_t *) table_r) + - entry_size * div_round (crv * (i-128), 76309)); + entry_size * div_round (crv * (i-128), ygain)); this->table_gU[i] = (((uint8_t *) table_g) + - entry_size * div_round (cgu * (i-128), 76309)); - this->table_gV[i] = entry_size * div_round (cgv * (i-128), 76309); + entry_size * div_round (cgu * (i-128), ygain)); + this->table_gV[i] = entry_size * div_round (cgv * (i-128), ygain); this->table_bU[i] = (((uint8_t *)table_b) + - entry_size * div_round (cbu * (i-128), 76309)); + entry_size * div_round (cbu * (i-128), ygain)); } #if defined(ARCH_X86) || defined(ARCH_X86_64) - mmx_yuv2rgb_set_csc_levels (this, brightness, contrast, saturation); + mmx_yuv2rgb_set_csc_levels (this, brightness, contrast, saturation, colormatrix); #endif } @@ -3243,12 +3265,11 @@ yuv2rgb_factory_t* yuv2rgb_factory_init (int mode, int swapped, this->create_converter = yuv2rgb_create_converter; this->set_csc_levels = yuv2rgb_set_csc_levels; this->dispose = yuv2rgb_factory_dispose; - this->matrix_coefficients = 6; this->table_base = NULL; this->table_mmx = NULL; - yuv2rgb_set_csc_levels (this, 0, 128, 128); + yuv2rgb_set_csc_levels (this, 0, 128, 128, CM_DEFAULT); /* * auto-probe for the best yuv2rgb function diff --git a/src/video_out/yuv2rgb.h b/src/video_out/yuv2rgb.h index 1a1252f40..334dba925 100644 --- a/src/video_out/yuv2rgb.h +++ b/src/video_out/yuv2rgb.h @@ -45,6 +45,15 @@ typedef uint32_t (*yuv2rgb_single_pixel_fun_t) (yuv2rgb_t *this, uint8_t y, uint #define MODE_8_GRAY 11 #define MODE_PALETTE 12 + /* + * colormatrix values - (mpeg_matrix_index << 1) | fullrange + */ + +#define CM_DEFAULT 10 +#define CM_SD 10 +#define CM_HD 2 +#define CM_FULLRANGE 1 + struct yuv2rgb_s { /* * configure converter for scaling factors @@ -129,7 +138,7 @@ struct yuv2rgb_factory_s { * for all converters produced by this factory */ void (*set_csc_levels) (yuv2rgb_factory_t *this, - int brightness, int contrast, int saturation); + int brightness, int contrast, int saturation, int colormatrix); /* * free resources @@ -142,8 +151,6 @@ struct yuv2rgb_factory_s { int swapped; uint8_t *cmap; - uint32_t matrix_coefficients; - void *table_base; void *table_rV[256]; void *table_gU[256]; @@ -166,7 +173,7 @@ yuv2rgb_factory_t *yuv2rgb_factory_init (int mode, int swapped, uint8_t *colorma */ void mmx_yuv2rgb_set_csc_levels(yuv2rgb_factory_t *this, - int brightness, int contrast, int saturation); + int brightness, int contrast, int saturation, int colormatrix); void yuv2rgb_init_mmxext (yuv2rgb_factory_t *this); void yuv2rgb_init_mmx (yuv2rgb_factory_t *this); void yuv2rgb_init_mlib (yuv2rgb_factory_t *this); diff --git a/src/video_out/yuv2rgb_mmx.c b/src/video_out/yuv2rgb_mmx.c index 9d4cb135c..da6114a52 100644 --- a/src/video_out/yuv2rgb_mmx.c +++ b/src/video_out/yuv2rgb_mmx.c @@ -70,14 +70,19 @@ struct mmx_csc_s { extern const int32_t Inverse_Table_6_9[8][4]; void mmx_yuv2rgb_set_csc_levels(yuv2rgb_factory_t *this, - int brightness, int contrast, int saturation) + int brightness, int contrast, int saturation, int colormatrix) { - int crv, cbu, cgu, cgv, cty; - int i; + int i, cty; int yoffset = -16; int ygain = ((1 << 16) * 255) / 219; + int cm = (colormatrix >> 1) & 7; + int crv = Inverse_Table_6_9[cm][0]; + int cbu = Inverse_Table_6_9[cm][1]; + int cgu = Inverse_Table_6_9[cm][2]; + int cgv = Inverse_Table_6_9[cm][3]; + mmx_csc_t *csc; /* 'table_mmx' is 64bit aligned for better performance */ @@ -85,20 +90,27 @@ void mmx_yuv2rgb_set_csc_levels(yuv2rgb_factory_t *this, this->table_mmx = av_mallocz(sizeof(mmx_csc_t)); } + /* full range mode */ + if (colormatrix & 1) { + yoffset = 0; + ygain = (1 << 16); + + crv = (crv * 112 + 63) / 127; + cbu = (cbu * 112 + 63) / 127; + cgu = (cgu * 112 + 63) / 127; + cgv = (cgv * 112 + 63) / 127; + } + yoffset += brightness; /* TV set behaviour: contrast affects color difference as well */ saturation = (contrast * saturation + 64) >> 7; csc = (mmx_csc_t *) this->table_mmx; - crv = Inverse_Table_6_9[this->matrix_coefficients][0]; crv = (crv * saturation + 512) / 1024; - cbu = Inverse_Table_6_9[this->matrix_coefficients][1]; cbu = (cbu * saturation + 512) / 1024; cbu = (cbu > 32767) ? 32767 : cbu; - cgu = Inverse_Table_6_9[this->matrix_coefficients][2]; cgu = (cgu * saturation + 512) / 1024; - cgv = Inverse_Table_6_9[this->matrix_coefficients][3]; cgv = (cgv * saturation + 512) / 1024; cty = (ygain * contrast + 512) / 1024; diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 8a2cc4bc3..c934578ce 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.c @@ -537,13 +537,17 @@ static int vo_grab_grab_video_frame (xine_grab_video_frame_t *frame_gen) { /* initialize yuv2rgb factory */ if (!frame->yuv2rgb_factory) { + int cm = VO_GET_FLAGS_CM (vo_frame->flags); frame->yuv2rgb_factory = yuv2rgb_factory_init(MODE_24_RGB, 0, NULL); if (!frame->yuv2rgb_factory) { vo_frame_dec_lock(vo_frame); return -1; /* error happened */ } - frame->yuv2rgb_factory->matrix_coefficients = 1; /* ITU-R Rec. 709 (1990) */ - frame->yuv2rgb_factory->set_csc_levels (frame->yuv2rgb_factory, 0, 128, 128); + if ((cm >> 1) == 2) /* color matrix undefined */ + cm = (cm & 1) | (vo_frame->height - vo_frame->crop_top - vo_frame->crop_bottom >= 720 ? 2 : 10); + else if ((cm >> 1) == 0) /* converted RGB source, always ITU 601 */ + cm = (cm & 1) | 10; + frame->yuv2rgb_factory->set_csc_levels (frame->yuv2rgb_factory, 0, 128, 128, cm); } /* retrieve a yuv2rgb converter */ |