From patchwork Sun Dec 30 18:45:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 11591 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id CDCAC44D01F for ; Sun, 30 Dec 2018 20:45:25 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8CAF168A81F; Sun, 30 Dec 2018 20:45:22 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 682E668A812 for ; Sun, 30 Dec 2018 20:45:16 +0200 (EET) Received: by mail-wr1-f68.google.com with SMTP id t27so25090341wra.6 for ; Sun, 30 Dec 2018 10:45:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=yLNBAY4MPPVUaWbarNOrPHS41EQHvfGtfSUlLRi5/mA=; b=ZWJP6r5yKkxczu/7F7ThQHT5WiJFPBnfs9P4lXtp2lec0KChCsKVeKecGFX01Me9fe 7qUN49Z1vyC3v5RkeWldHHgVhUc5qWgza3wIFIeuWQw8cwZ3pn50QLoms8et2EqmWOuO TAB97wA9vPFQbF3nl4Fue6pFhsiU+1NnUqSV8uqmOUJj4EA3DPqOxjPYK21Pmv9U/oLT rUfyitoUT7I4YW78FhiI7n4T7EIkwP7a4vFeTO6FSbQK5LlYSmtIAVMY4a8plbNxSO4l z55TsnY7nLXWGp+DX3/hfGd6kVzsGWGQvNvjC+rCnzpUbrWYCh/2u4u25ZTRrpPWpCPr xCfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=yLNBAY4MPPVUaWbarNOrPHS41EQHvfGtfSUlLRi5/mA=; b=RakEYyPIefLuQ58hUxx0RbTXXizg3zV8G/h/Tw7lRZb+pBiwbB2c1+q4yPy/KRnWbo n1enhMxnIoNReLu7s7bR46a3Z5K8OumqZwyEHU80r7l/7CJRZkYRZfbSV3i04cJ9FWDL G7TRu9hSfxV8rc0l9S3OlbcjQiOwVv2bWATIB6axxi+bQIeZyfamErxThtv9tiZl7jsn CWlAYOqXswUnR7wpSp7JA/CxG2RkudQM7+hPvN7Jek/c48qzWT90y+vamLqL04Y+e9aw QHQto/u5tBcefwPymo5BtZEUoVjrgtpXYDK5wGaT81Zl1gqF+4JAnxq7CvvWs6tquwp/ Q5Lg== X-Gm-Message-State: AJcUukd4adfOtyOZjSbRbgaBuC0G/22cEw/7ZKRWFbmAMZUogvxqFcaA IhTVjqdv/m0x5M2fGTJ8jj0a8R6DtJc= X-Google-Smtp-Source: ALg8bN79mDWVaYyXumlPpyg7HvgT3xUI5qFOFFnn5GE7BJuI/zLs8J4c2LBmQVXaX159N93cL912bQ== X-Received: by 2002:adf:ffca:: with SMTP id x10mr32823337wrs.289.1546195522725; Sun, 30 Dec 2018 10:45:22 -0800 (PST) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id j8sm84985136wmd.0.2018.12.30.10.45.21 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 30 Dec 2018 10:45:22 -0800 (PST) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 30 Dec 2018 18:45:17 +0000 Message-Id: <20181230184518.4774-1-sw@jkqxz.net> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] lavfi/vaapi: Improve support for colour properties X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Attempts to pick the set of supported colour properties best matching the input. Output is then set with the same values, except for the colour matrix which may change when converting between RGB and YUV. --- libavfilter/vaapi_vpp.c | 265 ++++++++++++++++++++++++++++- libavfilter/vaapi_vpp.h | 5 +- libavfilter/vf_deinterlace_vaapi.c | 16 +- libavfilter/vf_misc_vaapi.c | 13 +- libavfilter/vf_procamp_vaapi.c | 13 +- libavfilter/vf_scale_vaapi.c | 12 +- 6 files changed, 292 insertions(+), 32 deletions(-) diff --git a/libavfilter/vaapi_vpp.c b/libavfilter/vaapi_vpp.c index c5bbc3b85b..ee1075fd90 100644 --- a/libavfilter/vaapi_vpp.c +++ b/libavfilter/vaapi_vpp.c @@ -234,20 +234,267 @@ fail: return err; } -int ff_vaapi_vpp_colour_standard(enum AVColorSpace av_cs) +typedef struct VAAPIColourProperties { + VAProcColorStandardType va_color_standard; + + enum AVColorPrimaries color_primaries; + enum AVColorTransferCharacteristic color_trc; + enum AVColorSpace colorspace; + + uint8_t va_chroma_sample_location; + uint8_t va_color_range; + + enum AVColorRange color_range; + enum AVChromaLocation chroma_sample_location; +} VAAPIColourProperties; + +static const VAAPIColourProperties* + vaapi_vpp_find_colour_props(VAProcColorStandardType vacs) +{ + static const VAAPIColourProperties cs_map[] = { + { VAProcColorStandardBT601, 5, 6, 5 }, + { VAProcColorStandardBT601, 6, 6, 6 }, + { VAProcColorStandardBT709, 1, 1, 1 }, + { VAProcColorStandardBT470M, 4, 4, 4 }, + { VAProcColorStandardBT470BG, 5, 5, 5 }, + { VAProcColorStandardSMPTE170M, 6, 6, 6 }, + { VAProcColorStandardSMPTE240M, 7, 7, 7 }, + { VAProcColorStandardGenericFilm, 8, 1, 1 }, +#if VA_CHECK_VERSION(1, 1, 0) + { VAProcColorStandardSRGB, 1, 13, 0 }, + { VAProcColorStandardXVYCC601, 1, 11, 5 }, + { VAProcColorStandardXVYCC709, 1, 11, 1 }, + { VAProcColorStandardBT2020, 9, 14, 9 }, +#endif + }; + int i; + for (i = 0; i < FF_ARRAY_ELEMS(cs_map); i++) { + if (vacs == cs_map[i].va_color_standard) + return &cs_map[i]; + } + return NULL; +} + +static void vaapi_vpp_fill_colour_standard(VAAPIColourProperties *props, + VAProcColorStandardType *vacs, + int nb_vacs) +{ + const VAAPIColourProperties *t; + int i, k, score, best_score, worst_score; + + // If the driver supports explicit use of the standard values then just + // use them and avoid doing any mapping. (The driver may not support + // some particular code point, but it still has enough information to + // make a better fallback choice than we do in that case.) +#if VA_CHECK_VERSION(1, 1, 0) + for (i = 0; i < nb_vacs; i++) { + if (vacs[i] == VAProcColorStandardExplicit) { + props->va_color_standard = VAProcColorStandardExplicit; + return; + } + } +#endif + + // Give scores to the possible options and choose the lowest one. + // An exact match will score zero and therefore always be chosen, as + // will a partial match where all unmatched elements are explicitly + // unspecified. (If all elements are unspecified this will use the + // first available value.) If no options match at all then just + // pass "none" to the driver and let it make its own choice. + best_score = -1; + worst_score = 4 * (props->colorspace != AVCOL_SPC_UNSPECIFIED) + + 2 * (props->color_trc != AVCOL_TRC_UNSPECIFIED) + + (props->color_primaries != AVCOL_PRI_UNSPECIFIED); + for (k = 0; k < 2; k++) { + for (i = 0; i < nb_vacs; i++) { + t = vaapi_vpp_find_colour_props(vacs[i]); + if (!t) + continue; + + score = 0; + if (props->colorspace != AVCOL_SPC_UNSPECIFIED && + props->colorspace != AVCOL_SPC_RGB) + score += 4 * (props->colorspace != t->colorspace); + if (props->color_trc != AVCOL_TRC_UNSPECIFIED) + score += 2 * (props->color_trc != t->color_trc); + if (props->color_primaries != AVCOL_PRI_UNSPECIFIED) + score += (props->color_primaries != t->color_primaries); + + if (k == 0) { + // Only include things which matched something. + if ((worst_score == 0 || score < worst_score) && + (best_score == -1 || score < best_score)) + best_score = score; + } else { + if (score == best_score) { + props->va_color_standard = t->va_color_standard; + return; + } + } + } + + if (best_score == -1) + break; + } + props->va_color_standard = VAProcColorStandardNone; +} + +static void vaapi_vpp_fill_chroma_sample_location(VAAPIColourProperties *props) +{ + static const struct { + enum AVChromaLocation av; + uint8_t va; + } csl_map[] = { + { AVCHROMA_LOC_UNSPECIFIED, VA_CHROMA_SITING_UNKNOWN }, + { AVCHROMA_LOC_LEFT, VA_CHROMA_SITING_VERTICAL_CENTER | + VA_CHROMA_SITING_HORIZONTAL_LEFT }, + { AVCHROMA_LOC_CENTER, VA_CHROMA_SITING_VERTICAL_CENTER | + VA_CHROMA_SITING_HORIZONTAL_CENTER }, + { AVCHROMA_LOC_TOPLEFT, VA_CHROMA_SITING_VERTICAL_TOP | + VA_CHROMA_SITING_HORIZONTAL_LEFT }, + { AVCHROMA_LOC_TOP, VA_CHROMA_SITING_VERTICAL_TOP | + VA_CHROMA_SITING_HORIZONTAL_CENTER }, + { AVCHROMA_LOC_BOTTOMLEFT, VA_CHROMA_SITING_VERTICAL_BOTTOM | + VA_CHROMA_SITING_HORIZONTAL_LEFT }, + { AVCHROMA_LOC_BOTTOM, VA_CHROMA_SITING_VERTICAL_BOTTOM | + VA_CHROMA_SITING_HORIZONTAL_CENTER }, + }; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(csl_map); i++) { + if (props->chroma_sample_location == csl_map[i].av) { + props->va_chroma_sample_location = csl_map[i].va; + return; + } + } + props->va_chroma_sample_location = VA_CHROMA_SITING_UNKNOWN; +} + +static void vaapi_vpp_fill_colour_range(VAAPIColourProperties *props) { - switch(av_cs) { -#define CS(av, va) case AVCOL_SPC_ ## av: return VAProcColorStandard ## va; - CS(BT709, BT709); - CS(BT470BG, BT601); - CS(SMPTE170M, SMPTE170M); - CS(SMPTE240M, SMPTE240M); -#undef CS + switch (props->color_range) { + case AVCOL_RANGE_MPEG: + props->va_color_range = VA_SOURCE_RANGE_REDUCED; + break; + case AVCOL_RANGE_JPEG: + props->va_color_range = VA_SOURCE_RANGE_FULL; + break; + case AVCOL_RANGE_UNSPECIFIED: default: - return VAProcColorStandardNone; + props->va_color_range = VA_SOURCE_RANGE_UNKNOWN; } } +static void vaapi_vpp_fill_colour_properties(AVFilterContext *avctx, + VAAPIColourProperties *props, + VAProcColorStandardType *vacs, + int nb_vacs) +{ + vaapi_vpp_fill_colour_standard(props, vacs, nb_vacs); + vaapi_vpp_fill_chroma_sample_location(props); + vaapi_vpp_fill_colour_range(props); + + av_log(avctx, AV_LOG_DEBUG, "Mapped colour properties %s %s/%s/%s %s " + "to VA standard %d chroma siting %#x range %#x.\n", + av_color_range_name(props->color_range), + av_color_space_name(props->colorspace), + av_color_primaries_name(props->color_primaries), + av_color_transfer_name(props->color_trc), + av_chroma_location_name(props->chroma_sample_location), + props->va_color_standard, + props->va_chroma_sample_location, props->va_color_range); +} + +static int vaapi_vpp_frame_is_rgb(const AVFrame *frame) +{ + const AVHWFramesContext *hwfc; + const AVPixFmtDescriptor *desc; + av_assert0(frame->format == AV_PIX_FMT_VAAPI && + frame->hw_frames_ctx); + hwfc = (const AVHWFramesContext*)frame->hw_frames_ctx->data; + desc = av_pix_fmt_desc_get(hwfc->sw_format); + av_assert0(desc); + return !!(desc->flags & AV_PIX_FMT_FLAG_RGB); +} + +int ff_vaapi_vpp_colour_properties(AVFilterContext *avctx, + VAProcPipelineParameterBuffer *params, + const AVFrame *input_frame, + AVFrame *output_frame) +{ + VAAPIVPPContext *ctx = avctx->priv; + VAAPIColourProperties input_props, output_props; + const VAAPIColourProperties *output_standard; + VAProcPipelineCaps caps; + VAStatus vas; + + vas = vaQueryVideoProcPipelineCaps(ctx->hwctx->display, ctx->va_context, + ctx->filter_buffers, ctx->nb_filter_buffers, + &caps); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query capabilities for " + "colour standard support: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR_EXTERNAL; + } + + input_props = (VAAPIColourProperties) { + .colorspace = vaapi_vpp_frame_is_rgb(input_frame) + ? AVCOL_SPC_RGB : input_frame->colorspace, + .color_primaries = input_frame->color_primaries, + .color_trc = input_frame->color_trc, + .color_range = input_frame->color_range, + .chroma_sample_location = input_frame->chroma_location, + }; + + vaapi_vpp_fill_colour_properties(avctx, &input_props, + caps.input_color_standards, + caps.num_input_color_standards); + + output_props = (VAAPIColourProperties) { + .colorspace = vaapi_vpp_frame_is_rgb(output_frame) + ? AVCOL_SPC_RGB : output_frame->colorspace, + .color_primaries = output_frame->color_primaries, + .color_trc = output_frame->color_trc, + .color_range = output_frame->color_range, + .chroma_sample_location = output_frame->chroma_location, + }; + vaapi_vpp_fill_colour_properties(avctx, &output_props, + caps.output_color_standards, + caps.num_output_color_standards); + + // If the properties weren't filled completely in the output frame and + // we chose a fixed standard then fill the known values in here. + output_standard = vaapi_vpp_find_colour_props(output_props.va_color_standard); + if (output_standard) { + output_frame->colorspace = vaapi_vpp_frame_is_rgb(output_frame) + ? AVCOL_SPC_RGB : output_standard->color_primaries; + output_frame->color_primaries = output_standard->color_primaries; + output_frame->color_trc = output_standard->color_trc; + } + + params->surface_color_standard = input_props.va_color_standard; + params->output_color_standard = output_props.va_color_standard; + +#if VA_CHECK_VERSION(1, 1, 0) + params->input_color_properties = (VAProcColorProperties) { + .chroma_sample_location = input_props.va_chroma_sample_location, + .color_range = input_props.va_color_range, + .colour_primaries = input_props.color_primaries, + .transfer_characteristics = input_props.color_trc, + .matrix_coefficients = input_props.colorspace, + }; + params->output_color_properties = (VAProcColorProperties) { + .chroma_sample_location = output_props.va_chroma_sample_location, + .color_range = output_props.va_color_range, + .colour_primaries = output_props.color_primaries, + .transfer_characteristics = output_props.color_trc, + .matrix_coefficients = output_props.colorspace, + }; +#endif + + return 0; +} + int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx, int type, const void *data, diff --git a/libavfilter/vaapi_vpp.h b/libavfilter/vaapi_vpp.h index 96f720f07d..cb95737ccb 100644 --- a/libavfilter/vaapi_vpp.h +++ b/libavfilter/vaapi_vpp.h @@ -67,7 +67,10 @@ int ff_vaapi_vpp_config_input(AVFilterLink *inlink); int ff_vaapi_vpp_config_output(AVFilterLink *outlink); -int ff_vaapi_vpp_colour_standard(enum AVColorSpace av_cs); +int ff_vaapi_vpp_colour_properties(AVFilterContext *avctx, + VAProcPipelineParameterBuffer *params, + const AVFrame *input_frame, + AVFrame *output_frame); int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx, int type, diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c index 97aee6588f..0737bf03cf 100644 --- a/libavfilter/vf_deinterlace_vaapi.c +++ b/libavfilter/vf_deinterlace_vaapi.c @@ -237,6 +237,10 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) goto fail; } + err = av_frame_copy_props(output_frame, input_frame); + if (err < 0) + goto fail; + output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3]; av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for " "deinterlace output.\n", output_surface); @@ -252,16 +256,18 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) params.surface = input_surface; params.surface_region = &input_region; - params.surface_color_standard = - ff_vaapi_vpp_colour_standard(input_frame->colorspace); params.output_region = NULL; params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK; - params.output_color_standard = params.surface_color_standard; params.pipeline_flags = 0; params.filter_flags = VA_FRAME_PICTURE; + err = ff_vaapi_vpp_colour_properties(avctx, ¶ms, + input_frame, output_frame); + if (err < 0) + goto fail; + if (!ctx->auto_enable || input_frame->interlaced_frame) { vas = vaMapBuffer(vpp_ctx->hwctx->display, vpp_ctx->filter_buffers[0], &filter_params_addr); @@ -304,10 +310,6 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) if (err < 0) goto fail; - err = av_frame_copy_props(output_frame, input_frame); - if (err < 0) - goto fail; - if (ctx->field_rate == 2) { if (field == 0) output_frame->pts = 2 * input_frame->pts; diff --git a/libavfilter/vf_misc_vaapi.c b/libavfilter/vf_misc_vaapi.c index e227c9ff6b..0962fe7b69 100644 --- a/libavfilter/vf_misc_vaapi.c +++ b/libavfilter/vf_misc_vaapi.c @@ -153,6 +153,10 @@ static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) goto fail; } + err = av_frame_copy_props(output_frame, input_frame); + if (err < 0) + goto fail; + output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3]; av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for misc vpp output.\n", output_surface); @@ -170,23 +174,22 @@ static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) } params.surface = input_surface; params.surface_region = &input_region; - params.surface_color_standard = - ff_vaapi_vpp_colour_standard(input_frame->colorspace); params.output_region = NULL; params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK; - params.output_color_standard = params.surface_color_standard; params.pipeline_flags = 0; params.filter_flags = VA_FRAME_PICTURE; - err = ff_vaapi_vpp_render_picture(avctx, ¶ms, output_surface); + err = ff_vaapi_vpp_colour_properties(avctx, ¶ms, + input_frame, output_frame); if (err < 0) goto fail; - err = av_frame_copy_props(output_frame, input_frame); + err = ff_vaapi_vpp_render_picture(avctx, ¶ms, output_surface); if (err < 0) goto fail; + av_frame_free(&input_frame); av_log(avctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n", diff --git a/libavfilter/vf_procamp_vaapi.c b/libavfilter/vf_procamp_vaapi.c index 46f3ab6465..8c3ec94038 100644 --- a/libavfilter/vf_procamp_vaapi.c +++ b/libavfilter/vf_procamp_vaapi.c @@ -154,6 +154,10 @@ static int procamp_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame goto fail; } + err = av_frame_copy_props(output_frame, input_frame); + if (err < 0) + goto fail; + output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3]; av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for procamp output.\n", output_surface); @@ -167,12 +171,9 @@ static int procamp_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame params.surface = input_surface; params.surface_region = &input_region; - params.surface_color_standard = - ff_vaapi_vpp_colour_standard(input_frame->colorspace); params.output_region = NULL; params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK; - params.output_color_standard = params.surface_color_standard; params.pipeline_flags = 0; params.filter_flags = VA_FRAME_PICTURE; @@ -180,13 +181,15 @@ static int procamp_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame params.filters = &vpp_ctx->filter_buffers[0]; params.num_filters = 1; - err = ff_vaapi_vpp_render_picture(avctx, ¶ms, output_surface); + err = ff_vaapi_vpp_colour_properties(avctx, ¶ms, + input_frame, output_frame); if (err < 0) goto fail; - err = av_frame_copy_props(output_frame, input_frame); + err = ff_vaapi_vpp_render_picture(avctx, ¶ms, output_surface); if (err < 0) goto fail; + av_frame_free(&input_frame); av_log(avctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n", diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c index 3699363140..b56217c56d 100644 --- a/libavfilter/vf_scale_vaapi.c +++ b/libavfilter/vf_scale_vaapi.c @@ -112,6 +112,10 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) goto fail; } + err = av_frame_copy_props(output_frame, input_frame); + if (err < 0) + goto fail; + output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3]; av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for scale output.\n", output_surface); @@ -129,21 +133,19 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) params.surface = input_surface; params.surface_region = &input_region; - params.surface_color_standard = - ff_vaapi_vpp_colour_standard(input_frame->colorspace); params.output_region = 0; params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK; - params.output_color_standard = params.surface_color_standard; params.pipeline_flags = 0; params.filter_flags = ctx->mode; - err = ff_vaapi_vpp_render_picture(avctx, ¶ms, output_surface); + err = ff_vaapi_vpp_colour_properties(avctx, ¶ms, + input_frame, output_frame); if (err < 0) goto fail; - err = av_frame_copy_props(output_frame, input_frame); + err = ff_vaapi_vpp_render_picture(avctx, ¶ms, output_surface); if (err < 0) goto fail;