summaryrefslogtreecommitdiffstats
path: root/video/mp_image.c
diff options
context:
space:
mode:
authorNiklas Haas <git@nand.wakku.to>2014-03-26 01:46:38 +0100
committerwm4 <wm4@nowhere>2014-06-22 19:00:38 +0200
commit70f50ddc5e97020d64ea0702748a00eddebc2473 (patch)
treef115668aa97cf11770459a169cc777ffca113840 /video/mp_image.c
parent86d3d11a68510764504a2a3c5987ab8e059d6df5 (diff)
downloadmpv-70f50ddc5e97020d64ea0702748a00eddebc2473.tar.bz2
mpv-70f50ddc5e97020d64ea0702748a00eddebc2473.tar.xz
video: Add support for non-BT.709 primaries
This add support for reading primary information from lavc, categorized into BT.601-525, BT.601-625, BT.709 and BT.2020; and passes it on to the vo. In vo_opengl, we always generate the 3dlut against the wider BT.2020 and transform our source into this colorspace in the shader.
Diffstat (limited to 'video/mp_image.c')
-rw-r--r--video/mp_image.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/video/mp_image.c b/video/mp_image.c
index 64c310aaed..1c686e5193 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -371,6 +371,7 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
if ((dst->flags & MP_IMGFLAG_YUV) == (src->flags & MP_IMGFLAG_YUV)) {
dst->params.colorspace = src->params.colorspace;
dst->params.colorlevels = src->params.colorlevels;
+ dst->params.primaries = src->params.primaries;
dst->params.chroma_location = src->params.chroma_location;
}
if ((dst->fmt.flags & MP_IMGFLAG_PAL) && (src->fmt.flags & MP_IMGFLAG_PAL)) {
@@ -486,6 +487,7 @@ bool mp_image_params_equal(const struct mp_image_params *p1,
p1->colorspace == p2->colorspace &&
p1->colorlevels == p2->colorlevels &&
p1->outputlevels == p2->outputlevels &&
+ p1->primaries == p2->primaries &&
p1->chroma_location == p2->chroma_location &&
p1->rotate == p2->rotate;
}
@@ -533,16 +535,43 @@ void mp_image_params_guess_csp(struct mp_image_params *params)
params->colorspace = mp_csp_guess_colorspace(params->w, params->h);
if (params->colorlevels == MP_CSP_LEVELS_AUTO)
params->colorlevels = MP_CSP_LEVELS_TV;
+ if (params->primaries == MP_CSP_PRIM_AUTO) {
+ // We assume BT.709 primaries for all untagged BT.609/BT.709
+ // content, because it offers the minimal deviation from all three,
+ // including both NTSC and PAL/SECAM.
+ if (params->colorspace == MP_CSP_BT_2020_NC) {
+ params->primaries = MP_CSP_PRIM_BT_2020;
+ } else {
+ params->primaries = MP_CSP_PRIM_BT_709;
+ }
+ }
} else if (fmt.flags & MP_IMGFLAG_RGB) {
params->colorspace = MP_CSP_RGB;
params->colorlevels = 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;
} else if (fmt.flags & MP_IMGFLAG_XYZ) {
params->colorspace = MP_CSP_XYZ;
params->colorlevels = 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
+ // this field as well as the matrix and treat XYZ input as absolute,
+ // but for VOs which use the matrix (and hence, consult this field)
+ // this is the correct parameter.
+ if (params->primaries == MP_CSP_PRIM_AUTO)
+ params->primaries = MP_CSP_PRIM_BT_709;
} else {
// We have no clue.
params->colorspace = MP_CSP_AUTO;
params->colorlevels = MP_CSP_LEVELS_AUTO;
+ params->primaries = MP_CSP_PRIM_AUTO;
}
}