[FFmpeg-devel] Flushing yadif

Nicolas George nicolas.george at normalesup.org
Wed May 2 13:01:31 CEST 2012


Le quartidi 14 floréal, an CCXX, Robert Nagy a écrit :
> Note that this is NOT a patch, just an untested suggestion on how to solve
> the problem with flushing the last frame from the yadif filter.
> 
> Basically, if we receive an AVERROR_EOF, use "cur" as "next" and defer the
> return of AVERROR_EOF to the next call.
> 
> I do not take poll_frame into account.

That looks right in principle, at least from the structure point of view. I
am not familiar enough with interlaced material to judge if using the first
field a second time is an acceptable alternative when the second field is
missing.

> From f1ea307b91664262197bf4f12ac66b6b4d5cbe59 Mon Sep 17 00:00:00 2001
> From: Robert Nagy <ronag89 at gmail.com>
> Date: Wed, 2 May 2012 10:03:22 +0200
> Subject: [PATCH] yadif: Add flushing of last frame.
> 
> ---
>  libavfilter/vf_yadif.c |   30 +++++++++++++++++++++---------
>  1 files changed, 21 insertions(+), 9 deletions(-)
> 
> diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
> index d8e2ad6..14a7f3e 100644
> --- a/libavfilter/vf_yadif.c
> +++ b/libavfilter/vf_yadif.c
> @@ -155,7 +155,7 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
>              if ((y ^ parity) & 1) {
>                  uint8_t *prev = &yadif->prev->data[i][y*refs];
>                  uint8_t *cur  = &yadif->cur ->data[i][y*refs];
> -                uint8_t *next = &yadif->next->data[i][y*refs];
> +                uint8_t *next = yadif->next ? &yadif->next->data[i][y*refs] : cur;
>                  uint8_t *dst  = &dstpic->data[i][y*dstpic->linesize[i]];
>                  int     mode  = y==1 || y+2==h ? 2 : yadif->mode;
>                  yadif->filter_line(dst, prev, cur, next, w, y+1<h ? refs : -refs, y ? -refs : refs, parity ^ tff, mode);
> @@ -216,9 +216,9 @@ static void return_frame(AVFilterContext *ctx, int is_second)
>      filter(ctx, yadif->out, tff ^ !is_second, tff);
>  
>      if (is_second) {
> -        if (yadif->next->pts != AV_NOPTS_VALUE &&
> +        if ((!yadif->next || yadif->next->pts != AV_NOPTS_VALUE) &&
>              yadif->cur->pts != AV_NOPTS_VALUE) {
> -            uint64_t next_pts = yadif->next->pts;
> +            uint64_t next_pts = yadif->next ? yadif->next->pts : 2*yadif->cur->pts - yadif->prev->pts;
>              uint64_t cur_pts  = yadif->cur->pts;
>              uint64_t prev_pts = yadif->prev->pts;
>  
> @@ -307,9 +307,21 @@ static int request_frame(AVFilterLink *link)
>      }
>  
>      do {
> -        int ret;
> -
> -        if ((ret = avfilter_request_frame(link->src->inputs[0])))
> +        if(!yadif->next && yadif->cur) // If there is no next then it is EOF.
> +        {

Nit: the coding style wants the braces on the same line as the if.

> +            // Allow the filter to restart.
> +            avfilter_unref_bufferp(yadif->prev);
> +            avfilter_unref_bufferp(yadif->cur );
> +            return AVERRROR_EOF;
> +        }
> +        
> +        int ret = avfilter_request_frame(link->src->inputs[0]);
> +        
> +        if(ret == AVERRROR_EOF) {
> +            start_frame(link->src->inputs[0], NULL);
> +            end_frame(link->src->inputs[0]);
> +        }
> +        else if(ret < 0)

Same here.

>              return ret;
>      } while (!yadif->cur);
>  
> @@ -347,9 +359,9 @@ static av_cold void uninit(AVFilterContext *ctx)
>  {
>      YADIFContext *yadif = ctx->priv;
>  
> -    if (yadif->prev) avfilter_unref_buffer(yadif->prev);
> -    if (yadif->cur ) avfilter_unref_buffer(yadif->cur );
> -    if (yadif->next) avfilter_unref_buffer(yadif->next);
> +    avfilter_unref_bufferp(yadif->prev);
> +    avfilter_unref_bufferp(yadif->cur );
> +    avfilter_unref_bufferp(yadif->next);

This looks unrelated. And I believe you forgot the & operators.

On the whole, it looks correct, but someone who knows interlacing must look
at it.

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120502/05f476e3/attachment.asc>


More information about the ffmpeg-devel mailing list