summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Jager <t.jager@gmx.de>2012-07-06 21:58:29 +0300
committerTorsten Jager <t.jager@gmx.de>2012-07-06 21:58:29 +0300
commitb31054e542aaacc2c4c83a5e6d398121793d1a37 (patch)
treed434e18f8279fa7a43c27b13108c08ed2a1a864f
parent97841e0e129d0708750789a28fbaf8cb67b9ce26 (diff)
downloadxine-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.c2
-rw-r--r--src/video_out/video_out_fb.c12
-rw-r--r--src/video_out/video_out_opengl.c12
-rw-r--r--src/video_out/video_out_xcbshm.c12
-rw-r--r--src/video_out/video_out_xshm.c12
-rw-r--r--src/video_out/yuv2rgb.c47
-rw-r--r--src/video_out/yuv2rgb.h15
-rw-r--r--src/video_out/yuv2rgb_mmx.c26
-rw-r--r--src/xine-engine/video_out.c8
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 */