From patchwork Fri May 4 10:10:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 8777 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:155:0:0:0:0:0 with SMTP id c82-v6csp446891jad; Fri, 4 May 2018 03:10:37 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrE39jYOqrUjK+dlmcaYkF9E7hHK4B+Nbl/65HxN0kY2a48cIZGB0B563c+WSUHOat38yTJ X-Received: by 2002:adf:ca12:: with SMTP id o18-v6mr16914389wrh.272.1525428636929; Fri, 04 May 2018 03:10:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525428636; cv=none; d=google.com; s=arc-20160816; b=soRH17mwR25JuVOTawJmpGQ0Pj+wugEYh7cqOkPnHd1lOGYHFIgxdXrteupVpSNG+X SY8oZKJinHqTDI4fwq0HHcalIDZd2qD0RGCDhhVFlGPUhkBO/gAc5WcwGiExwVnlJkXE PQaWoDAXGC+RHdz/RobH8frAYvNTTEY02sMbwl+Quo85gtHJwfE0NwMJbFQKdt0p/df2 p3yvZWI9Y5t9wyF5rj2FQ/ipdNGwSyVH/xiSplNIe5+ImHSuJVI6OwlIRbl5UiPdx9Cx 3kRND9LNSov1LtOsE/HHlD7zumXVDs//8QDlbvxQsvNEZceuN9BITeEgHmSQYxeJFZtc dfnQ== 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:dkim-signature :delivered-to:arc-authentication-results; bh=eI7BR5b2r0+OoUHa1LXzj5eQyJBabcbSZp/N33SHrg8=; b=TCg/g1Bx+YVgVHGCn7g6TekXHwDQcWvN8075ii+kvHByNnZrqo7bS9AeVf1MqqiVCL kXgGc03vFPVAtL9gRLkYxSBsNw5XWI+/Ed5wTfYSOI+1WUK52NXKO+gqtspJzwQFa0hs k0+cmwOg8W/scfeITInPX9U7DuWD30L7ozplrxiTyDXf5PcUr/FH0ZSxnCxfKGgbaOr5 sv/LpEE2BYh7mIh647VHcRyLc1E6Xa2dFCgQXJsFGAibrx+iQK2El5nvohgZXpY2hYxz hgntZxbHO9y7cagfAieVIXPZ0TsoVThO6SJwUVNbk2TFiP/nU+bhxhk9oybWJ2EQPnZj EdEg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=hZA+0QrY; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id y67si1124619wmb.1.2018.05.04.03.10.36; Fri, 04 May 2018 03:10:36 -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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=hZA+0QrY; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C8CAD68A54C; Fri, 4 May 2018 13:10:00 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f194.google.com (mail-wr0-f194.google.com [209.85.128.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C089E68A4D6 for ; Fri, 4 May 2018 13:09:53 +0300 (EEST) Received: by mail-wr0-f194.google.com with SMTP id o2-v6so17568197wrj.13 for ; Fri, 04 May 2018 03:10:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=BPHxiZjpF7bSaK1x2uUd3iooy0pebW53QXxJajoRjXg=; b=hZA+0QrYlvWuUads4w9Vnt1K8hSBmSc5g2sEs94rmdN1EXClLgKZxd85N65CPN1nwG 2rE07HzTjYa0TCGtRrAQf/7jgWM9BrWVtgRBf0pEixUsa8AmYBIHjsX/vNpt16P2hqMV aNuB+Vlknqy+j5oMxcJ+EWao0hYLTK+BJjxmkLXCaLPRJmGJrAtsyBrkh6uGKa8D+NKb v6LrwXcUMB+Ti7hE+yibcYgUxF4qwe6WbVGkPrUiQcHfo6uMdl4KblNUesQiL0q6gs7C Jw1AldVgXVvyn0UJiYPQZib+o6Lx0/jkw7nEFua9AT0lwtj/tirbn5nWgoaV2uRzSSQd /D9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=BPHxiZjpF7bSaK1x2uUd3iooy0pebW53QXxJajoRjXg=; b=s2HnGmGMOttHucM4SmROV+gb9h6/vsrH7+RmG+RcYMJ+YI6i7spOffXEKaJY7+eDvf oWAaMfT0eHBpH2kPDccwKZtYZ+eCCS3z3wCt6vOrVdtYOio1COZUYwHhHU4vo6nasSPq uK45NskYEbCl0wSl6SKiU12742nj+qZehKLCKyVmJRwVC3nfe8D7xXEg5T6+RDrhhvAg Gp7KGziceppVdfu1QetqiTX81Kk3rnZi3HNpqn6gD8xCQ4FlowHVapxXbpiQPptBrHEg u5oM0ibXghGyoq8WyUx+SrXEk/qH41byhibxYHQ8Z3a3ByEHkx7GKk4FcR28ayAgur/B B90g== X-Gm-Message-State: ALQs6tAU1gwEztZQZE3P4TxQiwY/b5+Zag50Uqou3bwXtOfWPa+5Ww/j cR4e+VNs85DX68QeVlgQ7bvF5g== X-Received: by 2002:adf:992d:: with SMTP id x42-v6mr22088817wrb.145.1525428626667; Fri, 04 May 2018 03:10:26 -0700 (PDT) Received: from localhost.localdomain ([94.250.174.60]) by smtp.gmail.com with ESMTPSA id r200sm2166224wmb.39.2018.05.04.03.10.25 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 May 2018 03:10:26 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Fri, 4 May 2018 12:10:09 +0200 Message-Id: <20180504101009.6139-1-onemda@gmail.com> X-Mailer: git-send-email 2.11.0 Subject: [FFmpeg-devel] [PATCH] avfilter/af_amerge: port to activate API 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: Paul B Mahol --- libavfilter/af_amerge.c | 144 ++++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 77 deletions(-) diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c index 09c660ef49..8b71b3ce49 100644 --- a/libavfilter/af_amerge.c +++ b/libavfilter/af_amerge.c @@ -31,8 +31,8 @@ #include "libavutil/channel_layout.h" #include "libavutil/opt.h" #include "avfilter.h" +#include "filters.h" #include "audio.h" -#include "bufferqueue.h" #include "internal.h" #define SWR_CH_MAX 64 @@ -43,10 +43,7 @@ typedef struct AMergeContext { int route[SWR_CH_MAX]; /**< channels routing, see copy_samples */ int bps; struct amerge_input { - struct FFBufQueue queue; int nb_ch; /**< number of channels for the input */ - int nb_samples; - int pos; } *in; } AMergeContext; @@ -67,8 +64,6 @@ static av_cold void uninit(AVFilterContext *ctx) int i; for (i = 0; i < s->nb_inputs; i++) { - if (s->in) - ff_bufqueue_discard_all(&s->in[i].queue); if (ctx->input_pads) av_freep(&ctx->input_pads[i].name); } @@ -183,21 +178,6 @@ static int config_output(AVFilterLink *outlink) return 0; } -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AMergeContext *s = ctx->priv; - int i, ret; - - for (i = 0; i < s->nb_inputs; i++) - if (!s->in[i].nb_samples || - /* detect EOF immediately */ - (ctx->inputs[i]->status_in && !ctx->inputs[i]->status_out)) - if ((ret = ff_request_frame(ctx->inputs[i])) < 0) - return ret; - return 0; -} - /** * Copy samples from several input streams to one output stream. * @param nb_inputs number of inputs @@ -235,90 +215,101 @@ static inline void copy_samples(int nb_inputs, struct amerge_input in[], } } -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) +static void free_frames(int nb_inputs, AVFrame **input_frames) +{ + int i; + for (i = 0; i < nb_inputs; i++) + av_frame_free(&input_frames[i]); +} + +static int try_push_frame(AVFilterContext *ctx, int nb_samples) { - AVFilterContext *ctx = inlink->dst; AMergeContext *s = ctx->priv; - AVFilterLink *const outlink = ctx->outputs[0]; - int input_number; - int nb_samples, ns, i; - AVFrame *outbuf, *inbuf[SWR_CH_MAX]; - uint8_t *ins[SWR_CH_MAX], *outs; - - for (input_number = 0; input_number < s->nb_inputs; input_number++) - if (inlink == ctx->inputs[input_number]) - break; - av_assert1(input_number < s->nb_inputs); - if (ff_bufqueue_is_full(&s->in[input_number].queue)) { - av_frame_free(&insamples); - return AVERROR(ENOMEM); + AVFilterLink *outlink = ctx->outputs[0]; + int i, ret; + AVFrame *outbuf, *inbuf[SWR_CH_MAX] = { NULL }; + uint8_t *outs, *ins[SWR_CH_MAX]; + + for (i = 0; i < ctx->nb_inputs; i++) { + ret = ff_inlink_consume_samples(ctx->inputs[i], nb_samples, nb_samples, &inbuf[i]); + if (ret < 0) { + free_frames(i, inbuf); + return ret; + } + ins[i] = inbuf[i]->data[0]; } - ff_bufqueue_add(ctx, &s->in[input_number].queue, av_frame_clone(insamples)); - s->in[input_number].nb_samples += insamples->nb_samples; - av_frame_free(&insamples); - nb_samples = s->in[0].nb_samples; - for (i = 1; i < s->nb_inputs; i++) - nb_samples = FFMIN(nb_samples, s->in[i].nb_samples); - if (!nb_samples) - return 0; outbuf = ff_get_audio_buffer(ctx->outputs[0], nb_samples); - if (!outbuf) + if (!outbuf) { + free_frames(s->nb_inputs, inbuf); return AVERROR(ENOMEM); - outs = outbuf->data[0]; - for (i = 0; i < s->nb_inputs; i++) { - inbuf[i] = ff_bufqueue_peek(&s->in[i].queue, 0); - ins[i] = inbuf[i]->data[0] + - s->in[i].pos * s->in[i].nb_ch * s->bps; } - av_frame_copy_props(outbuf, inbuf[0]); - outbuf->pts = inbuf[0]->pts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE : - inbuf[0]->pts + - av_rescale_q(s->in[0].pos, - av_make_q(1, ctx->inputs[0]->sample_rate), - ctx->outputs[0]->time_base); + + outs = outbuf->data[0]; + outbuf->pts = inbuf[0]->pts; outbuf->nb_samples = nb_samples; outbuf->channel_layout = outlink->channel_layout; outbuf->channels = outlink->channels; while (nb_samples) { - ns = nb_samples; - for (i = 0; i < s->nb_inputs; i++) - ns = FFMIN(ns, inbuf[i]->nb_samples - s->in[i].pos); /* Unroll the most common sample formats: speed +~350% for the loop, +~13% overall (including two common decoders) */ switch (s->bps) { case 1: - copy_samples(s->nb_inputs, s->in, s->route, ins, &outs, ns, 1); + copy_samples(s->nb_inputs, s->in, s->route, ins, &outs, nb_samples, 1); break; case 2: - copy_samples(s->nb_inputs, s->in, s->route, ins, &outs, ns, 2); + copy_samples(s->nb_inputs, s->in, s->route, ins, &outs, nb_samples, 2); break; case 4: - copy_samples(s->nb_inputs, s->in, s->route, ins, &outs, ns, 4); + copy_samples(s->nb_inputs, s->in, s->route, ins, &outs, nb_samples, 4); break; default: - copy_samples(s->nb_inputs, s->in, s->route, ins, &outs, ns, s->bps); + copy_samples(s->nb_inputs, s->in, s->route, ins, &outs, nb_samples, s->bps); break; } - nb_samples -= ns; - for (i = 0; i < s->nb_inputs; i++) { - s->in[i].nb_samples -= ns; - s->in[i].pos += ns; - if (s->in[i].pos == inbuf[i]->nb_samples) { - s->in[i].pos = 0; - av_frame_free(&inbuf[i]); - ff_bufqueue_get(&s->in[i].queue); - inbuf[i] = ff_bufqueue_peek(&s->in[i].queue, 0); - ins[i] = inbuf[i] ? inbuf[i]->data[0] : NULL; - } - } + nb_samples = 0; } + + free_frames(s->nb_inputs, inbuf); return ff_filter_frame(ctx->outputs[0], outbuf); } +static int activate(AVFilterContext *ctx) +{ + int i, status; + int ret, nb_samples; + int64_t pts; + + nb_samples = ff_framequeue_queued_samples(&ctx->inputs[0]->fifo); + for (i = 1; i < ctx->nb_inputs && nb_samples > 0; i++) { + nb_samples = FFMIN(ff_framequeue_queued_samples(&ctx->inputs[i]->fifo), nb_samples); + } + + if (nb_samples) { + ret = try_push_frame(ctx, nb_samples); + if (ret < 0) + return ret; + } + + for (i = 0; i < ctx->nb_inputs; i++) { + if (ff_framequeue_queued_samples(&ctx->inputs[i]->fifo)) + continue; + + if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) { + ff_outlink_set_status(ctx->outputs[0], status, pts); + return 0; + } else if (ff_outlink_frame_wanted(ctx->outputs[0])) { + ff_inlink_request_frame(ctx->inputs[i]); + return 0; + } + } + + return 0; +} + static av_cold int init(AVFilterContext *ctx) { AMergeContext *s = ctx->priv; @@ -332,7 +323,6 @@ static av_cold int init(AVFilterContext *ctx) AVFilterPad pad = { .name = name, .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, }; if (!name) return AVERROR(ENOMEM); @@ -349,7 +339,6 @@ static const AVFilterPad amerge_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = config_output, - .request_frame = request_frame, }, { NULL } }; @@ -362,6 +351,7 @@ AVFilter ff_af_amerge = { .init = init, .uninit = uninit, .query_formats = query_formats, + .activate = activate, .inputs = NULL, .outputs = amerge_outputs, .priv_class = &amerge_class,