From 70f50ddc5e97020d64ea0702748a00eddebc2473 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Wed, 26 Mar 2014 01:46:38 +0100 Subject: 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. --- video/mp_image.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'video/mp_image.c') 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; } } -- cgit v1.2.3