summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_out/video_out_vdpau.c183
1 files changed, 95 insertions, 88 deletions
diff --git a/src/video_out/video_out_vdpau.c b/src/video_out/video_out_vdpau.c
index 29f365a78..9bc7ba14a 100644
--- a/src/video_out/video_out_vdpau.c
+++ b/src/video_out/video_out_vdpau.c
@@ -413,7 +413,6 @@ typedef struct {
int honor_progressive;
int skip_chroma;
int sd_only_properties;
- int studio_levels;
int background;
int vdp_runtime_nr;
@@ -424,8 +423,16 @@ typedef struct {
int allocated_surfaces;
int zoom_x;
int zoom_y;
+
+ int color_matrix;
+ int update_csc;
+ int cm_state;
} vdpau_driver_t;
+/* import common color matrix stuff */
+#define CM_DRIVER_T vdpau_driver_t
+#include "color_matrix.c"
+
typedef struct {
video_driver_class_t driver_class;
@@ -1322,7 +1329,7 @@ static int vdpau_redraw_needed (vo_driver_t *this_gen)
_x_vo_scale_compute_output_size( &this->sc );
return 1;
}
- return 0;
+ return this->update_csc;
}
@@ -1587,71 +1594,81 @@ static void vdpau_update_sd_only_properties( void *this_gen, xine_cfg_entry_t *e
-static void vdpau_update_csc( vdpau_driver_t *this_gen )
-{
- float hue = this_gen->hue/100.0;
- float saturation = this_gen->saturation/100.0;
- float contrast = this_gen->contrast/100.0;
- float brightness = this_gen->brightness/100.0;
-
- fprintf(stderr, "vo_vdpau: vdpau_update_csc: hue=%f, saturation=%f, contrast=%f, brightness=%f, color_standard=%d studio_levels=%d\n", hue, saturation, contrast, brightness, this_gen->color_standard, this_gen->studio_levels );
+static void vdpau_update_csc_matrix (vdpau_driver_t *that, vdpau_frame_t *frame) {
+ int color_matrix;
- VdpStatus st;
- VdpCSCMatrix matrix;
- VdpProcamp procamp = { VDP_PROCAMP_VERSION, brightness, contrast, saturation, hue };
+ color_matrix = cm_from_frame (&frame->vo_frame);
- if ( this_gen->studio_levels ) {
+ if ( that->update_csc || that->color_matrix != color_matrix ) {
+ VdpStatus st;
+ VdpCSCMatrix matrix;
+ float hue = (float)that->hue * 3.14159265359 / 128.0;
+ float saturation = (float)that->saturation / 128.0;
+ float contrast = (float)that->contrast / 128.0;
+ float brightness = that->brightness;
+ float uvcos = saturation * cos( hue );
+ float uvsin = saturation * sin( hue );
+ float kb, kr;
+ float vr, vg, ug, ub;
+ float ygain, yoffset;
int i;
- float Kr, Kg, Kb;
- float uvcos = procamp.saturation * cos(procamp.hue);
- float uvsin = procamp.saturation * sin(procamp.hue);
- int rgbmin = 16;
- int rgbr = 235 - 16;
- switch ( this_gen->color_standard ) {
- case VDP_COLOR_STANDARD_SMPTE_240M:
- Kr = 0.2122;
- Kg = 0.7013;
- Kb = 0.0865;
+
+ switch (color_matrix >> 1) {
+ case 1: kb = 0.0722; kr = 0.2126; /* ITU-R 709 */
+ that->color_standard = VDP_COLOR_STANDARD_ITUR_BT_709;
break;
- case VDP_COLOR_STANDARD_ITUR_BT_709:
- Kr = 0.2125;
- Kg = 0.7154;
- Kb = 0.0721;
+ case 4: kb = 0.1100; kr = 0.3000; /* FCC */
+ that->color_standard = VDP_COLOR_STANDARD_ITUR_BT_601;
break;
- case VDP_COLOR_STANDARD_ITUR_BT_601:
- default:
- Kr = 0.299;
- Kg = 0.587;
- Kb = 0.114;
+ case 7: kb = 0.0870; kr = 0.2120; /* SMPTE 240 */
+ that->color_standard = VDP_COLOR_STANDARD_SMPTE_240M;
break;
+ default: kb = 0.1140; kr = 0.2990; /* ITU-R 601 */
+ that->color_standard = VDP_COLOR_STANDARD_ITUR_BT_601;
}
- float uv_coeffs[3][2] = {{ 0.000, (rgbr / 112.0) * (1 - Kr) },
- {-(rgbr / 112.0) * (1 - Kb) * Kb / Kg, -(rgbr / 112.0) * (1 - Kr) * Kr / Kg },
- { (rgbr / 112.0) * (1 - Kb), 0.000 }};
- for (i = 0; i < 3; ++i) {
- matrix[i][3] = procamp.brightness;
- matrix[i][0] = rgbr * procamp.contrast / 219;
- matrix[i][3] += (-16 / 255.0) * matrix[i][0];
- matrix[i][1] = uv_coeffs[i][0] * uvcos + uv_coeffs[i][1] * uvsin;
- matrix[i][3] += (-128 / 255.0) * matrix[i][1];
- matrix[i][2] = uv_coeffs[i][0] * uvsin + uv_coeffs[i][1] * uvcos;
- matrix[i][3] += (-128 / 255.0) * matrix[i][2];
- matrix[i][3] += rgbmin / 255.0;
- matrix[i][3] += 0.5 - procamp.contrast / 2.0;
+ vr = 2.0 * (1.0 - kr);
+ vg = -2.0 * kr * (1.0 - kr) / (1.0 - kb - kr);
+ ug = -2.0 * kb * (1.0 - kb) / (1.0 - kb - kr);
+ ub = 2.0 * (1.0 - kb);
+
+ if (color_matrix & 1) {
+ /* fullrange mode */
+ yoffset = brightness;
+ ygain = contrast;
+ uvcos *= contrast * 255.0 / 254.0;
+ uvsin *= contrast * 255.0 / 254.0;
+ } else {
+ /* mpeg range */
+ yoffset = brightness - 16.0;
+ ygain = contrast * 255.0 / 219.0;
+ uvcos *= contrast * 255.0 / 224.0;
+ uvsin *= contrast * 255.0 / 224.0;
}
- }
- else {
- st = vdp_generate_csc_matrix( &procamp, this_gen->color_standard, &matrix );
- if ( st != VDP_STATUS_OK ) {
- fprintf(stderr, "vo_vdpau: error, can't generate csc matrix !!\n" );
- return;
+
+ /* matrix[rgb][yuv1] */
+ matrix[0][1] = -uvsin * vr;
+ matrix[0][2] = uvcos * vr;
+ matrix[1][1] = uvcos * ug - uvsin * vg;
+ matrix[1][2] = uvcos * vg + uvsin * ug;
+ matrix[2][1] = uvcos * ub;
+ matrix[2][2] = uvsin * ub;
+ for (i = 0; i < 3; i++) {
+ matrix[i][0] = ygain;
+ matrix[i][3] = (yoffset * ygain - 128.0 * (matrix[i][1] + matrix[i][2])) / 255.0;
}
+
+ that->color_matrix = color_matrix;
+ that->update_csc = 0;
+
+ VdpVideoMixerAttribute attributes [] = {VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX};
+ void* attribute_values[] = {&matrix};
+ st = vdp_video_mixer_set_attribute_values (that->video_mixer, 1, attributes, attribute_values);
+ if (st != VDP_STATUS_OK)
+ fprintf (stderr, "vo_vdpau: error, can't set csc matrix !!\n");
+
+ xprintf (that->xine, XINE_VERBOSITY_LOG,"video_out_vdpau: b %d c %d s %d h %d [%s]\n",
+ that->brightness, that->contrast, that->saturation, that->hue, cm_names[color_matrix]);
}
- VdpVideoMixerAttribute attributes [] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX };
- void* attribute_values[] = { &matrix };
- st = vdp_video_mixer_set_attribute_values( this_gen->video_mixer, 1, attributes, attribute_values );
- if ( st != VDP_STATUS_OK )
- fprintf(stderr, "vo_vdpau: error, can't set csc matrix !!\n" );
}
@@ -1681,15 +1698,6 @@ static void vdpau_set_skip_chroma( void *this_gen, xine_cfg_entry_t *entry )
-static void vdpau_set_studio_levels( void *this_gen, xine_cfg_entry_t *entry )
-{
- vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
- this->studio_levels = entry->num_value;
- vdpau_update_csc( this );
-}
-
-
-
static void vdpau_update_background( vdpau_driver_t *this_gen )
{
if ( !this_gen->background_is_supported )
@@ -1971,16 +1979,12 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
vdpau_update_noise( this );
vdpau_update_sharpness( this );
this->color_standard = color_standard;
- vdpau_update_csc( this );
+ this->update_csc = 1;
vdpau_update_skip_chroma( this );
vdpau_update_background( this );
}
- if (color_standard != this->color_standard) {
- lprintf("vo_vdpau: update color_standard: %d\n", color_standard);
- this->color_standard = color_standard;
- vdpau_update_csc( this );
- }
+ vdpau_update_csc_matrix (this, frame);
if (this->ovl_changed || redraw_needed)
vdpau_process_overlays(this);
@@ -2192,10 +2196,10 @@ static int vdpau_set_property (vo_driver_t *this_gen, int property, int value)
this->sc.user_ratio = value;
this->sc.force_redraw = 1; /* trigger re-calc of output size */
break;
- case VO_PROP_HUE: this->hue = value; vdpau_update_csc( this ); break;
- case VO_PROP_SATURATION: this->saturation = value; vdpau_update_csc( this ); break;
- case VO_PROP_CONTRAST: this->contrast = value; vdpau_update_csc( this ); break;
- case VO_PROP_BRIGHTNESS: this->brightness = value; vdpau_update_csc( this ); break;
+ case VO_PROP_HUE: this->hue = value; this->update_csc = 1; break;
+ case VO_PROP_SATURATION: this->saturation = value; this->update_csc = 1; break;
+ case VO_PROP_CONTRAST: this->contrast = value; this->update_csc = 1; break;
+ case VO_PROP_BRIGHTNESS: this->brightness = value; this->update_csc = 1; break;
case VO_PROP_SHARPNESS: this->sharpness = value; vdpau_update_sharpness( this ); break;
case VO_PROP_NOISE_REDUCTION: this->noise = value; vdpau_update_noise( this ); break;
}
@@ -2209,13 +2213,13 @@ static void vdpau_get_property_min_max (vo_driver_t *this_gen, int property, int
{
switch ( property ) {
case VO_PROP_HUE:
- *max = 314; *min = -314; break;
+ *max = 127; *min = -128; break;
case VO_PROP_SATURATION:
- *max = 1000; *min = 0; break;
+ *max = 255; *min = 0; break;
case VO_PROP_CONTRAST:
- *max = 1000; *min = 0; break;
+ *max = 255; *min = 0; break;
case VO_PROP_BRIGHTNESS:
- *max = 100; *min = -100; break;
+ *max = 127; *min = -128; break;
case VO_PROP_SHARPNESS:
*max = 100; *min = -100; break;
case VO_PROP_NOISE_REDUCTION:
@@ -2406,6 +2410,8 @@ static void vdpau_dispose (vo_driver_t *this_gen)
vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
int i;
+ cm_close (this);
+
if ( vdp_queue != VDP_INVALID_HANDLE )
vdp_queue_destroy( vdp_queue );
@@ -2589,7 +2595,7 @@ static void vdpau_reinit( vo_driver_t *this_gen )
vdpau_set_inverse_telecine( this_gen );
vdpau_update_noise( this );
vdpau_update_sharpness( this );
- vdpau_update_csc( this );
+ this->update_csc = 1;
vdpau_update_skip_chroma( this );
vdpau_update_background( this );
@@ -3131,11 +3137,6 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
10, vdpau_set_skip_chroma, this );
}
- this->studio_levels = config->register_bool( config, "video.output.vdpau_studio_levels", 0,
- _("vdpau: disable studio level"),
- _("Setting to true enables studio levels (16-219) instead of PC levels (0-255) in RGB colors.\n\n"),
- 10, vdpau_set_studio_levels, this );
-
if ( this->background_is_supported ) {
this->background = config->register_num( config, "video.output.vdpau_background_color", 0,
_("vdpau: color of none video area in output window"),
@@ -3218,14 +3219,20 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
for ( i=0; i<NUM_FRAMES_BACK; i++)
this->back_frame[i] = NULL;
+ this->capabilities |= VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE;
+
this->hue = 0;
- this->saturation = 100;
- this->contrast = 100;
+ this->saturation = 128;
+ this->contrast = 128;
this->brightness = 0;
this->sharpness = 0;
this->noise = 0;
this->deinterlace = 0;
+ this->update_csc = 1;
+ this->color_matrix = 10;
+ cm_init (this);
+
this->allocated_surfaces = 0;
this->vdp_runtime_nr = 1;