summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTorsten Jager <t.jager@gmx.de>2012-07-06 21:59:08 +0300
committerTorsten Jager <t.jager@gmx.de>2012-07-06 21:59:08 +0300
commit9fa49e23cc5341d17b246996da26915ab5b1db15 (patch)
tree8e46eb76e7ca84681cf0dc6aecf854dd249fefd1 /src
parentb31054e542aaacc2c4c83a5e6d398121793d1a37 (diff)
downloadxine-lib-9fa49e23cc5341d17b246996da26915ab5b1db15.tar.gz
xine-lib-9fa49e23cc5341d17b246996da26915ab5b1db15.tar.bz2
opengl/(xcb)xv/x(cb)shm: added color matrix and fullrange support
Diffstat (limited to 'src')
-rw-r--r--src/video_out/video_out_opengl.c156
-rw-r--r--src/video_out/video_out_xcbshm.c78
-rw-r--r--src/video_out/video_out_xcbxv.c62
-rw-r--r--src/video_out/video_out_xshm.c79
-rw-r--r--src/video_out/video_out_xv.c36
5 files changed, 288 insertions, 123 deletions
diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c
index e6108f0db..0d54dff1f 100644
--- a/src/video_out/video_out_opengl.c
+++ b/src/video_out/video_out_opengl.c
@@ -204,12 +204,15 @@ typedef struct {
PFNMYGLGENTEXTURESEXTPROC glGenTexturesEXT;
PFNMYGLBINDTEXTUREEXTPROC glBindTextureEXT;
- int yuv2rgb_brightness;
- int yuv2rgb_contrast;
- int yuv2rgb_saturation;
+ int brightness;
+ int contrast;
+ int saturation;
uint8_t *yuv2rgb_cmap;
yuv2rgb_factory_t *yuv2rgb_factory;
+ /* color matrix switching */
+ int cm_yuv2rgb, cm_fragprog, cm_state;
+
/* Frame state */
opengl_frame_t *frame[NUM_FRAMES_BACKLOG];
x11osd *xoverlay;
@@ -246,6 +249,12 @@ typedef struct {
} opengl_render_t;
+/* import common color matrix stuff */
+#define CM_DRIVER_T opengl_driver_t
+#include "color_matrix.c"
+
+extern const int32_t Inverse_Table_6_9[8][4]; /* from yuv2rgb.c */
+
/*
* Render functions
*/
@@ -929,7 +938,48 @@ static int render_setup_torus (opengl_driver_t *this) {
static int render_setup_fp_yuv (opengl_driver_t *this) {
GLint errorpos;
int ret;
- static const char *fragprog_yuv =
+
+ int i = (this->cm_fragprog >> 1) & 7;
+ int vr = Inverse_Table_6_9[i][0];
+ int ug = Inverse_Table_6_9[i][2];
+ int vg = Inverse_Table_6_9[i][3];
+ int ub = Inverse_Table_6_9[i][1];
+ int ygain, yoffset;
+ /* TV set behaviour: contrast affects colour difference as well */
+ int saturation = (this->saturation * this->contrast + 64) / 128;
+
+ static char fragprog_yuv[512];
+ const char *s = "";
+
+ /* full range mode */
+ if (this->cm_fragprog & 1) {
+ ygain = (1000 * this->contrast + 64) / 128;
+ yoffset = this->brightness * ygain / 255;
+ /* be careful to stay within 32 bit */
+ vr = (saturation * (112 / 4) * vr + 127 * 16) / (127 * 128 / 4);
+ ug = (saturation * (112 / 4) * ug + 127 * 16) / (127 * 128 / 4);
+ vg = (saturation * (112 / 4) * vg + 127 * 16) / (127 * 128 / 4);
+ ub = (saturation * (112 / 4) * ub + 127 * 16) / (127 * 128 / 4);
+ } else {
+ ygain = (1000 * 255 * this->contrast + 219 * 64) / (219 * 128);
+ yoffset = (this->brightness - 16) * ygain / 255;
+ vr = (saturation * vr + 64) / 128;
+ ug = (saturation * ug + 64) / 128;
+ vg = (saturation * vg + 64) / 128;
+ ub = (saturation * ub + 64) / 128;
+ }
+
+ vr = 1000 * vr / 65536;
+ ug = 1000 * ug / 65536;
+ vg = 1000 * vg / 65536;
+ ub = 1000 * ub / 65536;
+
+ if (yoffset < 0) {
+ s = "-";
+ yoffset = -yoffset;
+ }
+
+ sprintf (fragprog_yuv,
"!!ARBfp1.0\n"
"ATTRIB tex = fragment.texcoord[0];"
"PARAM off = program.env[0];"
@@ -941,16 +991,28 @@ static int render_setup_fp_yuv (opengl_driver_t *this) {
"ADD u, v, off.xyww;"
"ADD v, v, off.zyww;"
"TEX tmp.x, u, texture[0], 2D;"
- "MAD res, res, 1.164, -0.073;" /* -1.164*16/255 */
+ "MAD res, res, %d.%03d, %s%d.%03d;"
"TEX tmp.y, v, texture[0], 2D;"
"SUB tmp, tmp, { .5, .5 };"
- "MAD res, { 0, -.391, 2.018 }, tmp.xxxw, res;"
- "MAD result.color, { 1.596, -.813, 0 }, tmp.yyyw, res;"
- "END";
+ "MAD res, { 0, -%d.%03d, %d.%03d }, tmp.xxxw, res;"
+ "MAD result.color, { %d.%03d, -%d.%03d, 0 }, tmp.yyyw, res;"
+ "END",
+ /* nasty: "%.3f" may use comma as decimal point... */
+ ygain / 1000, ygain % 1000,
+ s, yoffset / 1000, yoffset % 1000,
+ ug / 1000, ug % 1000,
+ ub / 1000, ub % 1000,
+ vr / 1000, vr % 1000,
+ vg / 1000, vg % 1000);
ret = render_setup_tex2d (this);
if (! this->has_fragprog)
return 0;
+
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "video_out_open_opengl_fragprog: b %d c %d s %d [%s]\n",
+ this->brightness, this->contrast, this->saturation, cm_names[this->cm_fragprog]);
+
if (this->fprog == (GLuint)-1)
this->glGenProgramsARB (1, &this->fprog);
this->glBindProgramARB (MYGL_FRAGMENT_PROGRAM_ARB, this->fprog);
@@ -1058,6 +1120,15 @@ static void *render_run (opengl_driver_t *this) {
this->render_frame_changed = 0;
pthread_mutex_unlock (&this->render_action_mutex);
if (this->context && frame) {
+ /* update fragprog if color matrix changed */
+ if (this->render_fun_id == 0) {
+ int cm = cm_from_frame ((vo_frame_t *)frame);
+ if (cm != this->cm_fragprog) {
+ this->cm_fragprog = cm;
+ this->render_action = RENDER_SETUP;
+ break;
+ }
+ }
XLockDisplay (this->display);
CHECKERR ("pre-render");
ret = 1;
@@ -1209,7 +1280,8 @@ static void *render_run (opengl_driver_t *this) {
static uint32_t opengl_get_capabilities (vo_driver_t *this_gen) {
/* opengl_driver_t *this = (opengl_driver_t *) this_gen; */
- uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION;
+ uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS
+ | VO_CAP_CONTRAST | VO_CAP_SATURATION | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE;
/* TODO: somehow performance goes down during the first few frames */
/* if (this->xoverlay) */
@@ -1220,7 +1292,8 @@ static uint32_t opengl_get_capabilities (vo_driver_t *this_gen) {
static void opengl_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) {
opengl_frame_t *frame = (opengl_frame_t *) vo_img ;
-/* opengl_driver_t *this = (opengl_driver_t *) vo_img->driver; */
+ opengl_driver_t *this = (opengl_driver_t *) vo_img->driver;
+ int cm;
vo_img->proc_called = 1;
if (! frame->rgb_dst)
@@ -1236,6 +1309,16 @@ static void opengl_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) {
return;
}
+ cm = cm_from_frame (vo_img);
+ if (cm != this->cm_yuv2rgb) {
+ this->cm_yuv2rgb = cm;
+ this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
+ this->brightness, this->contrast, this->saturation, cm);
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "video_out_opengl: b %d c %d s %d [%s]\n",
+ this->brightness, this->contrast, this->saturation, cm_names[cm]);
+ }
+
if (frame->format == XINE_IMGFMT_YV12)
frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst,
src[0], src[1], src[2]);
@@ -1603,11 +1686,11 @@ static int opengl_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_MAX_NUM_FRAMES:
return 15;
case VO_PROP_BRIGHTNESS:
- return this->yuv2rgb_brightness;
+ return this->brightness;
case VO_PROP_CONTRAST:
- return this->yuv2rgb_contrast;
+ return this->contrast;
case VO_PROP_SATURATION:
- return this->yuv2rgb_saturation;
+ return this->saturation;
case VO_PROP_WINDOW_WIDTH:
return this->sc.gui_width;
case VO_PROP_WINDOW_HEIGHT:
@@ -1636,30 +1719,21 @@ static int opengl_set_property (vo_driver_t *this_gen,
"video_out_opengl: aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]);
break;
case VO_PROP_BRIGHTNESS:
- this->yuv2rgb_brightness = value;
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->brightness = value;
+ this->cm_yuv2rgb = 0;
+ this->cm_fragprog = 0;
this->sc.force_redraw = 1;
break;
case VO_PROP_CONTRAST:
- this->yuv2rgb_contrast = value;
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->contrast = value;
+ this->cm_yuv2rgb = 0;
+ this->cm_fragprog = 0;
this->sc.force_redraw = 1;
break;
case VO_PROP_SATURATION:
- this->yuv2rgb_saturation = value;
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->saturation = value;
+ this->cm_yuv2rgb = 0;
+ this->cm_fragprog = 0;
this->sc.force_redraw = 1;
break;
default:
@@ -1808,6 +1882,8 @@ static void opengl_dispose (vo_driver_t *this_gen) {
this->yuv2rgb_factory->dispose (this->yuv2rgb_factory);
+ cm_close (this);
+
if (this->xoverlay) {
XLockDisplay (this->display);
x11osd_destroy (this->xoverlay);
@@ -1883,17 +1959,13 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
this->vo_driver.dispose = opengl_dispose;
this->vo_driver.redraw_needed = opengl_redraw_needed;
- this->yuv2rgb_brightness = 0;
- this->yuv2rgb_contrast = 128;
- this->yuv2rgb_saturation = 128;
-
- this->yuv2rgb_factory = yuv2rgb_factory_init (YUV_FORMAT, YUV_SWAP_MODE,
- NULL);
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->brightness = 0;
+ this->contrast = 128;
+ this->saturation = 128;
+
+ cm_init (this);
+
+ this->yuv2rgb_factory = yuv2rgb_factory_init (YUV_FORMAT, YUV_SWAP_MODE, NULL);
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 76e4a79e3..05e5ad731 100644
--- a/src/video_out/video_out_xcbshm.c
+++ b/src/video_out/video_out_xcbshm.c
@@ -26,7 +26,7 @@
*
* ported to xcb by Christoph Pfister - Feb 2007
*
- * crop support added by Torsten Jager <t.jager@gmx.de>
+ * fullrange/HD color and crop support added by Torsten Jager <t.jager@gmx.de>
*/
#define LOG_MODULE "video_out_xcbshm"
@@ -113,12 +113,15 @@ typedef struct {
int scanline_pad;
int use_shm;
- int yuv2rgb_brightness;
- int yuv2rgb_contrast;
- int yuv2rgb_saturation;
+ int brightness;
+ int contrast;
+ int saturation;
uint8_t *yuv2rgb_cmap;
yuv2rgb_factory_t *yuv2rgb_factory;
+ /* color matrix switching */
+ int cm_active, cm_state;
+
vo_scale_t sc;
xshm_frame_t *cur_frame;
@@ -141,6 +144,10 @@ typedef struct {
} xshm_class_t;
+/* import common color matrix stuff */
+#define CM_DRIVER_T xshm_driver_t
+#include "color_matrix.c"
+
/*
* allocate an XImage, try XShm first but fall back to
* plain X11 if XShm should fail
@@ -238,7 +245,7 @@ static void dispose_ximage(xshm_driver_t *this, xshm_frame_t *frame)
static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) {
xshm_driver_t *this = (xshm_driver_t *) this_gen;
uint32_t capabilities = VO_CAP_CROP | VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS
- | VO_CAP_CONTRAST | VO_CAP_SATURATION;
+ | VO_CAP_CONTRAST | VO_CAP_SATURATION | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE;
if( this->xoverlay )
capabilities |= VO_CAP_UNSCALED_OVERLAY;
@@ -418,6 +425,17 @@ static void xshm_frame_proc_setup (vo_frame_t *vo_img) {
+ (frame->sc.delivered_height - frame->sc.crop_bottom) * vo_img->pitches[0];
if (i + frame->sc.crop_bottom < 0)
frame->crop_flush -= 16 * vo_img->pitches[0];
+
+ /* switch color matrix/range */
+ i = cm_from_frame (vo_img);
+ if (i != this->cm_active) {
+ this->cm_active = i;
+ this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
+ this->brightness, this->contrast, this->saturation, i);
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "video_out_xcbshm: b %d c %d s %d [%s]\n",
+ this->brightness, this->contrast, this->saturation, cm_names[i]);
+ }
}
static void xshm_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) {
@@ -820,11 +838,11 @@ static int xshm_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_MAX_NUM_FRAMES:
return 15;
case VO_PROP_BRIGHTNESS:
- return this->yuv2rgb_brightness;
+ return this->brightness;
case VO_PROP_CONTRAST:
- return this->yuv2rgb_contrast;
+ return this->contrast;
case VO_PROP_SATURATION:
- return this->yuv2rgb_saturation;
+ return this->saturation;
case VO_PROP_WINDOW_WIDTH:
return this->sc.gui_width;
case VO_PROP_WINDOW_HEIGHT:
@@ -859,32 +877,20 @@ static int xshm_set_property (vo_driver_t *this_gen,
break;
case VO_PROP_BRIGHTNESS:
- this->yuv2rgb_brightness = value;
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->brightness = value;
+ this->cm_active = 0;
this->sc.force_redraw = 1;
break;
case VO_PROP_CONTRAST:
- this->yuv2rgb_contrast = value;
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->contrast = value;
+ this->cm_active = 0;
this->sc.force_redraw = 1;
break;
case VO_PROP_SATURATION:
- this->yuv2rgb_saturation = value;
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->saturation = value;
+ this->cm_active = 0;
this->sc.force_redraw = 1;
break;
@@ -1019,6 +1025,8 @@ static void xshm_dispose (vo_driver_t *this_gen) {
this->yuv2rgb_factory->dispose (this->yuv2rgb_factory);
+ cm_close (this);
+
pthread_mutex_lock(&this->main_mutex);
xcb_free_gc(this->connection, this->gc);
pthread_mutex_unlock(&this->main_mutex);
@@ -1317,17 +1325,13 @@ static vo_driver_t *xshm_open_plugin(video_driver_class_t *class_gen, const void
return NULL;
}
- this->yuv2rgb_brightness = 0;
- this->yuv2rgb_contrast = 128;
- this->yuv2rgb_saturation = 128;
-
- this->yuv2rgb_factory = yuv2rgb_factory_init (mode, swapped,
- this->yuv2rgb_cmap);
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ cm_init (this);
+
+ this->brightness = 0;
+ this->contrast = 128;
+ this->saturation = 128;
+
+ this->yuv2rgb_factory = yuv2rgb_factory_init (mode, swapped, this->yuv2rgb_cmap);
this->xoverlay = xcbosd_create(this->xine, this->connection, this->screen,
this->window, XCBOSD_SHAPED);
diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c
index f24141db7..ad3b4b552 100644
--- a/src/video_out/video_out_xcbxv.c
+++ b/src/video_out/video_out_xcbxv.c
@@ -31,6 +31,12 @@
* ported to xcb by Christoph Pfister - Feb 2007
*/
+#define LOG_MODULE "video_out_xcbxv"
+#define LOG_VERBOSE
+/*
+#define LOG
+*/
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -51,12 +57,6 @@
#include <xcb/xv.h>
-#define LOG_MODULE "video_out_xcbxv"
-#define LOG_VERBOSE
-/*
-#define LOG
-*/
-
#include "xine.h"
#include <xine/video_out.h>
#include <xine/xine_internal.h>
@@ -145,6 +145,9 @@ struct xv_driver_s {
pthread_mutex_t main_mutex;
+ /* color matrix switching */
+ int cm_active, cm_state;
+ xcb_atom_t cm_atom;
};
typedef struct {
@@ -154,6 +157,10 @@ typedef struct {
xine_t *xine;
} xv_class_t;
+/* import common color matrix stuff */
+#define CM_DRIVER_T xv_driver_t
+#include "color_matrix.c"
+
VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES;
VIDEO_DEVICE_XV_DECL_PREFER_TYPES;
VIDEO_DEVICE_XV_DECL_SYNC_ATOMS;
@@ -581,10 +588,24 @@ static int xv_redraw_needed (vo_driver_t *this_gen) {
static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
xv_frame_t *frame = (xv_frame_t *) frame_gen;
+ int cm;
/*
printf (LOG_MODULE ": xv_display_frame...\n");
*/
+ cm = cm_from_frame (frame_gen);
+ if (cm != this->cm_active) {
+ this->cm_active = cm;
+ cm = (0xc00c >> cm) & 1;
+ if (this->cm_atom != XCB_NONE) {
+ pthread_mutex_lock(&this->main_mutex);
+ xcb_xv_set_port_attribute (this->connection, this->xv_port, this->cm_atom, cm);
+ pthread_mutex_unlock(&this->main_mutex);
+ xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_xcbxv: color_matrix %s\n",
+ cm_names[cm ? 2 : 10]);
+ }
+ }
+
/*
* queue frames (deinterlacing)
* free old frames
@@ -962,6 +983,8 @@ static void xv_dispose (vo_driver_t *this_gen) {
_x_alphablend_free(&this->alphablend_extra_data);
+ cm_close (this);
+
free (this);
}
@@ -1288,6 +1311,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
this->xoverlay = NULL;
this->ovl_changed = 0;
this->xine = class->xine;
+ this->cm_atom = XCB_NONE;
this->vo_driver.get_capabilities = xv_get_capabilities;
this->vo_driver.alloc_frame = xv_alloc_frame;
@@ -1321,6 +1345,8 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
this->props[VO_PROP_ZOOM_X].value = 100;
this->props[VO_PROP_ZOOM_Y].value = 100;
+ cm_init (this);
+
/*
* check this adaptor's capabilities
*/
@@ -1367,6 +1393,30 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
xv_check_capability (this, VO_PROP_GAMMA, attribute_it.data,
adaptor_it.data->base_id,
NULL, NULL, NULL);
+ } else if(!strcmp(name, "XV_ITURBT_709")) {
+ xcb_xv_get_port_attribute_cookie_t get_attribute_cookie;
+ xcb_xv_get_port_attribute_reply_t *get_attribute_reply;
+ xcb_intern_atom_cookie_t atom_cookie;
+ xcb_intern_atom_reply_t *atom_reply;
+ pthread_mutex_lock(&this->main_mutex);
+ atom_cookie = xcb_intern_atom (this->connection, 0, 13, name);
+ atom_reply = xcb_intern_atom_reply (this->connection, atom_cookie, NULL);
+ if (atom_reply) {
+ this->cm_atom = atom_reply->atom;
+ free (atom_reply);
+ }
+ if (this->cm_atom != XCB_NONE) {
+ get_attribute_cookie = xcb_xv_get_port_attribute (this->connection,
+ this->xv_port, this->cm_atom);
+ get_attribute_reply = xcb_xv_get_port_attribute_reply (this->connection,
+ get_attribute_cookie, NULL);
+ if (get_attribute_reply) {
+ this->cm_active = get_attribute_reply->value ? 2 : 10;
+ free(get_attribute_reply);
+ this->capabilities |= VO_CAP_COLOR_MATRIX;
+ }
+ }
+ pthread_mutex_unlock(&this->main_mutex);
} else if(!strcmp(name, "XV_COLORKEY")) {
this->capabilities |= VO_CAP_COLORKEY;
xv_check_capability (this, VO_PROP_COLORKEY, attribute_it.data,
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 2c443bb7d..6b52acccd 100644
--- a/src/video_out/video_out_xshm.c
+++ b/src/video_out/video_out_xshm.c
@@ -24,7 +24,7 @@
*
* xine-specific code by Guenter Bartsch <bartscgr@studbox.uni-stuttgart.de>
*
- * crop support added by Torsten Jager <t.jager@gmx.de>
+ * fullrange/HD color and crop support added by Torsten Jager <t.jager@gmx.de>
*/
#ifdef HAVE_CONFIG_H
@@ -114,12 +114,15 @@ typedef struct {
int use_shm;
XColor black;
- int yuv2rgb_brightness;
- int yuv2rgb_contrast;
- int yuv2rgb_saturation;
+ int brightness;
+ int contrast;
+ int saturation;
uint8_t *yuv2rgb_cmap;
yuv2rgb_factory_t *yuv2rgb_factory;
+ /* color matrix switching */
+ int cm_active, cm_state;
+
vo_scale_t sc;
xshm_frame_t *cur_frame;
@@ -148,11 +151,16 @@ typedef struct {
} xshm_class_t;
+/* import common color matrix stuff */
+#define CM_DRIVER_T xshm_driver_t
+#include "color_matrix.c"
+
static int gX11Fail;
/*
* first, some utility functions
*/
+
/* called xlocked */
static int HandleXError (Display *display, XErrorEvent *xevent) {
char str [1024];
@@ -328,7 +336,7 @@ static void dispose_ximage (xshm_driver_t *this,
static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) {
xshm_driver_t *this = (xshm_driver_t *) this_gen;
uint32_t capabilities = VO_CAP_CROP | VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS
- | VO_CAP_CONTRAST | VO_CAP_SATURATION;
+ | VO_CAP_CONTRAST | VO_CAP_SATURATION | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE;
if( this->xoverlay )
capabilities |= VO_CAP_UNSCALED_OVERLAY;
@@ -513,12 +521,21 @@ static void xshm_frame_proc_setup (vo_frame_t *vo_img) {
if (i + frame->sc.crop_bottom < 0)
frame->crop_flush -= 16 * vo_img->pitches[0];
+ /* switch color matrix/range */
+ i = cm_from_frame (vo_img);
+ if (i != this->cm_active) {
+ this->cm_active = i;
+ this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
+ this->brightness, this->contrast, this->saturation, i);
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "video_out_xshm: b %d c %d s %d [%s]\n",
+ this->brightness, this->contrast, this->saturation, cm_names[i]);
+ }
}
static void xshm_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) {
xshm_frame_t *frame = (xshm_frame_t *) vo_img ;
uint8_t *src0;
- /*xshm_driver_t *this = (xshm_driver_t *) vo_img->driver; */
/* delayed setup */
if (!vo_img->proc_called) {
@@ -908,11 +925,11 @@ static int xshm_get_property (vo_driver_t *this_gen, int property) {
case VO_PROP_MAX_NUM_FRAMES:
return 15;
case VO_PROP_BRIGHTNESS:
- return this->yuv2rgb_brightness;
+ return this->brightness;
case VO_PROP_CONTRAST:
- return this->yuv2rgb_contrast;
+ return this->contrast;
case VO_PROP_SATURATION:
- return this->yuv2rgb_saturation;
+ return this->saturation;
case VO_PROP_WINDOW_WIDTH:
return this->sc.gui_width;
case VO_PROP_WINDOW_HEIGHT:
@@ -947,32 +964,20 @@ static int xshm_set_property (vo_driver_t *this_gen,
break;
case VO_PROP_BRIGHTNESS:
- this->yuv2rgb_brightness = value;
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->brightness = value;
+ this->cm_active = 0;
this->sc.force_redraw = 1;
break;
case VO_PROP_CONTRAST:
- this->yuv2rgb_contrast = value;
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->contrast = value;
+ this->cm_active = 0;
this->sc.force_redraw = 1;
break;
case VO_PROP_SATURATION:
- this->yuv2rgb_saturation = value;
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ this->saturation = value;
+ this->cm_active = 0;
this->sc.force_redraw = 1;
break;
@@ -1102,6 +1107,8 @@ static void xshm_dispose (vo_driver_t *this_gen) {
this->yuv2rgb_factory->dispose (this->yuv2rgb_factory);
+ cm_close (this);
+
LOCK_DISPLAY(this);
XFreeGC(this->display, this->gc);
UNLOCK_DISPLAY(this);
@@ -1358,17 +1365,13 @@ static vo_driver_t *xshm_open_plugin_2 (video_driver_class_t *class_gen, const v
return NULL;
}
- this->yuv2rgb_brightness = 0;
- this->yuv2rgb_contrast = 128;
- this->yuv2rgb_saturation = 128;
-
- this->yuv2rgb_factory = yuv2rgb_factory_init (mode, swapped,
- this->yuv2rgb_cmap);
- this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory,
- this->yuv2rgb_brightness,
- this->yuv2rgb_contrast,
- this->yuv2rgb_saturation,
- CM_DEFAULT);
+ cm_init (this);
+
+ this->brightness = 0;
+ this->contrast = 128;
+ this->saturation = 128;
+
+ this->yuv2rgb_factory = yuv2rgb_factory_init (mode, swapped, this->yuv2rgb_cmap);
LOCK_DISPLAY(this);
this->xoverlay = x11osd_create (this->xine, this->display, this->screen,
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index a17017b7f..1a546d2b5 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.c
@@ -156,6 +156,9 @@ struct xv_driver_s {
void *user_data;
+ /* color matrix switching */
+ int cm_active, cm_state;
+ Atom cm_atom;
};
typedef struct {
@@ -165,6 +168,10 @@ typedef struct {
xine_t *xine;
} xv_class_t;
+/* import common color matrix stuff */
+#define CM_DRIVER_T xv_driver_t
+#include "color_matrix.c"
+
static int gX11Fail;
VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES;
@@ -669,10 +676,24 @@ static double timeOfDay()
static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
xv_frame_t *frame = (xv_frame_t *) frame_gen;
+ int cm;
/*
printf (LOG_MODULE ": xv_display_frame...\n");
*/
+ cm = cm_from_frame (frame_gen);
+ if (cm != this->cm_active) {
+ this->cm_active = cm;
+ cm = (0xc00c >> cm) & 1;
+ if (this->cm_atom != None) {
+ LOCK_DISPLAY(this);
+ XvSetPortAttribute (this->display, this->xv_port, this->cm_atom, cm);
+ UNLOCK_DISPLAY(this);
+ xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_xv: color_matrix %s\n",
+ cm_names[cm ? 2 : 10]);
+ }
+ }
+
/*
* queue frames (deinterlacing)
* free old frames
@@ -1035,6 +1056,8 @@ static void xv_dispose (vo_driver_t *this_gen) {
_x_alphablend_free(&this->alphablend_extra_data);
+ cm_close (this);
+
free (this);
}
@@ -1336,6 +1359,8 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
this->x11_old_error_handler = NULL;
this->xine = class->xine;
+ this->cm_atom = None;
+
LOCK_DISPLAY(this);
XAllocNamedColor (this->display,
DefaultColormap(this->display, this->screen),
@@ -1374,6 +1399,8 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
this->props[VO_PROP_ZOOM_X].value = 100;
this->props[VO_PROP_ZOOM_Y].value = 100;
+ cm_init (this);
+
/*
* check this adaptor's capabilities
*/
@@ -1419,6 +1446,15 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
xv_check_capability (this, VO_PROP_GAMMA, attr[k],
adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
+ } else if(!strcmp(name, "XV_ITURBT_709")) {
+ LOCK_DISPLAY(this);
+ this->cm_atom = XInternAtom (this->display, name, False);
+ if (this->cm_atom != None) {
+ XvGetPortAttribute (this->display, this->xv_port, this->cm_atom, &this->cm_active);
+ this->cm_active = this->cm_active ? 2 : 10;
+ this->capabilities |= VO_CAP_COLOR_MATRIX;
+ }
+ UNLOCK_DISPLAY(this);
} else if(!strcmp(name, "XV_COLORKEY")) {
this->capabilities |= VO_CAP_COLORKEY;
xv_check_capability (this, VO_PROP_COLORKEY, attr[k],