avfilter/vf_tinterlace: add mergex2 mode
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
99982524f9
commit
13090895cf
@ -10774,6 +10774,29 @@ Output:
|
|||||||
11111 11111 22222 22222 33333 33333 44444
|
11111 11111 22222 22222 33333 33333 44444
|
||||||
@end example
|
@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
|
@end table
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ enum TInterlaceMode {
|
|||||||
MODE_INTERLEAVE_TOP,
|
MODE_INTERLEAVE_TOP,
|
||||||
MODE_INTERLEAVE_BOTTOM,
|
MODE_INTERLEAVE_BOTTOM,
|
||||||
MODE_INTERLACEX2,
|
MODE_INTERLACEX2,
|
||||||
|
MODE_MERGEX2,
|
||||||
MODE_NB,
|
MODE_NB,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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_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"},
|
{"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"},
|
{"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" },
|
{"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" },
|
{"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;
|
tinterlace->vsub = desc->log2_chroma_h;
|
||||||
outlink->w = inlink->w;
|
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;
|
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,
|
outlink->sample_aspect_ratio = av_mul_q(inlink->sample_aspect_ratio,
|
||||||
av_make_q(2, 1));
|
av_make_q(2, 1));
|
||||||
|
|
||||||
@ -153,6 +154,9 @@ static int config_out_props(AVFilterLink *outlink)
|
|||||||
tinterlace->preout_time_base.den *= 2;
|
tinterlace->preout_time_base.den *= 2;
|
||||||
outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){2,1});
|
outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){2,1});
|
||||||
outlink->time_base = av_mul_q(inlink->time_base , (AVRational){1,2});
|
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) {
|
} else if (tinterlace->mode != MODE_PAD) {
|
||||||
outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){1,2});
|
outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){1,2});
|
||||||
outlink->time_base = av_mul_q(inlink->time_base , (AVRational){2,1});
|
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;
|
return 0;
|
||||||
|
|
||||||
switch (tinterlace->mode) {
|
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
|
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 */
|
* the lower field, generating a double-height video at half framerate */
|
||||||
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
|
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,
|
copy_picture_field(tinterlace, out->data, out->linesize,
|
||||||
(const uint8_t **)cur->data, cur->linesize,
|
(const uint8_t **)cur->data, cur->linesize,
|
||||||
inlink->format, inlink->w, inlink->h,
|
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 */
|
/* write even frame lines into the lower field of the new frame */
|
||||||
copy_picture_field(tinterlace, out->data, out->linesize,
|
copy_picture_field(tinterlace, out->data, out->linesize,
|
||||||
(const uint8_t **)next->data, next->linesize,
|
(const uint8_t **)next->data, next->linesize,
|
||||||
inlink->format, inlink->w, inlink->h,
|
inlink->format, inlink->w, inlink->h,
|
||||||
FIELD_UPPER_AND_LOWER, 1, FIELD_LOWER, tinterlace->flags);
|
FIELD_UPPER_AND_LOWER, 1, tinterlace->mode == MODE_MERGEX2 ? inlink->frame_count & 1 ? FIELD_UPPER : FIELD_LOWER : FIELD_LOWER, tinterlace->flags);
|
||||||
av_frame_free(&tinterlace->next);
|
if (tinterlace->mode != MODE_MERGEX2)
|
||||||
|
av_frame_free(&tinterlace->next);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MODE_DROP_ODD: /* only output even frames, odd frames are dropped; height unchanged, half framerate */
|
case MODE_DROP_ODD: /* only output even frames, odd frames are dropped; height unchanged, half framerate */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user