From patchwork Thu Aug 10 11:46:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas George X-Patchwork-Id: 4673 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.46.211 with SMTP id u202csp2307409vsu; Thu, 10 Aug 2017 04:47:20 -0700 (PDT) X-Received: by 10.28.214.13 with SMTP id n13mr6767528wmg.16.1502365639932; Thu, 10 Aug 2017 04:47:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502365639; cv=none; d=google.com; s=arc-20160816; b=uwXO8ZOt1vYaXkzrJcHWBHWUQGkEa13TByaLybvnaK7KBs0FC4haE2X7+sDW0fA3ey ZQHRoI4PB0esfpJW2eOE9wDns/gkXn1VNgwyh6NeYFtUQF1IZ6+ufSzckffMnMJJqcES QxXsTpVW+LxFacNWBZwKHILQ1stvVaNvbTG4aNcMG/flkzEPCb8zWMbvEfgd1+u8IheY JpgdRBPgZ4/25nXRnxnFXZ96d4AB8Dm92SNLb3xf/cthz8CY/GoOYZwE+AoC0y195o+c jbNE2wpg+yI2HdX9qQvZJcCDLDVUoXJ+BkUs8GWBzLOr+nYXva88Wk2HIFBiMBAGvmTp xQ9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:delivered-to:arc-authentication-results; bh=dq3tJR3x1RWXjev/ghPvwKuyA2jlAdLbVNW7bdtMSM0=; b=HHeHWORNNkHQrxs3OCt6x51VR0hbFFx6az3IjPNTt7vq9UqhRqNg8SVVKdACPmNpGl igcK4QdzEwx+2DkTLLlFDmlnAMlWgh5MjYWQd9pRU8TNYkKnO2aKxLrImDpOls7K4Zow 9IlPYt0O6RzxOXy6s0GCPq+sB+VCHkH0AXvCE7wKxJuXG81oL2GdZblrgcwYTPYALxB4 C8AWWjXAj91RvarQHH82vj9JzH845W7G+bfA5TxjxGudGQIXQ5HDmKt94+LShzya1SKa fKDSQOBUtFLTLJlAZYNMjbXDyFNm9+WOhz8R/ZUCrXm1GaJ9ZwGkFs7S0na/ddM+5qb5 paJA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id m205si4620900wma.224.2017.08.10.04.47.19; Thu, 10 Aug 2017 04:47:19 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id EC8BE689C1B; Thu, 10 Aug 2017 14:46:51 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from nef2.ens.fr (nef2.ens.fr [129.199.96.40]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A9617689C2C for ; Thu, 10 Aug 2017 14:46:45 +0300 (EEST) Received: from phare.normalesup.org (phare.normalesup.org [129.199.129.80]) by nef2.ens.fr (8.13.6/1.01.28121999) with ESMTP id v7ABklLg043673 for ; Thu, 10 Aug 2017 13:46:48 +0200 (CEST) Received: by phare.normalesup.org (Postfix, from userid 1001) id E577EE00F5; Thu, 10 Aug 2017 13:46:47 +0200 (CEST) From: Nicolas George To: ffmpeg-devel@ffmpeg.org Date: Thu, 10 Aug 2017 13:46:30 +0200 Message-Id: <20170810114642.26779-4-george@nsup.org> X-Mailer: git-send-email 2.13.2 In-Reply-To: <20170810114642.26779-1-george@nsup.org> References: <20170810114642.26779-1-george@nsup.org> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.4.3 (nef2.ens.fr [129.199.96.32]); Thu, 10 Aug 2017 13:46:48 +0200 (CEST) Subject: [FFmpeg-devel] [PATCH 04/16] lavfi/vf_overlay: move to framesync2. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Nicolas George --- libavfilter/Makefile | 2 +- libavfilter/vf_overlay.c | 70 ++++++++++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 33 deletions(-) Now uses ff_framesync2_dualinput_get_writable(). diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 2079ccb557..75a73c4cc0 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -245,7 +245,7 @@ OBJS-$(CONFIG_OCR_FILTER) += vf_ocr.o OBJS-$(CONFIG_OCV_FILTER) += vf_libopencv.o OBJS-$(CONFIG_OPENCL) += deshake_opencl.o unsharp_opencl.o OBJS-$(CONFIG_OSCILLOSCOPE_FILTER) += vf_datascope.o -OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o dualinput.o framesync.o +OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o framesync2.o OBJS-$(CONFIG_OWDENOISE_FILTER) += vf_owdenoise.o OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o OBJS-$(CONFIG_PALETTEGEN_FILTER) += vf_palettegen.o diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index ad292a61c1..80365ce8df 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -36,8 +36,8 @@ #include "libavutil/opt.h" #include "libavutil/timestamp.h" #include "internal.h" -#include "dualinput.h" #include "drawutils.h" +#include "framesync2.h" #include "video.h" static const char *const var_names[] = { @@ -121,7 +121,7 @@ typedef struct OverlayContext { int format; ///< OverlayFormat int eval_mode; ///< EvalMode - FFDualInputContext dinput; + FFFrameSync fs; int main_pix_step[4]; ///< steps per pixel for each plane of the main output int overlay_pix_step[4]; ///< steps per pixel for each plane of the overlay @@ -132,6 +132,8 @@ typedef struct OverlayContext { char *x_expr, *y_expr; int eof_action; ///< action to take on EOF from source + int opt_shortest; + int opt_repeatlast; AVExpr *x_pexpr, *y_pexpr; @@ -142,7 +144,7 @@ static av_cold void uninit(AVFilterContext *ctx) { OverlayContext *s = ctx->priv; - ff_dualinput_uninit(&s->dinput); + ff_framesync2_uninit(&s->fs); av_expr_free(s->x_pexpr); s->x_pexpr = NULL; av_expr_free(s->y_pexpr); s->y_pexpr = NULL; } @@ -390,14 +392,20 @@ static int config_output(AVFilterLink *outlink) OverlayContext *s = ctx->priv; int ret; - if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0) + if ((ret = ff_framesync2_init_dualinput(&s->fs, ctx)) < 0) return ret; + if (s->opt_shortest) + s->fs.in[0].after = s->fs.in[1].after = EXT_STOP; + if (!s->opt_repeatlast) { + s->fs.in[1].after = EXT_NULL; + s->fs.in[1].sync = 0; + } outlink->w = ctx->inputs[MAIN]->w; outlink->h = ctx->inputs[MAIN]->h; outlink->time_base = ctx->inputs[MAIN]->time_base; - return 0; + return ff_framesync2_configure(&s->fs); } // divide by 255 and round to nearest @@ -766,11 +774,19 @@ static int config_input_main(AVFilterLink *inlink) return 0; } -static AVFrame *do_blend(AVFilterContext *ctx, AVFrame *mainpic, - const AVFrame *second) +static int do_blend(FFFrameSync *fs) { + AVFilterContext *ctx = fs->parent; + AVFrame *mainpic, *second; OverlayContext *s = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; + int ret; + + ret = ff_framesync2_dualinput_get_writable(fs, &mainpic, &second); + if (ret < 0) + return ret; + if (!second) + return ff_filter_frame(ctx->outputs[0], mainpic); if (s->eval_mode == EVAL_MODE_FRAME) { int64_t pos = mainpic->pkt_pos; @@ -795,39 +811,32 @@ static AVFrame *do_blend(AVFilterContext *ctx, AVFrame *mainpic, if (s->x < mainpic->width && s->x + second->width >= 0 || s->y < mainpic->height && s->y + second->height >= 0) s->blend_image(ctx, mainpic, second, s->x, s->y); - return mainpic; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) -{ - OverlayContext *s = inlink->dst->priv; - av_log(inlink->dst, AV_LOG_DEBUG, "Incoming frame (time:%s) from link #%d\n", av_ts2timestr(inpicref->pts, &inlink->time_base), FF_INLINK_IDX(inlink)); - return ff_dualinput_filter_frame(&s->dinput, inlink, inpicref); -} - -static int request_frame(AVFilterLink *outlink) -{ - OverlayContext *s = outlink->src->priv; - return ff_dualinput_request_frame(&s->dinput, outlink); + return ff_filter_frame(ctx->outputs[0], mainpic); } static av_cold int init(AVFilterContext *ctx) { OverlayContext *s = ctx->priv; - if (!s->dinput.repeatlast || s->eof_action == EOF_ACTION_PASS) { - s->dinput.repeatlast = 0; + if (!s->opt_repeatlast || s->eof_action == EOF_ACTION_PASS) { + s->opt_repeatlast = 0; s->eof_action = EOF_ACTION_PASS; } - if (s->dinput.shortest || s->eof_action == EOF_ACTION_ENDALL) { - s->dinput.shortest = 1; + if (s->opt_shortest || s->eof_action == EOF_ACTION_ENDALL) { + s->opt_shortest = 1; s->eof_action = EOF_ACTION_ENDALL; } - s->dinput.process = do_blend; + s->fs.on_event = do_blend; return 0; } +static int activate(AVFilterContext *ctx) +{ + OverlayContext *s = ctx->priv; + return ff_framesync2_activate(&s->fs); +} + #define OFFSET(x) offsetof(OverlayContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM @@ -843,7 +852,7 @@ static const AVOption overlay_options[] = { { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, - { "shortest", "force termination when the shortest input terminates", OFFSET(dinput.shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { "shortest", "force termination when the shortest input terminates", OFFSET(opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" }, { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" }, { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" }, @@ -851,7 +860,7 @@ static const AVOption overlay_options[] = { { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" }, { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" }, { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" }, - { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(dinput.repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, + { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { NULL } }; @@ -862,14 +871,11 @@ static const AVFilterPad avfilter_vf_overlay_inputs[] = { .name = "main", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_input_main, - .filter_frame = filter_frame, - .needs_writable = 1, }, { .name = "overlay", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_input_overlay, - .filter_frame = filter_frame, }, { NULL } }; @@ -879,7 +885,6 @@ static const AVFilterPad avfilter_vf_overlay_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -892,6 +897,7 @@ AVFilter ff_vf_overlay = { .priv_size = sizeof(OverlayContext), .priv_class = &overlay_class, .query_formats = query_formats, + .activate = activate, .process_command = process_command, .inputs = avfilter_vf_overlay_inputs, .outputs = avfilter_vf_overlay_outputs,