History

avfilter/avf_showspatial: switch to lavu TX

Also try harder to make output constant frame rate.

Paul B Mahol committed 3 years ago

Commit 59b16351 parent 24cd4c93 files · +35 −51Browse files

Unified · Split

3 files
  1. configure +0 −2
  2. doc/filters.texi +0 −5
  3. libavfilter/avf_showspatial.c +35 −44
configure+0−2
@@ -3736,8 +3736,6 @@ select_filter_select="scene_sad" · 3735 unmodified lines
3736sharpness_vaapi_filter_deps="vaapi"3736sharpness_vaapi_filter_deps="vaapi"
3737showcqt_filter_deps="avformat swscale"3737showcqt_filter_deps="avformat swscale"
3738showcqt_filter_suggest="libfontconfig libfreetype"3738showcqt_filter_suggest="libfontconfig libfreetype"
3739showspatial_filter_deps="avcodec"
3740showspatial_filter_select="fft"
3741signature_filter_deps="gpl avcodec avformat"3739signature_filter_deps="gpl avcodec avformat"
3742smartblur_filter_deps="gpl swscale"3740smartblur_filter_deps="gpl swscale"
3743sobel_opencl_filter_deps="opencl"3741sobel_opencl_filter_deps="opencl"
doc/filters.texi+0−5
@@ -29452,11 +29452,6 @@ It accepts the following values: · 29451 unmodified lines
29452 29452
29453Default value is @code{hann}.29453Default value is @code{hann}.
29454 29454
29455@item overlap
29456Set ratio of overlap window. Default value is @code{0.5}.
29457When value is @code{1} overlap is set to recommended size for specific
29458window function currently used.
29459
29460@item rate, r29455@item rate, r
29461Set output framerate.29456Set output framerate.
29462@end table29457@end table
libavfilter/avf_showspatial.c+35−44
@@ -21,7 +21,7 @@ · 20 unmodified lines
21#include <float.h>21#include <float.h>
22#include <math.h>22#include <math.h>
23 23
24#include "libavcodec/avfft.h"24#include "libavutil/tx.h"
25#include "libavutil/audio_fifo.h"25#include "libavutil/audio_fifo.h"
26#include "libavutil/avassert.h"26#include "libavutil/avassert.h"
27#include "libavutil/channel_layout.h"27#include "libavutil/channel_layout.h"
@@ -38,15 +38,14 @@ typedef struct ShowSpatialContext { · 10 unmodified lines
38 const AVClass *class;38 const AVClass *class;
39 int w, h;39 int w, h;
40 AVRational frame_rate;40 AVRational frame_rate;
41 FFTContext *fft[2]; ///< Fast Fourier Transform context41 AVTXContext *fft[2]; ///< Fast Fourier Transform context
42 FFTContext *ifft[2]; ///< Inverse Fast Fourier Transform context42 AVComplexFloat *fft_data[2]; ///< bins holder for each (displayed) channels
43 int fft_bits; ///< number of bits (FFT window size = 1<<fft_bits)43 AVComplexFloat *fft_tdata[2]; ///< bins holder for each (displayed) channels
44 FFTComplex *fft_data[2]; ///< bins holder for each (displayed) channels
45 float *window_func_lut; ///< Window function LUT44 float *window_func_lut; ///< Window function LUT
45 av_tx_fn tx_fn[2];
46 int win_func;46 int win_func;
47 int win_size;47 int win_size;
48 int buf_size;48 int buf_size;
49 float overlap;
50 int consumed;49 int consumed;
51 int hop_size;50 int hop_size;
52 AVAudioFifo *fifo;51 AVAudioFifo *fifo;
@@ -61,7 +60,6 @@ static const AVOption showspatial_options[] = { · 8 unmodified lines
61 { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "512x512"}, 0, 0, FLAGS },60 { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "512x512"}, 0, 0, FLAGS },
62 { "win_size", "set window size", OFFSET(win_size), AV_OPT_TYPE_INT, {.i64 = 4096}, 1024, 65536, FLAGS },61 { "win_size", "set window size", OFFSET(win_size), AV_OPT_TYPE_INT, {.i64 = 4096}, 1024, 65536, FLAGS },
63 WIN_FUNC_OPTION("win_func", OFFSET(win_func), FLAGS, WFUNC_HANNING),62 WIN_FUNC_OPTION("win_func", OFFSET(win_func), FLAGS, WFUNC_HANNING),
64 { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
65 { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, INT_MAX, FLAGS },63 { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, INT_MAX, FLAGS },
66 { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, INT_MAX, FLAGS },64 { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, INT_MAX, FLAGS },
67 { NULL }65 { NULL }
@@ -72,14 +70,13 @@ AVFILTER_DEFINE_CLASS(showspatial); · 4 unmodified lines
72static av_cold void uninit(AVFilterContext *ctx)70static av_cold void uninit(AVFilterContext *ctx)
73{71{
74 ShowSpatialContext *s = ctx->priv;72 ShowSpatialContext *s = ctx->priv;
75 int i;
76 73
77 for (i = 0; i < 2; i++)74 for (int i = 0; i < 2; i++)
78 av_fft_end(s->fft[i]);75 av_tx_uninit(&s->fft[i]);
79 for (i = 0; i < 2; i++)76 for (int i = 0; i < 2; i++) {
80 av_fft_end(s->ifft[i]);
81 for (i = 0; i < 2; i++)
82 av_freep(&s->fft_data[i]);77 av_freep(&s->fft_data[i]);
78 av_freep(&s->fft_tdata[i]);
79 }
83 av_freep(&s->window_func_lut);80 av_freep(&s->window_func_lut);
84 av_audio_fifo_free(s->fifo);81 av_audio_fifo_free(s->fifo);
85}82}
@@ -120,12 +117,11 @@ static int run_channel_fft(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 34 unmodified lines
120 const float *p = (float *)fin->extended_data[ch];117 const float *p = (float *)fin->extended_data[ch];
121 118
122 for (int n = 0; n < fin->nb_samples; n++) {119 for (int n = 0; n < fin->nb_samples; n++) {
123 s->fft_data[ch][n].re = p[n] * window_func_lut[n];120 s->fft_tdata[ch][n].re = p[n] * window_func_lut[n];
124 s->fft_data[ch][n].im = 0;121 s->fft_tdata[ch][n].im = 0.f;
125 }122 }
126 123
127 av_fft_permute(s->fft[ch], s->fft_data[ch]);124 s->tx_fn[ch](s->fft[ch], s->fft_data[ch], s->fft_tdata[ch], sizeof(float));
128 av_fft_calc(s->fft[ch], s->fft_data[ch]);
129 125
130 return 0;126 return 0;
131}127}
@@ -135,38 +131,41 @@ static int config_output(AVFilterLink *outlink) · 3 unmodified lines
135 AVFilterContext *ctx = outlink->src;131 AVFilterContext *ctx = outlink->src;
136 AVFilterLink *inlink = ctx->inputs[0];132 AVFilterLink *inlink = ctx->inputs[0];
137 ShowSpatialContext *s = ctx->priv;133 ShowSpatialContext *s = ctx->priv;
138 int i, fft_bits;
139 float overlap;134 float overlap;
135 int ret;
140 136
141 outlink->w = s->w;137 outlink->w = s->w;
142 outlink->h = s->h;138 outlink->h = s->h;
143 outlink->sample_aspect_ratio = (AVRational){1,1};139 outlink->sample_aspect_ratio = (AVRational){1,1};
144 140
145 s->buf_size = 1 << av_log2(s->win_size);141 outlink->frame_rate = s->frame_rate;
146 s->win_size = s->buf_size;142 outlink->time_base = av_inv_q(outlink->frame_rate);
147 fft_bits = av_log2(s->win_size);
148 143
149 /* (re-)configuration if the video output changed (or first init) */144 /* (re-)configuration if the video output changed (or first init) */
150 if (fft_bits != s->fft_bits) {145 if (s->win_size != s->buf_size) {
151 s->fft_bits = fft_bits;146 s->buf_size = s->win_size;
152 147
153 /* FFT buffers: x2 for each channel buffer.148 /* FFT buffers: x2 for each channel buffer.
154 * Note: we use free and malloc instead of a realloc-like function to149 * Note: we use free and malloc instead of a realloc-like function to
155 * make sure the buffer is aligned in memory for the FFT functions. */150 * make sure the buffer is aligned in memory for the FFT functions. */
156 for (i = 0; i < 2; i++) {151 for (int i = 0; i < 2; i++) {
157 av_fft_end(s->fft[i]);152 av_tx_uninit(&s->fft[i]);
158 av_freep(&s->fft_data[i]);153 av_freep(&s->fft_data[i]);
154 av_freep(&s->fft_tdata[i]);
159 }155 }
160 for (i = 0; i < 2; i++) {156 for (int i = 0; i < 2; i++) {
161 s->fft[i] = av_fft_init(fft_bits, 0);157 float scale = 1.f;
162 if (!s->fft[i]) {158 ret = av_tx_init(&s->fft[i], &s->tx_fn[i], AV_TX_FLOAT_FFT,
163 av_log(ctx, AV_LOG_ERROR, "Unable to create FFT context. "159 0, s->win_size, &scale, 0);
164 "The window size might be too high.\n");160 if (ret < 0)
165 return AVERROR(EINVAL);161 return ret;
166 }
167 }162 }
168 163
169 for (i = 0; i < 2; i++) {164 for (int i = 0; i < 2; i++) {
165 s->fft_tdata[i] = av_calloc(s->buf_size, sizeof(**s->fft_tdata));
166 if (!s->fft_tdata[i])
167 return AVERROR(ENOMEM);
168
170 s->fft_data[i] = av_calloc(s->buf_size, sizeof(**s->fft_data));169 s->fft_data[i] = av_calloc(s->buf_size, sizeof(**s->fft_data));
171 if (!s->fft_data[i])170 if (!s->fft_data[i])
172 return AVERROR(ENOMEM);171 return AVERROR(ENOMEM);
@@ -179,19 +178,10 @@ static int config_output(AVFilterLink *outlink) · 6 unmodified lines
179 if (!s->window_func_lut)178 if (!s->window_func_lut)
180 return AVERROR(ENOMEM);179 return AVERROR(ENOMEM);
181 generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap);180 generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap);
182 if (s->overlap == 1)
183 s->overlap = overlap;
184 181
185 s->hop_size = (1.f - s->overlap) * s->win_size;182 s->hop_size = FFMAX(1, av_rescale(inlink->sample_rate, s->frame_rate.den, s->frame_rate.num));
186 if (s->hop_size < 1) {
187 av_log(ctx, AV_LOG_ERROR, "overlap %f too big\n", s->overlap);
188 return AVERROR(EINVAL);
189 }
190 }183 }
191 184
192 outlink->frame_rate = s->frame_rate;
193 outlink->time_base = av_inv_q(outlink->frame_rate);
194
195 av_audio_fifo_free(s->fifo);185 av_audio_fifo_free(s->fifo);
196 s->fifo = av_audio_fifo_alloc(inlink->format, inlink->ch_layout.nb_channels, s->win_size);186 s->fifo = av_audio_fifo_alloc(inlink->format, inlink->ch_layout.nb_channels, s->win_size);
197 if (!s->fifo)187 if (!s->fifo)
@@ -220,6 +210,7 @@ static int draw_spatial(AVFilterLink *inlink, AVFrame *insamples) · 22 unmodified lines
220 int h = s->h - 2;210 int h = s->h - 2;
221 int w = s->w - 2;211 int w = s->w - 2;
222 int z = s->win_size / 2;212 int z = s->win_size / 2;
213 int64_t pts = av_rescale_q(insamples->pts, inlink->time_base, outlink->time_base);
223 214
224 outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h);215 outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h);
225 if (!outpicref)216 if (!outpicref)
@@ -255,7 +246,7 @@ static int draw_spatial(AVFilterLink *inlink, AVFrame *insamples) · 29 unmodified lines
255 draw_dot(outpicref->data[2] + outpicref->linesize[2] * y + x, outpicref->linesize[2], cr);246 draw_dot(outpicref->data[2] + outpicref->linesize[2] * y + x, outpicref->linesize[2], cr);
256 }247 }
257 248
258 outpicref->pts = av_rescale_q(insamples->pts, inlink->time_base, outlink->time_base);249 outpicref->pts = pts;
259 outpicref->duration = 1;250 outpicref->duration = 1;
260 251
261 return ff_filter_frame(outlink, outpicref);252 return ff_filter_frame(outlink, outpicref);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t