[FFmpeg-devel] [PATCH] lavf/vf_deinterlace_vaapi: flush queued frame in field mode
Fu, Linjie
linjie.fu at intel.com
Mon Aug 19 04:22:32 EEST 2019
> -----Original Message-----
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf
> Of Aman Gupta
> Sent: Wednesday, August 14, 2019 10:05
> To: FFmpeg development discussions and patches <ffmpeg-
> devel at ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH] lavf/vf_deinterlace_vaapi: flush
> queued frame in field mode
>
> 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
>
Thanks for the review.
ping for merge, or other comments?
- linjie
More information about the ffmpeg-devel
mailing list