From a1380f394597e06e04195b1812300550f3c2df40 Mon Sep 17 00:00:00 2001 From: cantabile Date: Tue, 21 Aug 2012 00:03:59 +0300 Subject: video: honor the video's colormatrix and color range flags If either of them is not defined, the old behavior is used: - the colormatrix is guessed based on resolution. - the color range is assumed to be tv aka limited range. --- libmpcodecs/dec_video.c | 6 ++++++ libmpcodecs/vd_ffmpeg.c | 5 +++++ libmpdemux/stheader.h | 2 ++ libvo/csputils.c | 31 +++++++++++++++++++++++++++++++ libvo/csputils.h | 5 +++++ 5 files changed, 49 insertions(+) diff --git a/libmpcodecs/dec_video.c b/libmpcodecs/dec_video.c index 148514db95..e328f3e948 100644 --- a/libmpcodecs/dec_video.c +++ b/libmpcodecs/dec_video.c @@ -128,10 +128,16 @@ void get_detected_video_colorspace(struct sh_video *sh, struct mp_csp_details *c csp->levels_in = opts->requested_input_range; csp->levels_out = opts->requested_output_range; + if (csp->format == MP_CSP_AUTO) + csp->format = sh->colorspace; if (csp->format == MP_CSP_AUTO) csp->format = mp_csp_guess_colorspace(vf->w, vf->h); + + if (csp->levels_in == MP_CSP_LEVELS_AUTO) + csp->levels_in = sh->color_range; if (csp->levels_in == MP_CSP_LEVELS_AUTO) csp->levels_in = MP_CSP_LEVELS_TV; + if (csp->levels_out == MP_CSP_LEVELS_AUTO) csp->levels_out = MP_CSP_LEVELS_PC; } diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c index b30648b6f6..b2150579ea 100644 --- a/libmpcodecs/vd_ffmpeg.c +++ b/libmpcodecs/vd_ffmpeg.c @@ -42,6 +42,7 @@ #include "libmpdemux/demux_packet.h" #include "codec-cfg.h" #include "osdep/numcores.h" +#include "libvo/csputils.h" static const vd_info_t info = { "libavcodec video codecs", @@ -463,6 +464,10 @@ static int init_vo(sh_video_t *sh, enum PixelFormat pix_fmt) }; else supported_fmts = (const unsigned int[]){ctx->best_csp, 0xffffffff}; + + sh->colorspace = avcol_spc_to_mp_csp(avctx->colorspace); + sh->color_range = avcol_range_to_mp_csp_levels(avctx->color_range); + if (!mpcodecs_config_vo2(sh, sh->disp_w, sh->disp_h, supported_fmts, ctx->best_csp)) return -1; diff --git a/libmpdemux/stheader.h b/libmpdemux/stheader.h index c0bf9e4db0..f36ac8c347 100644 --- a/libmpdemux/stheader.h +++ b/libmpdemux/stheader.h @@ -147,6 +147,8 @@ typedef struct sh_video { float stream_aspect; // aspect ratio in media headers (DVD IFO files) int i_bps; // == bitrate (compressed bytes/sec) int disp_w, disp_h; // display size (filled by demuxer) + int colorspace; // mp_csp + int color_range; // mp_csp_levels // output driver/filters: (set by libmpcodecs core) unsigned int outfmt; unsigned int outfmtidx; diff --git a/libvo/csputils.c b/libvo/csputils.c index 3bd6e48f67..d6aed97864 100644 --- a/libvo/csputils.c +++ b/libvo/csputils.c @@ -47,6 +47,37 @@ char * const mp_csp_equalizer_names[MP_CSP_EQ_COUNT] = { "gamma", }; +enum mp_csp avcol_spc_to_mp_csp(enum AVColorSpace colorspace) +{ + switch (colorspace) { + case AVCOL_SPC_BT709: + return MP_CSP_BT_709; + break; + case AVCOL_SPC_BT470BG: + case AVCOL_SPC_SMPTE170M: + return MP_CSP_BT_601; + break; + case AVCOL_SPC_SMPTE240M: + return MP_CSP_SMPTE_240M; + break; + default: + return MP_CSP_AUTO; + } +} + +enum mp_csp_levels avcol_range_to_mp_csp_levels(enum AVColorRange range) +{ + switch (range) { + case AVCOL_RANGE_MPEG: + return MP_CSP_LEVELS_TV; + break; + case AVCOL_RANGE_JPEG: + return MP_CSP_LEVELS_PC; + break; + default: + return MP_CSP_LEVELS_AUTO; + } +} enum mp_csp mp_csp_guess_colorspace(int width, int height) { diff --git a/libvo/csputils.h b/libvo/csputils.h index 434be4a9a1..da826e84da 100644 --- a/libvo/csputils.h +++ b/libvo/csputils.h @@ -26,6 +26,7 @@ #include +#include "libavcodec/avcodec.h" /* NOTE: the csp and levels AUTO values are converted to specific ones * above vf/vo level. At least vf_scale relies on all valid settings being @@ -111,6 +112,10 @@ int mp_csp_equalizer_set(struct mp_csp_equalizer *eq, const char *property, int mp_csp_equalizer_get(struct mp_csp_equalizer *eq, const char *property, int *out_value); +enum mp_csp avcol_spc_to_mp_csp(enum AVColorSpace colorspace); + +enum mp_csp_levels avcol_range_to_mp_csp_levels(enum AVColorRange range); + enum mp_csp mp_csp_guess_colorspace(int width, int height); void mp_gen_gamma_map(unsigned char *map, int size, float gamma); -- cgit v1.2.3