From 13090895cf1cbc148242f1be570aa27c2d07e891 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 30 Sep 2015 15:35:55 +0200 Subject: avfilter/vf_tinterlace: add mergex2 mode Signed-off-by: Paul B Mahol --- 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 a4d828e04c..04b2d2207f 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -10774,6 +10774,29 @@ Output: 11111 11111 22222 22222 33333 33333 44444 @end example +@item mergex2, 7 +Move odd frames into the upper field, even into the lower field, +generating a double height frame at same frame rate. +@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 +@end example @end table diff --git a/libavfilter/tinterlace.h b/libavfilter/tinterlace.h index d80a6e2179..3b703e7b21 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 4bdcd45c05..3d6140fcc7 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 */ -- cgit v1.2.3