aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--player/command.c8
-rw-r--r--sub/draw_bmp.c17
-rw-r--r--sub/sd_ass.c27
-rw-r--r--video/csputils.c19
-rw-r--r--video/csputils.h21
-rw-r--r--video/decode/vd_lavc.c10
-rw-r--r--video/filter/vf_d3d11vpp.c12
-rw-r--r--video/filter/vf_format.c10
-rw-r--r--video/filter/vf_scale.c4
-rw-r--r--video/filter/vf_vapoursynth.c6
-rw-r--r--video/filter/vf_vavpp.c2
-rw-r--r--video/image_writer.c4
-rw-r--r--video/mp_image.c107
-rw-r--r--video/mp_image.h6
-rw-r--r--video/out/opengl/hwdec_vaglx.c2
-rw-r--r--video/out/opengl/video.c30
-rw-r--r--video/out/vo_lavc.c4
-rw-r--r--video/out/vo_opengl.c6
-rw-r--r--video/out/vo_rpi.c2
-rw-r--r--video/out/vo_vaapi.c2
-rw-r--r--video/out/vo_xv.c4
-rw-r--r--video/sws_utils.c8
22 files changed, 160 insertions, 151 deletions
diff --git a/player/command.c b/player/command.c
index caca0c32ec..85f453e0ef 100644
--- a/player/command.c
+++ b/player/command.c
@@ -2569,13 +2569,13 @@ static int property_imgparams(struct mp_image_params p, int action, void *arg)
{"aspect", SUB_PROP_FLOAT(d_w / (double)d_h)},
{"par", SUB_PROP_FLOAT(p.p_w / (double)p.p_h)},
{"colormatrix",
- SUB_PROP_STR(m_opt_choice_str(mp_csp_names, p.colorspace))},
+ SUB_PROP_STR(m_opt_choice_str(mp_csp_names, p.color.space))},
{"colorlevels",
- SUB_PROP_STR(m_opt_choice_str(mp_csp_levels_names, p.colorlevels))},
+ SUB_PROP_STR(m_opt_choice_str(mp_csp_levels_names, p.color.levels))},
{"primaries",
- SUB_PROP_STR(m_opt_choice_str(mp_csp_prim_names, p.primaries))},
+ SUB_PROP_STR(m_opt_choice_str(mp_csp_prim_names, p.color.primaries))},
{"gamma",
- SUB_PROP_STR(m_opt_choice_str(mp_csp_trc_names, p.gamma))},
+ SUB_PROP_STR(m_opt_choice_str(mp_csp_trc_names, p.color.gamma))},
{"chroma-location",
SUB_PROP_STR(m_opt_choice_str(mp_chroma_names, p.chroma_location))},
{"stereo-in",
diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c
index 5356a8fa99..b79810ce9a 100644
--- a/sub/draw_bmp.c
+++ b/sub/draw_bmp.c
@@ -193,8 +193,7 @@ static void scale_sb_rgba(struct sub_bitmap *sb, struct mp_image *dst_format,
mp_image_swscale(sbisrc2, &sbisrc, SWS_BILINEAR);
unpremultiply_and_split_BGR32(sbisrc2, sba);
- sbi->params.colorspace = dst_format->params.colorspace;
- sbi->params.colorlevels = dst_format->params.colorlevels;
+ sbi->params.color = dst_format->params.color;
mp_image_swscale(sbi, sbisrc2, SWS_BILINEAR);
talloc_free(sbisrc2);
@@ -367,8 +366,8 @@ static struct part *get_cache(struct mp_draw_sub_cache *cache,
if (part) {
if (part->change_id != sbs->change_id
|| part->imgfmt != format->imgfmt
- || part->colorspace != format->params.colorspace
- || part->levels != format->params.colorlevels)
+ || part->colorspace != format->params.color.space
+ || part->levels != format->params.color.levels)
{
talloc_free(part);
part = NULL;
@@ -380,8 +379,8 @@ static struct part *get_cache(struct mp_draw_sub_cache *cache,
.change_id = sbs->change_id,
.num_imgs = sbs->num_parts,
.imgfmt = format->imgfmt,
- .levels = format->params.colorlevels,
- .colorspace = format->params.colorspace,
+ .levels = format->params.color.levels,
+ .colorspace = format->params.color.space,
};
part->imgs = talloc_zero_array(part, struct sub_cache,
part->num_imgs);
@@ -436,10 +435,8 @@ static struct mp_image *chroma_up(struct mp_draw_sub_cache *cache, int imgfmt,
// The temp image is always YUV, but src not necessarily.
// Reduce amount of conversions in YUV case (upsampling/shifting only)
- if (src->fmt.flags & MP_IMGFLAG_YUV) {
- temp->params.colorspace = src->params.colorspace;
- temp->params.colorlevels = src->params.colorlevels;
- }
+ if (src->fmt.flags & MP_IMGFLAG_YUV)
+ temp->params.color = src->params.color;
if (src->imgfmt == IMGFMT_420P) {
assert(imgfmt == IMGFMT_444P);
diff --git a/sub/sd_ass.c b/sub/sd_ass.c
index 7abeea9eeb..34a49c1501 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -733,15 +733,17 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts)
struct mp_image_params params = ctx->video_params;
if (force_601) {
- params.colorspace = MP_CSP_BT_709;
- params.colorlevels = MP_CSP_LEVELS_TV;
+ params.color = (struct mp_colorspace){
+ .space = MP_CSP_BT_709,
+ .levels = MP_CSP_LEVELS_TV,
+ };
}
- if (csp == params.colorspace && levels == params.colorlevels)
+ if (csp == params.color.space && levels == params.color.levels)
return;
- bool basic_conv = params.colorspace == MP_CSP_BT_709 &&
- params.colorlevels == MP_CSP_LEVELS_TV &&
+ bool basic_conv = params.color.space == MP_CSP_BT_709 &&
+ params.color.levels == MP_CSP_LEVELS_TV &&
csp == MP_CSP_BT_601 &&
levels == MP_CSP_LEVELS_TV;
@@ -749,8 +751,8 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts)
if (opts->ass_vsfilter_color_compat == 1 && !basic_conv)
return;
- if (params.colorspace != ctx->last_params.colorspace ||
- params.colorlevels != ctx->last_params.colorlevels)
+ if (params.color.space != ctx->last_params.color.space ||
+ params.color.levels != ctx->last_params.color.levels)
{
int msgl = basic_conv ? MSGL_V : MSGL_WARN;
ctx->last_params = params;
@@ -758,22 +760,21 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts)
"RGB -> %s %s -> %s %s -> RGB\n",
m_opt_choice_str(mp_csp_names, csp),
m_opt_choice_str(mp_csp_levels_names, levels),
- m_opt_choice_str(mp_csp_names, params.colorspace),
- m_opt_choice_str(mp_csp_names, params.colorlevels));
+ m_opt_choice_str(mp_csp_names, params.color.space),
+ m_opt_choice_str(mp_csp_names, params.color.levels));
}
// Conversion that VSFilter would use
struct mp_csp_params vs_params = MP_CSP_PARAMS_DEFAULTS;
- vs_params.colorspace = csp;
- vs_params.levels_in = levels;
+ vs_params.color.space = csp;
+ vs_params.color.levels = levels;
struct mp_cmat vs_yuv2rgb, vs_rgb2yuv;
mp_get_csp_matrix(&vs_params, &vs_yuv2rgb);
mp_invert_cmat(&vs_rgb2yuv, &vs_yuv2rgb);
// Proper conversion to RGB
struct mp_csp_params rgb_params = MP_CSP_PARAMS_DEFAULTS;
- rgb_params.colorspace = params.colorspace;
- rgb_params.levels_in = params.colorlevels;
+ rgb_params.color = params.color;
struct mp_cmat vs2rgb;
mp_get_csp_matrix(&rgb_params, &vs2rgb);
diff --git a/video/csputils.c b/video/csputils.c
index d419152e2c..4c9cfbeebd 100644
--- a/video/csputils.c
+++ b/video/csputils.c
@@ -581,7 +581,7 @@ void mp_get_cms_matrix(struct mp_csp_primaries src, struct mp_csp_primaries dest
static void mp_get_xyz2rgb_coeffs(struct mp_csp_params *params,
enum mp_render_intent intent, struct mp_cmat *m)
{
- struct mp_csp_primaries prim = mp_get_csp_primaries(params->primaries);
+ struct mp_csp_primaries prim = mp_get_csp_primaries(params->color.primaries);
float brightness = params->brightness;
mp_get_rgb2xyz_matrix(prim, m->m);
mp_invert_matrix3x3(m->m);
@@ -658,10 +658,10 @@ static void luma_coeffs(struct mp_cmat *mat, float lr, float lg, float lb)
// get the coefficients of the yuv -> rgb conversion matrix
void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m)
{
- int colorspace = params->colorspace;
+ enum mp_csp colorspace = params->color.space;
if (colorspace <= MP_CSP_AUTO || colorspace >= MP_CSP_COUNT)
colorspace = MP_CSP_BT_601;
- int levels_in = params->levels_in;
+ enum mp_csp_levels levels_in = params->color.levels;
if (levels_in <= MP_CSP_LEVELS_AUTO || levels_in >= MP_CSP_LEVELS_COUNT)
levels_in = MP_CSP_LEVELS_TV;
@@ -772,9 +772,16 @@ void mp_csp_set_image_params(struct mp_csp_params *params,
{
struct mp_image_params p = *imgparams;
mp_image_params_guess_csp(&p); // ensure consistency
- params->colorspace = p.colorspace;
- params->levels_in = p.colorlevels;
- params->primaries = p.primaries;
+ params->color = p.color;
+}
+
+bool mp_colorspace_equal(struct mp_colorspace c1, struct mp_colorspace c2)
+{
+ return c1.space == c2.space &&
+ c1.levels == c2.levels &&
+ c1.primaries == c2.primaries &&
+ c1.gamma == c2.gamma &&
+ c1.peak == c2.peak;
}
// Copy settings from eq into params.
diff --git a/video/csputils.h b/video/csputils.h
index 274b548381..0743f2bee5 100644
--- a/video/csputils.h
+++ b/video/csputils.h
@@ -116,11 +116,17 @@ extern const struct m_opt_choice_alternatives mp_stereo3d_names[];
#define MP_STEREO3D_NAME_DEF(x, def) \
(MP_STEREO3D_NAME(x) ? MP_STEREO3D_NAME(x) : (def))
-struct mp_csp_params {
- enum mp_csp colorspace;
- enum mp_csp_levels levels_in; // encoded video
- enum mp_csp_levels levels_out; // output device
+struct mp_colorspace {
+ enum mp_csp space;
+ enum mp_csp_levels levels;
enum mp_csp_prim primaries;
+ enum mp_csp_trc gamma;
+ float peak; // 0 = auto/unknown
+};
+
+struct mp_csp_params {
+ struct mp_colorspace color; // input colorspace
+ enum mp_csp_levels levels_out; // output device
float brightness;
float contrast;
float hue;
@@ -134,9 +140,8 @@ struct mp_csp_params {
};
#define MP_CSP_PARAMS_DEFAULTS { \
- .colorspace = MP_CSP_BT_601, \
- .levels_in = MP_CSP_LEVELS_TV, \
- .primaries = MP_CSP_PRIM_AUTO, \
+ .color = { .space = MP_CSP_BT_601, \
+ .levels = MP_CSP_LEVELS_TV }, \
.levels_out = MP_CSP_LEVELS_PC, \
.brightness = 0, .contrast = 1, .hue = 0, .saturation = 1, \
.gamma = 1, .texture_bits = 8, .input_bits = 8}
@@ -145,6 +150,8 @@ struct mp_image_params;
void mp_csp_set_image_params(struct mp_csp_params *params,
const struct mp_image_params *imgparams);
+bool mp_colorspace_equal(struct mp_colorspace c1, struct mp_colorspace c2);
+
enum mp_chroma_location {
MP_CHROMA_AUTO,
MP_CHROMA_LEFT, // mpeg2/4, h264
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index be6aceb662..62fc4ff280 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -578,10 +578,12 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame,
.h = frame->height,
.p_w = frame->sample_aspect_ratio.num,
.p_h = frame->sample_aspect_ratio.den,
- .colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace),
- .colorlevels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range),
- .primaries = avcol_pri_to_mp_csp_prim(ctx->avctx->color_primaries),
- .gamma = avcol_trc_to_mp_csp_trc(ctx->avctx->color_trc),
+ .color = {
+ .space = avcol_spc_to_mp_csp(ctx->avctx->colorspace),
+ .levels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range),
+ .primaries = avcol_pri_to_mp_csp_prim(ctx->avctx->color_primaries),
+ .gamma = avcol_trc_to_mp_csp_trc(ctx->avctx->color_trc),
+ },
.chroma_location =
avchroma_location_to_mp(ctx->avctx->chroma_sample_location),
.rotate = vd->codec->rotate,
diff --git a/video/filter/vf_d3d11vpp.c b/video/filter/vf_d3d11vpp.c
index a0aa0edae2..658aec25b8 100644
--- a/video/filter/vf_d3d11vpp.c
+++ b/video/filter/vf_d3d11vpp.c
@@ -211,21 +211,21 @@ static int recreate_video_proc(struct vf_instance *vf)
FALSE, 0);
D3D11_VIDEO_PROCESSOR_COLOR_SPACE csp = {
- .YCbCr_Matrix = p->params.colorspace != MP_CSP_BT_601,
- .Nominal_Range = p->params.colorlevels == MP_CSP_LEVELS_TV ? 1 : 2,
+ .YCbCr_Matrix = p->params.color.space != MP_CSP_BT_601,
+ .Nominal_Range = p->params.color.levels == MP_CSP_LEVELS_TV ? 1 : 2,
};
ID3D11VideoContext_VideoProcessorSetStreamColorSpace(p->video_ctx,
p->video_proc,
0, &csp);
if (p->out_rgb) {
- if (p->params.colorspace != MP_CSP_BT_601 &&
- p->params.colorspace != MP_CSP_BT_709)
+ if (p->params.color.space != MP_CSP_BT_601 &&
+ p->params.color.space != MP_CSP_BT_709)
{
MP_WARN(vf, "Unsupported video colorspace (%s/%s). Consider "
"disabling hardware decoding, or using "
"--hwdec=d3d11va-copy to get correct output.\n",
- m_opt_choice_str(mp_csp_names, p->params.colorspace),
- m_opt_choice_str(mp_csp_levels_names, p->params.colorlevels));
+ m_opt_choice_str(mp_csp_names, p->params.color.space),
+ m_opt_choice_str(mp_csp_levels_names, p->params.color.levels));
}
} else {
ID3D11VideoContext_VideoProcessorSetOutputColorSpace(p->video_ctx,
diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c
index 109fda4053..36388e6288 100644
--- a/video/filter/vf_format.c
+++ b/video/filter/vf_format.c
@@ -88,15 +88,15 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
if (p->outfmt)
out->imgfmt = p->outfmt;
if (p->colormatrix)
- out->colorspace = p->colormatrix;
+ out->color.space = p->colormatrix;
if (p->colorlevels)
- out->colorlevels = p->colorlevels;
+ out->color.levels = p->colorlevels;
if (p->primaries)
- out->primaries = p->primaries;
+ out->color.primaries = p->primaries;
if (p->gamma)
- out->gamma = p->gamma;
+ out->color.gamma = p->gamma;
if (p->peak)
- out->peak = p->peak;
+ out->color.peak = p->peak;
if (p->chroma_location)
out->chroma_location = p->chroma_location;
if (p->stereo_in)
diff --git a/video/filter/vf_scale.c b/video/filter/vf_scale.c
index 518ff41beb..0b233e7098 100644
--- a/video/filter/vf_scale.c
+++ b/video/filter/vf_scale.c
@@ -166,8 +166,8 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
struct mp_imgfmt_desc d_fmt = mp_imgfmt_get_desc(out->imgfmt);
// keep colorspace settings if the data stays in yuv
if (!(s_fmt.flags & MP_IMGFLAG_YUV) || !(d_fmt.flags & MP_IMGFLAG_YUV)) {
- out->colorspace = MP_CSP_AUTO;
- out->colorlevels = MP_CSP_LEVELS_AUTO;
+ out->color.space = MP_CSP_AUTO;
+ out->color.levels = MP_CSP_LEVELS_AUTO;
}
mp_image_params_guess_csp(out);
diff --git a/video/filter/vf_vapoursynth.c b/video/filter/vf_vapoursynth.c
index 5592e032e4..625d539dc4 100644
--- a/video/filter/vf_vapoursynth.c
+++ b/video/filter/vf_vapoursynth.c
@@ -143,13 +143,13 @@ static void copy_mp_to_vs_frame_props_map(struct vf_priv_s *p, VSMap *map,
struct mp_image_params *params = &img->params;
p->vsapi->propSetInt(map, "_SARNum", params->p_w, 0);
p->vsapi->propSetInt(map, "_SARDen", params->p_h, 0);
- if (params->colorlevels) {
+ if (params->color.levels) {
p->vsapi->propSetInt(map, "_ColorRange",
- params->colorlevels == MP_CSP_LEVELS_TV, 0);
+ params->color.levels == MP_CSP_LEVELS_TV, 0);
}
// The docs explicitly say it uses libavcodec values.
p->vsapi->propSetInt(map, "_ColorSpace",
- mp_csp_to_avcol_spc(params->colorspace), 0);
+ mp_csp_to_avcol_spc(params->color.space), 0);
if (params->chroma_location) {
p->vsapi->propSetInt(map, "_ChromaLocation",
params->chroma_location == MP_CHROMA_CENTER, 0);
diff --git a/video/filter/vf_vavpp.c b/video/filter/vf_vavpp.c
index 0365b55fb3..b24f886241 100644
--- a/video/filter/vf_vavpp.c
+++ b/video/filter/vf_vavpp.c
@@ -168,7 +168,7 @@ static struct mp_image *render(struct vf_instance *vf)
mp_image_set_size(img, in->w, in->h);
mp_image_copy_attributes(img, in);
- unsigned int flags = va_get_colorspace_flag(p->params.colorspace);
+ unsigned int flags = va_get_colorspace_flag(p->params.color.space);
if (!mp_refqueue_is_interlaced(p->queue)) {
flags |= VA_FRAME_PICTURE;
} else if (mp_refqueue_is_top_field(p->queue)) {
diff --git a/video/image_writer.c b/video/image_writer.c
index 5ba89c8167..6b2f0f9a92 100644
--- a/video/image_writer.c
+++ b/video/image_writer.c
@@ -133,8 +133,8 @@ static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp
pic->width = avctx->width;
pic->height = avctx->height;
if (ctx->opts->tag_csp) {
- pic->color_primaries = mp_csp_prim_to_avcol_pri(image->params.primaries);
- pic->color_trc = mp_csp_trc_to_avcol_trc(image->params.gamma);
+ pic->color_primaries = mp_csp_prim_to_avcol_pri(image->params.color.primaries);
+ pic->color_trc = mp_csp_trc_to_avcol_trc(image->params.color.gamma);
}
#if HAVE_AVCODEC_NEW_CODEC_API
diff --git a/video/mp_image.c b/video/mp_image.c
index 0b46f947bc..286e40bf62 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -393,11 +393,12 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
dst->params.p_w = src->params.p_w;
dst->params.p_h = src->params.p_h;
}
- dst->params.primaries = src->params.primaries;
- dst->params.gamma = src->params.gamma;
+ dst->params.color.primaries = src->params.color.primaries;
+ dst->params.color.gamma = src->params.color.gamma;
+ dst->params.color.peak = src->params.color.peak;
if ((dst->fmt.flags & MP_IMGFLAG_YUV) == (src->fmt.flags & MP_IMGFLAG_YUV)) {
- dst->params.colorspace = src->params.colorspace;
- dst->params.colorlevels = src->params.colorlevels;
+ dst->params.color.space = src->params.color.space;
+ dst->params.color.levels = src->params.color.levels;
dst->params.chroma_location = src->params.chroma_location;
}
mp_image_params_guess_csp(&dst->params); // ensure colorspace consistency
@@ -512,8 +513,8 @@ char *mp_image_params_to_str_buf(char *b, size_t bs,
if (p->hw_subfmt)
mp_snprintf_cat(b, bs, "[%llu]", (unsigned long long)(p->hw_subfmt));
mp_snprintf_cat(b, bs, " %s/%s",
- m_opt_choice_str(mp_csp_names, p->colorspace),
- m_opt_choice_str(mp_csp_levels_names, p->colorlevels));
+ m_opt_choice_str(mp_csp_names, p->color.space),
+ m_opt_choice_str(mp_csp_levels_names, p->color.levels));
mp_snprintf_cat(b, bs, " CL=%s",
m_opt_choice_str(mp_chroma_names, p->chroma_location));
if (p->rotate)
@@ -564,11 +565,7 @@ bool mp_image_params_equal(const struct mp_image_params *p1,
p1->hw_subfmt == p2->hw_subfmt &&
p1->w == p2->w && p1->h == p2->h &&
p1->p_w == p2->p_w && p1->p_h == p2->p_h &&
- p1->colorspace == p2->colorspace &&
- p1->colorlevels == p2->colorlevels &&
- p1->primaries == p2->primaries &&
- p1->gamma == p2->gamma &&
- p1->peak == p2->peak &&
+ mp_colorspace_equal(p1->color, p2->color) &&
p1->chroma_location == p2->chroma_location &&
p1->rotate == p2->rotate &&
p1->stereo_in == p2->stereo_in &&
@@ -598,56 +595,56 @@ void mp_image_params_guess_csp(struct mp_image_params *params)
if (!fmt.id)
return;
if (fmt.flags & MP_IMGFLAG_YUV) {
- if (params->colorspace != MP_CSP_BT_601 &&
- params->colorspace != MP_CSP_BT_709 &&
- params->colorspace != MP_CSP_BT_2020_NC &&
- params->colorspace != MP_CSP_BT_2020_C &&
- params->colorspace != MP_CSP_SMPTE_240M &&
- params->colorspace != MP_CSP_YCGCO)
+ if (params->color.space != MP_CSP_BT_601 &&
+ params->color.space != MP_CSP_BT_709 &&
+ params->color.space != MP_CSP_BT_2020_NC &&
+ params->color.space != MP_CSP_BT_2020_C &&
+ params->color.space != MP_CSP_SMPTE_240M &&
+ params->color.space != MP_CSP_YCGCO)
{
// Makes no sense, so guess instead
// YCGCO should be separate, but libavcodec disagrees
- params->colorspace = MP_CSP_AUTO;
+ params->color.space = MP_CSP_AUTO;
}
- if (params->colorspace == MP_CSP_AUTO)
- params->colorspace = mp_csp_guess_colorspace(params->w, params->h);
- if (params->colorlevels == MP_CSP_LEVELS_AUTO) {
- if (params->gamma == MP_CSP_TRC_V_LOG) {
- params->colorlevels = MP_CSP_LEVELS_PC;
+ if (params->color.space == MP_CSP_AUTO)
+ params->color.space = mp_csp_guess_colorspace(params->w, params->h);
+ if (params->color.levels == MP_CSP_LEVELS_AUTO) {
+ if (params->color.gamma == MP_CSP_TRC_V_LOG) {
+ params->color.levels = MP_CSP_LEVELS_PC;
} else {
- params->colorlevels = MP_CSP_LEVELS_TV;
+ params->color.levels = MP_CSP_LEVELS_TV;
}
}
- if (params->primaries == MP_CSP_PRIM_AUTO) {
+ if (params->color.primaries == MP_CSP_PRIM_AUTO) {
// Guess based on the colormatrix as a first priority
- if (params->colorspace == MP_CSP_BT_2020_NC ||
- params->colorspace == MP_CSP_BT_2020_C) {
- params->primaries = MP_CSP_PRIM_BT_2020;
- } else if (params->colorspace == MP_CSP_BT_709) {
- params->primaries = MP_CSP_PRIM_BT_709;
+ if (params->color.space == MP_CSP_BT_2020_NC ||
+ params->color.space == MP_CSP_BT_2020_C) {
+ params->color.primaries = MP_CSP_PRIM_BT_2020;
+ } else if (params->color.space == MP_CSP_BT_709) {
+ params->color.primaries = MP_CSP_PRIM_BT_709;
} else {
// Ambiguous colormatrix for BT.601, guess based on res
- params->primaries = mp_csp_guess_primaries(params->w, params->h);
+ params->color.primaries = mp_csp_guess_primaries(params->w, params->h);
}
}
- if (params->gamma == MP_CSP_TRC_AUTO)
- params->gamma = MP_CSP_TRC_BT_1886;
+ if (params->color.gamma == MP_CSP_TRC_AUTO)
+ params->color.gamma = MP_CSP_TRC_BT_1886;
} else if (fmt.flags & MP_IMGFLAG_RGB) {
- params->colorspace = MP_CSP_RGB;
- params->colorlevels = MP_CSP_LEVELS_PC;
+ params->color.space = MP_CSP_RGB;
+ params->color.levels = MP_CSP_LEVELS_PC;
// The majority of RGB content is either sRGB or (rarely) some other
// color space which we don't even handle, like AdobeRGB or
// ProPhotoRGB. The only reasonable thing we can do is assume it's
// sRGB and hope for the best, which should usually just work out fine.
// Note: sRGB primaries = BT.709 primaries
- if (params->primaries == MP_CSP_PRIM_AUTO)
- params->primaries = MP_CSP_PRIM_BT_709;
- if (params->gamma == MP_CSP_TRC_AUTO)
- params->gamma = MP_CSP_TRC_SRGB;
+ if (params->color.primaries == MP_CSP_PRIM_AUTO)
+ params->color.primaries = MP_CSP_PRIM_BT_709;
+ if (params->color.gamma == MP_CSP_TRC_AUTO)
+ params->color.gamma = MP_CSP_TRC_SRGB;
} else if (fmt.flags & MP_IMGFLAG_XYZ) {
- params->colorspace = MP_CSP_XYZ;
- params->colorlevels = MP_CSP_LEVELS_PC;
+ params->color.space = MP_CSP_XYZ;
+ params->color.levels = MP_CSP_LEVELS_PC;
// The default XYZ matrix converts it to BT.709 color space
// since that's the most likely scenario. Proper VOs should ignore
@@ -657,22 +654,22 @@ void mp_image_params_guess_csp(struct mp_image_params *params)
// gamut for VOs which *do* use the specialized XYZ matrix but don't
// know any better output gamut other than whatever the source is
// tagged with.
- if (params->primaries == MP_CSP_PRIM_AUTO)
- params->primaries = MP_CSP_PRIM_BT_709;
- if (params->gamma == MP_CSP_TRC_AUTO)
- params->gamma = MP_CSP_TRC_LINEAR;
+ if (params->color.primaries == MP_CSP_PRIM_AUTO)
+ params->color.primaries = MP_CSP_PRIM_BT_709;
+ if (params->color.gamma == MP_CSP_TRC_AUTO)
+ params->color.gamma = MP_CSP_TRC_LINEAR;
} else {
// We have no clue.
- params->colorspace = MP_CSP_AUTO;
- params->colorlevels = MP_CSP_LEVELS_AUTO;
- params->primaries = MP_CSP_PRIM_AUTO;
- params->gamma = MP_CSP_TRC_AUTO;
+ params->color.space = MP_CSP_AUTO;
+ params->color.levels = MP_CSP_LEVELS_AUTO;
+ params->color.primaries = MP_CSP_PRIM_AUTO;
+ params->color.gamma = MP_CSP_TRC_AUTO;
}
- // Guess the reference peak (independent of the colorspace)
- if (params->gamma == MP_CSP_TRC_SMPTE_ST2084) {
- if (!params->peak)
- params->peak = 10000; // As per the spec
+ // Guess the nominal peak (independent of the colorspace)
+ if (params->color.gamma == MP_CSP_TRC_SMPTE_ST2084) {
+ if (!params->color.peak)
+ params->color.peak = 10000; // As per the spec
}
}
@@ -729,8 +726,8 @@ static void mp_image_copy_fields_to_av_frame(struct AVFrame *dst,
if (src->fields & MP_IMGFIELD_REPEAT_FIRST)
dst->repeat_pict = 1;
- dst->colorspace = mp_csp_to_avcol_spc(src->params.colorspace);
- dst->color_range = mp_csp_levels_to_avcol_range(src->params.colorlevels);
+ dst->colorspace = mp_csp_to_avcol_spc(src->params.color.space);
+ dst->color_range = mp_csp_levels_to_avcol_range(src->params.color.levels);
}
// Create a new mp_image reference to av_frame.
diff --git a/video/mp_image.h b/video/mp_image.h
index 18d25968c0..dfbe4ee0ba 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -43,11 +43,7 @@ struct mp_image_params {
// (will use the HW API's format identifiers)
int w, h; // image dimensions
int p_w, p_h; // define pixel aspect ratio (undefined: 0/0)
- enum mp_csp colorspace;
- enum mp_csp_levels colorlevels;
- enum mp_csp_prim primaries;
- enum mp_csp_trc gamma;
- float peak; // 0 = auto/unknown
+ struct mp_colorspace color;
enum mp_chroma_location chroma_location;
// The image should be rotated clockwise (0-359 degrees).
int rotate;
diff --git a/video/out/opengl/hwdec_vaglx.c b/video/out/opengl/hwdec_vaglx.c
index 2e3017c193..0400604067 100644
--- a/video/out/opengl/hwdec_vaglx.c
+++ b/video/out/opengl/hwdec_vaglx.c
@@ -185,7 +185,7 @@ static int map_frame(struct gl_hwdec *hw, struct mp_image *hw_image,
0, 0, hw_image->w, hw_image->h,
0, 0, hw_image->w, hw_image->h,
NULL, 0,
- va_get_colorspace_flag(hw_image->params.colorspace));
+ va_get_colorspace_flag(hw_image->params.color.space));
CHECK_VA_STATUS(p, "vaPutSurface()");
va_unlock(p->ctx);
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index 6c7646bef4..59dd64cb65 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -729,7 +729,7 @@ static void pass_get_img_tex(struct gl_video *p, struct video_image *vimg,
// The existing code assumes we just have a single tex multiplier for
// all of the planes. This may change in the future
- float tex_mul = 1.0 / mp_get_csp_mul(p->image_params.colorspace,
+ float tex_mul = 1.0 / mp_get_csp_mul(p->image_params.color.space,
p->image_desc.component_bits,
p->image_desc.component_full_bits);
@@ -793,7 +793,7 @@ static void init_video(struct gl_video *p)
mp_image_params_guess_csp(&p->image_params);
int eq_caps = MP_CSP_EQ_CAPS_GAMMA;
- if (p->image_params.colorspace != MP_CSP_BT_2020_C)
+ if (p->image_params.color.space != MP_CSP_BT_2020_C)
eq_caps |= MP_CSP_EQ_CAPS_COLORMATRIX;
if (p->image_desc.flags & MP_IMGFLAG_XYZ)
eq_caps |= MP_CSP_EQ_CAPS_BRIGHTNESS;
@@ -1985,7 +1985,7 @@ static void pass_convert_yuv(struct gl_video *p)
GLSLF("color = color.%s;\n", p->color_swizzle);
// Pre-colormatrix input gamma correction
- if (cparams.colorspace == MP_CSP_XYZ)
+ if (cparams.color.space == MP_CSP_XYZ)
GLSL(color.rgb = pow(color.rgb, vec3(2.6));) // linear light
// We always explicitly normalize the range in pass_read_video
@@ -2000,7 +2000,7 @@ static void pass_convert_yuv(struct gl_video *p)
GLSL(color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;)
- if (p->image_params.colorspace == MP_CSP_BT_2020_C) {
+ if (p->image_params.color.space == MP_CSP_BT_2020_C) {
// Conversion for C'rcY'cC'bc via the BT.2020 CL system:
// C'bc = (B'-Y'c) / 1.9404 | C'bc <= 0
// = (B'-Y'c) / 1.5816 | C'bc > 0
@@ -2111,7 +2111,7 @@ static void pass_scale_main(struct gl_video *p)
// Pre-conversion, like linear light/sigmoidization
GLSLF("// scaler pre-conversion\n");
if (p->use_linear) {
- pass_linearize(p->sc, p->image_params.gamma);
+ pass_linearize(p->sc, p->image_params.color.gamma);
pass_opt_hook_point(p, "LINEAR", NULL);
}
@@ -2171,8 +2171,8 @@ static void pass_colormanage(struct gl_video *p, float peak_src,
if (p->use_lut_3d) {
// The 3DLUT is always generated against the original source space
- enum mp_csp_prim prim_orig = p->image_params.primaries;
- enum mp_csp_trc trc_orig = p->image_params.gamma;
+ enum mp_csp_prim prim_orig = p->image_params.color.primaries;
+ enum mp_csp_trc trc_orig = p->image_params.color.gamma;
// One exception: HDR is not implemented by LittleCMS for technical
// limitation reasons, so we use a gamma 2.2 input curve here instead.
@@ -2196,14 +2196,14 @@ static void pass_colormanage(struct gl_video *p, float peak_src,
// this as the default output color space.
prim_dst = MP_CSP_PRIM_BT_709;
- if (p->image_params.primaries == MP_CSP_PRIM_BT_601_525 ||
- p->image_params.primaries == MP_CSP_PRIM_BT_601_625)
+ if (p->image_params.color.primaries == MP_CSP_PRIM_BT_601_525 ||
+ p->image_params.color.primaries == MP_CSP_PRIM_BT_601_625)
{
// Since we auto-pick BT.601 and BT.709 based on the dimensions,
// combined with the fact that they're very similar to begin with,
// and to avoid confusing the average user, just don't adapt BT.601
// content automatically at all.
- prim_dst = p->image_params.primaries;
+ prim_dst = p->image_params.color.primaries;
}
}
@@ -2213,7 +2213,7 @@ static void pass_colormanage(struct gl_video *p, float peak_src,
// altogether by default. The only exceptions to this rule apply to
// very unusual TRCs, which even hardcode technoluddites would probably
// not enjoy viewing unaltered.
- trc_dst = p->image_params.gamma;
+ trc_dst = p->image_params.color.gamma;
// Avoid outputting linear light or HDR content "by default". For these
// just pick gamma 2.2 as a default, since it's a good estimate for
@@ -2225,7 +2225,7 @@ static void pass_colormanage(struct gl_video *p, float peak_src,
if (!peak_src) {
// If the source has no information known, it's display-referred
// (and should be treated relative to the specified desired peak_dst)
- peak_src = peak_dst * mp_csp_trc_rel_peak(p->image_params.gamma);
+ peak_src = peak_dst * mp_csp_trc_rel_peak(p->image_params.color.gamma);
}
// All operations from here on require linear light as a starting point,
@@ -2513,7 +2513,7 @@ static void pass_render_frame(struct gl_video *p)
rect.mt *= scale[1]; rect.mb *= scale[1];
// We should always blend subtitles in non-linear light
if (p->use_linear) {
- pass_delinearize(p->sc, p->image_params.gamma);
+ pass_delinearize(p->sc, p->image_params.color.gamma);
p->use_linear = false;
}
finish_pass_fbo(p, &p->blend_subs_fbo, p->texture_w, p->texture_h,
@@ -2542,8 +2542,8 @@ static void pass_draw_to_screen(struct gl_video *p, int fbo)
GLSL(color.rgb = pow(color.rgb, vec3(user_gamma));)
}
- pass_colormanage(p, p->image_params.peak, p->image_params.primaries,
- p->use_linear ? MP_CSP_TRC_LINEAR : p->image_params.gamma);
+ pass_colormanage(p, p->image_params.color.peak, p->image_params.color.primaries,
+ p->use_linear ? MP_CSP_TRC_LINEAR : p->image_params.color.gamma);
// Draw checkerboard pattern to indicate transparency
if (p->has_alpha && p->opts.alpha_mode == ALPHA_BLEND_TILES) {
diff --git a/video/out/vo_lavc.c b/video/out/vo_lavc.c
index 7003bd17bd..1721136f8b 100644
--- a/video/out/vo_lavc.c
+++ b/video/out/vo_lavc.c
@@ -155,8 +155,8 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
vc->codec->height = height;
vc->codec->pix_fmt = pix_fmt;
- encode_lavc_set_csp(vo->encode_lavc_ctx, vc->codec, params->colorspace);
- encode_lavc_set_csp_levels(vo->encode_lavc_ctx, vc->codec, params->colorlevels);
+ encode_lavc_set_csp(vo->encode_lavc_ctx, vc->codec, params->color.space);
+ encode_lavc_set_csp_levels(vo->encode_lavc_ctx, vc->codec, params->color.levels);
if (encode_lavc_open_codec(vo->encode_lavc_ctx, vc->codec) < 0)
goto error;
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index 08b9b11fe0..095308f9b5 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -305,8 +305,10 @@ static int control(struct vo *vo, uint32_t request, void *data)
struct mp_image *screen = gl_read_window_contents(p->gl);
// set image parameters according to the display, if possible
if (screen) {
- screen->params.primaries = p->renderer_opts->target_prim;
- screen->params.gamma = p->renderer_opts->target_trc;
+ screen->params.color = (struct mp_colorspace) {
+ .primaries = p->renderer_opts->target_prim,
+ .gamma = p->renderer_opts->target_trc,
+ };
if (p->glctx->flip_v)
mp_image_vflip(screen);
}
diff --git a/video/out/vo_rpi.c b/video/out/vo_rpi.c
index cd37362a30..947e63037e 100644
--- a/video/out/vo_rpi.c
+++ b/video/out/vo_rpi.c
@@ -529,7 +529,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
input->format->es->video.height = MP_ALIGN_UP(params->h, ALIGN_H);
input->format->es->video.crop = (MMAL_RECT_T){0, 0, params->w, params->h};
input->format->es->video.par = (MMAL_RATIONAL_T){params->p_w, params->p_h};
- input->format->es->video.color_space = map_csp(params->colorspace);
+ input->format->es->video.color_space = map_csp(params->color.space);
if (mmal_port_format_commit(input))
return -1;
diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c
index 8380771e27..11bb469b24 100644
--- a/video/out/vo_vaapi.c
+++ b/video/out/vo_vaapi.c
@@ -225,7 +225,7 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi)
}
}
- int flags = va_get_colorspace_flag(p->image_params.colorspace) |
+ int flags = va_get_colorspace_flag(p->image_params.color.space) |
p->scaling | VA_FRAME_PICTURE;
status = vaPutSurface(p->display,
surface,
diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c
index a5a4728085..f450eb2df9 100644
--- a/video/out/vo_xv.c
+++ b/video/out/vo_xv.c
@@ -518,7 +518,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
ctx->current_buf = 0;
ctx->current_ip_buf = 0;
- int is_709 = params->colorspace == MP_CSP_BT_709;
+ int is_709 = params->color.space == MP_CSP_BT_709;
xv_set_eq(vo, ctx->xv_port, "bt_709", is_709 * 200 - 100);
read_xv_csp(vo);
@@ -661,7 +661,7 @@ static struct mp_image get_xv_buffer(struct vo *vo, int buf_index)
if (vo->params) {
struct mp_image_params params = *vo->params;
if (ctx->cached_csp)
- params.colorspace = ctx->cached_csp;
+ params.color.space = ctx->cached_csp;
mp_image_set_attributes(&img, &params);
}
diff --git a/video/sws_utils.c b/video/sws_utils.c
index ce44c67eeb..45918b19d1 100644
--- a/video/sws_utils.c
+++ b/video/sws_utils.c
@@ -192,11 +192,11 @@ int mp_sws_reinit(struct mp_sws_context *ctx)
return -1;
}
- int s_csp = mp_csp_to_sws_colorspace(src->colorspace);
- int s_range = src->colorlevels == MP_CSP_LEVELS_PC;
+ int s_csp = mp_csp_to_sws_colorspace(src->color.space);
+ int s_range = src->color.levels == MP_CSP_LEVELS_PC;
- int d_csp = mp_csp_to_sws_colorspace(dst->colorspace);
- int d_range = dst->colorlevels == MP_CSP_LEVELS_PC;
+ int d_csp = mp_csp_to_sws_colorspace(dst->color.space);
+ int d_range = dst->color.levels == MP_CSP_LEVELS_PC;
// Work around libswscale bug #1852 (fixed in ffmpeg commit 8edf9b1fa):
// setting range flags for RGB gives random bogus results.