Oups, sorry about the delay, I forgot that one. On Thu, Dec 04, 2014 at 12:36:43PM +0100, Stefano Sabatini wrote: > On date Sunday 2014-11-23 14:57:41 +0100, Clément Bœsch encoded: > > On Sun, Nov 23, 2014 at 02:50:51PM +0100, Stefano Sabatini wrote: > > > On date Sunday 2014-11-23 02:01:16 +0100, Clément Bœsch encoded: > > > > On Sat, Nov 22, 2014 at 11:44:29PM +0100, Stefano Sabatini wrote: > > > > > TODO: bump minor > > > > > --- > > > > > Changelog | 1 + > > > > > doc/filters.texi | 4 ++ > > > > > libavfilter/Makefile | 1 + > > > > > libavfilter/allfilters.c | 1 + > > > > > libavfilter/vf_tdiff.c | 131 > > > > > +++++++++++++++++++++++++++++++++++++++++++++++ > > > > > 5 files changed, 138 insertions(+) > > > > > create mode 100644 libavfilter/vf_tdiff.c > > > > > > > > > > > > > > > > What about adding a tblend in vf_blend.c instead? > > > > > > What do you exactly mean? tdiff works with a single input, blend with > > > two inputs. > > > > That's the point: make another filter with temporal dimension in blend. > > Blend filter has many features such as doing something more than diff > > and having threading. The main function takes 2 frames so just add the > > glue code around to take the previous and the current frame instead. > > > > That's just a suggestion, maybe the other functions don't make much sense. > > Feel free to ignore. > > Uh, what about this?
Yeah, I kind of like that much better :) > -- > FFmpeg = Frightening Faithless Martial Powerful Evil Goblin > From c805460ceb04ec2da3f607e69067f4cc710c0613 Mon Sep 17 00:00:00 2001 > From: Stefano Sabatini <stefa...@gmail.com> > Date: Thu, 4 Dec 2014 12:27:53 +0100 > Subject: [PATCH] lavfi: add tblend filter > > --- > libavfilter/Makefile | 1 + > libavfilter/allfilters.c | 1 + > libavfilter/vf_blend.c | 73 > +++++++++++++++++++++++++++++++++++++++++++++++- > 3 files changed, 74 insertions(+), 1 deletion(-) > > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index d41a52e..d1be7e3 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -187,6 +187,7 @@ OBJS-$(CONFIG_STEREO3D_FILTER) += > vf_stereo3d.o > OBJS-$(CONFIG_SUBTITLES_FILTER) += vf_subtitles.o > OBJS-$(CONFIG_SUPER2XSAI_FILTER) += vf_super2xsai.o > OBJS-$(CONFIG_SWAPUV_FILTER) += vf_swapuv.o > +OBJS-$(CONFIG_TBLEND_FILTER) += vf_blend.o > OBJS-$(CONFIG_TDIFF_FILTER) += vf_tdiff.o > OBJS-$(CONFIG_TELECINE_FILTER) += vf_telecine.o > OBJS-$(CONFIG_THUMBNAIL_FILTER) += vf_thumbnail.o > diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c > index f13f82d..e8914cc 100644 > --- a/libavfilter/allfilters.c > +++ b/libavfilter/allfilters.c > @@ -202,6 +202,7 @@ void avfilter_register_all(void) > REGISTER_FILTER(SUBTITLES, subtitles, vf); > REGISTER_FILTER(SUPER2XSAI, super2xsai, vf); > REGISTER_FILTER(SWAPUV, swapuv, vf); > + REGISTER_FILTER(TBLEND, tblend, vf); > REGISTER_FILTER(TDIFF, tdiff, vf); > REGISTER_FILTER(TELECINE, telecine, vf); > REGISTER_FILTER(THUMBNAIL, thumbnail, vf); > diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c > index 8bf19ff..3c1572c 100644 > --- a/libavfilter/vf_blend.c > +++ b/libavfilter/vf_blend.c > @@ -95,6 +95,8 @@ typedef struct { > double all_opacity; > > FilterParams params[4]; > + int tblend; > + AVFrame *prev_frame; /* only used with tblend */ > } BlendContext; > > #define OFFSET(x) offsetof(BlendContext, x) > @@ -285,7 +287,8 @@ static AVFrame *blend_frame(AVFilterContext *ctx, AVFrame > *top_buf, > ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outh, > ctx->graph->nb_threads)); > } > > - av_frame_free(&top_buf); > + if (!b->tblend) > + av_frame_free(&top_buf); > > return dst_buf; > } > @@ -295,6 +298,8 @@ static av_cold int init(AVFilterContext *ctx) > BlendContext *b = ctx->priv; > int ret, plane; > > + b->tblend = !strcmp(ctx->filter->name, "tblend"); > + > for (plane = 0; plane < FF_ARRAY_ELEMS(b->params); plane++) { > FilterParams *param = &b->params[plane]; > > @@ -412,6 +417,8 @@ static av_cold void uninit(AVFilterContext *ctx) > int i; > > ff_dualinput_uninit(&b->dinput); > + av_freep(&b->prev_frame); > + > for (i = 0; i < FF_ARRAY_ELEMS(b->params); i++) > av_expr_free(b->params[i].e); > } > @@ -463,3 +470,67 @@ AVFilter ff_vf_blend = { > .priv_class = &blend_class, > .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | > AVFILTER_FLAG_SLICE_THREADS, > }; > + > +static int tblend_config_output(AVFilterLink *outlink) > +{ > + AVFilterContext *ctx = outlink->src; > + AVFilterLink *inlink = ctx->inputs[0]; > + BlendContext *b = ctx->priv; > + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); > + > + b->hsub = pix_desc->log2_chroma_w; > + b->vsub = pix_desc->log2_chroma_h; > + b->nb_planes = av_pix_fmt_count_planes(inlink->format); > + outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; Do you need that? (it's single input) > + > + return 0; > +} > + > +static int tblend_filter_frame(AVFilterLink *inlink, AVFrame *frame) > +{ > + BlendContext *b = inlink->dst->priv; > + AVFilterLink *outlink = inlink->dst->outputs[0]; > + > + if (b->prev_frame) { > + AVFrame *out = blend_frame(inlink->dst, frame, b->prev_frame); > + av_frame_free(&b->prev_frame); > + b->prev_frame = frame; > + return ff_filter_frame(outlink, out); > + } > + b->prev_frame = frame; > + return 0; > +} > + > +#define tblend_options blend_options > +AVFILTER_DEFINE_CLASS(tblend); > + You probably want to sort out the shortest/repeatlast options > +static const AVFilterPad tblend_inputs[] = { > + { > + .name = "default", > + .type = AVMEDIA_TYPE_VIDEO, > + .filter_frame = tblend_filter_frame, > + }, > + { NULL } > +}; > + > +static const AVFilterPad tblend_outputs[] = { > + { > + .name = "default", > + .type = AVMEDIA_TYPE_VIDEO, > + .config_props = tblend_config_output, > + }, > + { NULL } > +}; > + > +AVFilter ff_vf_tblend = { > + .name = "tblend", > + .description = NULL_IF_CONFIG_SMALL("Blend successive frames."), > + .priv_size = sizeof(BlendContext), > + .priv_class = &blend_class, > + .query_formats = query_formats, > + .init = init, > + .uninit = uninit, > + .inputs = tblend_inputs, > + .outputs = tblend_outputs, > + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | > AVFILTER_FLAG_SLICE_THREADS, Does the timeline works as expected? Like, is it caching the previous frame even when skipping segment? > +}; > -- > 1.8.3.2 > > From 65455601f502dd148bcd140f8d70eef104b1bdbe Mon Sep 17 00:00:00 2001 > From: Stefano Sabatini <stefa...@gmail.com> > Date: Thu, 4 Dec 2014 12:34:30 +0100 > Subject: [PATCH] lavfi/blend: add difference128 mode > > --- > libavfilter/vf_blend.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c > index 3c1572c..e73ea35 100644 > --- a/libavfilter/vf_blend.c > +++ b/libavfilter/vf_blend.c > @@ -41,6 +41,7 @@ enum BlendMode { > BLEND_BURN, > BLEND_DARKEN, > BLEND_DIFFERENCE, > + BLEND_DIFFERENCE128, > BLEND_DIVIDE, > BLEND_DODGE, > BLEND_EXCLUSION, > @@ -114,6 +115,7 @@ static const AVOption blend_options[] = { > { "burn", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_BURN}, 0, 0, > FLAGS, "mode" }, > { "darken", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DARKEN}, 0, 0, > FLAGS, "mode" }, > { "difference", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE}, 0, 0, > FLAGS, "mode" }, > + { "difference128", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE128}, > 0, 0, FLAGS, "mode" }, > { "divide", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIVIDE}, 0, 0, > FLAGS, "mode" }, > { "dodge", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DODGE}, 0, 0, > FLAGS, "mode" }, > { "exclusion", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXCLUSION}, 0, 0, > FLAGS, "mode" }, > @@ -192,6 +194,7 @@ DEFINE_BLEND(subtract, FFMAX(0, A - B)) > DEFINE_BLEND(multiply, MULTIPLY(1, A, B)) > DEFINE_BLEND(negation, 255 - FFABS(255 - A - B)) > DEFINE_BLEND(difference, FFABS(A - B)) > +DEFINE_BLEND(difference128, av_clip_uint8(128 + A - B)) > DEFINE_BLEND(screen, SCREEN(1, A, B)) > DEFINE_BLEND(overlay, (A < 128) ? MULTIPLY(2, A, B) : SCREEN(2, A, B)) > DEFINE_BLEND(hardlight, (B < 128) ? MULTIPLY(2, B, A) : SCREEN(2, B, A)) > @@ -315,6 +318,7 @@ static av_cold int init(AVFilterContext *ctx) > case BLEND_BURN: param->blend = blend_burn; break; > case BLEND_DARKEN: param->blend = blend_darken; break; > case BLEND_DIFFERENCE: param->blend = blend_difference; break; > + case BLEND_DIFFERENCE128: param->blend = blend_difference128; break; > case BLEND_DIVIDE: param->blend = blend_divide; break; > case BLEND_DODGE: param->blend = blend_dodge; break; > case BLEND_EXCLUSION: param->blend = blend_exclusion; break; I'm not a maintainer of blend but it looks OK (assuming previous comments are honored). Would be nice to complete doc but I suppose you won't forget them. Thank you. [...] -- Clément B.
pgpxZM81ybddV.pgp
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel