[FFmpeg-devel] [PATCH] lavf/vf_deinterlace_vaapi: flush queued frame in field mode

Aman Gupta ffmpeg at tmm1.net
Wed Aug 14 05:04:40 EEST 2019


On Tue, Aug 13, 2019 at 7:01 PM Fu, Linjie <linjie.fu at intel.com> wrote:

> > -----Original Message-----
> > From: Fu, Linjie
> > Sent: Friday, August 2, 2019 17:54
> > To: ffmpeg-devel at ffmpeg.org
> > Cc: Fu, Linjie <linjie.fu at intel.com>
> > Subject: [PATCH] lavf/vf_deinterlace_vaapi: flush queued frame in field
> > mode
> >
> > Add deint_vaapi_request_frame for deinterlace_vaapi, send NULL frame
> > to flush the queued frame.
> >
> > Fix the frame drop issue in field mode:
> >
> > ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -v verbose -c:v
> > h264 -i ./input.h264 -vf 'format=nv12|vaapi,hwupload,
> >         deinterlace_vaapi=mode=bob:rate=field,hwdownload,format=nv12'
> > -pix_fmt yuv420p -f rawvideo -vsync passthrough -y dump.yuv
> >
> > Signed-off-by: Linjie Fu <linjie.fu at intel.com>
> > ---
> >  libavfilter/vf_deinterlace_vaapi.c | 46
> > ++++++++++++++++++++++++++++++++------
> >  1 file changed, 39 insertions(+), 7 deletions(-)
> >
> > diff --git a/libavfilter/vf_deinterlace_vaapi.c
> > b/libavfilter/vf_deinterlace_vaapi.c
> > index 72d0349..c811327 100644
> > --- a/libavfilter/vf_deinterlace_vaapi.c
> > +++ b/libavfilter/vf_deinterlace_vaapi.c
> > @@ -48,6 +48,9 @@ typedef struct DeintVAAPIContext {
> >      int                queue_count;
> >      AVFrame           *frame_queue[MAX_REFERENCES];
> >      int                extra_delay_for_timestamps;
> > +
> > +    int                eof;
> > +    int                prev_pts;
> >  } DeintVAAPIContext;
> >
> >  static const char *deint_vaapi_mode_name(int mode)
> > @@ -190,11 +193,16 @@ static int deint_vaapi_filter_frame(AVFilterLink
> > *inlink, AVFrame *input_frame)
> >      void *filter_params_addr = NULL;
> >      int err, i, field, current_frame_index;
> >
> > -    av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u
> (%"PRId64").\n",
> > -           av_get_pix_fmt_name(input_frame->format),
> > -           input_frame->width, input_frame->height, input_frame->pts);
> > +    // NULL frame is used to flush the queue in field mode
> > +    if (input_frame)
> > +        av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u
> > (%"PRId64").\n",
> > +            av_get_pix_fmt_name(input_frame->format),
> > +            input_frame->width, input_frame->height, input_frame->pts);
> > +    else if (ctx->field_rate == 1) {
> > +        return 0;
> > +    }
> >
> > -    if (ctx->queue_count < ctx->queue_depth) {
> > +    if (input_frame && ctx->queue_count < ctx->queue_depth) {
> >          ctx->frame_queue[ctx->queue_count++] = input_frame;
> >          if (ctx->queue_count < ctx->queue_depth) {
> >              // Need more reference surfaces before we can continue.
> > @@ -291,6 +299,8 @@ static int deint_vaapi_filter_frame(AVFilterLink
> *inlink,
> > AVFrame *input_frame)
> >          if (ctx->field_rate == 2) {
> >              if (field == 0)
> >                  output_frame->pts = 2 * input_frame->pts;
> > +            else if (ctx->eof)
> > +                output_frame->pts = 3 * input_frame->pts -
> ctx->prev_pts;
> >              else
> >                  output_frame->pts = input_frame->pts +
> >                      ctx->frame_queue[current_frame_index + 1]->pts;
> > @@ -306,6 +316,8 @@ static int deint_vaapi_filter_frame(AVFilterLink
> *inlink,
> > AVFrame *input_frame)
> >              break;
> >      }
> >
> > +    ctx->prev_pts = input_frame->pts;
> > +
> >      return err;
> >
> >  fail:
> > @@ -315,6 +327,25 @@ fail:
> >      return err;
> >  }
> >
> > +static int deint_vaapi_request_frame(AVFilterLink *link)
> > +{
> > +    AVFilterContext *avctx = link->src;
> > +    DeintVAAPIContext *ctx   = avctx->priv;
> > +    int ret;
> > +
> > +    if (ctx->eof)
> > +        return AVERROR_EOF;
> > +
> > +    ret = ff_request_frame(link->src->inputs[0]);
> > +    if (ret == AVERROR_EOF) {
> > +        ctx->eof = 1;
> > +        deint_vaapi_filter_frame(link->src->inputs[0], NULL);
> > +    } else if (ret < 0)
> > +        return ret;
> > +
> > +    return 0;
> > +}
> > +
> >  static av_cold int deint_vaapi_init(AVFilterContext *avctx)
> >  {
> >      VAAPIVPPContext *vpp_ctx = avctx->priv;
> > @@ -376,9 +407,10 @@ static const AVFilterPad deint_vaapi_inputs[] = {
> >
> >  static const AVFilterPad deint_vaapi_outputs[] = {
> >      {
> > -        .name = "default",
> > -        .type = AVMEDIA_TYPE_VIDEO,
> > -        .config_props = &deint_vaapi_config_output,
> > +        .name           = "default",
> > +        .type           = AVMEDIA_TYPE_VIDEO,
> > +        .request_frame  = &deint_vaapi_request_frame,
> > +        .config_props   = &deint_vaapi_config_output,
> >      },
> >      { NULL }
> >  };
> > --
> > 2.7.4
> Ping.
>

LGTM


> _______________________________________________
> 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".


More information about the ffmpeg-devel mailing list