From patchwork Sun Jul 30 10:48:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas George X-Patchwork-Id: 4514 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.1.85 with SMTP id 82csp1231962vsb; Sun, 30 Jul 2017 03:48:29 -0700 (PDT) X-Received: by 10.28.32.208 with SMTP id g199mr8232518wmg.180.1501411709849; Sun, 30 Jul 2017 03:48:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501411709; cv=none; d=google.com; s=arc-20160816; b=I3Kf9G5+sxReiqD1naFO1rJbLu+j/TyiNOLdPagZFtedO/+OPG4kSz32v7chamj1UQ BaC9b1xgtdej7tZhwaGcpgYxqowP6hwxwSwx3ydiXDtGTZtjd8360FlWEy3UCpiIMFNH NLaTs2DoDTDVPdZzEdICKl56dVX7+2y0/1o9EsaruFecd/3L/O0e7YnWOskxCV6mGEmc gyWCHTzs7hUNcgQhizJpsmZkbmX1hn2ubO2GNa9l3Rpe58sdnot81hws4vHHIaa1vEn+ 5PZkImTNfgqMMybMmz5kJ38QKVbzPCScaMDfR9oS6T7P7q7JypOV2XZsK5hokV85KjXy RG4A== 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=ZviOoSbxs3G9+S6XLzORB5R3jP+AhLYd68/KlJcYn1g=; b=0XtSEPDBYK7J+U/w6aUejcZSzI9ET+Vo0sZfN+kTHPZAztBM8+PAJB4fUEdzrOB+Si KJCY03PYqPSpxIT84bTj/csmyIEhLda/kxhCiMtHRokdzBxBLkHJuCbNYBVQQEt9rFRM u/58QzQNSNXpp+BkvmEcCnK6JczlZAozyFKo6iOwt1h79v1q8nHNps0NLrdu9CUhmT5+ zVPkTy5PgtSfJvtd+dRjZJYyqgXVsLYjWpQI0yGkCrWiTtJOle61UodEGspDxK3CEN4y 9n8MEZ5iTzoLeYNv3/ylenEWnfV5YfMvQ2JdLlfbRn5wUVK6Orf3v8299kdMvBzo+9ew bFQQ== 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 o13si20247441wra.507.2017.07.30.03.48.29; Sun, 30 Jul 2017 03:48:29 -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 1ACBC689FEB; Sun, 30 Jul 2017 13:48:20 +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 1A2C7689FE4 for ; Sun, 30 Jul 2017 13:48:13 +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 v6UAmE9f054091 for ; Sun, 30 Jul 2017 12:48:14 +0200 (CEST) Received: by phare.normalesup.org (Postfix, from userid 1001) id 8F006E00D1; Sun, 30 Jul 2017 12:48:14 +0200 (CEST) From: Nicolas George To: ffmpeg-devel@ffmpeg.org Date: Sun, 30 Jul 2017 12:48:10 +0200 Message-Id: <20170730104810.19068-2-george@nsup.org> X-Mailer: git-send-email 2.13.2 In-Reply-To: <20170730104810.19068-1-george@nsup.org> References: <20170730104810.19068-1-george@nsup.org> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.4.3 (nef2.ens.fr [129.199.96.32]); Sun, 30 Jul 2017 12:48:14 +0200 (CEST) Subject: [FFmpeg-devel] [PATCH 2/2] WIP 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/vf_overlay.c | 81 ++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index ad292a61c1..b08be28a4b 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,32 @@ 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(&s->fs, ctx, 2)) < 0) return ret; + /* TODO factor in ff_framesync2_set_dualinput */ + + s->fs.in[0].time_base = ctx->inputs[0]->time_base; + s->fs.in[1].time_base = ctx->inputs[1]->time_base; + s->fs.in[0].sync = 2; + s->fs.in[0].before = EXT_STOP; + s->fs.in[0].after = EXT_INFINITY; + s->fs.in[1].sync = 1; + s->fs.in[1].before = EXT_NULL; + s->fs.in[1].after = EXT_INFINITY; + + 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 +786,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_get_dualinput(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 +823,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 +864,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 +872,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 +883,12 @@ 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 +898,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 +910,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,