From patchwork Fri Aug 10 21:00:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas George X-Patchwork-Id: 9952 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:104:0:0:0:0:0 with SMTP id c4-v6csp439241jad; Fri, 10 Aug 2018 14:01:12 -0700 (PDT) X-Google-Smtp-Source: AA+uWPzvEoheBJfJ8oLpO7ngCagjp8xWU9yas2cMYf1TQ884mMdysl21Tjoult1DGzrn1Ztlp/VU X-Received: by 2002:a1c:8b86:: with SMTP id n128-v6mr888542wmd.42.1533934872638; Fri, 10 Aug 2018 14:01:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533934872; cv=none; d=google.com; s=arc-20160816; b=Yu+SVjXBqSpXfcUiDcSwSuVfxuesAIPfODeTnTSr5wvU8zUoNaSZ6m/6AepIO+8dP7 saG9zChQ9MA2DrXNAjAqDbpzuZnyip8bTubSmg6URcata+2Tu/k1gq/A4CGKhWsEunMS c/VRJKzn76Ili6UUPaZwXN/7tQJ0Jom9JoZFiVZ78iFVZz+y7CJPAoWVHLuNyeV3N0TH gpR5A7IhpWWtywAZ4f9FgrgnjyR3H1Q7rHMk3yq37M1TumPQnZ4y4ybUOXE2EIf6QIcM G9ZDMV6EDgkQgj7yOV6LnXyg903r2gBdDlTm+5KkGHLETDA0uVizGT8JKxmCZ8ntXQxV k8+Q== 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:message-id:date:to:from:delivered-to :arc-authentication-results; bh=k8VpgSgBz1+vrCFayVYIedUoQ1MFHuAn5vDu2S5wa0A=; b=SbR7eOa9v1UKGHxkjn+KjvFG5SghY7Jivk5Wbt66gPfiy4bF632H3+zS/Hvm7yS8oU VdgFFu+Yr0QqNiKsR31jbVdBeBaXGb3XUqgyVWeMRVSr4vOGIiYgbL+8RTo1qfLsbyLO Fk7pggNPaYEg5y4XYmaByytDBlltKoSs3pk5jOsX3af5Y7KSv2R3d4KhLQOQBaVSucKK gq4YYzoxS0Lu/uIEIl4qJQlL1ZbyPJ/Xf+z7cwWfDzY1ZqNwvicRg3FkA2ri9xAtHZIN QpmjvKp0GfDx0f/8crNwz44Ftyz3PUejnbzu+P7kliUdgF94/+6GIUzhileHBUZkWn67 0JeA== 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 h128-v6si1684674wmg.143.2018.08.10.14.01.11; Fri, 10 Aug 2018 14:01:12 -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 3402268A559; Sat, 11 Aug 2018 00:00:47 +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 EB3DC68A3F6 for ; Sat, 11 Aug 2018 00:00:40 +0300 (EEST) X-ENS-nef-client: 129.199.129.80 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 w7AL11cX094360 for ; Fri, 10 Aug 2018 23:01:01 +0200 (CEST) Received: by phare.normalesup.org (Postfix, from userid 1001) id 9AECCE00D0; Fri, 10 Aug 2018 23:01:01 +0200 (CEST) From: Nicolas George To: ffmpeg-devel@ffmpeg.org Date: Fri, 10 Aug 2018 23:00:58 +0200 Message-Id: <20180810210058.10141-1-george@nsup.org> X-Mailer: git-send-email 2.18.0 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.4.3 (nef2.ens.fr [129.199.96.32]); Fri, 10 Aug 2018 23:01:01 +0200 (CEST) Subject: [FFmpeg-devel] [PATCH] lavfi/avf_concat: switch to activate. 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" Fix trac ticket #7351. Signed-off-by: Nicolas George --- libavfilter/avf_concat.c | 156 +++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c index 46bd42359b..1d0c2de290 100644 --- a/libavfilter/avf_concat.c +++ b/libavfilter/avf_concat.c @@ -28,8 +28,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/opt.h" #include "avfilter.h" -#define FF_BUFQUEUE_SIZE 256 -#include "bufferqueue.h" +#include "filters.h" #include "internal.h" #include "video.h" #include "audio.h" @@ -48,7 +47,6 @@ typedef struct ConcatContext { int64_t pts; int64_t nb_frames; unsigned eof; - struct FFBufQueue queue; } *in; } ConcatContext; @@ -185,24 +183,6 @@ static int push_frame(AVFilterContext *ctx, unsigned in_no, AVFrame *buf) return ff_filter_frame(outlink, buf); } -static int process_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - ConcatContext *cat = ctx->priv; - unsigned in_no = FF_INLINK_IDX(inlink); - - if (in_no < cat->cur_idx) { - av_log(ctx, AV_LOG_ERROR, "Frame after EOF on input %s\n", - ctx->input_pads[in_no].name); - av_frame_free(&buf); - } else if (in_no >= cat->cur_idx + ctx->nb_outputs) { - ff_bufqueue_add(ctx, &cat->in[in_no].queue, buf); - } else { - return push_frame(ctx, in_no, buf); - } - return 0; -} - static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h) { AVFilterContext *ctx = inlink->dst; @@ -221,11 +201,6 @@ static AVFrame *get_audio_buffer(AVFilterLink *inlink, int nb_samples) return ff_get_audio_buffer(outlink, nb_samples); } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - return process_frame(inlink, buf); -} - static void close_input(AVFilterContext *ctx, unsigned in_no) { ConcatContext *cat = ctx->priv; @@ -306,57 +281,10 @@ static int flush_segment(AVFilterContext *ctx) if (ret < 0) return ret; } - /* flush queued buffers */ - /* possible enhancement: flush in PTS order */ - str_max = cat->cur_idx + ctx->nb_outputs; - for (str = cat->cur_idx; str < str_max; str++) { - while (cat->in[str].queue.available) { - ret = push_frame(ctx, str, ff_bufqueue_get(&cat->in[str].queue)); - if (ret < 0) - return ret; - } - } } return 0; } -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - ConcatContext *cat = ctx->priv; - unsigned out_no = FF_OUTLINK_IDX(outlink); - unsigned in_no = out_no + cat->cur_idx; - unsigned str, str_max; - int ret; - - while (1) { - if (in_no >= ctx->nb_inputs) - return AVERROR_EOF; - if (!cat->in[in_no].eof) { - ret = ff_request_frame(ctx->inputs[in_no]); - if (ret != AVERROR_EOF) - return ret; - close_input(ctx, in_no); - } - /* cycle on all inputs to finish the segment */ - /* possible enhancement: request in PTS order */ - str_max = cat->cur_idx + ctx->nb_outputs - 1; - for (str = cat->cur_idx; cat->nb_in_active; - str = str == str_max ? cat->cur_idx : str + 1) { - if (cat->in[str].eof) - continue; - ret = ff_request_frame(ctx->inputs[str]); - if (ret != AVERROR_EOF) - return ret; - close_input(ctx, str); - } - ret = flush_segment(ctx); - if (ret < 0) - return ret; - in_no += ctx->nb_outputs; - } -} - static av_cold int init(AVFilterContext *ctx) { ConcatContext *cat = ctx->priv; @@ -371,7 +299,6 @@ static av_cold int init(AVFilterContext *ctx) .type = type, .get_video_buffer = get_video_buffer, .get_audio_buffer = get_audio_buffer, - .filter_frame = filter_frame, }; pad.name = av_asprintf("in%d:%c%d", seg, "va"[type], str); if ((ret = ff_insert_inpad(ctx, ctx->nb_inputs, &pad)) < 0) { @@ -387,7 +314,6 @@ static av_cold int init(AVFilterContext *ctx) AVFilterPad pad = { .type = type, .config_props = config_output, - .request_frame = request_frame, }; pad.name = av_asprintf("out:%c%d", "va"[type], str); if ((ret = ff_insert_outpad(ctx, ctx->nb_outputs, &pad)) < 0) { @@ -409,15 +335,88 @@ static av_cold void uninit(AVFilterContext *ctx) ConcatContext *cat = ctx->priv; unsigned i; - for (i = 0; i < ctx->nb_inputs; i++) { + for (i = 0; i < ctx->nb_inputs; i++) av_freep(&ctx->input_pads[i].name); - ff_bufqueue_discard_all(&cat->in[i].queue); - } for (i = 0; i < ctx->nb_outputs; i++) av_freep(&ctx->output_pads[i].name); av_freep(&cat->in); } +static int activate(AVFilterContext *ctx) +{ + ConcatContext *cat = ctx->priv; + AVFrame *frame; + unsigned i, j; + int ret, status; + int64_t pts; + + /* Forward status back */ + for (i = 0; i < ctx->nb_outputs; i++) { + status = ff_outlink_get_status(ctx->outputs[i]); + if (!status) + continue; + for (j = i; j < ctx->nb_inputs; j += ctx->nb_outputs) { + if (!cat->in[j].eof) { + cat->in[j].eof = 1; + ff_inlink_set_status(ctx->inputs[j], status); + return 0; + } + } + + } + + /* Forward available frames */ + if (cat->cur_idx < ctx->nb_inputs) { + for (i = 0; i < ctx->nb_outputs; i++) { + ret = ff_inlink_consume_frame(ctx->inputs[cat->cur_idx + i], &frame); + if (ret < 0) + return ret; + if (ret) { + ff_filter_set_ready(ctx, 10); + return push_frame(ctx, cat->cur_idx + i, frame); + } + } + } + + /* Forward status change */ + if (cat->cur_idx < ctx->nb_inputs) { + for (i = 0; i < ctx->nb_outputs; i++) { + ret = ff_inlink_acknowledge_status(ctx->inputs[cat->cur_idx + i], &status, &pts); + /* TODO use pts */ + if (ret > 0) { + close_input(ctx, cat->cur_idx + i); + if (cat->cur_idx + ctx->nb_outputs >= ctx->nb_inputs) { + ff_outlink_set_status(ctx->outputs[i], status, pts); + } + if (!cat->nb_in_active) { + ret = flush_segment(ctx); + if (ret < 0) + return ret; + } + ff_filter_set_ready(ctx, 10); + return 0; + } + } + } + + ret = FFERROR_NOT_READY; + for (i = 0; i < ctx->nb_outputs; i++) { + if (ff_outlink_frame_wanted(ctx->outputs[i])) { + if (cat->in[cat->cur_idx + i].eof) { + for (j = 0; j < ctx->nb_outputs; j++) + if (!cat->in[cat->cur_idx + j].eof) + ff_inlink_request_frame(ctx->inputs[cat->cur_idx + j]); + return 0; + } else { + ff_inlink_request_frame(ctx->inputs[cat->cur_idx + i]); + ret = 0; + } + } + } + + return ret; +} + static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags) { @@ -437,6 +436,7 @@ AVFilter ff_avf_concat = { .init = init, .uninit = uninit, .query_formats = query_formats, + .activate = activate, .priv_size = sizeof(ConcatContext), .inputs = NULL, .outputs = NULL,