Commit 42a8ac94 authored by Stefano Sabatini's avatar Stefano Sabatini

vf_tinterlace: implement interlace mode 5

Allow creating interlaced bottom field first video.
parent 8dc973e6
...@@ -2525,6 +2525,10 @@ generating a frame with double height at the same input framerate. ...@@ -2525,6 +2525,10 @@ generating a frame with double height at the same input framerate.
@item 4 @item 4
Interleave the upper field from odd frames with the lower field from Interleave the upper field from odd frames with the lower field from
even frames, generating a frame with unchanged height at half framerate. 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.
@end table @end table
Default mode is 0. Default mode is 0.
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define LIBAVFILTER_VERSION_MAJOR 2 #define LIBAVFILTER_VERSION_MAJOR 2
#define LIBAVFILTER_VERSION_MINOR 57 #define LIBAVFILTER_VERSION_MINOR 57
#define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_MICRO 101
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \ LIBAVFILTER_VERSION_MINOR, \
......
...@@ -68,9 +68,9 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) ...@@ -68,9 +68,9 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
if (args) { if (args) {
n = sscanf(args, "%d", &tinterlace->mode); n = sscanf(args, "%d", &tinterlace->mode);
if (n != 1 || tinterlace->mode < 0 || tinterlace->mode > 4) { if (n != 1 || tinterlace->mode < 0 || tinterlace->mode > 5) {
av_log(ctx, AV_LOG_ERROR, av_log(ctx, AV_LOG_ERROR,
"Invalid mode '%s', use an integer between 0 and 4\n", args); "Invalid mode '%s', use an integer between 0 and 5\n", args);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
} }
...@@ -179,7 +179,7 @@ static void end_frame(AVFilterLink *inlink) ...@@ -179,7 +179,7 @@ static void end_frame(AVFilterLink *inlink)
AVFilterBufferRef *cur = tinterlace->cur; AVFilterBufferRef *cur = tinterlace->cur;
AVFilterBufferRef *next = tinterlace->next; AVFilterBufferRef *next = tinterlace->next;
AVFilterBufferRef *out = NULL; AVFilterBufferRef *out = NULL;
int field; int field, tff;
/* we need at least two frames */ /* we need at least two frames */
if (!tinterlace->cur) if (!tinterlace->cur)
...@@ -234,23 +234,26 @@ static void end_frame(AVFilterLink *inlink) ...@@ -234,23 +234,26 @@ static void end_frame(AVFilterLink *inlink)
FIELD_UPPER_AND_LOWER, 1, !field); FIELD_UPPER_AND_LOWER, 1, !field);
break; break;
case 4: /* interleave upper lines from odd frames with lower lines from even frames, /* interleave upper/lower lines from odd frames with lower/upper lines from even frames,
* halving the frame rate and preserving image height */ * halving the frame rate and preserving image height */
case 4: /* top field first */
case 5: /* bottom field first */
tff = tinterlace->mode == 4;
out = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); out = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
avfilter_copy_buffer_ref_props(out, cur); avfilter_copy_buffer_ref_props(out, cur);
out->video->interlaced = 1; out->video->interlaced = 1;
out->video->top_field_first = 1; out->video->top_field_first = tff;
/* copy upper field from cur */ /* copy upper/lower field from cur */
copy_picture_field(out->data, out->linesize, copy_picture_field(out->data, out->linesize,
cur->data, cur->linesize, cur->data, cur->linesize,
inlink->format, inlink->w, inlink->h, inlink->format, inlink->w, inlink->h,
FIELD_UPPER, 1, FIELD_UPPER); tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER);
/* copy lower fields from next */ /* copy lower/upper field from next */
copy_picture_field(out->data, out->linesize, copy_picture_field(out->data, out->linesize,
next->data, next->linesize, next->data, next->linesize,
inlink->format, inlink->w, inlink->h, inlink->format, inlink->w, inlink->h,
FIELD_LOWER, 1, FIELD_LOWER); tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER);
avfilter_unref_buffer(tinterlace->next); avfilter_unref_buffer(tinterlace->next);
tinterlace->next = NULL; tinterlace->next = NULL;
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment