mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/af_axcorrelate: always process all input samples
This commit is contained in:
parent
21914e7a4e
commit
eb22b8953c
|
@ -42,8 +42,9 @@ typedef struct AudioXCorrelateContext {
|
||||||
AVFrame *num_sum;
|
AVFrame *num_sum;
|
||||||
AVFrame *den_sum[2];
|
AVFrame *den_sum[2];
|
||||||
int used;
|
int used;
|
||||||
|
int eof;
|
||||||
|
|
||||||
int (*xcorrelate)(AVFilterContext *ctx, AVFrame *out);
|
int (*xcorrelate)(AVFilterContext *ctx, AVFrame *out, int available);
|
||||||
} AudioXCorrelateContext;
|
} AudioXCorrelateContext;
|
||||||
|
|
||||||
static float mean_sum(const float *in, int size)
|
static float mean_sum(const float *in, int size)
|
||||||
|
@ -86,10 +87,10 @@ static float xcorrelate(const float *x, const float *y, float sumx, float sumy,
|
||||||
return den <= 1e-6f ? 0.f : num / den;
|
return den <= 1e-6f ? 0.f : num / den;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xcorrelate_slow(AVFilterContext *ctx, AVFrame *out)
|
static int xcorrelate_slow(AVFilterContext *ctx, AVFrame *out, int available)
|
||||||
{
|
{
|
||||||
AudioXCorrelateContext *s = ctx->priv;
|
AudioXCorrelateContext *s = ctx->priv;
|
||||||
const int size = s->size;
|
const int size = FFMIN(available, s->size);
|
||||||
int used;
|
int used;
|
||||||
|
|
||||||
for (int ch = 0; ch < out->channels; ch++) {
|
for (int ch = 0; ch < out->channels; ch++) {
|
||||||
|
@ -107,22 +108,24 @@ static int xcorrelate_slow(AVFilterContext *ctx, AVFrame *out)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int n = 0; n < out->nb_samples; n++) {
|
for (int n = 0; n < out->nb_samples; n++) {
|
||||||
|
const int idx = available <= s->size ? out->nb_samples - n - 1 : n + size;
|
||||||
|
|
||||||
dst[n] = xcorrelate(x + n, y + n, sumx[0], sumy[0], size);
|
dst[n] = xcorrelate(x + n, y + n, sumx[0], sumy[0], size);
|
||||||
|
|
||||||
sumx[0] -= x[n];
|
sumx[0] -= x[n];
|
||||||
sumx[0] += x[n + size];
|
sumx[0] += x[idx];
|
||||||
sumy[0] -= y[n];
|
sumy[0] -= y[n];
|
||||||
sumy[0] += y[n + size];
|
sumy[0] += y[idx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return used;
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xcorrelate_fast(AVFilterContext *ctx, AVFrame *out)
|
static int xcorrelate_fast(AVFilterContext *ctx, AVFrame *out, int available)
|
||||||
{
|
{
|
||||||
AudioXCorrelateContext *s = ctx->priv;
|
AudioXCorrelateContext *s = ctx->priv;
|
||||||
const int size = s->size;
|
const int size = FFMIN(available, s->size);
|
||||||
int used;
|
int used;
|
||||||
|
|
||||||
for (int ch = 0; ch < out->channels; ch++) {
|
for (int ch = 0; ch < out->channels; ch++) {
|
||||||
|
@ -142,6 +145,7 @@ static int xcorrelate_fast(AVFilterContext *ctx, AVFrame *out)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int n = 0; n < out->nb_samples; n++) {
|
for (int n = 0; n < out->nb_samples; n++) {
|
||||||
|
const int idx = available <= s->size ? out->nb_samples - n - 1 : n + size;
|
||||||
float num, den;
|
float num, den;
|
||||||
|
|
||||||
num = num_sum[0] / size;
|
num = num_sum[0] / size;
|
||||||
|
@ -150,13 +154,13 @@ static int xcorrelate_fast(AVFilterContext *ctx, AVFrame *out)
|
||||||
dst[n] = den <= 1e-6f ? 0.f : num / den;
|
dst[n] = den <= 1e-6f ? 0.f : num / den;
|
||||||
|
|
||||||
num_sum[0] -= x[n] * y[n];
|
num_sum[0] -= x[n] * y[n];
|
||||||
num_sum[0] += x[n + size] * y[n + size];
|
num_sum[0] += x[idx] * y[idx];
|
||||||
den_sumx[0] -= x[n] * x[n];
|
den_sumx[0] -= x[n] * x[n];
|
||||||
|
den_sumx[0] += x[idx] * x[idx];
|
||||||
den_sumx[0] = FFMAX(den_sumx[0], 0.f);
|
den_sumx[0] = FFMAX(den_sumx[0], 0.f);
|
||||||
den_sumx[0] += x[n + size] * x[n + size];
|
|
||||||
den_sumy[0] -= y[n] * y[n];
|
den_sumy[0] -= y[n] * y[n];
|
||||||
|
den_sumy[0] += y[idx] * y[idx];
|
||||||
den_sumy[0] = FFMAX(den_sumy[0], 0.f);
|
den_sumy[0] = FFMAX(den_sumy[0], 0.f);
|
||||||
den_sumy[0] += y[n + size] * y[n + size];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,8 +191,8 @@ static int activate(AVFilterContext *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
available = FFMIN(av_audio_fifo_size(s->fifo[0]), av_audio_fifo_size(s->fifo[1]));
|
available = FFMIN(av_audio_fifo_size(s->fifo[0]), av_audio_fifo_size(s->fifo[1]));
|
||||||
if (available > s->size) {
|
if (available > s->size || (s->eof && available > 0)) {
|
||||||
const int out_samples = available - s->size;
|
const int out_samples = s->eof ? available : available - s->size;
|
||||||
AVFrame *out;
|
AVFrame *out;
|
||||||
|
|
||||||
if (!s->cache[0] || s->cache[0]->nb_samples < available) {
|
if (!s->cache[0] || s->cache[0]->nb_samples < available) {
|
||||||
|
@ -217,7 +221,7 @@ static int activate(AVFilterContext *ctx)
|
||||||
if (!out)
|
if (!out)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
s->used = s->xcorrelate(ctx, out);
|
s->used = s->xcorrelate(ctx, out, available);
|
||||||
|
|
||||||
out->pts = s->pts;
|
out->pts = s->pts;
|
||||||
s->pts += out_samples;
|
s->pts += out_samples;
|
||||||
|
@ -228,20 +232,25 @@ static int activate(AVFilterContext *ctx)
|
||||||
return ff_filter_frame(ctx->outputs[0], out);
|
return ff_filter_frame(ctx->outputs[0], out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (av_audio_fifo_size(s->fifo[0]) > s->size &&
|
for (int i = 0; i < 2 && !s->eof; i++) {
|
||||||
av_audio_fifo_size(s->fifo[1]) > s->size) {
|
if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts))
|
||||||
|
s->eof = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->eof &&
|
||||||
|
(av_audio_fifo_size(s->fifo[0]) <= 0 ||
|
||||||
|
av_audio_fifo_size(s->fifo[1]) <= 0)) {
|
||||||
|
ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, s->pts);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((av_audio_fifo_size(s->fifo[0]) > s->size &&
|
||||||
|
av_audio_fifo_size(s->fifo[1]) > s->size) || s->eof) {
|
||||||
ff_filter_set_ready(ctx, 10);
|
ff_filter_set_ready(ctx, 10);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
if (ff_outlink_frame_wanted(ctx->outputs[0]) && !s->eof) {
|
||||||
if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) {
|
|
||||||
ff_outlink_set_status(ctx->outputs[0], status, pts);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ff_outlink_frame_wanted(ctx->outputs[0])) {
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (av_audio_fifo_size(s->fifo[i]) > s->size)
|
if (av_audio_fifo_size(s->fifo[i]) > s->size)
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue