1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-04 22:03:09 +02:00

avfilter/af_afade: rework crossfade activate logic

The new logic should be easier to follow.

It also uses ff_inlink_consume_frame() for all simple passthrough operations
making custom get_audio_buffer callback unnecessary.

Fate changes are because the new logic does not repacketize input audio up
until the crossfade. Content is the same.

Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
Marton Balint
2025-07-20 21:48:02 +02:00
parent 84d831ec58
commit 0cc46f1f59
2 changed files with 80 additions and 87 deletions

View File

@ -42,9 +42,8 @@ typedef struct AudioFadeContext {
double silence;
double unity;
int overlap;
int status[2];
int passthrough;
int64_t pts;
int xfade_status;
void (*fade_samples)(uint8_t **dst, uint8_t * const *src,
int nb_samples, int channels, int direction,
@ -598,7 +597,6 @@ static int pass_crossfade(AVFilterContext *ctx)
out->pts = s->pts;
s->pts += av_rescale_q(s->nb_samples,
(AVRational){ 1, outlink->sample_rate }, outlink->time_base);
s->passthrough = 1;
av_frame_free(&cf[0]);
av_frame_free(&cf[1]);
return ff_filter_frame(outlink, out);
@ -638,7 +636,6 @@ static int pass_crossfade(AVFilterContext *ctx)
out->pts = s->pts;
s->pts += av_rescale_q(s->nb_samples,
(AVRational){ 1, outlink->sample_rate }, outlink->time_base);
s->passthrough = 1;
av_frame_free(&cf[1]);
return ff_filter_frame(outlink, out);
}
@ -648,42 +645,50 @@ static int activate(AVFilterContext *ctx)
{
AudioFadeContext *s = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
int ret = 0, nb_samples;
FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);
if (s->passthrough && s->status[0]) {
// Read first input until EOF
if (s->xfade_status == 0) {
int queued_samples = ff_inlink_queued_samples(ctx->inputs[0]);
if (queued_samples > s->nb_samples) {
AVFrame *frame = ff_inlink_peek_frame(ctx->inputs[0], 0);
if (queued_samples - s->nb_samples >= frame->nb_samples)
return pass_frame(ctx->inputs[0], outlink, &s->pts);
}
if (ff_outlink_get_status(ctx->inputs[0])) {
if (queued_samples > s->nb_samples)
return pass_samples(ctx->inputs[0], outlink, queued_samples - s->nb_samples, &s->pts);
s->xfade_status = 1;
} else {
FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[0]);
}
}
// Read second input until enough data is ready or EOF
if (s->xfade_status == 1) {
if (ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples || ff_outlink_get_status(ctx->inputs[1])) {
s->xfade_status = 2;
} else {
FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[1]);
}
}
// Do crossfade
if (s->xfade_status == 2) {
s->xfade_status = 3;
// TODO: Do some partial crossfade if not all inputs have enough duration?
if (ff_inlink_queued_samples(ctx->inputs[0]) >= s->nb_samples &&
ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples)
return pass_crossfade(ctx);
}
// Read second input until EOF
if (s->xfade_status == 3) {
if (ff_inlink_queued_frames(ctx->inputs[1]))
return pass_frame(ctx->inputs[1], outlink, &s->pts);
FF_FILTER_FORWARD_STATUS(ctx->inputs[1], outlink);
FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[1]);
}
nb_samples = ff_inlink_queued_samples(ctx->inputs[0]);
if (nb_samples > s->nb_samples) {
nb_samples -= s->nb_samples;
s->passthrough = 1;
return pass_samples(ctx->inputs[0], outlink, nb_samples, &s->pts);
} else if (s->status[0] && nb_samples >= s->nb_samples &&
ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples) {
return pass_crossfade(ctx);
} else if (ff_outlink_frame_wanted(outlink)) {
if (!s->status[0] && ff_outlink_get_status(ctx->inputs[0]))
s->status[0] = AVERROR_EOF;
s->passthrough = !s->status[0];
if (ff_outlink_get_status(ctx->inputs[1])) {
s->status[1] = AVERROR_EOF;
ff_outlink_set_status(outlink, AVERROR_EOF, AV_NOPTS_VALUE);
return 0;
}
if (!s->status[0])
ff_inlink_request_frame(ctx->inputs[0]);
else
ff_inlink_request_frame(ctx->inputs[1]);
return 0;
}
return ret;
return FFERROR_NOT_READY;
}
static int acrossfade_config_output(AVFilterLink *outlink)
@ -709,26 +714,14 @@ static int acrossfade_config_output(AVFilterLink *outlink)
return 0;
}
static AVFrame *get_audio_buffer(AVFilterLink *inlink, int nb_samples)
{
AVFilterContext *ctx = inlink->dst;
AudioFadeContext *s = ctx->priv;
return s->passthrough ?
ff_null_get_audio_buffer (inlink, nb_samples) :
ff_default_get_audio_buffer(inlink, nb_samples);
}
static const AVFilterPad avfilter_af_acrossfade_inputs[] = {
{
.name = "crossfade0",
.type = AVMEDIA_TYPE_AUDIO,
.get_buffer.audio = get_audio_buffer,
},
{
.name = "crossfade1",
.type = AVMEDIA_TYPE_AUDIO,
.get_buffer.audio = get_audio_buffer,
},
};

View File

@ -3,50 +3,50 @@
#codec_id 0: pcm_s16le
#sample_rate 0: 44100
#channel_layout_name 0: stereo
0, 0, 0, 1912, 7648, 0x1294dd84
0, 1912, 1912, 4096, 16384, 0x8d5eec9b
0, 6008, 6008, 4096, 16384, 0x9f15e8a9
0, 10104, 10104, 4096, 16384, 0x5594dd9d
0, 14200, 14200, 4096, 16384, 0x5115d9bb
0, 18296, 18296, 4096, 16384, 0x0511d717
0, 22392, 22392, 4096, 16384, 0x9cbdd713
0, 26488, 26488, 4096, 16384, 0x2f13e615
0, 30584, 30584, 4096, 16384, 0x415ae9f7
0, 34680, 34680, 4096, 16384, 0x8d5eec9b
0, 38776, 38776, 4096, 16384, 0x9f15e8a9
0, 42872, 42872, 4096, 16384, 0xd9809dcd
0, 46968, 46968, 4096, 16384, 0x7b60ec15
0, 51064, 51064, 4096, 16384, 0xe92de3eb
0, 55160, 55160, 4096, 16384, 0x063d2c76
0, 59256, 59256, 4096, 16384, 0xacbed331
0, 63352, 63352, 4096, 16384, 0x1137d0c7
0, 67448, 67448, 4096, 16384, 0xafbad1d7
0, 71544, 71544, 4096, 16384, 0xb2a0040c
0, 75640, 75640, 4096, 16384, 0x83222d0c
0, 79736, 79736, 4096, 16384, 0x97993592
0, 83832, 83832, 4096, 16384, 0x9e4200b2
0, 87928, 87928, 4096, 16384, 0xf24c2685
0, 92024, 92024, 4096, 16384, 0x0b23a4c8
0, 96120, 96120, 4096, 16384, 0x9105fcde
0, 100216, 100216, 4096, 16384, 0xd4b64a6f
0, 104312, 104312, 4096, 16384, 0xef56c48a
0, 108408, 108408, 4096, 16384, 0xb12b9599
0, 112504, 112504, 4096, 16384, 0x18bbeefd
0, 116600, 116600, 4096, 16384, 0x3fe2d14b
0, 120696, 120696, 4096, 16384, 0xf6d6fdff
0, 124792, 124792, 4096, 16384, 0x2e538447
0, 128888, 128888, 4096, 16384, 0xd8251663
0, 132984, 132984, 4096, 16384, 0xd783c943
0, 137080, 137080, 4096, 16384, 0x3d64f7cf
0, 141176, 141176, 4096, 16384, 0x80e2c034
0, 145272, 145272, 4096, 16384, 0x69a7e254
0, 149368, 149368, 4096, 16384, 0xb3f5efb9
0, 153464, 153464, 4096, 16384, 0x3975dea3
0, 157560, 157560, 4096, 16384, 0x7ff7d2c5
0, 161656, 161656, 4096, 16384, 0x5476e599
0, 165752, 165752, 4096, 16384, 0x30e4f37a
0, 169848, 169848, 4096, 16384, 0x57c1a83c
0, 173944, 173944, 2456, 9824, 0x498532b3
0, 0, 0, 4096, 16384, 0x02ebe66b
0, 4096, 4096, 4096, 16384, 0x35bfe081
0, 8192, 8192, 4096, 16384, 0x3f90e0a9
0, 12288, 12288, 4096, 16384, 0xd389dc43
0, 16384, 16384, 4096, 16384, 0x9d5add49
0, 20480, 20480, 4096, 16384, 0x378ee333
0, 24576, 24576, 4096, 16384, 0xabf6df0f
0, 28672, 28672, 4096, 16384, 0xedefe76f
0, 32768, 32768, 4096, 16384, 0x02ebe66b
0, 36864, 36864, 4096, 16384, 0x35bfe081
0, 40960, 40960, 4096, 16384, 0xdbc2b3b9
0, 45056, 45056, 4096, 16384, 0xe92bd835
0, 49152, 49152, 4096, 16384, 0x1126dca3
0, 53248, 53248, 4096, 16384, 0x9647edcf
0, 57344, 57344, 4096, 16384, 0x5cc345aa
0, 61440, 61440, 4096, 16384, 0x19d7bd51
0, 65536, 65536, 4096, 16384, 0x19eccef7
0, 69632, 69632, 4096, 16384, 0x4b68eeed
0, 73728, 73728, 4096, 16384, 0x0b3d1bfc
0, 77824, 77824, 4096, 16384, 0xe9b2e069
0, 81920, 81920, 4096, 16384, 0xcaa5590e
0, 86016, 86016, 4096, 16384, 0x47d0b227
0, 90112, 90112, 4096, 16384, 0x446ba7a4
0, 94208, 94208, 4096, 16384, 0x299b2e17
0, 98304, 98304, 4096, 16384, 0xc51affa2
0, 102400, 102400, 4096, 16384, 0xb4970fcf
0, 106496, 106496, 4096, 16384, 0xe48af9fc
0, 110592, 110592, 4096, 16384, 0xc2beffbb
0, 114688, 114688, 4096, 16384, 0xb9d99627
0, 118784, 118784, 4096, 16384, 0xb65a2086
0, 122880, 122880, 4096, 16384, 0x6386714b
0, 126976, 126976, 4096, 16384, 0x92a3171e
0, 131072, 131072, 4096, 16384, 0x78bad1e2
0, 135168, 135168, 4096, 16384, 0x63301330
0, 139264, 139264, 4096, 16384, 0xd663b943
0, 143360, 143360, 4096, 16384, 0xdcafe377
0, 147456, 147456, 4096, 16384, 0xfb2cd701
0, 151552, 151552, 4096, 16384, 0x91c30201
0, 155648, 155648, 4096, 16384, 0xf23da341
0, 159744, 159744, 4096, 16384, 0xe8d5fa0a
0, 163840, 163840, 4096, 16384, 0x519bdfef
0, 167936, 167936, 4096, 16384, 0xf2fcd803
0, 172032, 172032, 4096, 16384, 0xd5ceccbc
0, 176128, 176128, 272, 1088, 0xa8bc282b
0, 176400, 176400, 88200, 352800, 0x4fb492af
0, 264600, 264600, 1912, 7648, 0xf0c93a5a
0, 266512, 266512, 4096, 16384, 0x85454449