[FFmpeg-devel] [PATCH v3 1/2] lavfi/vaapi: Improve support for colour properties

Song, Ruiling ruiling.song at intel.com
Mon Mar 4 13:36:06 EET 2019


The patch basically looks good. Some comments inline.
> -----Original Message-----
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf Of
> Mark Thompson
> Sent: Thursday, February 28, 2019 8:38 AM
> To: ffmpeg-devel at ffmpeg.org
> Subject: [FFmpeg-devel] [PATCH v3 1/2] lavfi/vaapi: Improve support for colour
> properties
> 
> 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.
> ---
> Not much change since the version sent two months ago - rebased, and the
> transpose filter updated to match the others.
> 
> 
>  libavfilter/vaapi_vpp.c            | 273 ++++++++++++++++++++++++++++-
>  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 +-
>  libavfilter/vf_transpose_vaapi.c   |  15 +-
>  7 files changed, 309 insertions(+), 38 deletions(-)
> 
> diff --git a/libavfilter/vaapi_vpp.c b/libavfilter/vaapi_vpp.c
> index c5bbc3b85b..f4ee622a2b 100644
> --- a/libavfilter/vaapi_vpp.c
> +++ b/libavfilter/vaapi_vpp.c
> @@ -234,18 +234,273 @@ 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[] = {

Why using these magic number instead of meaningful enum value?
And two entries added for VAProcColorStandardBT601, seems that only the first will be returned?
> +        { 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.
Here (a*4+b*2+c)  is chosen as the score function, I am not sure whether (a + b + c) is just ok? 

> +    best_score = -1;
> +    worst_score = 4 * (props->colorspace != AVCOL_SPC_UNSPECIFIED) +
> +                  2 * (props->color_trc != AVCOL_TRC_UNSPECIFIED) +
> +                      (props->color_primaries != AVCOL_PRI_UNSPECIFIED);
Seems that the outer loop here is just used to re-iterate through nb_vacs to find the best match again?
Can we remove the outer-loop-over-k like below?

best_va_standard = VAProcColorStandardNone;
for (i = 0; i < nb_vacs; i++) {
	...
	...
               // Only include things which matched something.
                if ((worst_score == 0 || score < worst_score) &&
                    (best_score == -1 || score < best_score)) {
                    best_score = score;
	    best_va_standard = t->va_color_standard;
	}
}
props->va_color_standard = best_va_standard;

Thanks!
Ruiling
> +    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)
> +{
> +#if VA_CHECK_VERSION(1, 1, 0)
> +    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;
> +#else
> +    props->va_chroma_sample_location = 0;
> +#endif
> +}
> +
> +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
> +#if VA_CHECK_VERSION(1, 1, 0)
> +    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;
>      }
> +#else
> +    props->va_color_range = 0;
> +#endif
> +}
> +
> +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,
> 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 f67a1c8e79..665e395225 100644
> --- a/libavfilter/vf_deinterlace_vaapi.c
> +++ b/libavfilter/vf_deinterlace_vaapi.c
> @@ -238,6 +238,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);
> @@ -253,16 +257,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, &params,
> +                                             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);
> @@ -305,10 +311,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, &params, output_surface);
> +    err = ff_vaapi_vpp_colour_properties(avctx, &params,
> +                                         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, &params, 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, &params, output_surface);
> +    err = ff_vaapi_vpp_colour_properties(avctx, &params,
> +                                         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, &params, 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, &params, output_surface);
> +    err = ff_vaapi_vpp_colour_properties(avctx, &params,
> +                                         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, &params, output_surface);
>      if (err < 0)
>          goto fail;
> 
> diff --git a/libavfilter/vf_transpose_vaapi.c b/libavfilter/vf_transpose_vaapi.c
> index 0e2acc9983..6536fa8fe0 100644
> --- a/libavfilter/vf_transpose_vaapi.c
> +++ b/libavfilter/vf_transpose_vaapi.c
> @@ -150,6 +150,10 @@ static int transpose_vaapi_filter_frame(AVFilterLink
> *inlink, AVFrame *input_fra
>          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 transpose vpp
> output.\n",
>             output_surface);
> @@ -176,20 +180,19 @@ static int transpose_vaapi_filter_frame(AVFilterLink
> *inlink, AVFrame *input_fra
> 
>      params.surface = input_surface;
>      params.surface_region = &input_region;
> -    params.surface_color_standard =
> -        ff_vaapi_vpp_colour_standard(input_frame->colorspace);
> 
>      params.output_region = &output_region;
>      params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK;
> -    params.output_color_standard = params.surface_color_standard;
> +
> +    err = ff_vaapi_vpp_colour_properties(avctx, &params,
> +                                         input_frame, output_frame);
> +     if (err < 0)
> +         goto fail;
> 
>      err = ff_vaapi_vpp_render_picture(avctx, &params, output_surface);
>      if (err < 0)
>          goto fail;
> 
> -    err = av_frame_copy_props(output_frame, input_frame);
> -    if (err < 0)
> -        goto fail;
>      av_frame_free(&input_frame);
> 
>      av_log(avctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n",
> --
> 2.19.2
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel


More information about the ffmpeg-devel mailing list