You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
avfilter/af_afir: make IR switching work also with minp != maxp
This commit is contained in:
@@ -112,16 +112,59 @@ static int fir_channel(AVFilterContext *ctx, AVFrame *out, int ch)
|
|||||||
for (int offset = 0; offset < out->nb_samples; offset += min_part_size) {
|
for (int offset = 0; offset < out->nb_samples; offset += min_part_size) {
|
||||||
switch (s->format) {
|
switch (s->format) {
|
||||||
case AV_SAMPLE_FMT_FLTP:
|
case AV_SAMPLE_FMT_FLTP:
|
||||||
if (prev_selir != selir)
|
if (prev_selir != selir) {
|
||||||
fir_quantum_float(ctx, out, ch, offset, prev_selir);
|
const float *xfade0 = (const float *)s->xfade[0]->extended_data[ch];
|
||||||
fir_quantum_float(ctx, out, ch, offset, selir);
|
const float *xfade1 = (const float *)s->xfade[1]->extended_data[ch];
|
||||||
|
float *src0 = (float *)s->fadein[0]->extended_data[ch];
|
||||||
|
float *src1 = (float *)s->fadein[1]->extended_data[ch];
|
||||||
|
float *dst = ((float *)out->extended_data[ch]) + offset;
|
||||||
|
|
||||||
|
memset(src0, 0, min_part_size * sizeof(float));
|
||||||
|
memset(src1, 0, min_part_size * sizeof(float));
|
||||||
|
|
||||||
|
fir_quantum_float(ctx, s->fadein[0], ch, offset, 0, prev_selir);
|
||||||
|
fir_quantum_float(ctx, s->fadein[1], ch, offset, 0, selir);
|
||||||
|
|
||||||
|
if (s->loading[ch] > 0 && s->loading[ch] <= min_part_size) {
|
||||||
|
for (int n = 0; n < min_part_size; n++)
|
||||||
|
dst[n] = xfade1[n] * src0[n] + xfade0[n] * src1[n];
|
||||||
|
s->loading[ch] = 0;
|
||||||
|
} else {
|
||||||
|
memcpy(dst, src0, min_part_size * sizeof(float));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fir_quantum_float(ctx, out, ch, offset, offset, selir);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case AV_SAMPLE_FMT_DBLP:
|
case AV_SAMPLE_FMT_DBLP:
|
||||||
if (prev_selir != selir)
|
if (prev_selir != selir) {
|
||||||
fir_quantum_double(ctx, out, ch, offset, prev_selir);
|
const double *xfade0 = (const double *)s->xfade[0]->extended_data[ch];
|
||||||
fir_quantum_double(ctx, out, ch, offset, selir);
|
const double *xfade1 = (const double *)s->xfade[1]->extended_data[ch];
|
||||||
|
double *src0 = (double *)s->fadein[0]->extended_data[ch];
|
||||||
|
double *src1 = (double *)s->fadein[1]->extended_data[ch];
|
||||||
|
double *dst = ((double *)out->extended_data[ch]) + offset;
|
||||||
|
|
||||||
|
memset(src0, 0, min_part_size * sizeof(double));
|
||||||
|
memset(src1, 0, min_part_size * sizeof(double));
|
||||||
|
|
||||||
|
fir_quantum_double(ctx, s->fadein[0], ch, offset, 0, prev_selir);
|
||||||
|
fir_quantum_double(ctx, s->fadein[1], ch, offset, 0, selir);
|
||||||
|
|
||||||
|
if (s->loading[ch] > 0 && s->loading[ch] <= min_part_size) {
|
||||||
|
for (int n = 0; n < min_part_size; n++)
|
||||||
|
dst[n] = xfade1[n] * src0[n] + xfade0[n] * src1[n];
|
||||||
|
s->loading[ch] = 0;
|
||||||
|
} else {
|
||||||
|
memcpy(dst, src0, min_part_size * sizeof(double));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fir_quantum_double(ctx, out, ch, offset, offset, selir);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selir != prev_selir && s->loading[ch] > 0)
|
||||||
|
s->loading[ch] -= min_part_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -299,10 +342,11 @@ static int convert_coeffs(AVFilterContext *ctx, int selir)
|
|||||||
max_part_size = 1 << av_log2(s->maxp);
|
max_part_size = 1 << av_log2(s->maxp);
|
||||||
|
|
||||||
for (int i = 0; left > 0; i++) {
|
for (int i = 0; left > 0; i++) {
|
||||||
int step = part_size == max_part_size ? INT_MAX : 1 + (i == 0);
|
int step = (part_size == max_part_size) ? INT_MAX : 1 + (i == 0);
|
||||||
int nb_partitions = FFMIN(step, (left + part_size - 1) / part_size);
|
int nb_partitions = FFMIN(step, (left + part_size - 1) / part_size);
|
||||||
|
|
||||||
s->nb_segments[selir] = i + 1;
|
s->nb_segments[selir] = i + 1;
|
||||||
|
s->max_offset[selir] = offset;
|
||||||
ret = init_segment(ctx, &s->seg[selir][i], selir, offset, nb_partitions, part_size, i);
|
ret = init_segment(ctx, &s->seg[selir][i], selir, offset, nb_partitions, part_size, i);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -311,8 +355,6 @@ static int convert_coeffs(AVFilterContext *ctx, int selir)
|
|||||||
part_size *= 2;
|
part_size *= 2;
|
||||||
part_size = FFMIN(part_size, max_part_size);
|
part_size = FFMIN(part_size, max_part_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->max_offset[selir] = offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
@@ -455,7 +497,7 @@ static int activate(AVFilterContext *ctx)
|
|||||||
|
|
||||||
if (s->selir != s->prev_selir && s->loading[0] <= 0) {
|
if (s->selir != s->prev_selir && s->loading[0] <= 0) {
|
||||||
for (int ch = 0; ch < s->nb_channels; ch++)
|
for (int ch = 0; ch < s->nb_channels; ch++)
|
||||||
s->loading[ch] = s->max_offset[s->selir] + s->min_part_size;
|
s->loading[ch] = s->max_offset[s->selir] + s->max_part_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
available = ff_inlink_queued_samples(ctx->inputs[0]);
|
available = ff_inlink_queued_samples(ctx->inputs[0]);
|
||||||
@@ -464,11 +506,8 @@ static int activate(AVFilterContext *ctx)
|
|||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
ret = fir_frame(s, in, outlink);
|
ret = fir_frame(s, in, outlink);
|
||||||
|
|
||||||
if (s->selir != s->prev_selir && s->loading[0] <= 0) {
|
if (s->selir != s->prev_selir && s->loading[0] <= 0)
|
||||||
s->prev_selir = s->selir;
|
s->prev_selir = s->selir;
|
||||||
for (int ch = 0; ch < s->nb_channels; ch++)
|
|
||||||
s->loading[ch] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -590,6 +629,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
|||||||
if (!s->loading)
|
if (!s->loading)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
s->fadein[0] = ff_get_audio_buffer(outlink, s->min_part_size);
|
||||||
|
s->fadein[1] = ff_get_audio_buffer(outlink, s->min_part_size);
|
||||||
|
if (!s->fadein[0] || !s->fadein[1])
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
s->xfade[0] = ff_get_audio_buffer(outlink, s->min_part_size);
|
s->xfade[0] = ff_get_audio_buffer(outlink, s->min_part_size);
|
||||||
s->xfade[1] = ff_get_audio_buffer(outlink, s->min_part_size);
|
s->xfade[1] = ff_get_audio_buffer(outlink, s->min_part_size);
|
||||||
if (!s->xfade[0] || !s->xfade[1])
|
if (!s->xfade[0] || !s->xfade[1])
|
||||||
@@ -638,6 +682,9 @@ static av_cold void uninit(AVFilterContext *ctx)
|
|||||||
av_frame_free(&s->norm_ir[i]);
|
av_frame_free(&s->norm_ir[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
av_frame_free(&s->fadein[0]);
|
||||||
|
av_frame_free(&s->fadein[1]);
|
||||||
|
|
||||||
av_frame_free(&s->xfade[0]);
|
av_frame_free(&s->xfade[0]);
|
||||||
av_frame_free(&s->xfade[1]);
|
av_frame_free(&s->xfade[1]);
|
||||||
|
|
||||||
@@ -723,6 +770,7 @@ static av_cold int init(AVFilterContext *ctx)
|
|||||||
ff_afir_init(&s->afirdsp);
|
ff_afir_init(&s->afirdsp);
|
||||||
|
|
||||||
s->min_part_size = 1 << av_log2(s->minp);
|
s->min_part_size = 1 << av_log2(s->minp);
|
||||||
|
s->max_part_size = 1 << av_log2(s->maxp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -91,10 +91,12 @@ typedef struct AudioFIRContext {
|
|||||||
|
|
||||||
AVFrame *in;
|
AVFrame *in;
|
||||||
AVFrame *xfade[2];
|
AVFrame *xfade[2];
|
||||||
|
AVFrame *fadein[2];
|
||||||
AVFrame *ir[MAX_IR_STREAMS];
|
AVFrame *ir[MAX_IR_STREAMS];
|
||||||
AVFrame *norm_ir[MAX_IR_STREAMS];
|
AVFrame *norm_ir[MAX_IR_STREAMS];
|
||||||
AVFrame *video;
|
AVFrame *video;
|
||||||
int min_part_size;
|
int min_part_size;
|
||||||
|
int max_part_size;
|
||||||
int64_t pts;
|
int64_t pts;
|
||||||
|
|
||||||
AudioFIRDSPContext afirdsp;
|
AudioFIRDSPContext afirdsp;
|
||||||
|
@@ -285,15 +285,13 @@ static void fn(fir_fadd)(AudioFIRContext *s, ftype *dst, const ftype *src, int n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offset, int selir)
|
static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int ioffset, int offset, int selir)
|
||||||
{
|
{
|
||||||
AudioFIRContext *s = ctx->priv;
|
AudioFIRContext *s = ctx->priv;
|
||||||
const ftype *in = (const ftype *)s->in->extended_data[ch] + offset;
|
const ftype *in = (const ftype *)s->in->extended_data[ch] + ioffset;
|
||||||
ftype *blockout, *ptr = (ftype *)out->extended_data[ch] + offset;
|
ftype *blockout, *ptr = (ftype *)out->extended_data[ch] + offset;
|
||||||
const int min_part_size = s->min_part_size;
|
const int min_part_size = s->min_part_size;
|
||||||
const int nb_samples = FFMIN(min_part_size, out->nb_samples - offset);
|
const int nb_samples = FFMIN(min_part_size, out->nb_samples - offset);
|
||||||
const ftype *xfade0 = (const ftype *)s->xfade[0]->extended_data[ch];
|
|
||||||
const ftype *xfade1 = (const ftype *)s->xfade[1]->extended_data[ch];
|
|
||||||
const int nb_segments = s->nb_segments[selir];
|
const int nb_segments = s->nb_segments[selir];
|
||||||
const float dry_gain = s->dry_gain;
|
const float dry_gain = s->dry_gain;
|
||||||
|
|
||||||
@@ -368,18 +366,7 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offse
|
|||||||
memcpy(dst, buf, part_size * sizeof(*dst));
|
memcpy(dst, buf, part_size * sizeof(*dst));
|
||||||
memcpy(buf, sumout + part_size, part_size * sizeof(*buf));
|
memcpy(buf, sumout + part_size, part_size * sizeof(*buf));
|
||||||
|
|
||||||
if (s->selir != s->prev_selir) {
|
fn(fir_fadd)(s, ptr, dst, nb_samples);
|
||||||
if (selir == s->selir) {
|
|
||||||
if (s->loading[ch] <= min_part_size) {
|
|
||||||
for (int n = 0; n < nb_samples; n++)
|
|
||||||
ptr[n] += dst[n] * xfade0[n];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fn(fir_fadd)(s, ptr, dst, nb_samples);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fn(fir_fadd)(s, ptr, dst, nb_samples);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (part_size != min_part_size)
|
if (part_size != min_part_size)
|
||||||
memmove(src, src + min_part_size, (seg->input_size - min_part_size) * sizeof(*src));
|
memmove(src, src + min_part_size, (seg->input_size - min_part_size) * sizeof(*src));
|
||||||
@@ -387,17 +374,6 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offse
|
|||||||
seg->part_index[ch] = (seg->part_index[ch] + 1) % nb_partitions;
|
seg->part_index[ch] = (seg->part_index[ch] + 1) % nb_partitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selir != s->selir) {
|
|
||||||
if (s->loading[ch] <= min_part_size) {
|
|
||||||
for (int n = 0; n < nb_samples; n++)
|
|
||||||
ptr[n] *= xfade1[n];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->selir != s->prev_selir)
|
|
||||||
s->loading[ch] -= min_part_size;
|
|
||||||
|
|
||||||
if (s->wet_gain == 1.f)
|
if (s->wet_gain == 1.f)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user