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.
Unified · Split
| @@ -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 | ||
| 689 | static int acrossfade_config_output(AVFilterLink *outlink) | 694 | static 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 | ||
| 712 | static 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 | |||
| 722 | static const AVFilterPad avfilter_af_acrossfade_inputs[] = { | 717 | static 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 | ||
| @@ -3,50 +3,50 @@ · 2 unmodified lines | |||
| 3 | #codec_id 0: pcm_s16le | 3 | #codec_id 0: pcm_s16le |
| 4 | #sample_rate 0: 44100 | 4 | #sample_rate 0: 44100 |
| 5 | #channel_layout_name 0: stereo | 5 | #channel_layout_name 0: stereo |
| 6 | 0, 0, 0, 1912, 7648, 0x1294dd84 | 6 | 0, 0, 0, 4096, 16384, 0x02ebe66b |
| 7 | 0, 1912, 1912, 4096, 16384, 0x8d5eec9b | 7 | 0, 4096, 4096, 4096, 16384, 0x35bfe081 |
| 8 | 0, 6008, 6008, 4096, 16384, 0x9f15e8a9 | 8 | 0, 8192, 8192, 4096, 16384, 0x3f90e0a9 |
| 9 | 0, 10104, 10104, 4096, 16384, 0x5594dd9d | 9 | 0, 12288, 12288, 4096, 16384, 0xd389dc43 |
| 10 | 0, 14200, 14200, 4096, 16384, 0x5115d9bb | 10 | 0, 16384, 16384, 4096, 16384, 0x9d5add49 |
| 11 | 0, 18296, 18296, 4096, 16384, 0x0511d717 | 11 | 0, 20480, 20480, 4096, 16384, 0x378ee333 |
| 12 | 0, 22392, 22392, 4096, 16384, 0x9cbdd713 | 12 | 0, 24576, 24576, 4096, 16384, 0xabf6df0f |
| 13 | 0, 26488, 26488, 4096, 16384, 0x2f13e615 | 13 | 0, 28672, 28672, 4096, 16384, 0xedefe76f |
| 14 | 0, 30584, 30584, 4096, 16384, 0x415ae9f7 | 14 | 0, 32768, 32768, 4096, 16384, 0x02ebe66b |
| 15 | 0, 34680, 34680, 4096, 16384, 0x8d5eec9b | 15 | 0, 36864, 36864, 4096, 16384, 0x35bfe081 |
| 16 | 0, 38776, 38776, 4096, 16384, 0x9f15e8a9 | 16 | 0, 40960, 40960, 4096, 16384, 0xdbc2b3b9 |
| 17 | 0, 42872, 42872, 4096, 16384, 0xd9809dcd | 17 | 0, 45056, 45056, 4096, 16384, 0xe92bd835 |
| 18 | 0, 46968, 46968, 4096, 16384, 0x7b60ec15 | 18 | 0, 49152, 49152, 4096, 16384, 0x1126dca3 |
| 19 | 0, 51064, 51064, 4096, 16384, 0xe92de3eb | 19 | 0, 53248, 53248, 4096, 16384, 0x9647edcf |
| 20 | 0, 55160, 55160, 4096, 16384, 0x063d2c76 | 20 | 0, 57344, 57344, 4096, 16384, 0x5cc345aa |
| 21 | 0, 59256, 59256, 4096, 16384, 0xacbed331 | 21 | 0, 61440, 61440, 4096, 16384, 0x19d7bd51 |
| 22 | 0, 63352, 63352, 4096, 16384, 0x1137d0c7 | 22 | 0, 65536, 65536, 4096, 16384, 0x19eccef7 |
| 23 | 0, 67448, 67448, 4096, 16384, 0xafbad1d7 | 23 | 0, 69632, 69632, 4096, 16384, 0x4b68eeed |
| 24 | 0, 71544, 71544, 4096, 16384, 0xb2a0040c | 24 | 0, 73728, 73728, 4096, 16384, 0x0b3d1bfc |
| 25 | 0, 75640, 75640, 4096, 16384, 0x83222d0c | 25 | 0, 77824, 77824, 4096, 16384, 0xe9b2e069 |
| 26 | 0, 79736, 79736, 4096, 16384, 0x97993592 | 26 | 0, 81920, 81920, 4096, 16384, 0xcaa5590e |
| 27 | 0, 83832, 83832, 4096, 16384, 0x9e4200b2 | 27 | 0, 86016, 86016, 4096, 16384, 0x47d0b227 |
| 28 | 0, 87928, 87928, 4096, 16384, 0xf24c2685 | 28 | 0, 90112, 90112, 4096, 16384, 0x446ba7a4 |
| 29 | 0, 92024, 92024, 4096, 16384, 0x0b23a4c8 | 29 | 0, 94208, 94208, 4096, 16384, 0x299b2e17 |
| 30 | 0, 96120, 96120, 4096, 16384, 0x9105fcde | 30 | 0, 98304, 98304, 4096, 16384, 0xc51affa2 |
| 31 | 0, 100216, 100216, 4096, 16384, 0xd4b64a6f | 31 | 0, 102400, 102400, 4096, 16384, 0xb4970fcf |
| 32 | 0, 104312, 104312, 4096, 16384, 0xef56c48a | 32 | 0, 106496, 106496, 4096, 16384, 0xe48af9fc |
| 33 | 0, 108408, 108408, 4096, 16384, 0xb12b9599 | 33 | 0, 110592, 110592, 4096, 16384, 0xc2beffbb |
| 34 | 0, 112504, 112504, 4096, 16384, 0x18bbeefd | 34 | 0, 114688, 114688, 4096, 16384, 0xb9d99627 |
| 35 | 0, 116600, 116600, 4096, 16384, 0x3fe2d14b | 35 | 0, 118784, 118784, 4096, 16384, 0xb65a2086 |
| 36 | 0, 120696, 120696, 4096, 16384, 0xf6d6fdff | 36 | 0, 122880, 122880, 4096, 16384, 0x6386714b |
| 37 | 0, 124792, 124792, 4096, 16384, 0x2e538447 | 37 | 0, 126976, 126976, 4096, 16384, 0x92a3171e |
| 38 | 0, 128888, 128888, 4096, 16384, 0xd8251663 | 38 | 0, 131072, 131072, 4096, 16384, 0x78bad1e2 |
| 39 | 0, 132984, 132984, 4096, 16384, 0xd783c943 | 39 | 0, 135168, 135168, 4096, 16384, 0x63301330 |
| 40 | 0, 137080, 137080, 4096, 16384, 0x3d64f7cf | 40 | 0, 139264, 139264, 4096, 16384, 0xd663b943 |
| 41 | 0, 141176, 141176, 4096, 16384, 0x80e2c034 | 41 | 0, 143360, 143360, 4096, 16384, 0xdcafe377 |
| 42 | 0, 145272, 145272, 4096, 16384, 0x69a7e254 | 42 | 0, 147456, 147456, 4096, 16384, 0xfb2cd701 |
| 43 | 0, 149368, 149368, 4096, 16384, 0xb3f5efb9 | 43 | 0, 151552, 151552, 4096, 16384, 0x91c30201 |
| 44 | 0, 153464, 153464, 4096, 16384, 0x3975dea3 | 44 | 0, 155648, 155648, 4096, 16384, 0xf23da341 |
| 45 | 0, 157560, 157560, 4096, 16384, 0x7ff7d2c5 | 45 | 0, 159744, 159744, 4096, 16384, 0xe8d5fa0a |
| 46 | 0, 161656, 161656, 4096, 16384, 0x5476e599 | 46 | 0, 163840, 163840, 4096, 16384, 0x519bdfef |
| 47 | 0, 165752, 165752, 4096, 16384, 0x30e4f37a | 47 | 0, 167936, 167936, 4096, 16384, 0xf2fcd803 |
| 48 | 0, 169848, 169848, 4096, 16384, 0x57c1a83c | 48 | 0, 172032, 172032, 4096, 16384, 0xd5ceccbc |
| 49 | 0, 173944, 173944, 2456, 9824, 0x498532b3 | 49 | 0, 176128, 176128, 272, 1088, 0xa8bc282b |
| 50 | 0, 176400, 176400, 88200, 352800, 0x4fb492af | 50 | 0, 176400, 176400, 88200, 352800, 0x4fb492af |
| 51 | 0, 264600, 264600, 1912, 7648, 0xf0c93a5a | 51 | 0, 264600, 264600, 1912, 7648, 0xf0c93a5a |
| 52 | 0, 266512, 266512, 4096, 16384, 0x85454449 | 52 | 0, 266512, 266512, 4096, 16384, 0x85454449 |