avfilter/vf_tinterlace: add support for bypassing already interlaced frames
authorMarton Balint <cus@passwd.hu>
Fri, 6 Dec 2019 10:01:11 +0000 (11:01 +0100)
committerMarton Balint <cus@passwd.hu>
Sat, 14 Dec 2019 23:23:01 +0000 (00:23 +0100)
The old interlace filter worked this way before it was merged with tinterlace.

Signed-off-by: Marton Balint <cus@passwd.hu>
doc/filters.texi
libavfilter/tinterlace.h
libavfilter/version.h
libavfilter/vf_tinterlace.c

index 93f54a2..c543203 100644 (file)
@@ -18122,10 +18122,12 @@ Enable complex vertical low-pass filtering.
 This will slightly less reduce interlace 'twitter' and Moire
 patterning but better retain detail and subjective sharpness impression.
 
+@item bypass_il
+Bypass already interlaced frames, only adjust the frame rate.
 @end table
 
-Vertical low-pass filtering can only be enabled for @option{mode}
-@var{interleave_top} and @var{interleave_bottom}.
+Vertical low-pass filtering and bypassing already interlaced frames can only be
+enabled for @option{mode} @var{interleave_top} and @var{interleave_bottom}.
 
 @end table
 
index e204b61..020887f 100644 (file)
@@ -36,6 +36,7 @@
 #define TINTERLACE_FLAG_VLPF 01
 #define TINTERLACE_FLAG_CVLPF 2
 #define TINTERLACE_FLAG_EXACT_TB 4
+#define TINTERLACE_FLAG_BYPASS_IL 8
 
 enum VLPFilter {
     VLPF_OFF = 0,
index a362500..715be58 100644 (file)
@@ -31,7 +31,7 @@
 
 #define LIBAVFILTER_VERSION_MAJOR   7
 #define LIBAVFILTER_VERSION_MINOR  68
-#define LIBAVFILTER_VERSION_MICRO 100
+#define LIBAVFILTER_VERSION_MICRO 101
 
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
index 32b2ff9..0ee40ff 100644 (file)
@@ -53,6 +53,7 @@ static const AVOption tinterlace_options[] = {
     {"complex_filter",    "enable complex vertical low-pass filter",      0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_CVLPF},INT_MIN, INT_MAX, FLAGS, "flags" },
     {"cvlpf",             "enable complex vertical low-pass filter",      0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_CVLPF},INT_MIN, INT_MAX, FLAGS, "flags" },
     {"exact_tb",          "force a timebase which can represent timestamps exactly", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_EXACT_TB}, INT_MIN, INT_MAX, FLAGS, "flags" },
+    {"bypass_il",         "bypass already interlaced frames",             0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_BYPASS_IL}, INT_MIN, INT_MAX, FLAGS, "flags" },
 
     {NULL}
 };
@@ -439,6 +440,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
          * halving the frame rate and preserving image height */
     case MODE_INTERLEAVE_TOP:    /* top    field first */
     case MODE_INTERLEAVE_BOTTOM: /* bottom field first */
+        if ((tinterlace->flags & TINTERLACE_FLAG_BYPASS_IL) && cur->interlaced_frame) {
+            av_log(ctx, AV_LOG_WARNING,
+                   "video is already interlaced, adjusting framerate only\n");
+            out = av_frame_clone(cur);
+            if (!out)
+                return AVERROR(ENOMEM);
+            out->pts /= 2;  // adjust pts to new framerate
+            ret = ff_filter_frame(outlink, out);
+            return ret;
+        }
         tff = tinterlace->mode == MODE_INTERLEAVE_TOP;
         out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
         if (!out)