diff options
author | Stuart Morris <stuart_morris@talk21.com> | 2012-04-29 17:25:57 +0400 |
---|---|---|
committer | Stefano Sabatini <stefasab@gmail.com> | 2012-05-01 01:04:46 +0400 |
commit | 820c023142aa258b4d4a330e9ac2a568a07d491f (patch) | |
tree | 82194b957a0d653ab76ddb10c8305391d16e57b4 /libavfilter/vf_tinterlace.c | |
parent | d4f8d717ab458fb673dd3a0ae61112cacf10310e (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>
Diffstat (limited to 'libavfilter/vf_tinterlace.c')
-rw-r--r-- | libavfilter/vf_tinterlace.c | 29 |
1 files changed, 27 insertions, 2 deletions
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); |