[FFmpeg-devel] [PATCH 2/2] avfilter/vf_tinterlace: support full-range YUV

Thomas Mundt tmundt75 at gmail.com
Fri Dec 16 18:15:40 EET 2022


Am Fr., 9. Dez. 2022 um 01:28 Uhr schrieb Niklas Haas <ffmpeg at haasn.xyz>:

> From: Niklas Haas <git at haasn.dev>
>
> This filter, when used in the "pad" mode, currently makes the
> distinction between limited and full range solely by testing for YUVJ
> pixel formats at link setup time. This is deprecated and should be
> improved to perform the detection based on the per-frame metadata.
>
> In order to make this distinction based on color range metadata, which
> is only known at the time of filtering frames, for simplicity, we simply
> allocate two copies of the "black" frame - one for limited range and the
> other for full range metadata. This could be done more dynamically (e.g.
> as-needed or simply by blitting the appropriate pixel value directly),
> but this change is relatively simple and preserves the structure of the
> existing code.
>
> This commit actually fixes a bug in FATE - the new output is correct for
> the first time. The previous md5 ref was of a frame that incorrectly
> combined full-range pixel data with limited-range black fields. The
> corresponding result has been updated.
>
> Signed-off-by: Niklas Haas <git at haasn.dev>
> ---
>  libavfilter/tinterlace.h                     |  2 +-
>  libavfilter/vf_tinterlace.c                  | 26 ++++++++++++++------
>  tests/ref/fate/filter-pixfmts-tinterlace_pad |  2 +-
>  3 files changed, 20 insertions(+), 10 deletions(-)
>
> diff --git a/libavfilter/tinterlace.h b/libavfilter/tinterlace.h
> index 4059ebf81a..37b6c10c08 100644
> --- a/libavfilter/tinterlace.h
> +++ b/libavfilter/tinterlace.h
> @@ -70,7 +70,7 @@ typedef struct TInterlaceContext {
>      int vsub;                   ///< chroma vertical subsampling
>      AVFrame *cur;
>      AVFrame *next;
> -    uint8_t *black_data[4];     ///< buffer used to fill padded lines
> +    uint8_t *black_data[2][4];  ///< buffer used to fill padded lines
> (limited/full)
>      int black_linesize[4];
>      FFDrawContext draw;
>      FFDrawColor color;
> diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
> index 7c54861de4..032629279a 100644
> --- a/libavfilter/vf_tinterlace.c
> +++ b/libavfilter/vf_tinterlace.c
> @@ -201,7 +201,8 @@ static av_cold void uninit(AVFilterContext *ctx)
>
>      av_frame_free(&tinterlace->cur );
>      av_frame_free(&tinterlace->next);
> -    av_freep(&tinterlace->black_data[0]);
> +    av_freep(&tinterlace->black_data[0][0]);
> +    av_freep(&tinterlace->black_data[1][0]);
>  }
>
>  static int config_out_props(AVFilterLink *outlink)
> @@ -225,14 +226,22 @@ static int config_out_props(AVFilterLink *outlink)
>          int ret;
>          ff_draw_init(&tinterlace->draw, outlink->format, 0);
>          ff_draw_color(&tinterlace->draw, &tinterlace->color, black);
> -        if (ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts))
> -            tinterlace->color.comp[0].u8[0] = 0;
> -        ret = av_image_alloc(tinterlace->black_data,
> tinterlace->black_linesize,
> +        /* limited range */
> +        if (!ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts)) {
> +            ret = av_image_alloc(tinterlace->black_data[0],
> tinterlace->black_linesize,
> +                                 outlink->w, outlink->h, outlink->format,
> 16);
> +            if (ret < 0)
> +                return ret;
> +            ff_fill_rectangle(&tinterlace->draw, &tinterlace->color,
> tinterlace->black_data[0],
> +                              tinterlace->black_linesize, 0, 0,
> outlink->w, outlink->h);
> +        }
> +        /* full range */
> +        tinterlace->color.comp[0].u8[0] = 0;
> +        ret = av_image_alloc(tinterlace->black_data[1],
> tinterlace->black_linesize,
>                               outlink->w, outlink->h, outlink->format, 16);
>          if (ret < 0)
>              return ret;
> -
> -        ff_fill_rectangle(&tinterlace->draw, &tinterlace->color,
> tinterlace->black_data,
> +        ff_fill_rectangle(&tinterlace->draw, &tinterlace->color,
> tinterlace->black_data[1],
>                            tinterlace->black_linesize, 0, 0, outlink->w,
> outlink->h);
>      }
>      if (tinterlace->flags & (TINTERLACE_FLAG_VLPF | TINTERLACE_FLAG_CVLPF)
> @@ -360,7 +369,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame
> *picref)
>      AVFilterLink *outlink = ctx->outputs[0];
>      TInterlaceContext *tinterlace = ctx->priv;
>      AVFrame *cur, *next, *out;
> -    int field, tff, ret;
> +    int field, tff, full, ret;
>
>      av_frame_free(&tinterlace->cur);
>      tinterlace->cur  = tinterlace->next;
> @@ -418,6 +427,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame
> *picref)
>          out->sample_aspect_ratio = av_mul_q(cur->sample_aspect_ratio,
> av_make_q(2, 1));
>
>          field = (1 + outlink->frame_count_in) & 1 ? FIELD_UPPER :
> FIELD_LOWER;
> +        full = out->color_range == AVCOL_RANGE_JPEG ||
> ff_fmt_is_in(out->format, full_scale_yuvj_pix_fmts);
>          /* copy upper and lower fields */
>          copy_picture_field(tinterlace, out->data, out->linesize,
>                             (const uint8_t **)cur->data, cur->linesize,
> @@ -425,7 +435,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame
> *picref)
>                             FIELD_UPPER_AND_LOWER, 1, field,
> tinterlace->flags);
>          /* pad with black the other field */
>          copy_picture_field(tinterlace, out->data, out->linesize,
> -                           (const uint8_t **)tinterlace->black_data,
> tinterlace->black_linesize,
> +                           (const uint8_t
> **)tinterlace->black_data[full], tinterlace->black_linesize,
>                             inlink->format, inlink->w, inlink->h,
>                             FIELD_UPPER_AND_LOWER, 1, !field,
> tinterlace->flags);
>          break;
> diff --git a/tests/ref/fate/filter-pixfmts-tinterlace_pad
> b/tests/ref/fate/filter-pixfmts-tinterlace_pad
> index 81a6961215..29321e542b 100644
> --- a/tests/ref/fate/filter-pixfmts-tinterlace_pad
> +++ b/tests/ref/fate/filter-pixfmts-tinterlace_pad
> @@ -1,4 +1,4 @@
> -gray                7ef396fecd8d1c9fe32173e4415ba671
> +gray                227a6fe36a31fbef80210823454131ea
>  yuv410p             35bc11d0d32efc9e9a969be7d720f4e6
>  yuv411p             17ef3cd22a74f7368b5e02f68779f294
>  yuv420p             93d5b6a4c44d67e4d4447e8dd0bf3d33
> --
> 2.38.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
>

Looks OK for me.

Regards,
Thomas


More information about the ffmpeg-devel mailing list