Browse code

avfilter/vf_idet: Add analyze_interlaced_flag mode

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>

Michael Niedermayer authored on 2015/01/01 10:35:39
Showing 3 changed files
... ...
@@ -5760,6 +5760,13 @@ Number of frames after which a given frame's contribution to the
5760 5760
 statistics is halved (i.e., it contributes only 0.5 to it's
5761 5761
 classification). The default of 0 means that all frames seen are given
5762 5762
 full weight of 1.0 forever.
5763
+@item analyze_interlaced_flag
5764
+When this is not 0 then idet will use the specified number of frames to determine
5765
+if the interlaced flag is accurate, it will not count undetermined frames.
5766
+If the flag is found to be accurate it will be used without any further
5767
+computations, if it is found to be inaccuarte it will be cleared without any
5768
+further computations. This allows inserting the idet filter as a low computational
5769
+method to clean up the interlaced flag
5763 5770
 @end table
5764 5771
 
5765 5772
 @section il
... ...
@@ -34,6 +34,7 @@ static const AVOption idet_options[] = {
34 34
     { "prog_thres", "set progressive threshold", OFFSET(progressive_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 1.5},  -1, FLT_MAX, FLAGS },
35 35
     { "rep_thres",  "set repeat threshold",      OFFSET(repeat_threshold),      AV_OPT_TYPE_FLOAT, {.dbl = 3.0},  -1, FLT_MAX, FLAGS },
36 36
     { "half_life", "half life of cumulative statistics", OFFSET(half_life),     AV_OPT_TYPE_FLOAT, {.dbl = 0.0},  -1, INT_MAX, FLAGS },
37
+    { "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 },
37 38
     { NULL }
38 39
 };
39 40
 
... ...
@@ -235,6 +236,19 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref)
235 235
     AVFilterContext *ctx = link->dst;
236 236
     IDETContext *idet = ctx->priv;
237 237
 
238
+    // initial frame(s) and not interlaced, just pass through for
239
+    // the analyze_interlaced_flag mode
240
+    if (idet->analyze_interlaced_flag &&
241
+        !picref->interlaced_frame &&
242
+        !idet->next) {
243
+        return ff_filter_frame(ctx->outputs[0], picref);
244
+    }
245
+    if (idet->analyze_interlaced_flag_done) {
246
+        if (picref->interlaced_frame && idet->interlaced_flag_accuracy < 0)
247
+            picref->interlaced_frame = 0;
248
+        return ff_filter_frame(ctx->outputs[0], picref);
249
+    }
250
+
238 251
     if (idet->prev)
239 252
         av_frame_free(&idet->prev);
240 253
     idet->prev = idet->cur;
... ...
@@ -256,7 +270,30 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref)
256 256
             ff_idet_init_x86(idet, 1);
257 257
     }
258 258
 
259
-    filter(ctx);
259
+    if (idet->analyze_interlaced_flag) {
260
+        if (idet->cur->interlaced_frame) {
261
+            idet->cur->interlaced_frame = 0;
262
+            filter(ctx);
263
+            if (idet->last_type == PROGRESSIVE) {
264
+                idet->interlaced_flag_accuracy --;
265
+                idet->analyze_interlaced_flag --;
266
+            } else if (idet->last_type != UNDETERMINED) {
267
+                idet->interlaced_flag_accuracy ++;
268
+                idet->analyze_interlaced_flag --;
269
+            }
270
+            if (idet->analyze_interlaced_flag == 1) {
271
+                ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
272
+
273
+                if (idet->next->interlaced_frame && idet->interlaced_flag_accuracy < 0)
274
+                    idet->next->interlaced_frame = 0;
275
+                idet->analyze_interlaced_flag_done = 1;
276
+                av_log(ctx, AV_LOG_INFO, "Final flag accuracy %d\n", idet->interlaced_flag_accuracy);
277
+                return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->next));
278
+            }
279
+        }
280
+    } else {
281
+        filter(ctx);
282
+    }
260 283
 
261 284
     return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
262 285
 }
... ...
@@ -274,7 +311,7 @@ static int request_frame(AVFilterLink *link)
274 274
 
275 275
         ret = ff_request_frame(link->src->inputs[0]);
276 276
 
277
-        if (ret == AVERROR_EOF && idet->cur) {
277
+        if (ret == AVERROR_EOF && idet->cur && !idet->analyze_interlaced_flag_done) {
278 278
             AVFrame *next = av_frame_clone(idet->next);
279 279
 
280 280
             if (!next)
... ...
@@ -63,6 +63,10 @@ typedef struct {
63 63
     AVFrame *prev;
64 64
     ff_idet_filter_func filter_line;
65 65
 
66
+    int interlaced_flag_accuracy;
67
+    int analyze_interlaced_flag;
68
+    int analyze_interlaced_flag_done;
69
+
66 70
     const AVPixFmtDescriptor *csp;
67 71
     int eof;
68 72
 } IDETContext;