History

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.

Marton Balint committed 1 year ago

Commit 0cc46f11 parent 84d831e2 files · +80 −87Browse files

Unified · Split

2 files
  1. libavfilter/af_afade.c +36 −43
  2. tests/ref/fate/filter-acrossfade +44 −44
libavfilter/af_afade.c+36−43
@@ -42,9 +42,8 @@ typedef struct AudioFadeContext { · 41 unmodified lines
42 double silence;42 double silence;
43 double unity;43 double unity;
44 int overlap;44 int overlap;
45 int status[2];
46 int passthrough;
47 int64_t pts;45 int64_t pts;
46 int xfade_status;
48 47
49 void (*fade_samples)(uint8_t **dst, uint8_t * const *src,48 void (*fade_samples)(uint8_t **dst, uint8_t * const *src,
50 int nb_samples, int channels, int direction,49 int nb_samples, int channels, int direction,
@@ -598,7 +597,6 @@ static int pass_crossfade(AVFilterContext *ctx) · 547 unmodified lines
598 out->pts = s->pts;597 out->pts = s->pts;
599 s->pts += av_rescale_q(s->nb_samples,598 s->pts += av_rescale_q(s->nb_samples,
600 (AVRational){ 1, outlink->sample_rate }, outlink->time_base);599 (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
601 s->passthrough = 1;
602 av_frame_free(&cf[0]);600 av_frame_free(&cf[0]);
603 av_frame_free(&cf[1]);601 av_frame_free(&cf[1]);
604 return ff_filter_frame(outlink, out);602 return ff_filter_frame(outlink, out);
@@ -638,7 +636,6 @@ static int pass_crossfade(AVFilterContext *ctx) · 33 unmodified lines
638 out->pts = s->pts;636 out->pts = s->pts;
639 s->pts += av_rescale_q(s->nb_samples,637 s->pts += av_rescale_q(s->nb_samples,
640 (AVRational){ 1, outlink->sample_rate }, outlink->time_base);638 (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
641 s->passthrough = 1;
642 av_frame_free(&cf[1]);639 av_frame_free(&cf[1]);
643 return ff_filter_frame(outlink, out);640 return ff_filter_frame(outlink, out);
644 }641 }
@@ -648,42 +645,50 @@ static int activate(AVFilterContext *ctx) · 3 unmodified lines
648{645{
649 AudioFadeContext *s = ctx->priv;646 AudioFadeContext *s = ctx->priv;
650 AVFilterLink *outlink = ctx->outputs[0];647 AVFilterLink *outlink = ctx->outputs[0];
651 int ret = 0, nb_samples;
652 648
653 FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);649 FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);
654 650
655 if (s->passthrough && s->status[0]) {651 // Read first input until EOF
652 if (s->xfade_status == 0) {
653 int queued_samples = ff_inlink_queued_samples(ctx->inputs[0]);
654 if (queued_samples > s->nb_samples) {
655 AVFrame *frame = ff_inlink_peek_frame(ctx->inputs[0], 0);
656 if (queued_samples - s->nb_samples >= frame->nb_samples)
657 return pass_frame(ctx->inputs[0], outlink, &s->pts);
658 }
659 if (ff_outlink_get_status(ctx->inputs[0])) {
660 if (queued_samples > s->nb_samples)
661 return pass_samples(ctx->inputs[0], outlink, queued_samples - s->nb_samples, &s->pts);
662 s->xfade_status = 1;
663 } else {
664 FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[0]);
665 }
666 }
667 // Read second input until enough data is ready or EOF
668 if (s->xfade_status == 1) {
669 if (ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples || ff_outlink_get_status(ctx->inputs[1])) {
670 s->xfade_status = 2;
671 } else {
672 FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[1]);
673 }
674 }
675 // Do crossfade
676 if (s->xfade_status == 2) {
677 s->xfade_status = 3;
678 // TODO: Do some partial crossfade if not all inputs have enough duration?
679 if (ff_inlink_queued_samples(ctx->inputs[0]) >= s->nb_samples &&
680 ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples)
681 return pass_crossfade(ctx);
682 }
683 // Read second input until EOF
684 if (s->xfade_status == 3) {
656 if (ff_inlink_queued_frames(ctx->inputs[1]))685 if (ff_inlink_queued_frames(ctx->inputs[1]))
657 return pass_frame(ctx->inputs[1], outlink, &s->pts);686 return pass_frame(ctx->inputs[1], outlink, &s->pts);
658 FF_FILTER_FORWARD_STATUS(ctx->inputs[1], outlink);687 FF_FILTER_FORWARD_STATUS(ctx->inputs[1], outlink);
659 FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[1]);688 FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[1]);
660 }689 }
661 690
662 nb_samples = ff_inlink_queued_samples(ctx->inputs[0]);691 return FFERROR_NOT_READY;
663 if (nb_samples > s->nb_samples) {
664 nb_samples -= s->nb_samples;
665 s->passthrough = 1;
666 return pass_samples(ctx->inputs[0], outlink, nb_samples, &s->pts);
667 } else if (s->status[0] && nb_samples >= s->nb_samples &&
668 ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples) {
669 return pass_crossfade(ctx);
670 } else if (ff_outlink_frame_wanted(outlink)) {
671 if (!s->status[0] && ff_outlink_get_status(ctx->inputs[0]))
672 s->status[0] = AVERROR_EOF;
673 s->passthrough = !s->status[0];
674 if (ff_outlink_get_status(ctx->inputs[1])) {
675 s->status[1] = AVERROR_EOF;
676 ff_outlink_set_status(outlink, AVERROR_EOF, AV_NOPTS_VALUE);
677 return 0;
678 }
679 if (!s->status[0])
680 ff_inlink_request_frame(ctx->inputs[0]);
681 else
682 ff_inlink_request_frame(ctx->inputs[1]);
683 return 0;
684 }
685
686 return ret;
687}692}
688 693
689static int acrossfade_config_output(AVFilterLink *outlink)694static int acrossfade_config_output(AVFilterLink *outlink)
@@ -709,26 +714,14 @@ static int acrossfade_config_output(AVFilterLink *outlink) · 19 unmodified lines
709 return 0;714 return 0;
710}715}
711 716
712static AVFrame *get_audio_buffer(AVFilterLink *inlink, int nb_samples)
713{
714 AVFilterContext *ctx = inlink->dst;
715 AudioFadeContext *s = ctx->priv;
716
717 return s->passthrough ?
718 ff_null_get_audio_buffer (inlink, nb_samples) :
719 ff_default_get_audio_buffer(inlink, nb_samples);
720}
721
722static const AVFilterPad avfilter_af_acrossfade_inputs[] = {717static const AVFilterPad avfilter_af_acrossfade_inputs[] = {
723 {718 {
724 .name = "crossfade0",719 .name = "crossfade0",
725 .type = AVMEDIA_TYPE_AUDIO,720 .type = AVMEDIA_TYPE_AUDIO,
726 .get_buffer.audio = get_audio_buffer,
727 },721 },
728 {722 {
729 .name = "crossfade1",723 .name = "crossfade1",
730 .type = AVMEDIA_TYPE_AUDIO,724 .type = AVMEDIA_TYPE_AUDIO,
731 .get_buffer.audio = get_audio_buffer,
732 },725 },
733};726};
734 727
tests/ref/fate/filter-acrossfade+44−44
@@ -3,50 +3,50 @@ · 2 unmodified lines
3#codec_id 0: pcm_s16le3#codec_id 0: pcm_s16le
4#sample_rate 0: 441004#sample_rate 0: 44100
5#channel_layout_name 0: stereo5#channel_layout_name 0: stereo
60, 0, 0, 1912, 7648, 0x1294dd8460, 0, 0, 4096, 16384, 0x02ebe66b
70, 1912, 1912, 4096, 16384, 0x8d5eec9b70, 4096, 4096, 4096, 16384, 0x35bfe081
80, 6008, 6008, 4096, 16384, 0x9f15e8a980, 8192, 8192, 4096, 16384, 0x3f90e0a9
90, 10104, 10104, 4096, 16384, 0x5594dd9d90, 12288, 12288, 4096, 16384, 0xd389dc43
100, 14200, 14200, 4096, 16384, 0x5115d9bb100, 16384, 16384, 4096, 16384, 0x9d5add49
110, 18296, 18296, 4096, 16384, 0x0511d717110, 20480, 20480, 4096, 16384, 0x378ee333
120, 22392, 22392, 4096, 16384, 0x9cbdd713120, 24576, 24576, 4096, 16384, 0xabf6df0f
130, 26488, 26488, 4096, 16384, 0x2f13e615130, 28672, 28672, 4096, 16384, 0xedefe76f
140, 30584, 30584, 4096, 16384, 0x415ae9f7140, 32768, 32768, 4096, 16384, 0x02ebe66b
150, 34680, 34680, 4096, 16384, 0x8d5eec9b150, 36864, 36864, 4096, 16384, 0x35bfe081
160, 38776, 38776, 4096, 16384, 0x9f15e8a9160, 40960, 40960, 4096, 16384, 0xdbc2b3b9
170, 42872, 42872, 4096, 16384, 0xd9809dcd170, 45056, 45056, 4096, 16384, 0xe92bd835
180, 46968, 46968, 4096, 16384, 0x7b60ec15180, 49152, 49152, 4096, 16384, 0x1126dca3
190, 51064, 51064, 4096, 16384, 0xe92de3eb190, 53248, 53248, 4096, 16384, 0x9647edcf
200, 55160, 55160, 4096, 16384, 0x063d2c76200, 57344, 57344, 4096, 16384, 0x5cc345aa
210, 59256, 59256, 4096, 16384, 0xacbed331210, 61440, 61440, 4096, 16384, 0x19d7bd51
220, 63352, 63352, 4096, 16384, 0x1137d0c7220, 65536, 65536, 4096, 16384, 0x19eccef7
230, 67448, 67448, 4096, 16384, 0xafbad1d7230, 69632, 69632, 4096, 16384, 0x4b68eeed
240, 71544, 71544, 4096, 16384, 0xb2a0040c240, 73728, 73728, 4096, 16384, 0x0b3d1bfc
250, 75640, 75640, 4096, 16384, 0x83222d0c250, 77824, 77824, 4096, 16384, 0xe9b2e069
260, 79736, 79736, 4096, 16384, 0x97993592260, 81920, 81920, 4096, 16384, 0xcaa5590e
270, 83832, 83832, 4096, 16384, 0x9e4200b2270, 86016, 86016, 4096, 16384, 0x47d0b227
280, 87928, 87928, 4096, 16384, 0xf24c2685280, 90112, 90112, 4096, 16384, 0x446ba7a4
290, 92024, 92024, 4096, 16384, 0x0b23a4c8290, 94208, 94208, 4096, 16384, 0x299b2e17
300, 96120, 96120, 4096, 16384, 0x9105fcde300, 98304, 98304, 4096, 16384, 0xc51affa2
310, 100216, 100216, 4096, 16384, 0xd4b64a6f310, 102400, 102400, 4096, 16384, 0xb4970fcf
320, 104312, 104312, 4096, 16384, 0xef56c48a320, 106496, 106496, 4096, 16384, 0xe48af9fc
330, 108408, 108408, 4096, 16384, 0xb12b9599330, 110592, 110592, 4096, 16384, 0xc2beffbb
340, 112504, 112504, 4096, 16384, 0x18bbeefd340, 114688, 114688, 4096, 16384, 0xb9d99627
350, 116600, 116600, 4096, 16384, 0x3fe2d14b350, 118784, 118784, 4096, 16384, 0xb65a2086
360, 120696, 120696, 4096, 16384, 0xf6d6fdff360, 122880, 122880, 4096, 16384, 0x6386714b
370, 124792, 124792, 4096, 16384, 0x2e538447370, 126976, 126976, 4096, 16384, 0x92a3171e
380, 128888, 128888, 4096, 16384, 0xd8251663380, 131072, 131072, 4096, 16384, 0x78bad1e2
390, 132984, 132984, 4096, 16384, 0xd783c943390, 135168, 135168, 4096, 16384, 0x63301330
400, 137080, 137080, 4096, 16384, 0x3d64f7cf400, 139264, 139264, 4096, 16384, 0xd663b943
410, 141176, 141176, 4096, 16384, 0x80e2c034410, 143360, 143360, 4096, 16384, 0xdcafe377
420, 145272, 145272, 4096, 16384, 0x69a7e254420, 147456, 147456, 4096, 16384, 0xfb2cd701
430, 149368, 149368, 4096, 16384, 0xb3f5efb9430, 151552, 151552, 4096, 16384, 0x91c30201
440, 153464, 153464, 4096, 16384, 0x3975dea3440, 155648, 155648, 4096, 16384, 0xf23da341
450, 157560, 157560, 4096, 16384, 0x7ff7d2c5450, 159744, 159744, 4096, 16384, 0xe8d5fa0a
460, 161656, 161656, 4096, 16384, 0x5476e599460, 163840, 163840, 4096, 16384, 0x519bdfef
470, 165752, 165752, 4096, 16384, 0x30e4f37a470, 167936, 167936, 4096, 16384, 0xf2fcd803
480, 169848, 169848, 4096, 16384, 0x57c1a83c480, 172032, 172032, 4096, 16384, 0xd5ceccbc
490, 173944, 173944, 2456, 9824, 0x498532b3490, 176128, 176128, 272, 1088, 0xa8bc282b
500, 176400, 176400, 88200, 352800, 0x4fb492af500, 176400, 176400, 88200, 352800, 0x4fb492af
510, 264600, 264600, 1912, 7648, 0xf0c93a5a510, 264600, 264600, 1912, 7648, 0xf0c93a5a
520, 266512, 266512, 4096, 16384, 0x85454449520, 266512, 266512, 4096, 16384, 0x85454449

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