diff options
author | Niklas Haas <git@nand.wakku.to> | 2014-03-26 01:46:38 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-06-22 19:00:38 +0200 |
commit | 70f50ddc5e97020d64ea0702748a00eddebc2473 (patch) | |
tree | f115668aa97cf11770459a169cc777ffca113840 /video/mp_image.c | |
parent | 86d3d11a68510764504a2a3c5987ab8e059d6df5 (diff) | |
download | mpv-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.c | 29 |
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; } } |