[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