[FFmpeg-devel] [PATCH] avfilter/vf_tinterlace: add mergex2 mode
Paul B Mahol
onemda at gmail.com
Thu Oct 1 09:30:51 CEST 2015
Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
doc/filters.texi | 23 +++++++++++++++++++++++
libavfilter/tinterlace.h | 1 +
libavfilter/vf_tinterlace.c | 17 ++++++++++++-----
3 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index a4d828e..04b2d22 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -10774,6 +10774,29 @@ Output:
11111 11111 22222 22222 33333 33333 44444
@end example
+ at item mergex2, 7
+Move odd frames into the upper field, even into the lower field,
+generating a double height frame at same frame rate.
+ at example
+ ------> time
+Input:
+Frame 1 Frame 2 Frame 3 Frame 4
+
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+
+Output:
+11111 33333 33333 55555
+22222 22222 44444 44444
+11111 33333 33333 55555
+22222 22222 44444 44444
+11111 33333 33333 55555
+22222 22222 44444 44444
+11111 33333 33333 55555
+22222 22222 44444 44444
+ at end example
@end table
diff --git a/libavfilter/tinterlace.h b/libavfilter/tinterlace.h
index d80a6e2..3b703e7 100644
--- a/libavfilter/tinterlace.h
+++ b/libavfilter/tinterlace.h
@@ -38,6 +38,7 @@ enum TInterlaceMode {
MODE_INTERLEAVE_TOP,
MODE_INTERLEAVE_BOTTOM,
MODE_INTERLACEX2,
+ MODE_MERGEX2,
MODE_NB,
};
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
index 4bdcd45..3d6140f 100644
--- a/libavfilter/vf_tinterlace.c
+++ b/libavfilter/vf_tinterlace.c
@@ -46,6 +46,7 @@ static const AVOption tinterlace_options[] = {
{"interleave_top", "interleave top and bottom fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_TOP}, INT_MIN, INT_MAX, FLAGS, "mode"},
{"interleave_bottom", "interleave bottom and top fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_BOTTOM}, INT_MIN, INT_MAX, FLAGS, "mode"},
{"interlacex2", "interlace fields from two consecutive frames", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLACEX2}, INT_MIN, INT_MAX, FLAGS, "mode"},
+ {"mergex2", "merge fields keeping same frame rate", 0, AV_OPT_TYPE_CONST, {.i64=MODE_MERGEX2}, INT_MIN, INT_MAX, FLAGS, "mode"},
{"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
{"low_pass_filter", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
@@ -118,9 +119,9 @@ static int config_out_props(AVFilterLink *outlink)
tinterlace->vsub = desc->log2_chroma_h;
outlink->w = inlink->w;
- outlink->h = tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD ?
+ outlink->h = tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD || tinterlace->mode == MODE_MERGEX2?
inlink->h*2 : inlink->h;
- if (tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD)
+ if (tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD || tinterlace->mode == MODE_MERGEX2)
outlink->sample_aspect_ratio = av_mul_q(inlink->sample_aspect_ratio,
av_make_q(2, 1));
@@ -153,6 +154,9 @@ static int config_out_props(AVFilterLink *outlink)
tinterlace->preout_time_base.den *= 2;
outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){2,1});
outlink->time_base = av_mul_q(inlink->time_base , (AVRational){1,2});
+ } else if (tinterlace->mode == MODE_MERGEX2) {
+ outlink->frame_rate = inlink->frame_rate;
+ outlink->time_base = inlink->time_base;
} else if (tinterlace->mode != MODE_PAD) {
outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){1,2});
outlink->time_base = av_mul_q(inlink->time_base , (AVRational){2,1});
@@ -259,6 +263,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
return 0;
switch (tinterlace->mode) {
+ case MODE_MERGEX2: /* move the odd frame into the upper field of the new image, even into
+ * the lower field, generating a double-height video at same framerate */
case MODE_MERGE: /* move the odd frame into the upper field of the new image, even into
* the lower field, generating a double-height video at half framerate */
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
@@ -274,13 +280,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)cur->data, cur->linesize,
inlink->format, inlink->w, inlink->h,
- FIELD_UPPER_AND_LOWER, 1, FIELD_UPPER, tinterlace->flags);
+ FIELD_UPPER_AND_LOWER, 1, tinterlace->mode == MODE_MERGEX2 ? inlink->frame_count & 1 ? FIELD_LOWER : FIELD_UPPER : FIELD_UPPER, tinterlace->flags);
/* write even frame lines into the lower field of the new frame */
copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)next->data, next->linesize,
inlink->format, inlink->w, inlink->h,
- FIELD_UPPER_AND_LOWER, 1, FIELD_LOWER, tinterlace->flags);
- av_frame_free(&tinterlace->next);
+ FIELD_UPPER_AND_LOWER, 1, tinterlace->mode == MODE_MERGEX2 ? inlink->frame_count & 1 ? FIELD_UPPER : FIELD_LOWER : FIELD_LOWER, tinterlace->flags);
+ if (tinterlace->mode != MODE_MERGEX2)
+ av_frame_free(&tinterlace->next);
break;
case MODE_DROP_ODD: /* only output even frames, odd frames are dropped; height unchanged, half framerate */
--
1.9.1
More information about the ffmpeg-devel
mailing list