summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Morris <stuart_morris@talk21.com>2012-04-29 15:25:57 +0200
committerStefano Sabatini <stefasab@gmail.com>2012-04-30 23:04:46 +0200
commit820c023142aa258b4d4a330e9ac2a568a07d491f (patch)
tree82194b957a0d653ab76ddb10c8305391d16e57b4
parentd4f8d717ab458fb673dd3a0ae61112cacf10310e (diff)
lavfi/tinterlace: add tinterlace mode 6
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. Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
-rw-r--r--doc/filters.texi7
-rw-r--r--libavfilter/version.h2
-rw-r--r--libavfilter/vf_tinterlace.c29
3 files changed, 35 insertions, 3 deletions
diff --git a/doc/filters.texi b/doc/filters.texi
index f5740394e6..3b5e556eef 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -2801,6 +2801,13 @@ even frames, generating a frame with unchanged height at half framerate.
@item 5
Interleave the lower field from odd frames with the upper field from
even frames, generating a frame with unchanged height at half framerate.
+
+@item 6
+Double frame rate with unchanged height. Frames are inserted each
+containing the second temporal field from the previous input frame and
+the first temporal field from the next input frame. This mode relies on
+the top_field_first flag. Useful for interlaced video displays with no
+field synchronisation.
@end table
Default mode is 0.
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 0f7ea501e6..c79f37de73 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -30,7 +30,7 @@
#define LIBAVFILTER_VERSION_MAJOR 2
#define LIBAVFILTER_VERSION_MINOR 72
-#define LIBAVFILTER_VERSION_MICRO 100
+#define LIBAVFILTER_VERSION_MICRO 101
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
index 62e8d46d25..683aa0c551 100644
--- 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);
}
}
@@ -253,6 +253,31 @@ static void end_frame(AVFilterLink *inlink)
tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER);
avfilter_unref_bufferp(&tinterlace->next);
break;
+ case 6: /* re-interlace preserving image height, double frame rate */
+ /* output current frame first */
+ out = avfilter_ref_buffer(cur, AV_PERM_READ);
+
+ avfilter_start_frame(outlink, out);
+ avfilter_draw_slice(outlink, 0, outlink->h, 1);
+ avfilter_end_frame(outlink);
+
+ /* 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 current 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 next 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);
+ break;
}
avfilter_start_frame(outlink, out);