On 12/10/14, Clement Boesch <u...@pkh.me> wrote: > 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, Clement Boesch encoded: >> > On Sun, Nov 23, 2014 at 02:50:51PM +0100, Stefano Sabatini wrote: >> > > On date Sunday 2014-11-23 02:01:16 +0100, Clement Boesch 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).
The new difference mode is useful, thanks. > > Would be nice to complete doc but I suppose you won't forget them. > > Thank you. > > [...] > > -- > Clement B. > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel