From ad5c43bb36b0d3615bb5f9c8ebf626038abb384a Mon Sep 17 00:00:00 2001 From: Neil Birkbeck Date: Tue, 21 Oct 2014 23:40:06 -0700 Subject: avfilter/vf_idet: Fixes issue with idet not flushing last frame. Uses a similar approach as vf_yadif to flush the last frame in idet. Quick test with 50 frames from vsynth1: ./ffmpeg.old -i fate-suite/ffmpeg-synthetic/vsynth1/%02d.pgm -vf idet -f mp4 -y /dev/null 2>&1 | grep Multi (gives) [Parsed_idet_0 @ 0x261ebb0] Multi frame detection: TFF:0 BFF:0 Progressive:48 Undetermined:1 ./ffmpeg -i fate-suite/ffmpeg-synthetic/vsynth1/%02d.pgm -vf idet -f mp4 -y /dev/null 2>&1 | grep Multi (gives) [Parsed_idet_0 @ 0x35a0bb0] Multi frame detection: TFF:0 BFF:0 Progressive:49 Undetermined:1 Fate tests have been updated. (In testing, it seems this filter will also need a subsequent patch for single frame input) Signed-off-by: Neil Birkbeck Signed-off-by: Michael Niedermayer --- libavfilter/vf_idet.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'libavfilter/vf_idet.c') diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c index 339f4a6507..b9c4070d48 100644 --- a/libavfilter/vf_idet.c +++ b/libavfilter/vf_idet.c @@ -191,6 +191,35 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref) return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur)); } +static int request_frame(AVFilterLink *link) +{ + AVFilterContext *ctx = link->src; + IDETContext *idet = ctx->priv; + + do { + int ret; + + if (idet->eof) + return AVERROR_EOF; + + ret = ff_request_frame(link->src->inputs[0]); + + if (ret == AVERROR_EOF && idet->cur) { + AVFrame *next = av_frame_clone(idet->next); + + if (!next) + return AVERROR(ENOMEM); + + filter_frame(link->src->inputs[0], next); + idet->eof = 1; + } else if (ret < 0) { + return ret; + } + } while (!idet->cur); + + return 0; +} + static av_cold void uninit(AVFilterContext *ctx) { IDETContext *idet = ctx->priv; @@ -253,6 +282,7 @@ static av_cold int init(AVFilterContext *ctx) { IDETContext *idet = ctx->priv; + idet->eof = 0; idet->last_type = UNDETERMINED; memset(idet->history, UNDETERMINED, HIST_SIZE); @@ -279,6 +309,7 @@ static const AVFilterPad idet_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, + .request_frame = request_frame }, { NULL } }; -- cgit v1.2.3