summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
Diffstat (limited to 'libvo')
-rw-r--r--libvo/csputils.c98
-rw-r--r--libvo/csputils.h76
-rw-r--r--libvo/video_out.h6
-rw-r--r--libvo/vo_gl.c121
-rw-r--r--libvo/vo_gl2.c2
-rw-r--r--libvo/vo_vdpau.c91
-rw-r--r--libvo/vo_xv.c14
7 files changed, 241 insertions, 167 deletions
diff --git a/libvo/csputils.c b/libvo/csputils.c
index 831e5c774a..6656e5e196 100644
--- a/libvo/csputils.c
+++ b/libvo/csputils.c
@@ -32,6 +32,27 @@
#include "csputils.h"
+char * const mp_csp_names[MP_CSP_COUNT] = {
+ "Autoselect",
+ "BT.601 (SD)",
+ "BT.709 (HD)",
+ "SMPTE-240M",
+};
+
+char * const mp_csp_equalizer_names[MP_CSP_EQ_COUNT] = {
+ "brightness",
+ "contrast",
+ "hue",
+ "saturation",
+ "gamma",
+};
+
+
+enum mp_csp mp_csp_guess_colorspace(int width, int height)
+{
+ return width >= 1280 || height > 576 ? MP_CSP_BT_709 : MP_CSP_BT_601;
+}
+
/**
* \brief little helper function to create a lookup table for gamma
* \param map buffer to create map into
@@ -98,8 +119,8 @@ static void luma_coeffs(float m[3][4], float lr, float lg, float lb)
*/
void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4])
{
- int format = params->format;
- if (format <= MP_CSP_DEFAULT || format >= MP_CSP_COUNT)
+ int format = params->colorspace.format;
+ if (format <= MP_CSP_AUTO || format >= MP_CSP_COUNT)
format = MP_CSP_BT_601;
switch (format) {
case MP_CSP_BT_601: luma_coeffs(m, 0.299, 0.587, 0.114 ); break;
@@ -119,25 +140,35 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4])
m[i][COL_V] = huesin * u + huecos * m[i][COL_V];
}
- int levelconv = params->levelconv;
- if (levelconv < 0 || levelconv >= MP_CSP_LEVELCONV_COUNT)
- levelconv = MP_CSP_LEVELCONV_TV_TO_PC;
+ int levels_in = params->colorspace.levels_in;
+ if (levels_in <= MP_CSP_LEVELS_AUTO || levels_in >= MP_CSP_LEVELS_COUNT)
+ levels_in = MP_CSP_LEVELS_TV;
// The values below are written in 0-255 scale
struct yuvlevels { double ymin, ymax, cmin, cmid; }
yuvlim = { 16, 235, 16, 128 },
- yuvfull = { 16, 235, 1, 128 }, // '1' to make it symmetric around 128
+ yuvfull = { 0, 255, 1, 128 }, // '1' to make it symmetric around 128
yuvlev;
+ switch (levels_in) {
+ case MP_CSP_LEVELS_TV: yuvlev = yuvlim; break;
+ case MP_CSP_LEVELS_PC: yuvlev = yuvfull; break;
+ default:
+ abort();
+ }
+
+ int levels_out = params->colorspace.levels_out;
+ if (levels_out <= MP_CSP_LEVELS_AUTO || levels_out >= MP_CSP_LEVELS_COUNT)
+ levels_out = MP_CSP_LEVELS_PC;
struct rgblevels { double min, max; }
rgblim = { 16, 235 },
rgbfull = { 0, 255 },
rgblev;
- switch (levelconv) {
- case MP_CSP_LEVELCONV_TV_TO_PC: yuvlev = yuvlim; rgblev = rgbfull; break;
- case MP_CSP_LEVELCONV_PC_TO_TV: yuvlev = yuvfull; rgblev = rgblim; break;
- case MP_CSP_LEVELCONV_TV_TO_TV: yuvlev = yuvlim; rgblev = rgblim; break;
+ switch (levels_out) {
+ case MP_CSP_LEVELS_TV: rgblev = rgblim; break;
+ case MP_CSP_LEVELS_PC: rgblev = rgbfull; break;
default:
abort();
}
+
double ymul = (rgblev.max - rgblev.min) / (yuvlev.ymax - yuvlev.ymin);
double cmul = (rgblev.max - rgblev.min) / (yuvlev.cmid - yuvlev.cmin) / 2;
for (int i = 0; i < 3; i++) {
@@ -205,3 +236,50 @@ void mp_gen_yuv2rgb_map(struct mp_csp_params *params, unsigned char *map, int si
v += (i == -1 || i == size - 1) ? step / 2 : step;
}
}
+
+// Copy settings from eq into params.
+void mp_csp_copy_equalizer_values(struct mp_csp_params *params,
+ const struct mp_csp_equalizer *eq)
+{
+ params->brightness = eq->values[MP_CSP_EQ_BRIGHTNESS] / 100.0;
+ params->contrast = (eq->values[MP_CSP_EQ_CONTRAST] + 100) / 100.0;
+ params->hue = eq->values[MP_CSP_EQ_HUE] / 100.0 * 3.1415927;
+ params->saturation = (eq->values[MP_CSP_EQ_SATURATION] + 100) / 100.0;
+ float gamma = exp(log(8.0) * eq->values[MP_CSP_EQ_GAMMA] / 100.0);
+ params->rgamma = gamma;
+ params->ggamma = gamma;
+ params->bgamma = gamma;
+}
+
+static int find_eq(int capabilities, const char *name)
+{
+ for (int i = 0; i < MP_CSP_EQ_COUNT; i++) {
+ if (strcmp(name, mp_csp_equalizer_names[i]) == 0)
+ return ((1 << i) & capabilities) ? i : -1;
+ }
+ return -1;
+}
+
+int mp_csp_equalizer_get(struct mp_csp_equalizer *eq, const char *property,
+ int *out_value)
+{
+ int index = find_eq(eq->capabilities, property);
+ if (index < 0)
+ return -1;
+
+ *out_value = eq->values[index];
+
+ return 0;
+}
+
+int mp_csp_equalizer_set(struct mp_csp_equalizer *eq, const char *property,
+ int value)
+{
+ int index = find_eq(eq->capabilities, property);
+ if (index < 0)
+ return 0;
+
+ eq->values[index] = value;
+
+ return 1;
+}
diff --git a/libvo/csputils.h b/libvo/csputils.h
index 93f9ca0316..3a754a8273 100644
--- a/libvo/csputils.h
+++ b/libvo/csputils.h
@@ -26,24 +26,41 @@
#include <stdint.h>
-enum mp_csp_standard {
- MP_CSP_DEFAULT,
+
+/* NOTE: the csp and levels AUTO values are converted to specific ones
+ * above vf/vo level. At least vf_scale relies on all valid settings being
+ * nonzero at vf/vo level.
+ */
+
+enum mp_csp {
+ MP_CSP_AUTO,
MP_CSP_BT_601,
MP_CSP_BT_709,
MP_CSP_SMPTE_240M,
MP_CSP_COUNT
};
-enum mp_csp_levelconv {
- MP_CSP_LEVELCONV_TV_TO_PC,
- MP_CSP_LEVELCONV_PC_TO_TV,
- MP_CSP_LEVELCONV_TV_TO_TV,
- MP_CSP_LEVELCONV_COUNT
+// Any enum mp_csp value is a valid index (except MP_CSP_COUNT)
+extern char * const mp_csp_names[MP_CSP_COUNT];
+
+enum mp_csp_levels {
+ MP_CSP_LEVELS_AUTO,
+ MP_CSP_LEVELS_TV,
+ MP_CSP_LEVELS_PC,
+ MP_CSP_LEVELS_COUNT,
+};
+
+struct mp_csp_details {
+ enum mp_csp format;
+ enum mp_csp_levels levels_in; // encoded video
+ enum mp_csp_levels levels_out; // output device
};
+// initializer for struct mp_csp_details that contains reasonable defaults
+#define MP_CSP_DETAILS_DEFAULTS {MP_CSP_BT_601, MP_CSP_LEVELS_TV, MP_CSP_LEVELS_PC}
+
struct mp_csp_params {
- enum mp_csp_standard format;
- enum mp_csp_levelconv levelconv;
+ struct mp_csp_details colorspace;
float brightness;
float contrast;
float hue;
@@ -54,6 +71,47 @@ struct mp_csp_params {
int input_shift;
};
+enum mp_csp_equalizer_param {
+ MP_CSP_EQ_BRIGHTNESS,
+ MP_CSP_EQ_CONTRAST,
+ MP_CSP_EQ_HUE,
+ MP_CSP_EQ_SATURATION,
+ MP_CSP_EQ_GAMMA,
+ MP_CSP_EQ_COUNT,
+};
+
+#define MP_CSP_EQ_CAPS_COLORMATRIX \
+ ( (1 << MP_CSP_EQ_BRIGHTNESS) \
+ | (1 << MP_CSP_EQ_CONTRAST) \
+ | (1 << MP_CSP_EQ_HUE) \
+ | (1 << MP_CSP_EQ_SATURATION) )
+
+#define MP_CSP_EQ_CAPS_GAMMA (1 << MP_CSP_EQ_GAMMA)
+
+extern char * const mp_csp_equalizer_names[MP_CSP_EQ_COUNT];
+
+// Default initialization with 0 is enough, except for the capabilities field
+struct mp_csp_equalizer {
+ // Bit field of capabilities. For example (1 << MP_CSP_EQ_HUE) means hue
+ // support is available.
+ int capabilities;
+ // Value for each property is in the range [-100, 100].
+ // 0 is default, meaning neutral or no change.
+ int values[MP_CSP_EQ_COUNT];
+};
+
+
+void mp_csp_copy_equalizer_values(struct mp_csp_params *params,
+ const struct mp_csp_equalizer *eq);
+
+int mp_csp_equalizer_set(struct mp_csp_equalizer *eq, const char *property,
+ int value);
+
+int mp_csp_equalizer_get(struct mp_csp_equalizer *eq, const char *property,
+ int *out_value);
+
+enum mp_csp mp_csp_guess_colorspace(int width, int height);
+
void mp_gen_gamma_map(unsigned char *map, int size, float gamma);
#define ROW_R 0
#define ROW_G 1
diff --git a/libvo/video_out.h b/libvo/video_out.h
index ca249819ff..d1a2a7f65a 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -76,8 +76,8 @@ enum mp_voctrl {
VOCTRL_UPDATE_SCREENINFO,
- VOCTRL_SET_YUV_COLORSPACE,
- VOCTRL_GET_YUV_COLORSPACE,
+ VOCTRL_SET_YUV_COLORSPACE, // struct mp_csp_details
+ VOCTRL_GET_YUV_COLORSPACE, // struct mp_csp_details
};
// VOCTRL_SET_EQUALIZER
@@ -98,7 +98,7 @@ typedef struct {
uint16_t r,g,b;
} mp_colorkey_t;
-//VOCTRL_GET_EOSD_RES
+// VOCTRL_GET_EOSD_RES
typedef struct mp_eosd_res {
int w, h; // screen dimensions, including black borders
int mt, mb, ml, mr; // borders (top, bottom, left, right)
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index cefa30cba3..cb1ccc593b 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <stdbool.h>
#include "config.h"
#include "mp_msg.h"
@@ -129,8 +130,9 @@ static int use_ycbcr;
#define MASK_NOT_COMBINERS (~((1 << YUV_CONVERSION_NONE) | (1 << YUV_CONVERSION_COMBINERS)))
#define MASK_GAMMA_SUPPORT (MASK_NOT_COMBINERS & ~(1 << YUV_CONVERSION_FRAGMENT))
static int use_yuv;
-static int colorspace;
-static int levelconv;
+static struct mp_csp_details colorspace = MP_CSP_DETAILS_DEFAULTS;
+static int user_colorspace; //essentially unused; legacy warning
+static int levelconv; //essentially unused; legacy warning
static int is_yuv;
static int lscale;
static int cscale;
@@ -169,13 +171,8 @@ static int mipmap_gen;
static int stereo_mode;
static int int_pause;
-static int eq_bri = 0;
-static int eq_cont = 0;
-static int eq_sat = 0;
-static int eq_hue = 0;
-static int eq_rgamma = 0;
-static int eq_ggamma = 0;
-static int eq_bgamma = 0;
+
+static struct mp_csp_equalizer video_eq;
static int texture_width;
static int texture_height;
@@ -248,15 +245,9 @@ static void texSize(int w, int h, int *texw, int *texh) {
#define MAX_CUSTOM_PROG_SIZE (1024 * 1024)
static void update_yuvconv(void) {
int xs, ys, depth;
- float bri = eq_bri / 100.0;
- float cont = (eq_cont + 100) / 100.0;
- float hue = eq_hue / 100.0 * 3.1415927;
- float sat = (eq_sat + 100) / 100.0;
- float rgamma = exp(log(8.0) * eq_rgamma / 100.0);
- 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, levelconv, bri, cont, hue, sat, rgamma, ggamma, bgamma, 0},
+ struct mp_csp_params cparams = { .colorspace = colorspace };
+ mp_csp_copy_equalizer_values(&cparams, &video_eq);
+ gl_conversion_params_t params = {gl_target, yuvconvtype, cparams,
texture_width, texture_height, 0, 0, filter_strength};
mp_get_chroma_shift(image_format, &xs, &ys, &depth);
params.chrom_texw = params.texw >> xs;
@@ -521,6 +512,19 @@ static void autodetectGlExtensions(void) {
use_osd = mpglBindTexture != NULL;
if (use_yuv == -1)
use_yuv = glAutodetectYUVConversion();
+
+ int eq_caps = 0;
+ int yuv_mask = (1 << use_yuv);
+ if (!(yuv_mask & MASK_NOT_COMBINERS)) {
+ // combiners
+ eq_caps = (1 << MP_CSP_EQ_HUE) | (1 << MP_CSP_EQ_SATURATION);
+ } else if (yuv_mask & MASK_ALL_YUV) {
+ eq_caps = MP_CSP_EQ_CAPS_COLORMATRIX;
+ if (yuv_mask & MASK_GAMMA_SUPPORT)
+ eq_caps |= MP_CSP_EQ_CAPS_GAMMA;
+ }
+ video_eq.capabilities = eq_caps;
+
if (is_ati && (lscale == 1 || lscale == 2 || cscale == 1 || cscale == 2))
mp_msg(MSGT_VO, MSGL_WARN, "[gl] Selected scaling mode may be broken on ATI cards.\n"
"Tell _them_ to fix GL_REPEAT if you have issues.\n");
@@ -1133,18 +1137,6 @@ uninit(void)
uninit_mpglcontext(&glctx);
}
-static int valid_csp(void *p)
-{
- int *csp = 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},
@@ -1154,8 +1146,8 @@ static const opt_t subopts[] = {
{"slice-height", OPT_ARG_INT, &slice_height, int_non_neg},
{"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},
+ {"colorspace", OPT_ARG_INT, &user_colorspace, NULL},
+ {"levelconv", OPT_ARG_INT, &levelconv, NULL},
{"lscale", OPT_ARG_INT, &lscale, int_non_neg},
{"cscale", OPT_ARG_INT, &cscale, int_non_neg},
{"filter-strength", OPT_ARG_FLOAT, &filter_strength, NULL},
@@ -1184,7 +1176,7 @@ static int preinit_internal(const char *arg, int allow_sw)
use_aspect = 1;
use_ycbcr = 0;
use_yuv = -1;
- colorspace = -1;
+ user_colorspace = 0;
levelconv = -1;
lscale = 0;
cscale = 0;
@@ -1242,17 +1234,6 @@ static int preinit_internal(const char *arg, int allow_sw)
" 4: use fragment program with gamma correction via lookup.\n"
" 5: use ATI-specific method (for older cards).\n"
" 6: use lookup via 3D texture.\n"
- " colorspace=<n>\n"
- " 0: MPlayer's default YUV to RGB conversion\n"
- " 1: YUV to RGB according to BT.601\n"
- " 2: YUV to RGB according to BT.709\n"
- " 3: YUV to RGB according to SMPT-240M\n"
- " 4: YUV to RGB according to EBU\n"
- " 5: XYZ to RGB\n"
- " levelconv=<n>\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>\n"
" 0: use standard bilinear scaling for luma.\n"
" 1: use improved bicubic scaling for luma.\n"
@@ -1284,6 +1265,12 @@ static int preinit_internal(const char *arg, int allow_sw)
"\n" );
return -1;
}
+ if (user_colorspace != 0 || levelconv != -1) {
+ mp_msg(MSGT_VO, MSGL_ERR, "[gl] \"colorspace\" and \"levelconv\" "
+ "suboptions have been removed. Use options --colormatrix and"
+ " --colormatrix-input-range/--colormatrix-output-range instead.\n");
+ return -1;
+ }
if (!init_mpglcontext(&glctx, gltype))
goto err_out;
if (use_yuv == -1 || !allow_sw) {
@@ -1318,22 +1305,6 @@ static int preinit_nosw(const char *arg)
return preinit_internal(arg, 0);
}
-static const struct {
- const char *name;
- int *value;
- int supportmask;
-} eq_map[] = {
- {"brightness", &eq_bri, MASK_NOT_COMBINERS},
- {"contrast", &eq_cont, MASK_NOT_COMBINERS},
- {"saturation", &eq_sat, MASK_ALL_YUV },
- {"hue", &eq_hue, MASK_ALL_YUV },
- {"gamma", &eq_rgamma, MASK_GAMMA_SUPPORT},
- {"red_gamma", &eq_rgamma, MASK_GAMMA_SUPPORT},
- {"green_gamma", &eq_ggamma, MASK_GAMMA_SUPPORT},
- {"blue_gamma", &eq_bgamma, MASK_GAMMA_SUPPORT},
- {NULL, NULL, 0 }
-};
-
static int control(uint32_t request, void *data)
{
switch (request) {
@@ -1386,30 +1357,30 @@ static int control(uint32_t request, void *data)
case VOCTRL_GET_EQUALIZER:
if (is_yuv) {
struct voctrl_get_equalizer_args *args = data;
- int i;
- for (i = 0; eq_map[i].name; i++)
- if (strcmp(args->name, eq_map[i].name) == 0) break;
- if (!(eq_map[i].supportmask & (1 << use_yuv)))
- break;
- *args->valueptr = *eq_map[i].value;
- return VO_TRUE;
+ return mp_csp_equalizer_get(&video_eq, args->name, args->valueptr) >= 0 ?
+ VO_TRUE : VO_NOTIMPL;
}
break;
case VOCTRL_SET_EQUALIZER:
if (is_yuv) {
struct voctrl_set_equalizer_args *args = data;
- int i;
- for (i = 0; eq_map[i].name; i++)
- if (strcmp(args->name, eq_map[i].name) == 0) break;
- if (!(eq_map[i].supportmask & (1 << use_yuv)))
- break;
- *eq_map[i].value = args->value;
- if (strcmp(args->name, "gamma") == 0)
- eq_rgamma = eq_ggamma = eq_bgamma = args->value;
+ if (mp_csp_equalizer_set(&video_eq, args->name, args->value) < 0)
+ return VO_NOTIMPL;
update_yuvconv();
return VO_TRUE;
}
break;
+ case VOCTRL_SET_YUV_COLORSPACE: {
+ bool supports_csp = (1 << use_yuv) & MASK_NOT_COMBINERS;
+ if (vo_config_count && supports_csp) {
+ colorspace = *(struct mp_csp_details *)data;
+ update_yuvconv();
+ }
+ return VO_TRUE;
+ }
+ case VOCTRL_GET_YUV_COLORSPACE:
+ *(struct mp_csp_details *)data = colorspace;
+ return VO_TRUE;
case VOCTRL_UPDATE_SCREENINFO:
glctx.update_xinerama_info();
return VO_TRUE;
diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c
index ac1d957136..6dd9597412 100644
--- a/libvo/vo_gl2.c
+++ b/libvo/vo_gl2.c
@@ -565,7 +565,7 @@ static int initGl(uint32_t d_width, uint32_t d_height)
if (is_yuv) {
int xs, ys, depth;
gl_conversion_params_t params = {GL_TEXTURE_2D, use_yuv,
- {-1, -1, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0},
+ { { -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:
diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c
index f487b3b2a3..322645ebd3 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -41,6 +41,7 @@
#include "video_out.h"
#include "x11_common.h"
#include "aspect.h"
+#include "csputils.h"
#include "sub/sub.h"
#include "subopt-helper.h"
#include "libmpcodecs/vfcap.h"
@@ -124,9 +125,7 @@ struct vdpctx {
int output_surface_width, output_surface_height;
VdpVideoMixer video_mixer;
- int user_colorspace;
- int colorspace;
- int studio_levels;
+ struct mp_csp_details colorspace;
int deint;
int deint_type;
int deint_counter;
@@ -190,7 +189,7 @@ struct vdpctx {
int eosd_render_count;
// Video equalizer
- VdpProcamp procamp;
+ struct mp_csp_equalizer video_eq;
int num_shown_frames;
bool paused;
@@ -574,33 +573,16 @@ static int set_video_attribute(struct vdpctx *vc, VdpVideoMixerAttribute attr,
static void update_csc_matrix(struct vo *vo)
{
struct vdpctx *vc = vo->priv;
- struct vdp_functions *vdp = vc->vdp;
- VdpStatus vdp_st;
- const VdpColorStandard vdp_colors[] = {VDP_COLOR_STANDARD_ITUR_BT_601,
- VDP_COLOR_STANDARD_ITUR_BT_709,
- VDP_COLOR_STANDARD_SMPTE_240M};
- char * const vdp_names[] = {"BT.601", "BT.709", "SMPTE-240M"};
- int csp = vc->colorspace;
- mp_msg(MSGT_VO, MSGL_V, "[vdpau] Updating CSC matrix for %s\n",
- vdp_names[csp]);
+ mp_msg(MSGT_VO, MSGL_V, "[vdpau] Updating CSC matrix\n");
+ // VdpCSCMatrix happens to be compatible with mplayer's CSC matrix type
+ // both are float[3][4]
VdpCSCMatrix matrix;
- vdp_st = vdp->generate_csc_matrix(&vc->procamp, vdp_colors[csp], &matrix);
- CHECK_ST_WARNING("Error when generating CSC matrix");
-
- if (vc->studio_levels) {
- /* Modify matrix to change output range from 0..255 to 16..235.
- * Clipping limits can't be changed, so out-of-range results that
- * would have been clipped to 0 or 255 before can still go below
- * 16 or above 235.
- */
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 4; j++)
- matrix[i][j] *= 220. / 256;
- matrix[i][3] += 16. / 256;
- }
- }
+
+ struct mp_csp_params cparams = { .colorspace = vc->colorspace };
+ mp_csp_copy_equalizer_values(&cparams, &vc->video_eq);
+ mp_get_yuv2rgb_coeffs(&cparams, matrix);
set_video_attribute(vc, VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX,
&matrix, "CSC matrix");
@@ -886,10 +868,6 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
vc->image_format = format;
vc->vid_width = width;
vc->vid_height = height;
- if (vc->user_colorspace == 0)
- vc->colorspace = width >= 1280 || height > 576 ? 1 : 0;
- else
- vc->colorspace = vc->user_colorspace - 1;
free_video_specific(vo);
if (IMGFMT_IS_VDPAU(vc->image_format) && !create_vdp_decoder(vo, 2))
return -1;
@@ -1607,6 +1585,8 @@ static void uninit(struct vo *vo)
static int preinit(struct vo *vo, const char *arg)
{
int i;
+ int user_colorspace = 0;
+ int studio_levels = 0;
struct vdpctx *vc = talloc_zero(vo, struct vdpctx);
vo->priv = vc;
@@ -1615,20 +1595,21 @@ static int preinit(struct vo *vo, const char *arg)
// allocated
mark_vdpau_objects_uninitialized(vo);
+ vc->colorspace = (struct mp_csp_details) MP_CSP_DETAILS_DEFAULTS;
vc->deint_type = 3;
vc->chroma_deint = 1;
- vc->user_colorspace = 1;
vc->flip_offset_window = 50;
vc->flip_offset_fs = 50;
vc->num_output_surfaces = 3;
+ vc->video_eq.capabilities = MP_CSP_EQ_CAPS_COLORMATRIX;
const opt_t subopts[] = {
{"deint", OPT_ARG_INT, &vc->deint, NULL},
{"chroma-deint", OPT_ARG_BOOL, &vc->chroma_deint, NULL},
{"pullup", OPT_ARG_BOOL, &vc->pullup, NULL},
{"denoise", OPT_ARG_FLOAT, &vc->denoise, NULL},
{"sharpen", OPT_ARG_FLOAT, &vc->sharpen, NULL},
- {"colorspace", OPT_ARG_INT, &vc->user_colorspace, NULL},
- {"studio", OPT_ARG_BOOL, &vc->studio_levels, NULL},
+ {"colorspace", OPT_ARG_INT, &user_colorspace, NULL},
+ {"studio", OPT_ARG_BOOL, &studio_levels, NULL},
{"hqscaling", OPT_ARG_INT, &vc->hqscaling, NULL},
{"fps", OPT_ARG_FLOAT, &vc->user_fps, NULL},
{"queuetime_windowed", OPT_ARG_INT, &vc->flip_offset_window, NULL},
@@ -1650,6 +1631,12 @@ static int preinit(struct vo *vo, const char *arg)
"output_surfaces: can't use less than 2 surfaces\n");
return -1;
}
+ if (user_colorspace != 0 || studio_levels != 0) {
+ mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] \"colorspace\" and \"studio\""
+ " suboptions have been removed. Use options --colormatrix and"
+ " --colormatrix-output-range=limited instead.\n");
+ return -1;
+ }
if (vc->num_output_surfaces > MAX_OUTPUT_SURFACES) {
mp_msg(MSGT_VO, MSGL_WARN, "[vdpau] Number of output surfaces "
"is limited to %d.\n", MAX_OUTPUT_SURFACES);
@@ -1676,30 +1663,14 @@ static int preinit(struct vo *vo, const char *arg)
for (i = 0; i < PALETTE_SIZE; ++i)
vc->palette[i] = (i << 16) | (i << 8) | i;
- vc->procamp.struct_version = VDP_PROCAMP_VERSION;
- vc->procamp.brightness = 0.0;
- vc->procamp.contrast = 1.0;
- vc->procamp.saturation = 1.0;
- vc->procamp.hue = 0.0;
-
return 0;
}
static int get_equalizer(struct vo *vo, const char *name, int *value)
{
struct vdpctx *vc = vo->priv;
-
- if (!strcasecmp(name, "brightness"))
- *value = vc->procamp.brightness * 100;
- else if (!strcasecmp(name, "contrast"))
- *value = (vc->procamp.contrast - 1.0) * 100;
- else if (!strcasecmp(name, "saturation"))
- *value = (vc->procamp.saturation - 1.0) * 100;
- else if (!strcasecmp(name, "hue"))
- *value = vc->procamp.hue * 100 / M_PI;
- else
- return VO_NOTIMPL;
- return VO_TRUE;
+ return mp_csp_equalizer_get(&vc->video_eq, name, value) >= 0 ?
+ VO_TRUE : VO_NOTIMPL;
}
static bool status_ok(struct vo *vo)
@@ -1713,15 +1684,7 @@ static int set_equalizer(struct vo *vo, const char *name, int value)
{
struct vdpctx *vc = vo->priv;
- if (!strcasecmp(name, "brightness"))
- vc->procamp.brightness = value / 100.0;
- else if (!strcasecmp(name, "contrast"))
- vc->procamp.contrast = value / 100.0 + 1.0;
- else if (!strcasecmp(name, "saturation"))
- vc->procamp.saturation = value / 100.0 + 1.0;
- else if (!strcasecmp(name, "hue"))
- vc->procamp.hue = value / 100.0 * M_PI;
- else
+ if (mp_csp_equalizer_set(&vc->video_eq, name, value) < 0)
return VO_NOTIMPL;
if (status_ok(vo))
@@ -1798,12 +1761,12 @@ static int control(struct vo *vo, uint32_t request, void *data)
return get_equalizer(vo, args->name, args->valueptr);
}
case VOCTRL_SET_YUV_COLORSPACE:
- vc->colorspace = *(int *)data % 3;
+ vc->colorspace = *(struct mp_csp_details *)data;
if (status_ok(vo))
update_csc_matrix(vo);
return true;
case VOCTRL_GET_YUV_COLORSPACE:
- *(int *)data = vc->colorspace;
+ *(struct mp_csp_details *)data = vc->colorspace;
return true;
case VOCTRL_ONTOP:
vo_x11_ontop(vo);
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 64324c9785..3c8b040195 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -58,6 +58,7 @@ Buffer allocation:
#include "fastmemcpy.h"
#include "sub/sub.h"
#include "aspect.h"
+#include "csputils.h"
#include "subopt-helper.h"
@@ -809,13 +810,16 @@ static int control(struct vo *vo, uint32_t request, void *data)
return vo_xv_get_eq(vo, x11->xv_port, args->name, args->valueptr);
}
case VOCTRL_SET_YUV_COLORSPACE:;
- int given_cspc = *(int *)data % 2;
- return vo_xv_set_eq(vo, x11->xv_port, "bt_709", given_cspc * 200 - 100);
+ struct mp_csp_details* given_cspc = data;
+ int is_709 = given_cspc->format == MP_CSP_BT_709;
+ vo_xv_set_eq(vo, x11->xv_port, "bt_709", is_709 * 200 - 100);
+ return true;
case VOCTRL_GET_YUV_COLORSPACE:;
+ struct mp_csp_details* cspc = data;
+ *cspc = (struct mp_csp_details) MP_CSP_DETAILS_DEFAULTS;
int bt709_enabled;
- if (!vo_xv_get_eq(vo, x11->xv_port, "bt_709", &bt709_enabled))
- return false;
- *(int *)data = bt709_enabled == 100;
+ if (vo_xv_get_eq(vo, x11->xv_port, "bt_709", &bt709_enabled))
+ cspc->format = bt709_enabled == 100 ? MP_CSP_BT_709 : MP_CSP_BT_601;
return true;
case VOCTRL_ONTOP:
vo_x11_ontop(vo);