From 1b10d9dd9cbc4164ed0ddbba0b64e64e638f1a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Mon, 7 Aug 2023 17:10:34 +0200 Subject: [PATCH] mp_image: properly infer color levels for some pixfmts ffmpeg does not tag yuv levels for GRAY formats, but apparently they should be infered as full range. Instead of defaulting to limited range always. Fixes (M)JPEG playback. This mimic ffmpeg's behaviour. See: https://github.com/FFmpeg/FFmpeg/blob/d295b6b6936c9c691a4871851fdaec04d407e54b/libswscale/utils.c#L926-L962 Fixes: #12089 --- video/mp_image.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/video/mp_image.c b/video/mp_image.c index 40678d10bd..c55b205ec0 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -837,6 +837,34 @@ void mp_image_set_attributes(struct mp_image *image, mp_image_set_params(image, &nparams); } +static enum mp_csp_levels infer_levels(enum mp_imgfmt imgfmt) +{ + switch (imgfmt2pixfmt(imgfmt)) { + case AV_PIX_FMT_YUVJ420P: + case AV_PIX_FMT_YUVJ411P: + case AV_PIX_FMT_YUVJ422P: + case AV_PIX_FMT_YUVJ444P: + case AV_PIX_FMT_YUVJ440P: + case AV_PIX_FMT_GRAY8: + case AV_PIX_FMT_YA8: + case AV_PIX_FMT_GRAY9LE: + case AV_PIX_FMT_GRAY9BE: + case AV_PIX_FMT_GRAY10LE: + case AV_PIX_FMT_GRAY10BE: + case AV_PIX_FMT_GRAY12LE: + case AV_PIX_FMT_GRAY12BE: + case AV_PIX_FMT_GRAY14LE: + case AV_PIX_FMT_GRAY14BE: + case AV_PIX_FMT_GRAY16LE: + case AV_PIX_FMT_GRAY16BE: + case AV_PIX_FMT_YA16BE: + case AV_PIX_FMT_YA16LE: + return MP_CSP_LEVELS_PC; + default: + return MP_CSP_LEVELS_TV; + } +} + // If details like params->colorspace/colorlevels are missing, guess them from // the other settings. Also, even if they are set, make them consistent with // the colorspace as implied by the pixel format. @@ -861,7 +889,7 @@ void mp_image_params_guess_csp(struct mp_image_params *params) if (params->color.gamma == MP_CSP_TRC_V_LOG) { params->color.levels = MP_CSP_LEVELS_PC; } else { - params->color.levels = MP_CSP_LEVELS_TV; + params->color.levels = infer_levels(params->imgfmt); } } if (params->color.primaries == MP_CSP_PRIM_AUTO) {