From patchwork Sat Apr 18 11:59:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 19052 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 390B844BE54 for ; Sat, 18 Apr 2020 15:06:28 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 22E5668BCEC; Sat, 18 Apr 2020 15:06:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f65.google.com (mail-wm1-f65.google.com [209.85.128.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2D4FB68BA6F for ; Sat, 18 Apr 2020 15:06:21 +0300 (EEST) Received: by mail-wm1-f65.google.com with SMTP id e26so5480990wmk.5 for ; Sat, 18 Apr 2020 05:06:21 -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=9cIBiabO+FfB6z7qNg5n0BPmfx852Mlgdo5vb5xX+GY=; b=XQZbyI5DWtqL39Q1Ap5b/xm9ndKrQ933ebLybEKJdzoFZi0Naiz2ZUUYnTJi+am81N SNJVVRXlETztRtc++Fl6x00i5V/FbWOSweJWD4eYTOS1nAOJkrQyoaAZfiboZaO+rsoQ kIWCQ5HXkuOjs2d4T7x0dtkMqynzYwB9EYrVJQchkROtcMgPskJsLG/EFprUtQDQODZX QPWgdrBON6PGhFNWtWi2mbBmZCMBsDj9l4mKPx58xsDRk6xTbEbKMnrxs6u7D+7Wy6M/ SX2CpSdkvxhjUg4OVGTPZSjL2p1neAPcCjjW+Mao4Psurv5wxQ3ZU0DDd4TGRJJZqq2J 9sGg== 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=9cIBiabO+FfB6z7qNg5n0BPmfx852Mlgdo5vb5xX+GY=; b=hwKIVaKC98iUh7BxjUMdC0obCjaoPcylwmSiVPA/F5V4z+kxHS3QxC9lU6S6wpxhOc y5oaUg3K/Z+5xucsxasXPxmN/ajdYvrC3JltyJt2F8PKwxfmlh53NEYr4l1bWLpQHWYg d92lMqohMpFIH5v3XVcIuTIR65tYGfp8F4ZFcJoU/tn9WBr3xti5gID/yb5gP+3MhI8q jZu97IPOwI4h6D36qnRwASlXLKDbKTD1mwrgcbMmnAfuFl/uJrmhw10ivxx3UbyGCfpp thNsYSuWQkcRl4T7H6NHPmHu/yJmH2zyA260MT7fJ6Ihg5hB24nCWa43RwMneTfFIZGq Qczg== X-Gm-Message-State: AGi0Pubg/cBp/La5LXEyuaP+8qfQa9fvrPnl2a3NEc/qGFW+jhtX/e+5 rJ128W2Sv41Bprx9jQqS2B+09xCb X-Google-Smtp-Source: APiQypJa4Hmwm0LmzDR1DwZ4fZznT0U7/z5bvUxRBIfaFp5nuI+q8ODwzWirXP0if8qIdK3aDpneaw== X-Received: by 2002:a05:600c:210:: with SMTP id 16mr7573756wmi.57.1587211181122; Sat, 18 Apr 2020 04:59:41 -0700 (PDT) Received: from localhost.localdomain ([94.250.184.60]) by smtp.gmail.com with ESMTPSA id t8sm35460929wrq.88.2020.04.18.04.59.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Apr 2020 04:59:39 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sat, 18 Apr 2020 13:59:30 +0200 Message-Id: <20200418115931.9277-1-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH 1/2] avfilter: add ff_inlink_peek_samples and ff_inlink_skip samples 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/avfilter.c | 96 ++++++++++++++++++++++++++++++++++++++++++ libavfilter/filters.h | 17 ++++++++ 2 files changed, 113 insertions(+) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 394811916d..90c73fb64b 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -1190,6 +1190,61 @@ static int take_samples(AVFilterLink *link, unsigned min, unsigned max, return 0; } +static int peek_samples(AVFilterLink *link, unsigned peek_samples, + AVFrame **rframe) +{ + AVFrame *frame0, *frame, *buf; + unsigned nb_samples, nb_frames, i, p; + int ret; + + /* Note: this function relies on no format changes and must only be + called with enough samples. */ + av_assert1(samples_ready(link, link->min_samples)); + frame0 = frame = ff_framequeue_peek(&link->fifo, 0); + if (!link->fifo.samples_skipped && frame->nb_samples == peek_samples) { + *rframe = av_frame_clone(frame); + return 0; + } + nb_frames = 0; + nb_samples = 0; + while (1) { + if (nb_samples + frame->nb_samples >= peek_samples) + break; + nb_samples += frame->nb_samples; + nb_frames++; + if (nb_frames == ff_framequeue_queued_frames(&link->fifo)) + break; + frame = ff_framequeue_peek(&link->fifo, nb_frames); + } + + buf = ff_get_audio_buffer(link, peek_samples); + if (!buf) + return AVERROR(ENOMEM); + ret = av_frame_copy_props(buf, frame0); + if (ret < 0) { + av_frame_free(&buf); + return ret; + } + buf->pts = frame0->pts; + + p = 0; + for (i = 0; i < nb_frames; i++) { + frame = ff_framequeue_peek(&link->fifo, i); + av_samples_copy(buf->extended_data, frame->extended_data, p, 0, + frame->nb_samples, link->channels, link->format); + p += frame->nb_samples; + } + if (p < peek_samples) { + unsigned n = peek_samples - p; + frame = ff_framequeue_peek(&link->fifo, i); + av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n, + link->channels, link->format); + } + + *rframe = buf; + return 0; +} + static int ff_filter_frame_to_filter(AVFilterLink *link) { AVFrame *frame = NULL; @@ -1512,6 +1567,47 @@ int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, return 1; } +int ff_inlink_peek_samples(AVFilterLink *link, unsigned nb_samples, + AVFrame **rframe) +{ + AVFrame *frame; + int ret; + + av_assert1(nb_samples); + *rframe = NULL; + if (!ff_inlink_check_available_samples(link, nb_samples)) + return 0; + if (link->status_in) + nb_samples = FFMIN(nb_samples, ff_framequeue_queued_samples(&link->fifo)); + ret = peek_samples(link, nb_samples, &frame); + if (ret < 0) + return ret; + *rframe = frame; + return !!frame; +} + +void ff_inlink_skip_samples(AVFilterLink *link, unsigned skip_samples) +{ + while (skip_samples > 0) { + AVFrame *frame = ff_inlink_peek_frame(link, 0); + if (skip_samples >= frame->nb_samples) { + frame = ff_framequeue_take(&link->fifo); + skip_samples -= frame->nb_samples; + av_frame_free(&frame); + } else { + break; + } + } + + if (skip_samples) + ff_framequeue_skip_samples(&link->fifo, skip_samples, link->time_base); + + if (ff_inlink_queued_frames(link)) { + AVFrame *frame = ff_inlink_peek_frame(link, 0); + consume_update(link, frame); + } +} + AVFrame *ff_inlink_peek_frame(AVFilterLink *link, size_t idx) { return ff_framequeue_peek(&link->fifo, idx); diff --git a/libavfilter/filters.h b/libavfilter/filters.h index 1157755403..7dc0b35981 100644 --- a/libavfilter/filters.h +++ b/libavfilter/filters.h @@ -115,6 +115,23 @@ int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe); int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe); +/** + * Peek samples from the link's FIFO. + * + * @return >0 if a samples are available, + * 0 and set rframe to NULL if no samples are available, + * or AVERROR code + */ +int ff_inlink_peek_samples(AVFilterLink *link, unsigned nb_samples, + AVFrame **rframe); + +/** + * Skip samples from the link's FIFO. + * + * @note May trigger process_command() and/or update is_disabled. + */ +void ff_inlink_skip_samples(AVFilterLink *link, unsigned skip); + /** * Access a frame in the link fifo without consuming it. * The first frame is numbered 0; the designated frame must exist. From patchwork Sat Apr 18 11:59:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 19051 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 5439944BA56 for ; Sat, 18 Apr 2020 15:04:57 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2D29F68BFA6; Sat, 18 Apr 2020 15:04:57 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8ADDE68BF9D for ; Sat, 18 Apr 2020 15:04:50 +0300 (EEST) Received: by mail-wm1-f66.google.com with SMTP id y24so5692016wma.4 for ; Sat, 18 Apr 2020 05:04:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=M2VYX7luywcwvlGxcnQ+Ya574xCocgJz6vNTL2PTxEg=; b=gInVadG+JgVnC4xhNEvVHTRRRa3lSSQql6NV62XU8dnlu2USEHO7Q+dgfM+iApr8yC 9y6q1g5qOizWbgUP/sS+tmO8IrZRgIou1MR/XhoA+gfTxfzuv5U9u+rgS+oZSe5AF0sd 58lab3gUDNUZagg8fDNQRJMTlx7q0tUnty2JjpMM49TijQaYtgpnTd03pNI1jRWmoHZi MTY7Ib+cgudtxCPCZlt+p+tizex2N0uQt1JZ7PFCwa1PStYwpNZKGcunpdXELRnLHM1C YXjjyYmr2VJ/6bNu/4v3fSlBooIWQGfjD/CJWJJvIHxya+rAURFo8y8oREUCBnAm36+J MkrA== 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:in-reply-to :references; bh=M2VYX7luywcwvlGxcnQ+Ya574xCocgJz6vNTL2PTxEg=; b=p87DhwbnVi0MHsIxSHbON2+TmotNcCDQS6GCf9x2iZVhZlB5sGs77KqIUNa0F07VQE kapYU5mJ2Gb7h8BbrfYfyF+TSUp4DhFcFM3kz6jDB+f/aD0QubMWG8ZKbE+QGSR/zcvP cGitwjfC7I5hKfllo/0rZZdudGhrZ00VKI8Kbi+xOi43GLHAWqhUhVRJoWCTgxmEPxWo 53YJQW2Li2z2KBkYS2TCCyWYSvOYTfT7Yp56OC8si7LwrNEm1Mx7wr2OCRV6ypxYofdV LeKau23mpVc6Z6EwRCEukIxLqMn06XbKAs89SOqxzLOE3vP21oL+QTPdGsVjHzcIpNz2 zuWA== X-Gm-Message-State: AGi0Puaxt2pk9+/UBEbb7OJu1/WYB77uJdwezOjdVLuD+6OmoN22CTRf 8aR/R8K2HxhFvnyQuHER+hqRwsq9 X-Google-Smtp-Source: APiQypJfjEc5vJ1vAI+/qsk8Ksx/kpkk5BEPbnSCT+sTlI5OkiK5QcDha993CsUiBeUdWS8UynEoAw== X-Received: by 2002:a1c:7d4b:: with SMTP id y72mr8108715wmc.11.1587211182160; Sat, 18 Apr 2020 04:59:42 -0700 (PDT) Received: from localhost.localdomain ([94.250.184.60]) by smtp.gmail.com with ESMTPSA id t8sm35460929wrq.88.2020.04.18.04.59.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Apr 2020 04:59:41 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sat, 18 Apr 2020 13:59:31 +0200 Message-Id: <20200418115931.9277-2-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200418115931.9277-1-onemda@gmail.com> References: <20200418115931.9277-1-onemda@gmail.com> Subject: [FFmpeg-devel] [PATCH 2/2] avfilter/avf_showspectrumpic: switch to internal queue 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" Fixes filtering audio with more than 1.5h length. Signed-off-by: Paul B Mahol --- libavfilter/avf_showspectrum.c | 119 ++++++++++++++++----------------- 1 file changed, 59 insertions(+), 60 deletions(-) diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c index a4dd7b7879..9425c4ded6 100644 --- a/libavfilter/avf_showspectrum.c +++ b/libavfilter/avf_showspectrum.c @@ -1606,91 +1606,90 @@ static const AVOption showspectrumpic_options[] = { AVFILTER_DEFINE_CLASS(showspectrumpic); -static int showspectrumpic_request_frame(AVFilterLink *outlink) +static int showspectrumpic_request_frame(AVFilterLink *outlink, int64_t samples) { AVFilterContext *ctx = outlink->src; ShowSpectrumContext *s = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; - int ret, samples; + int consumed = 0; + int x = 0, sz = s->orientation == VERTICAL ? s->w : s->h; + int ret, ch, spf, spb; + AVFrame *fin = NULL; - ret = ff_request_frame(inlink); - samples = av_audio_fifo_size(s->fifo); - if (ret == AVERROR_EOF && s->outpicref && samples > 0) { - int consumed = 0; - int x = 0, sz = s->orientation == VERTICAL ? s->w : s->h; - int ch, spf, spb; - AVFrame *fin; + spf = s->win_size * (samples / ((s->win_size * sz) * ceil(samples / (float)(s->win_size * sz)))); + spf = FFMAX(1, spf); - spf = s->win_size * (samples / ((s->win_size * sz) * ceil(samples / (float)(s->win_size * sz)))); - spf = FFMAX(1, spf); + spb = (samples / (spf * sz)) * spf; - spb = (samples / (spf * sz)) * spf; - - fin = ff_get_audio_buffer(inlink, s->win_size); - if (!fin) - return AVERROR(ENOMEM); - - while (x < sz) { - ret = av_audio_fifo_peek(s->fifo, (void **)fin->extended_data, s->win_size); - if (ret < 0) { - av_frame_free(&fin); - return ret; - } - - av_audio_fifo_drain(s->fifo, spf); - - if (ret < s->win_size) { - for (ch = 0; ch < s->nb_display_channels; ch++) { - memset(fin->extended_data[ch] + ret * sizeof(float), 0, - (s->win_size - ret) * sizeof(float)); - } - } - - ctx->internal->execute(ctx, run_channel_fft, fin, NULL, s->nb_display_channels); - acalc_magnitudes(s); - - consumed += spf; - if (consumed >= spb) { - int h = s->orientation == VERTICAL ? s->h : s->w; + while (x < sz) { + ret = ff_inlink_peek_samples(inlink, s->win_size, &fin); + if (ret < 0) + return ret; + if (ret == 0) + break; - scale_magnitudes(s, 1.f / (consumed / spf)); - plot_spectrum_column(inlink, fin); - consumed = 0; - x++; - for (ch = 0; ch < s->nb_display_channels; ch++) - memset(s->magnitudes[ch], 0, h * sizeof(float)); - } + ctx->internal->execute(ctx, run_channel_fft, fin, NULL, s->nb_display_channels); + acalc_magnitudes(s); + + consumed += spf; + if (consumed >= spb) { + int h = s->orientation == VERTICAL ? s->h : s->w; + + scale_magnitudes(s, 1.f / (consumed / spf)); + plot_spectrum_column(inlink, fin); + consumed = 0; + x++; + for (ch = 0; ch < s->nb_display_channels; ch++) + memset(s->magnitudes[ch], 0, h * sizeof(float)); } - av_frame_free(&fin); - s->outpicref->pts = 0; + ff_inlink_skip_samples(inlink, spf); + } - if (s->legend) - draw_legend(ctx, samples); + s->outpicref->pts = 0; - ret = ff_filter_frame(outlink, s->outpicref); - s->outpicref = NULL; - } + if (s->legend) + draw_legend(ctx, samples); + + ret = ff_filter_frame(outlink, s->outpicref); + s->outpicref = NULL; return ret; } -static int showspectrumpic_filter_frame(AVFilterLink *inlink, AVFrame *insamples) +static int showspectrumpic_activate(AVFilterContext *ctx) { - AVFilterContext *ctx = inlink->dst; + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; ShowSpectrumContext *s = ctx->priv; int ret; - ret = av_audio_fifo_write(s->fifo, (void **)insamples->extended_data, insamples->nb_samples); - av_frame_free(&insamples); - return ret; + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); + + if (ff_outlink_get_status(inlink) == AVERROR_EOF && + s->outpicref) { + int64_t samples = 0; + + for (int i = 0; i < ff_inlink_queued_frames(inlink); i++) { + AVFrame *frame = ff_inlink_peek_frame(inlink, i); + + samples += frame->nb_samples; + } + + ret = showspectrumpic_request_frame(outlink, samples); + ff_outlink_set_status(outlink, AVERROR_EOF, 0); + return ret; + } + + FF_FILTER_FORWARD_WANTED(outlink, inlink); + + return FFERROR_NOT_READY; } static const AVFilterPad showspectrumpic_inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = showspectrumpic_filter_frame, }, { NULL } }; @@ -1700,7 +1699,6 @@ static const AVFilterPad showspectrumpic_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, - .request_frame = showspectrumpic_request_frame, }, { NULL } }; @@ -1711,6 +1709,7 @@ AVFilter ff_avf_showspectrumpic = { .uninit = uninit, .query_formats = query_formats, .priv_size = sizeof(ShowSpectrumContext), + .activate = showspectrumpic_activate, .inputs = showspectrumpic_inputs, .outputs = showspectrumpic_outputs, .priv_class = &showspectrumpic_class,