From patchwork Sat Aug 26 15:53:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 4852 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.15.201 with SMTP id 70csp1074463jao; Sat, 26 Aug 2017 08:53:40 -0700 (PDT) X-Received: by 10.223.170.133 with SMTP id h5mr1479150wrc.79.1503762820260; Sat, 26 Aug 2017 08:53:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503762820; cv=none; d=google.com; s=arc-20160816; b=npOBetHZ0xeoV1lc0ZiNSoe1K6OVIC3aYo7BnNqlaqJIn/le0qj21rwCchTH4yiBKw /4yl5z/cIombOVF/X8xrBnpvVQZ9k4Vo65gNH86Vbb6+caQ6hWRNoSgyzWfVBMwgmWzc S4IYgHiUHO9+I7tR0MSmKt8IzJOEea1D7OUoO+oYIctfYPaw1sGVUJo9ECgaUBzpu6ZL HzlRVBeRT6LZ8Q4T7sgg71/KsU4G270zbRiQn3U/3ZPN7Ec5D0nTr8rsQJp01uoJuy+e M8OSgmCtTQFmfpCwyDQYV4M4rS0HCDJwHZq5bFiizjaqNxwVfKX2jkBo+QGE9OdU2pux 9NVw== 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=8ffm604S+SMSDXRnE3oA7Aoet0PR8DhW4fYyfE3iXF8=; b=0vFCa4d8uS9nla43xUNfdErgwRuey6iBD6dLthRX14NMtlomYGUkpZHsk5k01rtudA GfKawdtAEdZH3OpOYhhCC83U1UvVFffKW3oY8D/IeQlXaZriGlChg/aUKzU+awkac9vS GFMx27nqx7b/bru5waJMqK8Jclg8atGhL1DIk1MM8+0zse+fxIV3fG5Ssn59OTPFQmB2 gtmQS6cbRmaHILFlQplj+WW/nvkKmQnnaiL20V6LdKrv2MTFODKTk6Sd/owoo2etH/MR QHoDL7tThQzeINau2xC/TcDxokr3TjFWQEdukiqPSCQraw11Kg5y5V9Wo4vQgaRLaPZq +SYQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=texeap1S; 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=NONE 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 i71si2390130wri.209.2017.08.26.08.53.39; Sat, 26 Aug 2017 08:53:40 -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=texeap1S; 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=NONE 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 81DD7689D31; Sat, 26 Aug 2017 18:53:27 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f193.google.com (mail-wr0-f193.google.com [209.85.128.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D0610689B73 for ; Sat, 26 Aug 2017 18:53:20 +0300 (EEST) Received: by mail-wr0-f193.google.com with SMTP id a47so1561155wra.2 for ; Sat, 26 Aug 2017 08:53:30 -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=c6tHQjUyiZKiTegXIphY6usyZ67/LxwJ46Tsd+Toa3Q=; b=texeap1SCPOXjlzOfoiRsOwqZV040affgfu+m3QjU8OxdoscGjWWIkJB/0uIi/3+F7 3YQGenGr8IkXXyelnC8Gsp9/bEsaELsQSwsT+HbMxQgTkxH8whkkNhL5FjawYewSlchG K1RWo2E71wq8yXhPPG2cojo5uRAn4w+U9IP2XUWg2bEdnBv4e0ofrYw8MZ7rCpZQgkzq 9NPhB/Sgwt9dPecNYh25ksBxP5/olOT7y6PvNyygi4IWALSLj9b4pIlYdyC58/fwE+AU 0iLXJHRh0C0+qtN4RW9VXOVHvZFWlnjabGpBM4saQ5Lzj81VpJjhrk48XX+kf4DMmIcE eSfw== 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=c6tHQjUyiZKiTegXIphY6usyZ67/LxwJ46Tsd+Toa3Q=; b=S3wvwl9r1YyFkeb+WcHbi4BvtCgrxZ1YHQ5fI9CWzCUWeD+7fdtu7FhfuR6nloaXpJ ZZVs5+u6/66mqQB9UfLamOxmK1TLg9GUYD7DPGEFqiTBuINnHrnA2fggfKO9biVq5Uyx xJEOVl7/4QChMm6ze9pgHnY15JhdnbAZKhxT3c0CGKgNGrhDJzkSCO8REkDVs2Be/4Rd LY+ZIRrTigui3BrasNu+DJoMYNRkwwrmpeXB52vbBhPPVMQm4+FIaMNP6omXYS7iG4lI UHPxyLewGGigKznYo0tA0t4THAForL/eb8kae2css9BPetfY5KSoVTmk8hSkPwDzYjGg 5Z2Q== X-Gm-Message-State: AHYfb5gCdAffvPBxMStDe59b2pqZ5Jyp2TgF9IIsc4k8z4gah1HzRNJn Zjrc1gz6yo5SYIug X-Received: by 10.223.133.67 with SMTP id 61mr1260502wrh.100.1503762809323; Sat, 26 Aug 2017 08:53:29 -0700 (PDT) Received: from localhost.localdomain ([94.250.174.60]) by smtp.gmail.com with ESMTPSA id a6sm7283837wrh.51.2017.08.26.08.53.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 26 Aug 2017 08:53:28 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sat, 26 Aug 2017 17:53:18 +0200 Message-Id: <20170826155318.17408-1-onemda@gmail.com> X-Mailer: git-send-email 2.9.3 Subject: [FFmpeg-devel] [PATCH] avfilter/af_amix: 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" Really fixes hangs and infinite loops. Signed-off-by: Paul B Mahol --- libavfilter/af_amix.c | 161 +++++++++++++++++++++++++------------------------- 1 file changed, 81 insertions(+), 80 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 78be57a..989fd84 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -41,6 +41,7 @@ #include "audio.h" #include "avfilter.h" +#include "filters.h" #include "formats.h" #include "internal.h" @@ -263,21 +264,15 @@ static int config_output(AVFilterLink *outlink) return 0; } -static int calc_active_inputs(MixContext *s); - /** * Read samples from the input FIFOs, mix, and write to the output link. */ -static int output_frame(AVFilterLink *outlink, int need_request) +static int output_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; MixContext *s = ctx->priv; AVFrame *out_buf, *in_buf; - int nb_samples, ns, ret, i; - - ret = calc_active_inputs(s); - if (ret < 0) - return ret; + int nb_samples, ns, i; if (s->input_state[0] & INPUT_ON) { /* first input live: use the corresponding frame size */ @@ -288,7 +283,7 @@ static int output_frame(AVFilterLink *outlink, int need_request) if (ns < nb_samples) { if (!(s->input_state[i] & INPUT_EOF)) /* unclosed input with not enough samples */ - return need_request ? ff_request_frame(ctx->inputs[i]) : 0; + return 0; /* closed input to drain */ nb_samples = ns; } @@ -303,8 +298,10 @@ static int output_frame(AVFilterLink *outlink, int need_request) nb_samples = FFMIN(nb_samples, ns); } } - if (nb_samples == INT_MAX) - return AVERROR_EOF; + if (nb_samples == INT_MAX) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts); + return 0; + } } s->next_pts = frame_list_next_pts(s->frame_list); @@ -367,27 +364,18 @@ static int output_frame(AVFilterLink *outlink, int need_request) static int request_samples(AVFilterContext *ctx, int min_samples) { MixContext *s = ctx->priv; - int i, ret; + int i; av_assert0(s->nb_inputs > 1); for (i = 1; i < s->nb_inputs; i++) { - ret = 0; if (!(s->input_state[i] & INPUT_ON)) continue; if (av_audio_fifo_size(s->fifos[i]) >= min_samples) continue; - ret = ff_request_frame(ctx->inputs[i]); - if (ret == AVERROR_EOF) { - s->input_state[i] |= INPUT_EOF; - if (av_audio_fifo_size(s->fifos[i]) == 0) { - s->input_state[i] = 0; - continue; - } - } else if (ret < 0) - return ret; + ff_inlink_request_frame(ctx->inputs[i]); } - return output_frame(ctx->outputs[0], 1); + return output_frame(ctx->outputs[0]); } /** @@ -411,73 +399,87 @@ static int calc_active_inputs(MixContext *s) return 0; } -static int request_frame(AVFilterLink *outlink) +static int activate(AVFilterContext *ctx) { - AVFilterContext *ctx = outlink->src; - MixContext *s = ctx->priv; - int ret; - int wanted_samples; - - ret = calc_active_inputs(s); - if (ret < 0) - return ret; - - if (!(s->input_state[0] & INPUT_ON)) - return request_samples(ctx, 1); - - if (s->frame_list->nb_frames == 0) { - ret = ff_request_frame(ctx->inputs[0]); - if (ret == AVERROR_EOF) { - s->input_state[0] = 0; - if (s->nb_inputs == 1) - return AVERROR_EOF; - return output_frame(ctx->outputs[0], 1); - } - return ret; - } - av_assert0(s->frame_list->nb_frames > 0); + AVFilterLink *outlink = ctx->outputs[0]; + MixContext *s = ctx->priv; + AVFrame *buf = NULL; + int i, ret; - wanted_samples = frame_list_next_frame_size(s->frame_list); + for (i = 0; i < s->nb_inputs; i++) { + AVFilterLink *inlink = ctx->inputs[i]; + + if ((ret = ff_inlink_consume_frame(ctx->inputs[i], &buf)) > 0) { + if (i == 0) { + int64_t pts = av_rescale_q(buf->pts, inlink->time_base, + outlink->time_base); + ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts); + if (ret < 0) { + av_frame_free(&buf); + return ret; + } + } - return request_samples(ctx, wanted_samples); -} + ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data, + buf->nb_samples); + if (ret < 0) { + av_frame_free(&buf); + return ret; + } -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - MixContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int i, ret = 0; + av_frame_free(&buf); - for (i = 0; i < ctx->nb_inputs; i++) - if (ctx->inputs[i] == inlink) - break; - if (i >= ctx->nb_inputs) { - av_log(ctx, AV_LOG_ERROR, "unknown input link\n"); - ret = AVERROR(EINVAL); - goto fail; + ret = output_frame(outlink); + if (ret < 0) + return ret; + } } - if (i == 0) { - int64_t pts = av_rescale_q(buf->pts, inlink->time_base, - outlink->time_base); - ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts); - if (ret < 0) - goto fail; + for (i = 0; i < s->nb_inputs; i++) { + int64_t pts; + int status; + + if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) { + if (status == AVERROR_EOF) { + if (i == 0) { + s->input_state[i] = 0; + if (s->nb_inputs == 1) { + ff_outlink_set_status(outlink, status, pts); + return 0; + } + } else { + s->input_state[i] |= INPUT_EOF; + if (av_audio_fifo_size(s->fifos[i]) == 0) { + s->input_state[i] = 0; + } + } + } + } } - ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data, - buf->nb_samples); - if (ret < 0) - goto fail; + if (calc_active_inputs(s)) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts); + return 0; + } - av_frame_free(&buf); - return output_frame(outlink, 0); + if (ff_outlink_frame_wanted(outlink)) { + int wanted_samples; -fail: - av_frame_free(&buf); + if (!(s->input_state[0] & INPUT_ON)) + return request_samples(ctx, 1); - return ret; + if (s->frame_list->nb_frames == 0) { + ff_inlink_request_frame(ctx->inputs[0]); + return 0; + } + av_assert0(s->frame_list->nb_frames > 0); + + wanted_samples = frame_list_next_frame_size(s->frame_list); + + return request_samples(ctx, wanted_samples); + } + + return 0; } static av_cold int init(AVFilterContext *ctx) @@ -494,7 +496,6 @@ static av_cold int init(AVFilterContext *ctx) pad.name = av_strdup(name); if (!pad.name) return AVERROR(ENOMEM); - pad.filter_frame = filter_frame; if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) { av_freep(&pad.name); @@ -562,7 +563,6 @@ static const AVFilterPad avfilter_af_amix_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = config_output, - .request_frame = request_frame }, { NULL } }; @@ -574,6 +574,7 @@ AVFilter ff_af_amix = { .priv_class = &amix_class, .init = init, .uninit = uninit, + .activate = activate, .query_formats = query_formats, .inputs = NULL, .outputs = avfilter_af_amix_outputs,