avfilter/vf_idet: Fixes issue with idet not flushing last frame.
authorNeil Birkbeck <neil.birkbeck@gmail.com>
Wed, 22 Oct 2014 06:40:06 +0000 (23:40 -0700)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 22 Oct 2014 13:07:36 +0000 (15:07 +0200)
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 <neil.birkbeck@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavfilter/vf_idet.c
libavfilter/vf_idet.h
tests/ref/fate/filter-idet

index 339f4a650764dacac57a4d287e3a11d7aa247bf3..b9c4070d48767ec1419d97b824fec163995e06b6 100644 (file)
@@ -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 }
 };
index ef29fff701037324e8a1f2ecb406df2a9c2d89dc..57332dfbdde5dd3fd19fd76434ad6cc22ebce2df 100644 (file)
@@ -50,6 +50,7 @@ typedef struct {
     ff_idet_filter_func filter_line;
 
     const AVPixFmtDescriptor *csp;
+    int eof;
 } IDETContext;
 
 void ff_idet_init_x86(IDETContext *idet, int for_16b);
index f1396c5338d205b9ae49e3d566a146547a22710d..2f9f11ca52ca9267db376e6cb4c688705ae2f399 100644 (file)
@@ -1 +1 @@
-idet                1790336872e844c867a53150b8ee8810
+idet                005e6ddc8a5daf11cf866a1ec76c2572