avfilter/vf_idet: Add analyze_interlaced_flag mode
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 1 Jan 2015 01:35:39 +0000 (02:35 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 6 Jan 2015 00:21:19 +0000 (01:21 +0100)
This should allow us to insert idet before scale and let scale have interl=-1 as default in that case

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
doc/filters.texi
libavfilter/vf_idet.c
libavfilter/vf_idet.h

index 1e2567e..f14f6a9 100644 (file)
@@ -5760,6 +5760,13 @@ Number of frames after which a given frame's contribution to the
 statistics is halved (i.e., it contributes only 0.5 to it's
 classification). The default of 0 means that all frames seen are given
 full weight of 1.0 forever.
+@item analyze_interlaced_flag
+When this is not 0 then idet will use the specified number of frames to determine
+if the interlaced flag is accurate, it will not count undetermined frames.
+If the flag is found to be accurate it will be used without any further
+computations, if it is found to be inaccuarte it will be cleared without any
+further computations. This allows inserting the idet filter as a low computational
+method to clean up the interlaced flag
 @end table
 
 @section il
index 56e6e76..4532e48 100644 (file)
@@ -34,6 +34,7 @@ static const AVOption idet_options[] = {
     { "prog_thres", "set progressive threshold", OFFSET(progressive_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 1.5},  -1, FLT_MAX, FLAGS },
     { "rep_thres",  "set repeat threshold",      OFFSET(repeat_threshold),      AV_OPT_TYPE_FLOAT, {.dbl = 3.0},  -1, FLT_MAX, FLAGS },
     { "half_life", "half life of cumulative statistics", OFFSET(half_life),     AV_OPT_TYPE_FLOAT, {.dbl = 0.0},  -1, INT_MAX, FLAGS },
+    { "analyze_interlaced_flag", "set number of frames to use to determine if the interlace flag is accurate", OFFSET(analyze_interlaced_flag), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, FLAGS },
     { NULL }
 };
 
@@ -235,6 +236,19 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref)
     AVFilterContext *ctx = link->dst;
     IDETContext *idet = ctx->priv;
 
+    // initial frame(s) and not interlaced, just pass through for
+    // the analyze_interlaced_flag mode
+    if (idet->analyze_interlaced_flag &&
+        !picref->interlaced_frame &&
+        !idet->next) {
+        return ff_filter_frame(ctx->outputs[0], picref);
+    }
+    if (idet->analyze_interlaced_flag_done) {
+        if (picref->interlaced_frame && idet->interlaced_flag_accuracy < 0)
+            picref->interlaced_frame = 0;
+        return ff_filter_frame(ctx->outputs[0], picref);
+    }
+
     if (idet->prev)
         av_frame_free(&idet->prev);
     idet->prev = idet->cur;
@@ -256,7 +270,30 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref)
             ff_idet_init_x86(idet, 1);
     }
 
-    filter(ctx);
+    if (idet->analyze_interlaced_flag) {
+        if (idet->cur->interlaced_frame) {
+            idet->cur->interlaced_frame = 0;
+            filter(ctx);
+            if (idet->last_type == PROGRESSIVE) {
+                idet->interlaced_flag_accuracy --;
+                idet->analyze_interlaced_flag --;
+            } else if (idet->last_type != UNDETERMINED) {
+                idet->interlaced_flag_accuracy ++;
+                idet->analyze_interlaced_flag --;
+            }
+            if (idet->analyze_interlaced_flag == 1) {
+                ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
+
+                if (idet->next->interlaced_frame && idet->interlaced_flag_accuracy < 0)
+                    idet->next->interlaced_frame = 0;
+                idet->analyze_interlaced_flag_done = 1;
+                av_log(ctx, AV_LOG_INFO, "Final flag accuracy %d\n", idet->interlaced_flag_accuracy);
+                return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->next));
+            }
+        }
+    } else {
+        filter(ctx);
+    }
 
     return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
 }
@@ -274,7 +311,7 @@ static int request_frame(AVFilterLink *link)
 
         ret = ff_request_frame(link->src->inputs[0]);
 
-        if (ret == AVERROR_EOF && idet->cur) {
+        if (ret == AVERROR_EOF && idet->cur && !idet->analyze_interlaced_flag_done) {
             AVFrame *next = av_frame_clone(idet->next);
 
             if (!next)
index af759b4..47e3d9c 100644 (file)
@@ -63,6 +63,10 @@ typedef struct {
     AVFrame *prev;
     ff_idet_filter_func filter_line;
 
+    int interlaced_flag_accuracy;
+    int analyze_interlaced_flag;
+    int analyze_interlaced_flag_done;
+
     const AVPixFmtDescriptor *csp;
     int eof;
 } IDETContext;