From 9cc5630fd54d9abadd52fdedb1bac30d1b09d99a Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 25 Jul 2013 23:02:23 +0200 Subject: video: support setting libswscale chroma position --- configure | 12 ++++++++++++ video/csputils.c | 9 +++++++++ video/csputils.h | 1 + video/mp_image.c | 4 +++- video/out/vo_x11.c | 1 + video/sws_utils.c | 15 +++++++++++++++ 6 files changed, 41 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 2e6dc67723..1426fd3cb0 100755 --- a/configure +++ b/configure @@ -2647,6 +2647,17 @@ fi echores "$_avcodec_has_text_flag_api" +echocheck "libavcodec avcodec_enum_to_chroma_pos API" +_avcodec_has_chroma_pos_api=no +statement_check libavcodec/avcodec.h 'int x, y; avcodec_enum_to_chroma_pos(&x, &y, AVCHROMA_LOC_UNSPECIFIED)' && _avcodec_has_chroma_pos_api=yes +if test "$_avcodec_has_chroma_pos_api" = yes ; then + def_avcodec_has_chroma_pos_api='#define HAVE_AVCODEC_CHROMA_POS_API 1' +else + def_avcodec_has_chroma_pos_api='#define HAVE_AVCODEC_CHROMA_POS_API 0' +fi +echores "$_avcodec_has_chroma_pos_api" + + echocheck "libavutil QP API" _avutil_has_qp_api=no statement_check libavutil/frame.h 'av_frame_get_qp_table(NULL, NULL, NULL)' && _avutil_has_qp_api=yes @@ -3169,6 +3180,7 @@ $def_zlib $def_avutil_has_refcounting $def_avutil_has_qp_api $def_avcodec_has_text_flag_api +$def_avcodec_has_chroma_pos_api $def_libpostproc $def_libavdevice $def_libavfilter diff --git a/video/csputils.c b/video/csputils.c index f25d20e517..1d622f6261 100644 --- a/video/csputils.c +++ b/video/csputils.c @@ -116,6 +116,15 @@ enum mp_chroma_location avchroma_location_to_mp(int avloc) } } +int mp_chroma_location_to_av(enum mp_chroma_location mploc) +{ + switch (mploc) { + case MP_CHROMA_LEFT: return AVCHROMA_LOC_LEFT; + case MP_CHROMA_CENTER: return AVCHROMA_LOC_CENTER; + default: return AVCHROMA_LOC_UNSPECIFIED; + } +} + // Return location of chroma samples relative to luma samples. 0/0 means // centered. Other possible values are -1 (top/left) and +1 (right/bottom). void mp_get_chroma_location(enum mp_chroma_location loc, int *x, int *y) diff --git a/video/csputils.h b/video/csputils.h index 8c9806a1a3..2a0f2e14fb 100644 --- a/video/csputils.h +++ b/video/csputils.h @@ -144,6 +144,7 @@ int mp_csp_levels_to_avcol_range(enum mp_csp_levels range); enum mp_csp mp_csp_guess_colorspace(int width, int height); enum mp_chroma_location avchroma_location_to_mp(int avloc); +int mp_chroma_location_to_av(enum mp_chroma_location mploc); void mp_get_chroma_location(enum mp_chroma_location loc, int *x, int *y); diff --git a/video/mp_image.c b/video/mp_image.c index 34bd143547..9324e50882 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -411,7 +411,8 @@ bool mp_image_params_equals(const struct mp_image_params *p1, p1->w == p2->w && p1->h == p2->h && p1->d_w == p2->d_w && p1->d_h == p2->d_h && p1->colorspace == p2->colorspace && - p1->colorlevels == p2->colorlevels; + p1->colorlevels == p2->colorlevels && + p1->chroma_location == p2->chroma_location; } void mp_image_params_from_image(struct mp_image_params *params, @@ -426,6 +427,7 @@ void mp_image_params_from_image(struct mp_image_params *params, .d_h = image->display_h, .colorspace = image->colorspace, .colorlevels = image->levels, + .chroma_location = image->chroma_location, }; } diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c index 6eef918b9e..e5def2fc9a 100644 --- a/video/out/vo_x11.c +++ b/video/out/vo_x11.c @@ -387,6 +387,7 @@ static bool resize(struct vo *vo) .d_w = p->dst_w, .d_h = p->dst_h, }; + mp_image_params_guess_csp(&p->sws->dst); if (mp_sws_reinit(p->sws) < 0) return false; diff --git a/video/sws_utils.c b/video/sws_utils.c index ff139ea794..c63e447762 100644 --- a/video/sws_utils.c +++ b/video/sws_utils.c @@ -19,6 +19,7 @@ #include #include +#include #include #include "sws_utils.h" @@ -227,6 +228,20 @@ int mp_sws_reinit(struct mp_sws_context *ctx) av_opt_set_double(ctx->sws, "param0", ctx->params[0], 0); av_opt_set_double(ctx->sws, "param1", ctx->params[1], 0); +#if HAVE_AVCODEC_CHROMA_POS_API + int cr_src = mp_chroma_location_to_av(src->chroma_location); + int cr_dst = mp_chroma_location_to_av(dst->chroma_location); + int cr_xpos, cr_ypos; + if (avcodec_enum_to_chroma_pos(&cr_xpos, &cr_ypos, cr_src) >= 0) { + av_opt_set_int(ctx->sws, "src_h_chr_pos", cr_xpos, 0); + av_opt_set_int(ctx->sws, "src_v_chr_pos", cr_ypos, 0); + } + if (avcodec_enum_to_chroma_pos(&cr_xpos, &cr_ypos, cr_dst) >= 0) { + av_opt_set_int(ctx->sws, "dst_h_chr_pos", cr_xpos, 0); + av_opt_set_int(ctx->sws, "dst_v_chr_pos", cr_ypos, 0); + } +#endif + // This can fail even with normal operation, e.g. if a conversion path // simply does not support these settings. sws_setColorspaceDetails(ctx->sws, sws_getCoefficients(s_csp), s_range, -- cgit v1.2.3