[FFmpeg-devel] [PATCH 1/2] libavfilter: Add new tinterlace mode

Stuart Morris stuart_morris at talk21.com
Thu Apr 26 22:35:37 CEST 2012


This new mode is useful for generating frames for interlaced video displays.
Typically interlaced video displays have no form of field synchronisation.
This new mode guarantees correct field order without any requirement for
field synchronisation.

---
 libavfilter/vf_tinterlace.c |   33 +++++++++++++++++++++++++++++++--
 1 files changed, 31 insertions(+), 2 deletions(-)
 mode change 100644 => 100755 libavfilter/vf_tinterlace.c

diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
old mode 100644
new mode 100755
index 8407d1f..0f79708
--- a/libavfilter/vf_tinterlace.c
+++ b/libavfilter/vf_tinterlace.c
@@ -68,9 +68,9 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
     if (args) {
         n = sscanf(args, "%d", &tinterlace->mode);
 
-        if (n != 1 || tinterlace->mode < 0 || tinterlace->mode > 5) {
+        if (n != 1 || tinterlace->mode < 0 || tinterlace->mode > 6) {
             av_log(ctx, AV_LOG_ERROR,
-                   "Invalid mode '%s', use an integer between 0 and 5\n", args);
+                   "Invalid mode '%s', use an integer between 0 and 6\n", args);
             return AVERROR(EINVAL);
         }
     }
@@ -257,12 +257,41 @@ static void end_frame(AVFilterLink *inlink)
         avfilter_unref_buffer(tinterlace->next);
         tinterlace->next = NULL;
         break;
+    case 6: /* re-interlace preserving image height, double frame rate 
+             * Output current frame first */
+        out = avfilter_ref_buffer(cur, AV_PERM_READ);
+        break;
     }
 
     avfilter_start_frame(outlink, out);
     avfilter_draw_slice(outlink, 0, outlink->h, 1);
     avfilter_end_frame(outlink);
 
+    switch (tinterlace->mode) {
+    case 6: /* re-interlace preserving image height, double frame rate 
+             * Output mix of current and next frame */
+        tff = next->video->top_field_first;
+        out = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        avfilter_copy_buffer_ref_props(out, next);
+        out->video->interlaced = 1;
+
+        /* write odd frame second field lines into the second field of the new frame */
+        copy_picture_field(out->data, out->linesize,
+                           cur->data, cur->linesize,
+                           inlink->format, inlink->w, inlink->h,
+                           tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER);
+        /* write even frame first field lines into the first field of the new frame */
+        copy_picture_field(out->data, out->linesize,
+                           next->data, next->linesize,
+                           inlink->format, inlink->w, inlink->h,
+                           tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER);
+                           
+        avfilter_start_frame(outlink, out);
+        avfilter_draw_slice(outlink, 0, outlink->h, 1);
+        avfilter_end_frame(outlink);
+        break;    
+    }
+    
     tinterlace->frame++;
 }
 
-- 
1.7.3.4




More information about the ffmpeg-devel mailing list