History

avfilter/af_axcorrelate: add another algorithm for calculation

Rewrite EOF logic while here.

Paul B Mahol committed 3 years ago

Commit c183f841 parent f0322342 files · +114 −33Browse files

Showing the changes to libavfilter (1 of 2 files). Show all

Unified · Split

libavfilter/af_axcorrelate.c+112−31
@@ -110,7 +110,7 @@ static int xcorrelate_slow_##suffix(AVFilterContext *ctx, \ · 109 unmodified lines
110110 AVFrame *out, int available) \
111111 { \
112112 AudioXCorrelateContext *s = ctx->priv; \
113− const int size = FFMIN(available, s->size); \
113+ const int size = s->size; \
114114 int used; \
115115 \
116116 for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) { \
@@ -127,13 +127,13 @@ static int xcorrelate_slow_##suffix(AVFilterContext *ctx, \ · 10 unmodified lines
127127 used = 1; \
128128 } \
129129 \
130− for (int n = 0; n < out->nb_samples; n++) { \
131− const int idx = available <= s->size ? out->nb_samples - n - 1 : n + size; \
132− \
133− dst[n] = xcorrelate_##suffix(x + n, y + n, \
134− sumx[0], sumy[0], \
135− size); \
136− \
130+ for (int n = 0; n < out->nb_samples; n++) { \
131+ const int idx = n + size; \
132+ \
133+ dst[n] = xcorrelate_##suffix(x + n, y + n, \
134+ sumx[0], sumy[0],\
135+ size); \
136+ \
137137 sumx[0] -= x[n]; \
138138 sumx[0] += x[idx]; \
139139 sumy[0] -= y[n]; \
@@ -147,12 +147,15 @@ static int xcorrelate_slow_##suffix(AVFilterContext *ctx, \ · 7 unmodified lines
147147 XCORRELATE_SLOW(f, float)
148148 XCORRELATE_SLOW(d, double)
149149
150−#define XCORRELATE_FAST(suffix, type, zero, small, sqrtfun) \
150+#define clipf(x) (av_clipf(x, -1.f, 1.f))
151+#define clipd(x) (av_clipd(x, -1.0, 1.0))
152+
153+#define XCORRELATE_FAST(suffix, type, zero, small, sqrtfun, CLIP) \
151154 static int xcorrelate_fast_##suffix(AVFilterContext *ctx, AVFrame *out, \
152155 int available) \
153156 { \
154157 AudioXCorrelateContext *s = ctx->priv; \
155− const int size = FFMIN(available, s->size); \
158+ const int size = s->size; \
156159 int used; \
157160 \
158161 for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) { \
@@ -171,14 +174,14 @@ static int xcorrelate_fast_##suffix(AVFilterContext *ctx, AVFrame *out, \ · 12 unmodified lines
171174 used = 1; \
172175 } \
173176 \
174− for (int n = 0; n < out->nb_samples; n++) { \
175− const int idx = available <= s->size ? out->nb_samples - n - 1 : n + size; \
176− type num, den; \
177+ for (int n = 0; n < out->nb_samples; n++) { \
178+ const int idx = n + size; \
179+ type num, den; \
177180 \
178181 num = num_sum[0] / size; \
179182 den = sqrtfun((den_sumx[0] * den_sumy[0]) / size / size); \
180183 \
181− dst[n] = den <= small ? zero : num / den; \
184+ dst[n] = den <= small ? zero : CLIP(num / den); \
182185 \
183186 num_sum[0] -= x[n] * y[n]; \
184187 num_sum[0] += x[idx] * y[idx]; \
@@ -194,20 +197,82 @@ static int xcorrelate_fast_##suffix(AVFilterContext *ctx, AVFrame *out, \ · 9 unmodified lines
194197 return used; \
195198 }
196199
197−XCORRELATE_FAST(f, float, 0.f, 1e-6f, sqrtf)
198−XCORRELATE_FAST(d, double, 0.0, 1e-9, sqrt)
200+XCORRELATE_FAST(f, float, 0.f, 1e-6f, sqrtf, clipf)
201+XCORRELATE_FAST(d, double, 0.0, 1e-9, sqrt, clipd)
202+
203+#define XCORRELATE_BEST(suffix, type, zero, small, sqrtfun, FMAX, CLIP) \
204+static int xcorrelate_best_##suffix(AVFilterContext *ctx, AVFrame *out, \
205+ int available) \
206+{ \
207+ AudioXCorrelateContext *s = ctx->priv; \
208+ const int size = s->size; \
209+ int used; \
210+ \
211+ for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) { \
212+ const type *x = (const type *)s->cache[0]->extended_data[ch]; \
213+ const type *y = (const type *)s->cache[1]->extended_data[ch]; \
214+ type *mean_sumx = (type *)s->mean_sum[0]->extended_data[ch]; \
215+ type *mean_sumy = (type *)s->mean_sum[1]->extended_data[ch]; \
216+ type *num_sum = (type *)s->num_sum->extended_data[ch]; \
217+ type *den_sumx = (type *)s->den_sum[0]->extended_data[ch]; \
218+ type *den_sumy = (type *)s->den_sum[1]->extended_data[ch]; \
219+ type *dst = (type *)out->extended_data[ch]; \
220+ \
221+ used = s->used; \
222+ if (!used) { \
223+ num_sum[0] = square_sum_##suffix(x, y, size); \
224+ den_sumx[0] = square_sum_##suffix(x, x, size); \
225+ den_sumy[0] = square_sum_##suffix(y, y, size); \
226+ mean_sumx[0] = mean_sum_##suffix(x, size); \
227+ mean_sumy[0] = mean_sum_##suffix(y, size); \
228+ used = 1; \
229+ } \
230+ \
231+ for (int n = 0; n < out->nb_samples; n++) { \
232+ const int idx = n + size; \
233+ type num, den, xm, ym; \
234+ \
235+ xm = mean_sumx[0] / size; \
236+ ym = mean_sumy[0] / size; \
237+ num = num_sum[0] - size * xm * ym; \
238+ den = sqrtfun(FMAX(den_sumx[0] - size * xm * xm, zero)) * \
239+ sqrtfun(FMAX(den_sumy[0] - size * ym * ym, zero)); \
240+ \
241+ dst[n] = den <= small ? zero : CLIP(num / den); \
242+ \
243+ mean_sumx[0]-= x[n]; \
244+ mean_sumx[0]+= x[idx]; \
245+ mean_sumy[0]-= y[n]; \
246+ mean_sumy[0]+= y[idx]; \
247+ num_sum[0] -= x[n] * y[n]; \
248+ num_sum[0] += x[idx] * y[idx]; \
249+ den_sumx[0] -= x[n] * x[n]; \
250+ den_sumx[0] += x[idx] * x[idx]; \
251+ den_sumx[0] = FMAX(den_sumx[0], zero); \
252+ den_sumy[0] -= y[n] * y[n]; \
253+ den_sumy[0] += y[idx] * y[idx]; \
254+ den_sumy[0] = FMAX(den_sumy[0], zero); \
255+ } \
256+ } \
257+ \
258+ return used; \
259+}
260+
261+XCORRELATE_BEST(f, float, 0.f, 1e-6f, sqrtf, fmaxf, clipf)
262+XCORRELATE_BEST(d, double, 0.0, 1e-9, sqrt, fmax, clipd)
199263
200264 static int activate(AVFilterContext *ctx)
201265 {
202266 AudioXCorrelateContext *s = ctx->priv;
267+ AVFilterLink *outlink = ctx->outputs[0];
203268 AVFrame *frame = NULL;
204269 int ret, status;
205270 int available;
206271 int64_t pts;
207272
208− FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[0], ctx);
273+ FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);
209274
210− for (int i = 0; i < 2; i++) {
275+ for (int i = 0; i < 2 && !s->eof; i++) {
211276 ret = ff_inlink_consume_frame(ctx->inputs[i], &frame);
212277 if (ret > 0) {
213278 if (s->pts == AV_NOPTS_VALUE)
@@ -221,20 +286,20 @@ static int activate(AVFilterContext *ctx) · 7 unmodified lines
221286 }
222287
223288 available = FFMIN(av_audio_fifo_size(s->fifo[0]), av_audio_fifo_size(s->fifo[1]));
224− if (available > s->size || (s->eof && available > 0)) {
225− const int out_samples = s->eof ? available : available - s->size;
289+ if (available > s->size) {
290+ const int out_samples = available - s->size;
226291 AVFrame *out;
227292
228293 if (!s->cache[0] || s->cache[0]->nb_samples < available) {
229294 av_frame_free(&s->cache[0]);
230− s->cache[0] = ff_get_audio_buffer(ctx->outputs[0], available);
295+ s->cache[0] = ff_get_audio_buffer(outlink, available);
231296 if (!s->cache[0])
232297 return AVERROR(ENOMEM);
233298 }
234299
235300 if (!s->cache[1] || s->cache[1]->nb_samples < available) {
236301 av_frame_free(&s->cache[1]);
237− s->cache[1] = ff_get_audio_buffer(ctx->outputs[0], available);
302+ s->cache[1] = ff_get_audio_buffer(outlink, available);
238303 if (!s->cache[1])
239304 return AVERROR(ENOMEM);
240305 }
@@ -247,7 +312,7 @@ static int activate(AVFilterContext *ctx) · 6 unmodified lines
247312 if (ret < 0)
248313 return ret;
249314
250− out = ff_get_audio_buffer(ctx->outputs[0], out_samples);
315+ out = ff_get_audio_buffer(outlink, out_samples);
251316 if (!out)
252317 return AVERROR(ENOMEM);
253318
@@ -259,18 +324,31 @@ static int activate(AVFilterContext *ctx) · 5 unmodified lines
259324 av_audio_fifo_drain(s->fifo[0], out_samples);
260325 av_audio_fifo_drain(s->fifo[1], out_samples);
261326
262− return ff_filter_frame(ctx->outputs[0], out);
327+ return ff_filter_frame(outlink, out);
263328 }
264329
265330 for (int i = 0; i < 2 && !s->eof; i++) {
266− if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts))
331+ if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) {
332+ AVFrame *silence = ff_get_audio_buffer(outlink, s->size);
333+
267334 s->eof = 1;
335+ if (!silence)
336+ return AVERROR(ENOMEM);
337+
338+ av_audio_fifo_write(s->fifo[0], (void **)silence->extended_data,
339+ silence->nb_samples);
340+
341+ av_audio_fifo_write(s->fifo[1], (void **)silence->extended_data,
342+ silence->nb_samples);
343+
344+ av_frame_free(&silence);
345+ }
268346 }
269347
270348 if (s->eof &&
271− (av_audio_fifo_size(s->fifo[0]) <= 0 ||
272− av_audio_fifo_size(s->fifo[1]) <= 0)) {
273− ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, s->pts);
349+ (av_audio_fifo_size(s->fifo[0]) <= s->size ||
350+ av_audio_fifo_size(s->fifo[1]) <= s->size)) {
351+ ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
274352 return 0;
275353 }
276354
@@ -280,7 +358,7 @@ static int activate(AVFilterContext *ctx) · 3 unmodified lines
280358 return 0;
281359 }
282360
283− if (ff_outlink_frame_wanted(ctx->outputs[0]) && !s->eof) {
361+ if (ff_outlink_frame_wanted(outlink) && !s->eof) {
284362 for (int i = 0; i < 2; i++) {
285363 if (av_audio_fifo_size(s->fifo[i]) > s->size)
286364 continue;
@@ -316,12 +394,14 @@ static int config_output(AVFilterLink *outlink) · 29 unmodified lines
316394 switch (s->algo) {
317395 case 0: s->xcorrelate = xcorrelate_slow_f; break;
318396 case 1: s->xcorrelate = xcorrelate_fast_f; break;
397+ case 2: s->xcorrelate = xcorrelate_best_f; break;
319398 }
320399
321400 if (outlink->format == AV_SAMPLE_FMT_DBLP) {
322401 switch (s->algo) {
323402 case 0: s->xcorrelate = xcorrelate_slow_d; break;
324403 case 1: s->xcorrelate = xcorrelate_fast_d; break;
404+ case 2: s->xcorrelate = xcorrelate_best_d; break;
325405 }
326406 }
327407
@@ -366,10 +446,11 @@ static const AVFilterPad outputs[] = { · 38 unmodified lines
366446 #define OFFSET(x) offsetof(AudioXCorrelateContext, x)
367447
368448 static const AVOption axcorrelate_options[] = {
369− { "size", "set segment size", OFFSET(size), AV_OPT_TYPE_INT, {.i64=256}, 2, 131072, AF },
370− { "algo", "set algorithm", OFFSET(algo), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "algo" },
449+ { "size", "set the segment size", OFFSET(size), AV_OPT_TYPE_INT, {.i64=256}, 2, 131072, AF },
450+ { "algo", "set the algorithm", OFFSET(algo), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, AF, "algo" },
371451 { "slow", "slow algorithm", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "algo" },
372452 { "fast", "fast algorithm", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "algo" },
453+ { "best", "best algorithm", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "algo" },
373454 { NULL }
374455 };
375456

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