Commit 7f7a9dd7 authored by Paul B Mahol's avatar Paul B Mahol

avfilter/avf_showspectrum: store win_size in private context and calculate it only once

Signed-off-by: 's avatarPaul B Mahol <onemda@gmail.com>
parent 8bcd1997
...@@ -64,6 +64,7 @@ typedef struct { ...@@ -64,6 +64,7 @@ typedef struct {
FFTSample **rdft_data; ///< bins holder for each (displayed) channels FFTSample **rdft_data; ///< bins holder for each (displayed) channels
float *window_func_lut; ///< Window function LUT float *window_func_lut; ///< Window function LUT
int win_func; int win_func;
int win_size;
double win_scale; double win_scale;
float overlap; float overlap;
int skip_samples; int skip_samples;
...@@ -225,7 +226,7 @@ static int config_output(AVFilterLink *outlink) ...@@ -225,7 +226,7 @@ static int config_output(AVFilterLink *outlink)
AVFilterContext *ctx = outlink->src; AVFilterContext *ctx = outlink->src;
AVFilterLink *inlink = ctx->inputs[0]; AVFilterLink *inlink = ctx->inputs[0];
ShowSpectrumContext *s = ctx->priv; ShowSpectrumContext *s = ctx->priv;
int i, rdft_bits, win_size, h, w; int i, rdft_bits, h, w;
float overlap; float overlap;
outlink->w = s->w; outlink->w = s->w;
...@@ -243,7 +244,7 @@ static int config_output(AVFilterLink *outlink) ...@@ -243,7 +244,7 @@ static int config_output(AVFilterLink *outlink)
/* RDFT window size (precision) according to the requested output frame width */ /* RDFT window size (precision) according to the requested output frame width */
for (rdft_bits = 1; 1 << rdft_bits < 2 * w; rdft_bits++); for (rdft_bits = 1; 1 << rdft_bits < 2 * w; rdft_bits++);
} }
win_size = 1 << rdft_bits; s->win_size = 1 << rdft_bits;
/* (re-)configuration if the video output changed (or first init) */ /* (re-)configuration if the video output changed (or first init) */
if (rdft_bits != s->rdft_bits) { if (rdft_bits != s->rdft_bits) {
...@@ -270,27 +271,27 @@ static int config_output(AVFilterLink *outlink) ...@@ -270,27 +271,27 @@ static int config_output(AVFilterLink *outlink)
if (!s->rdft_data) if (!s->rdft_data)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
for (i = 0; i < s->nb_display_channels; i++) { for (i = 0; i < s->nb_display_channels; i++) {
s->rdft_data[i] = av_calloc(win_size, sizeof(**s->rdft_data)); s->rdft_data[i] = av_calloc(s->win_size, sizeof(**s->rdft_data));
if (!s->rdft_data[i]) if (!s->rdft_data[i])
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
/* pre-calc windowing function */ /* pre-calc windowing function */
s->window_func_lut = s->window_func_lut =
av_realloc_f(s->window_func_lut, win_size, av_realloc_f(s->window_func_lut, s->win_size,
sizeof(*s->window_func_lut)); sizeof(*s->window_func_lut));
if (!s->window_func_lut) if (!s->window_func_lut)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
ff_generate_window_func(s->window_func_lut, win_size, s->win_func, &overlap); ff_generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap);
if (s->overlap == 1) if (s->overlap == 1)
s->overlap = overlap; s->overlap = overlap;
s->skip_samples = (1. - s->overlap) * win_size; s->skip_samples = (1. - s->overlap) * s->win_size;
if (s->skip_samples < 1) { if (s->skip_samples < 1) {
av_log(ctx, AV_LOG_ERROR, "overlap %f too big\n", s->overlap); av_log(ctx, AV_LOG_ERROR, "overlap %f too big\n", s->overlap);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
for (s->win_scale = 0, i = 0; i < win_size; i++) { for (s->win_scale = 0, i = 0; i < s->win_size; i++) {
s->win_scale += s->window_func_lut[i] * s->window_func_lut[i]; s->win_scale += s->window_func_lut[i] * s->window_func_lut[i];
} }
s->win_scale = 1. / (sqrt(s->win_scale) * 32768.); s->win_scale = 1. / (sqrt(s->win_scale) * 32768.);
...@@ -313,7 +314,7 @@ static int config_output(AVFilterLink *outlink) ...@@ -313,7 +314,7 @@ static int config_output(AVFilterLink *outlink)
(s->orientation == HORIZONTAL && s->xpos >= outlink->h)) (s->orientation == HORIZONTAL && s->xpos >= outlink->h))
s->xpos = 0; s->xpos = 0;
outlink->frame_rate = av_make_q(inlink->sample_rate, win_size * (1.-s->overlap)); outlink->frame_rate = av_make_q(inlink->sample_rate, s->win_size * (1.-s->overlap));
if (s->orientation == VERTICAL && s->sliding == FULLFRAME) if (s->orientation == VERTICAL && s->sliding == FULLFRAME)
outlink->frame_rate.den *= outlink->w; outlink->frame_rate.den *= outlink->w;
if (s->orientation == HORIZONTAL && s->sliding == FULLFRAME) if (s->orientation == HORIZONTAL && s->sliding == FULLFRAME)
...@@ -330,10 +331,10 @@ static int config_output(AVFilterLink *outlink) ...@@ -330,10 +331,10 @@ static int config_output(AVFilterLink *outlink)
} }
av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d RDFT window size:%d\n", av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d RDFT window size:%d\n",
s->w, s->h, win_size); s->w, s->h, s->win_size);
av_audio_fifo_free(s->fifo); av_audio_fifo_free(s->fifo);
s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, win_size); s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->win_size);
if (!s->fifo) if (!s->fifo)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
return 0; return 0;
...@@ -376,23 +377,18 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples) ...@@ -376,23 +377,18 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
AVFilterLink *outlink = ctx->outputs[0]; AVFilterLink *outlink = ctx->outputs[0];
ShowSpectrumContext *s = ctx->priv; ShowSpectrumContext *s = ctx->priv;
AVFrame *outpicref = s->outpicref; AVFrame *outpicref = s->outpicref;
/* nb_freq contains the power of two superior or equal to the output image
* height (or half the RDFT window size) */
const int nb_freq = 1 << (s->rdft_bits - 1);
const int win_size = nb_freq << 1;
const double w = s->win_scale; const double w = s->win_scale;
int h = s->orientation == VERTICAL ? s->channel_height : s->channel_width; int h = s->orientation == VERTICAL ? s->channel_height : s->channel_width;
int ch, plane, n, x, y; int ch, plane, n, x, y;
av_assert0(insamples->nb_samples == win_size); av_assert0(insamples->nb_samples == s->win_size);
/* fill RDFT input with the number of samples available */ /* fill RDFT input with the number of samples available */
for (ch = 0; ch < s->nb_display_channels; ch++) { for (ch = 0; ch < s->nb_display_channels; ch++) {
const int16_t *p = (int16_t *)insamples->extended_data[ch]; const int16_t *p = (int16_t *)insamples->extended_data[ch];
for (n = 0; n < win_size; n++) for (n = 0; n < s->win_size; n++)
s->rdft_data[ch][n] = p[n] * s->window_func_lut[n]; s->rdft_data[ch][n] = p[n] * s->window_func_lut[n];
} }
...@@ -610,21 +606,20 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples) ...@@ -610,21 +606,20 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples)
return ret; return ret;
} }
return win_size; return s->win_size;
} }
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
ShowSpectrumContext *s = ctx->priv; ShowSpectrumContext *s = ctx->priv;
unsigned win_size = 1 << s->rdft_bits;
AVFrame *fin = NULL; AVFrame *fin = NULL;
int ret = 0; int ret = 0;
av_audio_fifo_write(s->fifo, (void **)insamples->extended_data, insamples->nb_samples); av_audio_fifo_write(s->fifo, (void **)insamples->extended_data, insamples->nb_samples);
av_frame_free(&insamples); av_frame_free(&insamples);
while (av_audio_fifo_size(s->fifo) >= win_size) { while (av_audio_fifo_size(s->fifo) >= s->win_size) {
fin = ff_get_audio_buffer(inlink, win_size); fin = ff_get_audio_buffer(inlink, s->win_size);
if (!fin) { if (!fin) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail; goto fail;
...@@ -632,7 +627,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) ...@@ -632,7 +627,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
fin->pts = s->pts; fin->pts = s->pts;
s->pts += s->skip_samples; s->pts += s->skip_samples;
ret = av_audio_fifo_peek(s->fifo, (void **)fin->extended_data, win_size); ret = av_audio_fifo_peek(s->fifo, (void **)fin->extended_data, s->win_size);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment