From 01729f77dd2a34d023d422e5d593861e864cf3de Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 22 Apr 2017 13:07:33 +0200 Subject: avfilter: add doubleweave filter Signed-off-by: Paul B Mahol --- libavfilter/vf_weave.c | 69 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 14 deletions(-) (limited to 'libavfilter/vf_weave.c') diff --git a/libavfilter/vf_weave.c b/libavfilter/vf_weave.c index a5fc1b7403..6d3dd7c299 100644 --- a/libavfilter/vf_weave.c +++ b/libavfilter/vf_weave.c @@ -27,6 +27,7 @@ typedef struct WeaveContext { const AVClass *class; int first_field; + int double_weave; int nb_planes; int planeheight[4]; int linesize[4]; @@ -56,10 +57,12 @@ static int config_props_output(AVFilterLink *outlink) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); int ret; - outlink->time_base.num = inlink->time_base.num * 2; - outlink->time_base.den = inlink->time_base.den; - outlink->frame_rate.num = inlink->frame_rate.num; - outlink->frame_rate.den = inlink->frame_rate.den * 2; + if (!s->double_weave) { + outlink->time_base.num = inlink->time_base.num * 2; + outlink->time_base.den = inlink->time_base.den; + outlink->frame_rate.num = inlink->frame_rate.num; + outlink->frame_rate.den = inlink->frame_rate.den * 2; + } outlink->w = inlink->w; outlink->h = inlink->h * 2; @@ -96,22 +99,36 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) av_frame_copy_props(out, in); for (i = 0; i < s->nb_planes; i++) { - av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, - out->linesize[i] * 2, - in->data[i], in->linesize[i], - s->linesize[i], s->planeheight[i]); - av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, - out->linesize[i] * 2, - s->prev->data[i], s->prev->linesize[i], - s->linesize[i], s->planeheight[i]); + if (s->double_weave && !(inlink->frame_count_out & 1)) { + av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, + out->linesize[i] * 2, + in->data[i], in->linesize[i], + s->linesize[i], s->planeheight[i]); + av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, + out->linesize[i] * 2, + s->prev->data[i], s->prev->linesize[i], + s->linesize[i], s->planeheight[i]); + } else { + av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, + out->linesize[i] * 2, + in->data[i], in->linesize[i], + s->linesize[i], s->planeheight[i]); + av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, + out->linesize[i] * 2, + s->prev->data[i], s->prev->linesize[i], + s->linesize[i], s->planeheight[i]); + } } - out->pts = in->pts / 2; + out->pts = s->double_weave ? s->prev->pts : in->pts / 2; out->interlaced_frame = 1; out->top_field_first = !s->first_field; - av_frame_free(&in); + if (!s->double_weave) + av_frame_free(&in); av_frame_free(&s->prev); + if (s->double_weave) + s->prev = in; return ff_filter_frame(outlink, out); } @@ -149,3 +166,27 @@ AVFilter ff_vf_weave = { .inputs = weave_inputs, .outputs = weave_outputs, }; + +static av_cold int init(AVFilterContext *ctx) +{ + WeaveContext *s = ctx->priv; + + if (!strcmp(ctx->filter->name, "doubleweave")) + s->double_weave = 1; + + return 0; +} + +#define doubleweave_options weave_options +AVFILTER_DEFINE_CLASS(doubleweave); + +AVFilter ff_vf_doubleweave = { + .name = "doubleweave", + .description = NULL_IF_CONFIG_SMALL("Weave input video fields into double number of frames."), + .priv_size = sizeof(WeaveContext), + .priv_class = &doubleweave_class, + .init = init, + .uninit = uninit, + .inputs = weave_inputs, + .outputs = weave_outputs, +}; -- cgit v1.2.3