* [FFmpeg-devel] [PATCH v5 0/2] GSoC 2023: Add Audio Overlay Filter
@ 2024-02-01 13:01 Harshit Karwal
2024-02-01 13:01 ` [FFmpeg-devel] [PATCH v5 1/2] avfilter: add audio overlay filter Harshit Karwal
2024-02-01 13:01 ` [FFmpeg-devel] [PATCH v5 2/2] fate: Add tests for aoverlay filter Harshit Karwal
0 siblings, 2 replies; 4+ messages in thread
From: Harshit Karwal @ 2024-02-01 13:01 UTC (permalink / raw)
To: ffmpeg-devel
Added enum for crossfade modes, av_logs for stream transitions and minor change to the docs
Harshit Karwal (2):
avfilter: add audio overlay filter
fate: Add tests for aoverlay filter
doc/filters.texi | 40 ++
libavfilter/Makefile | 1 +
libavfilter/af_aoverlay.c | 548 +++++++++++++++++++++
libavfilter/allfilters.c | 1 +
tests/fate/filter-audio.mak | 22 +
tests/ref/fate/filter-aoverlay-crossfade-d | 224 +++++++++
tests/ref/fate/filter-aoverlay-crossfade-t | 202 ++++++++
tests/ref/fate/filter-aoverlay-default | 259 ++++++++++
tests/ref/fate/filter-aoverlay-timeline | 254 ++++++++++
9 files changed, 1551 insertions(+)
create mode 100644 libavfilter/af_aoverlay.c
create mode 100644 tests/ref/fate/filter-aoverlay-crossfade-d
create mode 100644 tests/ref/fate/filter-aoverlay-crossfade-t
create mode 100644 tests/ref/fate/filter-aoverlay-default
create mode 100644 tests/ref/fate/filter-aoverlay-timeline
--
2.39.3 (Apple Git-145)
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* [FFmpeg-devel] [PATCH v5 1/2] avfilter: add audio overlay filter
2024-02-01 13:01 [FFmpeg-devel] [PATCH v5 0/2] GSoC 2023: Add Audio Overlay Filter Harshit Karwal
@ 2024-02-01 13:01 ` Harshit Karwal
2024-02-04 23:41 ` Stefano Sabatini
2024-02-01 13:01 ` [FFmpeg-devel] [PATCH v5 2/2] fate: Add tests for aoverlay filter Harshit Karwal
1 sibling, 1 reply; 4+ messages in thread
From: Harshit Karwal @ 2024-02-01 13:01 UTC (permalink / raw)
To: ffmpeg-devel
Co-authored-by: Paul B Mahol <onemda@gmail.com>
Signed-off-by: Harshit Karwal <karwalharshit@gmail.com>
---
doc/filters.texi | 40 +++
libavfilter/Makefile | 1 +
libavfilter/af_aoverlay.c | 548 ++++++++++++++++++++++++++++++++++++++
libavfilter/allfilters.c | 1 +
4 files changed, 590 insertions(+)
create mode 100644 libavfilter/af_aoverlay.c
diff --git a/doc/filters.texi b/doc/filters.texi
index 20c91bab3a..f36ad9a2fd 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -2779,6 +2779,46 @@ This filter supports the same commands as options, excluding option @code{order}
Pass the audio source unchanged to the output.
+@section aoverlay
+
+Replace a specified section of an audio stream with another input audio stream.
+
+In case no @option{enable} for timeline editing is specified, the second audio stream will
+be output at sections of the first stream which have a gap in PTS (Presentation TimeStamp) values
+such that the output stream's PTS values are monotonous.
+
+This filter also supports linear cross fading when transitioning from one
+input stream to another.
+
+The filter accepts the following options:
+
+@table @option
+@item cf_duration
+Set duration (in seconds) for cross fade between the inputs. Default value is @code{100} milliseconds.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Replace the first stream with the second stream from @code{t=10} seconds to @code{t=20} seconds:
+@example
+ffmpeg -i first.wav -i second.wav -filter_complex "aoverlay=enable='between(t,10,20)'" output.wav
+@end example
+
+@item
+Do the same as above, but with crossfading for @code{2} seconds between the streams:
+@example
+ffmpeg -i first.wav -i second.wav -filter_complex "aoverlay=cf_duration=2:enable='between(t,10,20)'" output.wav
+@end example
+
+@item
+Introduce a PTS gap from @code{t=4} seconds to @code{t=8} seconds in the first stream and output the second stream during this gap:
+@example
+ffmpeg -i first.wav -i second.wav -filter_complex "[0]aselect='not(between(t,4,8))'[temp];[temp][1]aoverlay[out]" -map "[out]" output.wav
+@end example
+@end itemize
+
@section apad
Pad the end of an audio stream with silence.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index bba0219876..0f2b403441 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -81,6 +81,7 @@ OBJS-$(CONFIG_ANLMDN_FILTER) += af_anlmdn.o
OBJS-$(CONFIG_ANLMF_FILTER) += af_anlms.o
OBJS-$(CONFIG_ANLMS_FILTER) += af_anlms.o
OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o
+OBJS-$(CONFIG_AOVERLAY_FILTER) += af_aoverlay.o
OBJS-$(CONFIG_APAD_FILTER) += af_apad.o
OBJS-$(CONFIG_APERMS_FILTER) += f_perms.o
OBJS-$(CONFIG_APHASER_FILTER) += af_aphaser.o generate_wave_table.o
diff --git a/libavfilter/af_aoverlay.c b/libavfilter/af_aoverlay.c
new file mode 100644
index 0000000000..8dd2d02951
--- /dev/null
+++ b/libavfilter/af_aoverlay.c
@@ -0,0 +1,548 @@
+/*
+ * Copyright (c) 2023 Harshit Karwal
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/audio_fifo.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "filters.h"
+#include "internal.h"
+
+typedef struct AOverlayContext {
+ const AVClass *class;
+ AVFrame *main_input;
+ AVFrame *overlay_input;
+ int64_t pts;
+ int main_eof;
+ int overlay_eof;
+
+ int default_mode;
+ int previous_samples;
+ int64_t pts_gap;
+ int64_t previous_pts;
+ int64_t pts_gap_start;
+ int64_t pts_gap_end;
+
+ int is_disabled;
+ int nb_channels;
+ int crossfade_ready;
+ AVAudioFifo *main_sample_buffers;
+ AVAudioFifo *overlay_sample_buffers;
+ int64_t cf_duration;
+ int64_t cf_samples;
+ void (*crossfade_samples)(uint8_t **dst, uint8_t * const *cf0,
+ uint8_t * const *cf1,
+ int nb_samples, int channels);
+
+ int64_t transition_pts;
+ int64_t transition_pts2;
+
+ uint8_t **cf0;
+ uint8_t **cf1;
+} AOverlayContext;
+
+static const enum AVSampleFormat sample_fmts[] = {
+ AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_FLTP,
+ AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P,
+ AV_SAMPLE_FMT_NONE
+};
+
+enum CrossfadeModes {
+ MODE_TIMELINE,
+ MODE_DEFAULT,
+ MODE_OVERLAY_EOF
+};
+
+#define SEGMENT_SIZE 1024
+#define OFFSET(x) offsetof(AOverlayContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption aoverlay_options[] = {
+ { "cf_duration", "set duration for cross fade between the inputs", OFFSET(cf_duration), AV_OPT_TYPE_DURATION, {.i64 = 100000}, 0, 60000000, FLAGS },
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(aoverlay);
+
+#define CROSSFADE_PLANAR(name, type) \
+static void crossfade_samples_## name ##p(uint8_t **dst, uint8_t * const *cf0, \
+ uint8_t * const *cf1, \
+ int nb_samples, int channels) \
+{ \
+ for (int i = 0; i < nb_samples; i++) { \
+ double main_gain = av_clipd(1.0 * (nb_samples - 1 - i) / nb_samples, 0, 1.); \
+ double overlay_gain = av_clipd(1.0 * i / nb_samples, 0, 1.); \
+ for (int c = 0; c < channels; c++) { \
+ type *d = (type *)dst[c]; \
+ const type *s0 = (type *)cf0[c]; \
+ const type *s1 = (type *)cf1[c]; \
+ \
+ d[i] = s0[i] * main_gain + s1[i] * overlay_gain; \
+ } \
+ } \
+}
+
+CROSSFADE_PLANAR(dbl, double)
+CROSSFADE_PLANAR(flt, float)
+CROSSFADE_PLANAR(s16, int16_t)
+CROSSFADE_PLANAR(s32, int32_t)
+
+static av_cold int init(AVFilterContext *ctx)
+{
+ AOverlayContext *s = ctx->priv;
+
+ s->is_disabled = 1;
+ s->transition_pts = AV_NOPTS_VALUE;
+ s->transition_pts2 = AV_NOPTS_VALUE;
+
+ return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ AOverlayContext *s = ctx->priv;
+
+ av_audio_fifo_free(s->main_sample_buffers);
+ av_audio_fifo_free(s->overlay_sample_buffers);
+
+ for (int i = 0; i < s->nb_channels; i++) {
+ if (s->cf0)
+ av_freep(&s->cf0[i]);
+ if (s->cf1)
+ av_freep(&s->cf1[i]);
+ }
+ av_freep(&s->cf0);
+ av_freep(&s->cf1);
+
+ av_frame_free(&s->main_input);
+ av_frame_free(&s->overlay_input);
+}
+
+static int crossfade_prepare(AOverlayContext *s, AVFilterLink *main_inlink, AVFilterLink *overlay_inlink, AVFilterLink *outlink,
+ int nb_samples, AVFrame **main_buffer, AVFrame **overlay_buffer, enum CrossfadeModes mode)
+{
+ int ret;
+
+ *main_buffer = ff_get_audio_buffer(outlink, nb_samples);
+ if (!(*main_buffer))
+ return AVERROR(ENOMEM);
+
+ (*main_buffer)->pts = s->pts;
+ s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+
+ if ((ret = av_audio_fifo_read(s->main_sample_buffers, (void **)(*main_buffer)->extended_data, nb_samples)) < 0)
+ return ret;
+
+ if (mode == MODE_DEFAULT) {
+ s->previous_samples = (*main_buffer)->nb_samples;
+ } else if (mode == MODE_OVERLAY_EOF || (mode == MODE_TIMELINE && s->is_disabled)) {
+ *overlay_buffer = ff_get_audio_buffer(outlink, nb_samples);
+ if (!(*overlay_buffer))
+ return AVERROR(ENOMEM);
+
+ if ((ret = av_audio_fifo_read(s->overlay_sample_buffers, (void **)(*overlay_buffer)->extended_data, nb_samples)) < 0)
+ return ret;
+
+ (*overlay_buffer)->pts = (*main_buffer)->pts;
+ }
+
+ s->crossfade_ready = 1;
+
+ return 0;
+}
+
+static int crossfade_samples(AOverlayContext *s, AVFilterLink *main_inlink, AVFilterLink *overlay_inlink, AVFilterLink *outlink,
+ int nb_samples, AVFrame **out, enum CrossfadeModes mode)
+{
+ int ret;
+
+ *out = ff_get_audio_buffer(outlink, nb_samples);
+ if (!(*out))
+ return AVERROR(ENOMEM);
+
+ if ((ret = av_audio_fifo_read(s->main_sample_buffers, (void **) s->cf0, nb_samples)) < 0)
+ return ret;
+
+ if ((ret = av_audio_fifo_read(s->overlay_sample_buffers, (void **) s->cf1, nb_samples)) < 0)
+ return ret;
+
+ if (mode == MODE_TIMELINE) {
+ s->is_disabled ? s->crossfade_samples((*out)->extended_data, s->cf1, s->cf0, nb_samples, (*out)->ch_layout.nb_channels)
+ : s->crossfade_samples((*out)->extended_data, s->cf0, s->cf1, nb_samples, (*out)->ch_layout.nb_channels);
+ } else if (mode == MODE_OVERLAY_EOF) {
+ s->crossfade_samples((*out)->extended_data, s->cf1, s->cf0, s->cf_samples, (*out)->ch_layout.nb_channels);
+ } else if (mode == MODE_DEFAULT) {
+ s->transition_pts2 != AV_NOPTS_VALUE ? s->crossfade_samples((*out)->extended_data, s->cf1, s->cf0, nb_samples, (*out)->ch_layout.nb_channels)
+ : s->crossfade_samples((*out)->extended_data, s->cf0, s->cf1, nb_samples, (*out)->ch_layout.nb_channels);
+ }
+
+ (*out)->pts = s->pts;
+ s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+ s->transition_pts = AV_NOPTS_VALUE;
+ s->transition_pts2 = AV_NOPTS_VALUE;
+ s->crossfade_ready = 0;
+
+ return 0;
+}
+
+static int consume_samples(AOverlayContext *s, AVFilterLink *overlay_inlink, AVFilterLink *outlink)
+{
+ int ret, status, nb_samples;
+ int64_t pts;
+
+ nb_samples = FFMIN(SEGMENT_SIZE, av_audio_fifo_space(s->overlay_sample_buffers));
+
+ ret = ff_inlink_consume_samples(overlay_inlink, nb_samples, nb_samples, &s->overlay_input);
+ if (ret < 0) {
+ return ret;
+ } else if (ff_inlink_acknowledge_status(overlay_inlink, &status, &pts)) {
+ s->overlay_eof = 1;
+ return 0;
+ } else if (!ret) {
+ if (ff_outlink_frame_wanted(outlink))
+ ff_inlink_request_frame(overlay_inlink);
+ return 0;
+ }
+
+ ret = av_audio_fifo_write(s->overlay_sample_buffers, (void **)s->overlay_input->extended_data, nb_samples);
+ av_frame_free(&s->overlay_input);
+ if (ret < 0)
+ return ret;
+
+ return 1;
+}
+
+static int activate(AVFilterContext *ctx)
+{
+ AOverlayContext *s = ctx->priv;
+ int status, ret, nb_samples;
+ int64_t pts;
+ AVFrame *out = NULL, *main_buffer = NULL, *overlay_buffer = NULL;
+
+ AVFilterLink *main_inlink = ctx->inputs[0];
+ AVFilterLink *overlay_inlink = ctx->inputs[1];
+ AVFilterLink *outlink = ctx->outputs[0];
+
+ FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);
+
+ if (s->default_mode && (s->pts_gap_end - s->pts_gap_start <= 0 || s->overlay_eof)) {
+ s->default_mode = 0;
+ s->transition_pts2 = s->pts_gap_end;
+ }
+
+ if (av_audio_fifo_space(s->main_sample_buffers) != 0 && !s->main_eof && !s->default_mode) {
+ nb_samples = FFMIN(SEGMENT_SIZE, av_audio_fifo_space(s->main_sample_buffers));
+
+ ret = ff_inlink_consume_samples(main_inlink, nb_samples, nb_samples, &s->main_input);
+ if (ret > 0) {
+ if (ctx->enable_str && s->is_disabled != ctx->is_disabled && !s->overlay_eof) {
+ s->is_disabled = ctx->is_disabled;
+ s->transition_pts = s->main_input->pts;
+
+ if (s->main_input->nb_samples < av_audio_fifo_space(s->main_sample_buffers))
+ s->crossfade_ready = 1;
+ if (av_audio_fifo_size(s->main_sample_buffers) == 0) {
+ s->transition_pts = AV_NOPTS_VALUE;
+ s->crossfade_ready = 0;
+ }
+ }
+ else if (!ctx->enable_str && !s->default_mode) {
+ if (s->previous_pts + av_rescale_q(s->previous_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base) >= s->main_input->pts) {
+ s->default_mode = 0;
+ s->previous_pts = s->main_input->pts;
+ s->previous_samples = s->main_input->nb_samples;
+ } else if (!s->overlay_eof) {
+ s->pts_gap_start = s->previous_pts;
+ if (s->pts > 0 || av_audio_fifo_size(s->main_sample_buffers) > 0)
+ s->transition_pts = s->pts_gap_start;
+ s->pts_gap_end = s->main_input->pts;
+ s->default_mode = 1;
+ }
+ }
+
+ ret = av_audio_fifo_write(s->main_sample_buffers, (void **)s->main_input->extended_data, nb_samples);
+ av_frame_free(&s->main_input);
+ if (ret < 0)
+ return ret;
+ } else if (ret < 0) {
+ return ret;
+ } else if (ff_inlink_acknowledge_status(main_inlink, &status, &pts)) {
+ s->main_eof = 1;
+ s->crossfade_ready = 1;
+ } else if (!ret) {
+ if (ff_outlink_frame_wanted(outlink))
+ ff_inlink_request_frame(main_inlink);
+ return 0;
+ }
+ }
+
+ if (s->main_eof && av_audio_fifo_size(s->main_sample_buffers) == 0 && ff_inlink_acknowledge_status(main_inlink, &status, &pts)) {
+ ff_outlink_set_status(outlink, status, pts);
+ return 0;
+ }
+
+ if (av_audio_fifo_space(s->main_sample_buffers) > 0 &&
+ (s->transition_pts == AV_NOPTS_VALUE || av_audio_fifo_size(s->main_sample_buffers) != s->cf_samples) && !s->default_mode) {
+ if (ff_inlink_acknowledge_status(main_inlink, &status, &pts)) {
+ s->main_eof = 1;
+ s->crossfade_ready = 1;
+ } else {
+ ff_inlink_request_frame(main_inlink);
+ return 0;
+ }
+ }
+
+ if (!s->overlay_eof) {
+ if (av_audio_fifo_space(s->overlay_sample_buffers) > 0) {
+ ret = consume_samples(s, overlay_inlink, outlink);
+ if (ret <= 0) {
+ if (!s->overlay_eof)
+ return ret;
+ }
+ }
+
+ if (av_audio_fifo_space(s->overlay_sample_buffers) > 0) {
+ if (ff_inlink_acknowledge_status(overlay_inlink, &status, &pts)) {
+ s->overlay_eof = 1;
+ s->transition_pts = s->pts + av_rescale_q(av_audio_fifo_size(s->overlay_sample_buffers) - (s->cf_samples / 2),
+ (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+ s->is_disabled = 1;
+ } else {
+ ff_inlink_request_frame(overlay_inlink);
+ return 0;
+ }
+ }
+ }
+
+ if (!ctx->enable_str) {
+ if (s->transition_pts != AV_NOPTS_VALUE && av_audio_fifo_size(s->main_sample_buffers) > s->cf_samples + SEGMENT_SIZE) {
+ nb_samples = av_audio_fifo_size(s->main_sample_buffers) + av_audio_fifo_space(s->main_sample_buffers) - s->cf_samples - SEGMENT_SIZE;
+
+ if ((ret = crossfade_prepare(s, main_inlink, overlay_inlink, outlink, nb_samples, &main_buffer, &overlay_buffer, MODE_DEFAULT)) < 0)
+ return ret;
+
+ return ff_filter_frame(outlink, main_buffer);
+ } else if (s->transition_pts != AV_NOPTS_VALUE || s->transition_pts2 != AV_NOPTS_VALUE) {
+ nb_samples = FFMIN(s->cf_samples, av_audio_fifo_size(s->main_sample_buffers) - SEGMENT_SIZE);
+
+ if ((ret = crossfade_samples(s, main_inlink, overlay_inlink, outlink, nb_samples, &out, MODE_DEFAULT)) < 0)
+ return ret;
+
+ av_log(ctx, AV_LOG_DEBUG, "PTS at stream transition: %lld\n", out->pts);
+
+ return ff_filter_frame(outlink, out);
+ } else if (!s->default_mode) {
+ nb_samples = FFMIN(av_audio_fifo_size(s->main_sample_buffers), SEGMENT_SIZE);
+
+ main_buffer = ff_get_audio_buffer(outlink, nb_samples);
+ if (!main_buffer)
+ return AVERROR(ENOMEM);
+
+ main_buffer->pts = s->pts;
+ s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+
+ if ((ret = av_audio_fifo_read(s->main_sample_buffers, (void **)main_buffer->extended_data, nb_samples)) < 0)
+ return ret;
+ }
+
+ if (!s->default_mode || s->overlay_eof) {
+ s->previous_samples = main_buffer->nb_samples;
+ return ff_filter_frame(outlink, main_buffer);
+ }
+
+ s->pts_gap = s->pts_gap_end - s->pts_gap_start;
+
+ nb_samples = FFMIN(SEGMENT_SIZE, av_rescale_q(s->pts_gap, outlink->time_base, (AVRational){ 1, outlink->sample_rate }));
+
+ overlay_buffer = ff_get_audio_buffer(outlink, nb_samples);
+ if (!overlay_buffer)
+ return AVERROR(ENOMEM);
+
+ if ((ret = av_audio_fifo_read(s->overlay_sample_buffers, (void **)overlay_buffer->extended_data, nb_samples)) < 0)
+ return ret;
+
+ s->previous_samples = nb_samples;
+ s->previous_pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+ s->pts_gap_start += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+
+ overlay_buffer->pts = s->pts;
+ s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+
+ av_frame_free(&main_buffer);
+
+ return ff_filter_frame(outlink, overlay_buffer);
+ }
+
+ if (s->overlay_eof && av_audio_fifo_size(s->overlay_sample_buffers) > 0) {
+ if (av_audio_fifo_size(s->overlay_sample_buffers) > s->cf_samples) {
+ nb_samples = av_audio_fifo_size(s->overlay_sample_buffers) - s->cf_samples;
+
+ if ((ret = crossfade_prepare(s, main_inlink, overlay_inlink, outlink, nb_samples, &main_buffer, &overlay_buffer, MODE_OVERLAY_EOF)) < 0)
+ return ret;
+
+ return ff_filter_frame(outlink, overlay_buffer);
+ } else if (av_audio_fifo_size(s->overlay_sample_buffers) >= s->cf_samples) {
+ if ((ret = crossfade_samples(s, main_inlink, overlay_inlink, outlink, s->cf_samples, &out, MODE_OVERLAY_EOF)) < 0)
+ return ret;
+
+ av_log(ctx, AV_LOG_DEBUG, "PTS at stream transition: %lld\n", out->pts);
+
+ return ff_filter_frame(outlink, out);
+ }
+ }
+
+ if (s->transition_pts != AV_NOPTS_VALUE && !s->crossfade_ready) {
+ nb_samples = av_rescale_q(s->transition_pts - (s->cf_samples / 2) - s->pts, outlink->time_base, (AVRational) { 1, outlink->sample_rate });
+
+ if ((ret = crossfade_prepare(s, main_inlink, overlay_inlink, outlink, nb_samples, &main_buffer, &overlay_buffer, MODE_TIMELINE)) < 0)
+ return ret;
+ } else if (s->transition_pts != AV_NOPTS_VALUE) {
+ nb_samples = s->main_eof ? av_audio_fifo_size(s->main_sample_buffers) : s->cf_samples;
+ if (s->transition_pts < av_rescale_q(s->cf_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base)) {
+ nb_samples = av_rescale_q(s->transition_pts, outlink->time_base, (AVRational){ 1, outlink->sample_rate });
+ }
+
+ if ((ret = crossfade_samples(s, main_inlink, overlay_inlink, outlink, nb_samples, &out, MODE_TIMELINE)) < 0)
+ return ret;
+
+ av_log(ctx, AV_LOG_DEBUG, "PTS at stream transition: %lld\n", out->pts);
+
+ return ff_filter_frame(outlink, out);
+ } else {
+ nb_samples = FFMIN(av_audio_fifo_size(s->main_sample_buffers), SEGMENT_SIZE);
+ main_buffer = ff_get_audio_buffer(outlink, nb_samples);
+ if (!main_buffer)
+ return AVERROR(ENOMEM);
+
+ main_buffer->pts = s->pts;
+ s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+
+ if ((ret = av_audio_fifo_read(s->main_sample_buffers, (void **)main_buffer->extended_data, nb_samples)) < 0)
+ return ret;
+ }
+
+ if (!ff_inlink_evaluate_timeline_at_frame(main_inlink, main_buffer) || (s->overlay_eof && av_audio_fifo_size(s->overlay_sample_buffers) == 0)) {
+ return ff_filter_frame(outlink, main_buffer);
+ } else {
+ if (s->transition_pts == AV_NOPTS_VALUE) {
+ nb_samples = FFMIN(av_audio_fifo_size(s->overlay_sample_buffers), SEGMENT_SIZE);
+ overlay_buffer = ff_get_audio_buffer(outlink, nb_samples);
+ if (!overlay_buffer)
+ return AVERROR(ENOMEM);
+
+ if ((ret = av_audio_fifo_read(s->overlay_sample_buffers, (void **)overlay_buffer->extended_data, nb_samples)) < 0)
+ return ret;
+
+ overlay_buffer->pts = main_buffer->pts;
+ }
+ av_frame_free(&main_buffer);
+ return ff_filter_frame(outlink, overlay_buffer);
+ }
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ AOverlayContext *s = ctx->priv;
+ int size, fifo_size;
+
+ switch (outlink->format) {
+ case AV_SAMPLE_FMT_DBLP: s->crossfade_samples = crossfade_samples_dblp;
+ size = sizeof(double);
+ break;
+ case AV_SAMPLE_FMT_FLTP: s->crossfade_samples = crossfade_samples_fltp;
+ size = sizeof(float);
+ break;
+ case AV_SAMPLE_FMT_S16P: s->crossfade_samples = crossfade_samples_s16p;
+ size = sizeof(int16_t);
+ break;
+ case AV_SAMPLE_FMT_S32P: s->crossfade_samples = crossfade_samples_s32p;
+ size = sizeof(int32_t);
+ break;
+ }
+
+ if (s->cf_duration)
+ s->cf_samples = av_rescale(s->cf_duration, outlink->sample_rate, AV_TIME_BASE);
+
+ s->nb_channels = outlink->ch_layout.nb_channels;
+
+ fifo_size = SEGMENT_SIZE + SEGMENT_SIZE * (1 + ((s->cf_samples - 1) / SEGMENT_SIZE));
+
+ s->main_sample_buffers = av_audio_fifo_alloc(outlink->format, s->nb_channels, fifo_size);
+ if (!s->main_sample_buffers)
+ return AVERROR(ENOMEM);
+
+ s->overlay_sample_buffers = av_audio_fifo_alloc(outlink->format, s->nb_channels, fifo_size);
+ if (!s->overlay_sample_buffers)
+ return AVERROR(ENOMEM);
+
+ s->cf0 = av_calloc(s->nb_channels, sizeof(*s->cf0));
+ if (!s->cf0)
+ return AVERROR(ENOMEM);
+
+ s->cf1 = av_calloc(s->nb_channels, sizeof(*s->cf1));
+ if (!s->cf1)
+ return AVERROR(ENOMEM);
+
+ for (int i = 0; i < s->nb_channels; i++) {
+ s->cf0[i] = av_malloc_array(s->cf_samples, size);
+ if (!s->cf0[i])
+ return AVERROR(ENOMEM);
+ s->cf1[i] = av_malloc_array(s->cf_samples, size);
+ if (!s->cf1[i])
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
+static const AVFilterPad inputs[] = {
+ {
+ .name = "main",
+ .type = AVMEDIA_TYPE_AUDIO,
+ },
+ {
+ .name = "overlay",
+ .type = AVMEDIA_TYPE_AUDIO,
+ },
+};
+
+static const AVFilterPad outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .config_props = config_output,
+ },
+};
+
+const AVFilter ff_af_aoverlay = {
+ .name = "aoverlay",
+ .description = NULL_IF_CONFIG_SMALL("Replace a specified section of an audio stream with another audio input."),
+ .priv_size = sizeof(AOverlayContext),
+ .priv_class = &aoverlay_class,
+ .activate = activate,
+ .init = init,
+ .uninit = uninit,
+ FILTER_INPUTS(inputs),
+ FILTER_OUTPUTS(outputs),
+ FILTER_SAMPLEFMTS_ARRAY(sample_fmts),
+ .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
+};
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index af84aa3d97..2310cbb250 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -67,6 +67,7 @@ extern const AVFilter ff_af_anlmdn;
extern const AVFilter ff_af_anlmf;
extern const AVFilter ff_af_anlms;
extern const AVFilter ff_af_anull;
+extern const AVFilter ff_af_aoverlay;
extern const AVFilter ff_af_apad;
extern const AVFilter ff_af_aperms;
extern const AVFilter ff_af_aphaser;
--
2.39.3 (Apple Git-145)
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* [FFmpeg-devel] [PATCH v5 2/2] fate: Add tests for aoverlay filter
2024-02-01 13:01 [FFmpeg-devel] [PATCH v5 0/2] GSoC 2023: Add Audio Overlay Filter Harshit Karwal
2024-02-01 13:01 ` [FFmpeg-devel] [PATCH v5 1/2] avfilter: add audio overlay filter Harshit Karwal
@ 2024-02-01 13:01 ` Harshit Karwal
1 sibling, 0 replies; 4+ messages in thread
From: Harshit Karwal @ 2024-02-01 13:01 UTC (permalink / raw)
To: ffmpeg-devel
---
tests/fate/filter-audio.mak | 22 ++
tests/ref/fate/filter-aoverlay-crossfade-d | 224 ++++++++++++++++++
tests/ref/fate/filter-aoverlay-crossfade-t | 202 ++++++++++++++++
tests/ref/fate/filter-aoverlay-default | 259 +++++++++++++++++++++
tests/ref/fate/filter-aoverlay-timeline | 254 ++++++++++++++++++++
5 files changed, 961 insertions(+)
create mode 100644 tests/ref/fate/filter-aoverlay-crossfade-d
create mode 100644 tests/ref/fate/filter-aoverlay-crossfade-t
create mode 100644 tests/ref/fate/filter-aoverlay-default
create mode 100644 tests/ref/fate/filter-aoverlay-timeline
diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index adf61cf074..718558636b 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -73,6 +73,28 @@ fate-filter-amerge: tests/data/asynth-44100-1.wav
fate-filter-amerge: SRC = $(TARGET_PATH)/tests/data/asynth-44100-1.wav
fate-filter-amerge: CMD = framecrc -i $(SRC) -i $(SRC) -filter_complex "[0:a][1:a]amerge=inputs=2[aout]" -map "[aout]"
+FATE_AFILTER_AOVERLAY += fate-filter-aoverlay-timeline
+fate-filter-aoverlay-timeline: tests/data/asynth-44100-1.wav
+fate-filter-aoverlay-timeline: SRC = $(TARGET_PATH)/tests/data/asynth-44100-1.wav
+fate-filter-aoverlay-timeline: CMD = framecrc -i $(SRC) -i $(SRC) -auto_conversion_filters -filter_complex "aoverlay=enable='\''between\(t,2,3\)'\''"
+
+FATE_AFILTER_AOVERLAY += fate-filter-aoverlay-default
+fate-filter-aoverlay-default: tests/data/asynth-44100-1.wav
+fate-filter-aoverlay-default: SRC = $(TARGET_PATH)/tests/data/asynth-44100-1.wav
+fate-filter-aoverlay-default: CMD = framecrc -i $(SRC) -i $(SRC) -auto_conversion_filters -filter_complex "[0]aselect='\''not\(between\(t,2,3\)\)'\''[temp];[temp][1]aoverlay[out]" -map "[out]"
+
+FATE_AFILTER_AOVERLAY += fate-filter-aoverlay-crossfade-t
+fate-filter-aoverlay-crossfade-t: tests/data/asynth-44100-1.wav
+fate-filter-aoverlay-crossfade-t: SRC = $(TARGET_PATH)/tests/data/asynth-44100-1.wav
+fate-filter-aoverlay-crossfade-t: CMD = framecrc -i $(SRC) -i $(SRC) -auto_conversion_filters -filter_complex "aoverlay=cf_duration=0.5:enable='\''between\(t,2,3\)'\''"
+
+FATE_AFILTER_AOVERLAY += fate-filter-aoverlay-crossfade-d
+fate-filter-aoverlay-crossfade-d: tests/data/asynth-44100-1.wav
+fate-filter-aoverlay-crossfade-d: SRC = $(TARGET_PATH)/tests/data/asynth-44100-1.wav
+fate-filter-aoverlay-crossfade-d: CMD = framecrc -i $(SRC) -i $(SRC) -auto_conversion_filters -filter_complex "[0]aselect='\''not\(between\(t,2,3\)\)'\''[temp];[temp][1]aoverlay=cf_duration=0.5[out]" -map "[out]"
+
+FATE_AFILTER-$(call FILTERDEMDECENCMUX, AOVERLAY, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_AFILTER_AOVERLAY)
+
FATE_AFILTER-$(call FILTERDEMDECENCMUX, APAD, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-apad
fate-filter-apad: tests/data/asynth-44100-2.wav
fate-filter-apad: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
diff --git a/tests/ref/fate/filter-aoverlay-crossfade-d b/tests/ref/fate/filter-aoverlay-crossfade-d
new file mode 100644
index 0000000000..b3975bde2f
--- /dev/null
+++ b/tests/ref/fate/filter-aoverlay-crossfade-d
@@ -0,0 +1,224 @@
+#tb 0: 1/44100
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44100
+#channel_layout_name 0: mono
+0, 0, 0, 1024, 2048, 0x490ff760
+0, 1024, 1024, 1024, 2048, 0xc8a405cb
+0, 2048, 2048, 1024, 2048, 0xeed6fd45
+0, 3072, 3072, 1024, 2048, 0x8cabf8a0
+0, 4096, 4096, 1024, 2048, 0x4707f6c1
+0, 5120, 5120, 1024, 2048, 0xc1a50038
+0, 6144, 6144, 1024, 2048, 0x3e75fa60
+0, 7168, 7168, 1024, 2048, 0x988ffec2
+0, 8192, 8192, 1024, 2048, 0x0537f926
+0, 9216, 9216, 1024, 2048, 0x6919fd71
+0, 10240, 10240, 1024, 2048, 0xeef4f7d0
+0, 11264, 11264, 1024, 2048, 0xcf7a01c8
+0, 12288, 12288, 1024, 2048, 0x2cf70048
+0, 13312, 13312, 1024, 2048, 0x8a51fba6
+0, 14336, 14336, 1024, 2048, 0x311af181
+0, 15360, 15360, 1024, 2048, 0x8248009c
+0, 16384, 16384, 1024, 2048, 0x9aa4010b
+0, 17408, 17408, 1024, 2048, 0x1a2df2a0
+0, 18432, 18432, 1024, 2048, 0xf6e2fb18
+0, 19456, 19456, 1024, 2048, 0x548effbc
+0, 20480, 20480, 1024, 2048, 0x965a01a9
+0, 21504, 21504, 1024, 2048, 0x2554f834
+0, 22528, 22528, 1024, 2048, 0xa390fdfc
+0, 23552, 23552, 1024, 2048, 0x51d8f99b
+0, 24576, 24576, 1024, 2048, 0xed47fd39
+0, 25600, 25600, 1024, 2048, 0x79b8faeb
+0, 26624, 26624, 1024, 2048, 0xf6da009c
+0, 27648, 27648, 1024, 2048, 0x0ffbf6a2
+0, 28672, 28672, 1024, 2048, 0xb6a6f823
+0, 29696, 29696, 1024, 2048, 0x5cbefcb7
+0, 30720, 30720, 1024, 2048, 0xb0eb06ea
+0, 31744, 31744, 1024, 2048, 0x5edbf7ce
+0, 32768, 32768, 1024, 2048, 0x490ff760
+0, 33792, 33792, 1024, 2048, 0xc8a405cb
+0, 34816, 34816, 1024, 2048, 0xeed6fd45
+0, 35840, 35840, 1024, 2048, 0x8cabf8a0
+0, 36864, 36864, 1024, 2048, 0x4707f6c1
+0, 37888, 37888, 1024, 2048, 0xc1a50038
+0, 38912, 38912, 1024, 2048, 0x3e75fa60
+0, 39936, 39936, 1024, 2048, 0x988ffec2
+0, 40960, 40960, 1024, 2048, 0x0537f926
+0, 41984, 41984, 1024, 2048, 0x6919fd71
+0, 43008, 43008, 1024, 2048, 0xeef4f7d0
+0, 44032, 44032, 1024, 2048, 0xee07eb41
+0, 45056, 45056, 1024, 2048, 0xd8d9f658
+0, 46080, 46080, 1024, 2048, 0x9b30051b
+0, 47104, 47104, 1024, 2048, 0x5605f37f
+0, 48128, 48128, 1024, 2048, 0x6f6afd03
+0, 49152, 49152, 1024, 2048, 0x9ca8fd97
+0, 50176, 50176, 1024, 2048, 0x37f4fe98
+0, 51200, 51200, 1024, 2048, 0x8e66fb1f
+0, 52224, 52224, 1024, 2048, 0x3268f6cf
+0, 53248, 53248, 1024, 2048, 0x4636fb46
+0, 54272, 54272, 1024, 2048, 0xb413fbd5
+0, 55296, 55296, 1024, 2048, 0xabfd08c3
+0, 56320, 56320, 1024, 2048, 0x7810f6e4
+0, 57344, 57344, 1024, 2048, 0xb59f19b5
+0, 58368, 58368, 1024, 2048, 0xd8ea0714
+0, 59392, 59392, 1024, 2048, 0xd49a00e4
+0, 60416, 60416, 1024, 2048, 0xffed0128
+0, 61440, 61440, 1024, 2048, 0x50cbec23
+0, 62464, 62464, 1024, 2048, 0xe215f92b
+0, 63488, 63488, 1024, 2048, 0xa8bb00e1
+0, 64512, 64512, 1024, 2048, 0x2b55f854
+0, 65536, 65536, 1024, 2048, 0xca1cf07e
+0, 66560, 66560, 1024, 2048, 0xd059ff29
+0, 67584, 67584, 478, 956, 0x76bcdcd8
+0, 68062, 68062, 22050, 44100, 0x09d1e336
+0, 90112, 90112, 1024, 2048, 0x51b4f388
+0, 91136, 91136, 1024, 2048, 0x18580097
+0, 92160, 92160, 1024, 2048, 0x1a42fd47
+0, 93184, 93184, 1024, 2048, 0x07d4f9b6
+0, 94208, 94208, 1024, 2048, 0x88b8fe81
+0, 95232, 95232, 1024, 2048, 0x9409f791
+0, 96256, 96256, 1024, 2048, 0x2f66019c
+0, 97280, 97280, 1024, 2048, 0xdbcffacf
+0, 98304, 98304, 1024, 2048, 0x63320225
+0, 99328, 99328, 1024, 2048, 0x2e0af834
+0, 100352, 100352, 1024, 2048, 0x003af60d
+0, 101376, 101376, 1024, 2048, 0x7cb2ffd1
+0, 102400, 102400, 1024, 2048, 0x4e610a1a
+0, 103424, 103424, 1024, 2048, 0xb77bf001
+0, 104448, 104448, 1024, 2048, 0xb9bff604
+0, 105472, 105472, 1024, 2048, 0x1da401eb
+0, 106496, 106496, 1024, 2048, 0x8f9104e3
+0, 107520, 107520, 1024, 2048, 0xcd93f7d5
+0, 108544, 108544, 1024, 2048, 0x49c0f917
+0, 109568, 109568, 1024, 2048, 0xe0affea7
+0, 110592, 110592, 1024, 2048, 0x5beff9dc
+0, 111616, 111616, 1024, 2048, 0x4504040c
+0, 112640, 112640, 1024, 2048, 0x633cd8bb
+0, 113664, 113664, 1024, 2048, 0x36ec0943
+0, 114688, 114688, 1024, 2048, 0xa4a1ebbe
+0, 115712, 115712, 1024, 2048, 0xa67e03bc
+0, 116736, 116736, 1024, 2048, 0xdfb3fbb4
+0, 117760, 117760, 1024, 2048, 0x23d0f8d1
+0, 118784, 118784, 1024, 2048, 0xd84f001c
+0, 119808, 119808, 1024, 2048, 0xfb98f8b5
+0, 120832, 120832, 1024, 2048, 0xba36fb2a
+0, 121856, 121856, 1024, 2048, 0xced8040f
+0, 122880, 122880, 1024, 2048, 0x78c7f690
+0, 123904, 123904, 1024, 2048, 0x87c0fc2a
+0, 124928, 124928, 1024, 2048, 0xffb8150f
+0, 125952, 125952, 1024, 2048, 0xe2611396
+0, 126976, 126976, 1024, 2048, 0xa30c0373
+0, 128000, 128000, 1024, 2048, 0xc481f859
+0, 129024, 129024, 1024, 2048, 0x3946f1fd
+0, 130048, 130048, 1024, 2048, 0x34c6f30d
+0, 131072, 131072, 1024, 2048, 0x44c802bd
+0, 132096, 132096, 1024, 2048, 0x97c1f1dd
+0, 133120, 133120, 1024, 2048, 0x4617fc06
+0, 134144, 134144, 22050, 44100, 0xebddcd05
+0, 156194, 156194, 1024, 2048, 0x23a7eb59
+0, 157218, 157218, 1024, 2048, 0xb1e3efed
+0, 158242, 158242, 1024, 2048, 0xe504fe7c
+0, 159266, 159266, 1024, 2048, 0xbf4defe7
+0, 160290, 160290, 1024, 2048, 0x2629ef35
+0, 161314, 161314, 1024, 2048, 0x0761fe63
+0, 162338, 162338, 1024, 2048, 0x323709ae
+0, 163362, 163362, 1024, 2048, 0xdf0c117e
+0, 164386, 164386, 1024, 2048, 0x8b25f7f3
+0, 165410, 165410, 1024, 2048, 0xd068faa3
+0, 166434, 166434, 1024, 2048, 0x2b900f6d
+0, 167458, 167458, 1024, 2048, 0x15c4f0ad
+0, 168482, 168482, 1024, 2048, 0x45910273
+0, 169506, 169506, 1024, 2048, 0xe29500a7
+0, 170530, 170530, 1024, 2048, 0x54680195
+0, 171554, 171554, 1024, 2048, 0x80a3fbde
+0, 172578, 172578, 1024, 2048, 0x8395fb70
+0, 173602, 173602, 1024, 2048, 0x3d15f14f
+0, 174626, 174626, 1024, 2048, 0xb9e7e897
+0, 175650, 175650, 1024, 2048, 0x4a07024a
+0, 176674, 176674, 1024, 2048, 0x2dfffe54
+0, 177698, 177698, 1024, 2048, 0x5e3f099f
+0, 178722, 178722, 1024, 2048, 0x30dae724
+0, 179746, 179746, 1024, 2048, 0x0362f4b5
+0, 180770, 180770, 1024, 2048, 0x4596f032
+0, 181794, 181794, 1024, 2048, 0x9593ec8d
+0, 182818, 182818, 1024, 2048, 0x882d05ef
+0, 183842, 183842, 1024, 2048, 0x83daead3
+0, 184866, 184866, 1024, 2048, 0x5c67fa0d
+0, 185890, 185890, 1024, 2048, 0xdaecf969
+0, 186914, 186914, 1024, 2048, 0xbb2af075
+0, 187938, 187938, 1024, 2048, 0x51aa06bd
+0, 188962, 188962, 1024, 2048, 0x466ee9c4
+0, 189986, 189986, 1024, 2048, 0x091bfc2f
+0, 191010, 191010, 1024, 2048, 0x174605be
+0, 192034, 192034, 1024, 2048, 0x3a9ce183
+0, 193058, 193058, 1024, 2048, 0x794651e0
+0, 194082, 194082, 1024, 2048, 0xf411f059
+0, 195106, 195106, 1024, 2048, 0xa70bfdc8
+0, 196130, 196130, 1024, 2048, 0x129c0423
+0, 197154, 197154, 1024, 2048, 0xe774effd
+0, 198178, 198178, 1024, 2048, 0xd32912a6
+0, 199202, 199202, 1024, 2048, 0x74d4fc97
+0, 200226, 200226, 1024, 2048, 0xc72df7e1
+0, 201250, 201250, 1024, 2048, 0x97230fc8
+0, 202274, 202274, 1024, 2048, 0xd2e3f46c
+0, 203298, 203298, 1024, 2048, 0xc7b30179
+0, 204322, 204322, 1024, 2048, 0xb7c50386
+0, 205346, 205346, 1024, 2048, 0x9cb5015e
+0, 206370, 206370, 1024, 2048, 0x722b1be6
+0, 207394, 207394, 1024, 2048, 0xa09cf2de
+0, 208418, 208418, 1024, 2048, 0xb606049e
+0, 209442, 209442, 1024, 2048, 0x2297fb20
+0, 210466, 210466, 1024, 2048, 0x8304eecc
+0, 211490, 211490, 1024, 2048, 0xaf871147
+0, 212514, 212514, 1024, 2048, 0xdcd903b5
+0, 213538, 213538, 1024, 2048, 0xa05f083b
+0, 214562, 214562, 1024, 2048, 0x4d080bde
+0, 215586, 215586, 1024, 2048, 0x5b90f27c
+0, 216610, 216610, 1024, 2048, 0x63650d99
+0, 217634, 217634, 1024, 2048, 0x8592fe4f
+0, 218658, 218658, 1024, 2048, 0x0311fef3
+0, 219682, 219682, 1024, 2048, 0x250b07f6
+0, 220706, 220706, 1024, 2048, 0x9173f1ae
+0, 221730, 221730, 1024, 2048, 0x9ee70ea7
+0, 222754, 222754, 1024, 2048, 0xdcf0fc2e
+0, 223778, 223778, 1024, 2048, 0xcc4bf2ad
+0, 224802, 224802, 1024, 2048, 0xacb916e9
+0, 225826, 225826, 1024, 2048, 0xd117160d
+0, 226850, 226850, 1024, 2048, 0xf0950812
+0, 227874, 227874, 1024, 2048, 0x4150fa95
+0, 228898, 228898, 1024, 2048, 0xd055f448
+0, 229922, 229922, 1024, 2048, 0x0231086f
+0, 230946, 230946, 1024, 2048, 0x0e04e5c5
+0, 231970, 231970, 1024, 2048, 0x6ee9fbc5
+0, 232994, 232994, 1024, 2048, 0x1fe6008b
+0, 234018, 234018, 1024, 2048, 0x4582e8a2
+0, 235042, 235042, 1024, 2048, 0x11a603ff
+0, 236066, 236066, 1024, 2048, 0x20bef6f3
+0, 237090, 237090, 1024, 2048, 0x2b00f4e5
+0, 238114, 238114, 1024, 2048, 0x4c34f70f
+0, 239138, 239138, 1024, 2048, 0x6d44dc84
+0, 240162, 240162, 1024, 2048, 0x434d058d
+0, 241186, 241186, 1024, 2048, 0x301bf3cd
+0, 242210, 242210, 1024, 2048, 0xbf8efd3c
+0, 243234, 243234, 1024, 2048, 0x5e3f099f
+0, 244258, 244258, 1024, 2048, 0x30dae724
+0, 245282, 245282, 1024, 2048, 0x0362f4b5
+0, 246306, 246306, 1024, 2048, 0x4596f032
+0, 247330, 247330, 1024, 2048, 0x9593ec8d
+0, 248354, 248354, 1024, 2048, 0x882d05ef
+0, 249378, 249378, 1024, 2048, 0x83daead3
+0, 250402, 250402, 1024, 2048, 0x5c67fa0d
+0, 251426, 251426, 1024, 2048, 0xdaecf969
+0, 252450, 252450, 1024, 2048, 0xbb2af075
+0, 253474, 253474, 1024, 2048, 0x51aa06bd
+0, 254498, 254498, 1024, 2048, 0x466ee9c4
+0, 255522, 255522, 1024, 2048, 0x091bfc2f
+0, 256546, 256546, 1024, 2048, 0x174605be
+0, 257570, 257570, 1024, 2048, 0x3a9ce183
+0, 258594, 258594, 1024, 2048, 0x794651e0
+0, 259618, 259618, 1024, 2048, 0xf411f059
+0, 260642, 260642, 1024, 2048, 0xa70bfdc8
+0, 261666, 261666, 1024, 2048, 0x129c0423
+0, 262690, 262690, 1024, 2048, 0xe774effd
+0, 263714, 263714, 1024, 2048, 0xd32912a6
+0, 264738, 264738, 1024, 2048, 0x72a07316
diff --git a/tests/ref/fate/filter-aoverlay-crossfade-t b/tests/ref/fate/filter-aoverlay-crossfade-t
new file mode 100644
index 0000000000..604499de98
--- /dev/null
+++ b/tests/ref/fate/filter-aoverlay-crossfade-t
@@ -0,0 +1,202 @@
+#tb 0: 1/44100
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44100
+#channel_layout_name 0: mono
+0, 0, 0, 1024, 2048, 0x490ff760
+0, 1024, 1024, 1024, 2048, 0xc8a405cb
+0, 2048, 2048, 1024, 2048, 0xeed6fd45
+0, 3072, 3072, 1024, 2048, 0x8cabf8a0
+0, 4096, 4096, 1024, 2048, 0x4707f6c1
+0, 5120, 5120, 1024, 2048, 0xc1a50038
+0, 6144, 6144, 1024, 2048, 0x3e75fa60
+0, 7168, 7168, 1024, 2048, 0x988ffec2
+0, 8192, 8192, 1024, 2048, 0x0537f926
+0, 9216, 9216, 1024, 2048, 0x6919fd71
+0, 10240, 10240, 1024, 2048, 0xeef4f7d0
+0, 11264, 11264, 1024, 2048, 0xcf7a01c8
+0, 12288, 12288, 1024, 2048, 0x2cf70048
+0, 13312, 13312, 1024, 2048, 0x8a51fba6
+0, 14336, 14336, 1024, 2048, 0x311af181
+0, 15360, 15360, 1024, 2048, 0x8248009c
+0, 16384, 16384, 1024, 2048, 0x9aa4010b
+0, 17408, 17408, 1024, 2048, 0x1a2df2a0
+0, 18432, 18432, 1024, 2048, 0xf6e2fb18
+0, 19456, 19456, 1024, 2048, 0x548effbc
+0, 20480, 20480, 1024, 2048, 0x965a01a9
+0, 21504, 21504, 1024, 2048, 0x2554f834
+0, 22528, 22528, 1024, 2048, 0xa390fdfc
+0, 23552, 23552, 1024, 2048, 0x51d8f99b
+0, 24576, 24576, 1024, 2048, 0xed47fd39
+0, 25600, 25600, 1024, 2048, 0x79b8faeb
+0, 26624, 26624, 1024, 2048, 0xf6da009c
+0, 27648, 27648, 1024, 2048, 0x0ffbf6a2
+0, 28672, 28672, 1024, 2048, 0xb6a6f823
+0, 29696, 29696, 1024, 2048, 0x5cbefcb7
+0, 30720, 30720, 1024, 2048, 0xb0eb06ea
+0, 31744, 31744, 1024, 2048, 0x5edbf7ce
+0, 32768, 32768, 1024, 2048, 0x490ff760
+0, 33792, 33792, 1024, 2048, 0xc8a405cb
+0, 34816, 34816, 1024, 2048, 0xeed6fd45
+0, 35840, 35840, 1024, 2048, 0x8cabf8a0
+0, 36864, 36864, 1024, 2048, 0x4707f6c1
+0, 37888, 37888, 1024, 2048, 0xc1a50038
+0, 38912, 38912, 1024, 2048, 0x3e75fa60
+0, 39936, 39936, 1024, 2048, 0x988ffec2
+0, 40960, 40960, 1024, 2048, 0x0537f926
+0, 41984, 41984, 1024, 2048, 0x6919fd71
+0, 43008, 43008, 1024, 2048, 0xeef4f7d0
+0, 44032, 44032, 1024, 2048, 0xee07eb41
+0, 45056, 45056, 1024, 2048, 0xd8d9f658
+0, 46080, 46080, 1024, 2048, 0x9b30051b
+0, 47104, 47104, 1024, 2048, 0x5605f37f
+0, 48128, 48128, 1024, 2048, 0x6f6afd03
+0, 49152, 49152, 1024, 2048, 0x9ca8fd97
+0, 50176, 50176, 1024, 2048, 0x37f4fe98
+0, 51200, 51200, 1024, 2048, 0x8e66fb1f
+0, 52224, 52224, 1024, 2048, 0x3268f6cf
+0, 53248, 53248, 1024, 2048, 0x4636fb46
+0, 54272, 54272, 1024, 2048, 0xb413fbd5
+0, 55296, 55296, 1024, 2048, 0xabfd08c3
+0, 56320, 56320, 1024, 2048, 0x7810f6e4
+0, 57344, 57344, 1024, 2048, 0xb59f19b5
+0, 58368, 58368, 1024, 2048, 0xd8ea0714
+0, 59392, 59392, 1024, 2048, 0xd49a00e4
+0, 60416, 60416, 1024, 2048, 0xffed0128
+0, 61440, 61440, 1024, 2048, 0x50cbec23
+0, 62464, 62464, 1024, 2048, 0xe215f92b
+0, 63488, 63488, 1024, 2048, 0xa8bb00e1
+0, 64512, 64512, 1024, 2048, 0x2b55f854
+0, 65536, 65536, 1024, 2048, 0xca1cf07e
+0, 66560, 66560, 11503, 23006, 0xd668f1a6
+0, 78063, 78063, 22050, 44100, 0xc088e277
+0, 100113, 100113, 1024, 2048, 0x51b4f388
+0, 101137, 101137, 1024, 2048, 0x18580097
+0, 102161, 102161, 1024, 2048, 0x1a42fd47
+0, 103185, 103185, 1024, 2048, 0x07d4f9b6
+0, 104209, 104209, 1024, 2048, 0x88b8fe81
+0, 105233, 105233, 1024, 2048, 0x9409f791
+0, 106257, 106257, 1024, 2048, 0x2f66019c
+0, 107281, 107281, 1024, 2048, 0xdbcffacf
+0, 108305, 108305, 1024, 2048, 0x63320225
+0, 109329, 109329, 1024, 2048, 0x2e0af834
+0, 110353, 110353, 11503, 23006, 0x3ca2bf8d
+0, 121856, 121856, 22050, 44100, 0x58feea82
+0, 143906, 143906, 1024, 2048, 0x9eabf7db
+0, 144930, 144930, 1024, 2048, 0x004f0681
+0, 145954, 145954, 1024, 2048, 0x81ba0b3c
+0, 146978, 146978, 1024, 2048, 0xc7dff275
+0, 148002, 148002, 1024, 2048, 0x5568f204
+0, 149026, 149026, 1024, 2048, 0xfa53fb21
+0, 150050, 150050, 1024, 2048, 0x747a00bd
+0, 151074, 151074, 1024, 2048, 0xfcb4f5db
+0, 152098, 152098, 1024, 2048, 0xd8b8eafd
+0, 153122, 153122, 1024, 2048, 0xa84f0580
+0, 154146, 154146, 1024, 2048, 0xb73f029a
+0, 155170, 155170, 1024, 2048, 0x23a7eb59
+0, 156194, 156194, 1024, 2048, 0xb1e3efed
+0, 157218, 157218, 1024, 2048, 0xe504fe7c
+0, 158242, 158242, 1024, 2048, 0xbf4defe7
+0, 159266, 159266, 1024, 2048, 0x2629ef35
+0, 160290, 160290, 1024, 2048, 0x0761fe63
+0, 161314, 161314, 1024, 2048, 0x323709ae
+0, 162338, 162338, 1024, 2048, 0xdf0c117e
+0, 163362, 163362, 1024, 2048, 0x8b25f7f3
+0, 164386, 164386, 1024, 2048, 0xd068faa3
+0, 165410, 165410, 1024, 2048, 0x2b900f6d
+0, 166434, 166434, 1024, 2048, 0x15c4f0ad
+0, 167458, 167458, 1024, 2048, 0x45910273
+0, 168482, 168482, 1024, 2048, 0xe29500a7
+0, 169506, 169506, 1024, 2048, 0x54680195
+0, 170530, 170530, 1024, 2048, 0x80a3fbde
+0, 171554, 171554, 1024, 2048, 0x8395fb70
+0, 172578, 172578, 1024, 2048, 0x3d15f14f
+0, 173602, 173602, 1024, 2048, 0xb9e7e897
+0, 174626, 174626, 1024, 2048, 0x4a07024a
+0, 175650, 175650, 1024, 2048, 0x2dfffe54
+0, 176674, 176674, 1024, 2048, 0x5e3f099f
+0, 177698, 177698, 1024, 2048, 0x30dae724
+0, 178722, 178722, 1024, 2048, 0x0362f4b5
+0, 179746, 179746, 1024, 2048, 0x4596f032
+0, 180770, 180770, 1024, 2048, 0x9593ec8d
+0, 181794, 181794, 1024, 2048, 0x882d05ef
+0, 182818, 182818, 1024, 2048, 0x83daead3
+0, 183842, 183842, 1024, 2048, 0x5c67fa0d
+0, 184866, 184866, 1024, 2048, 0xdaecf969
+0, 185890, 185890, 1024, 2048, 0xbb2af075
+0, 186914, 186914, 1024, 2048, 0x51aa06bd
+0, 187938, 187938, 1024, 2048, 0x466ee9c4
+0, 188962, 188962, 1024, 2048, 0x091bfc2f
+0, 189986, 189986, 1024, 2048, 0x174605be
+0, 191010, 191010, 1024, 2048, 0x3a9ce183
+0, 192034, 192034, 1024, 2048, 0x794651e0
+0, 193058, 193058, 1024, 2048, 0xf411f059
+0, 194082, 194082, 1024, 2048, 0xa70bfdc8
+0, 195106, 195106, 1024, 2048, 0x129c0423
+0, 196130, 196130, 1024, 2048, 0xe774effd
+0, 197154, 197154, 1024, 2048, 0xd32912a6
+0, 198178, 198178, 1024, 2048, 0x74d4fc97
+0, 199202, 199202, 1024, 2048, 0xc72df7e1
+0, 200226, 200226, 1024, 2048, 0x97230fc8
+0, 201250, 201250, 1024, 2048, 0xd2e3f46c
+0, 202274, 202274, 1024, 2048, 0xc7b30179
+0, 203298, 203298, 1024, 2048, 0xb7c50386
+0, 204322, 204322, 1024, 2048, 0x9cb5015e
+0, 205346, 205346, 1024, 2048, 0x722b1be6
+0, 206370, 206370, 1024, 2048, 0xa09cf2de
+0, 207394, 207394, 1024, 2048, 0xb606049e
+0, 208418, 208418, 1024, 2048, 0x2297fb20
+0, 209442, 209442, 1024, 2048, 0x8304eecc
+0, 210466, 210466, 1024, 2048, 0xaf871147
+0, 211490, 211490, 1024, 2048, 0xdcd903b5
+0, 212514, 212514, 1024, 2048, 0xa05f083b
+0, 213538, 213538, 1024, 2048, 0x4d080bde
+0, 214562, 214562, 1024, 2048, 0x5b90f27c
+0, 215586, 215586, 1024, 2048, 0x63650d99
+0, 216610, 216610, 1024, 2048, 0x8592fe4f
+0, 217634, 217634, 1024, 2048, 0x0311fef3
+0, 218658, 218658, 1024, 2048, 0x250b07f6
+0, 219682, 219682, 1024, 2048, 0x9173f1ae
+0, 220706, 220706, 1024, 2048, 0x9ee70ea7
+0, 221730, 221730, 1024, 2048, 0xdcf0fc2e
+0, 222754, 222754, 1024, 2048, 0xcc4bf2ad
+0, 223778, 223778, 1024, 2048, 0xacb916e9
+0, 224802, 224802, 1024, 2048, 0xd117160d
+0, 225826, 225826, 1024, 2048, 0xf0950812
+0, 226850, 226850, 1024, 2048, 0x4150fa95
+0, 227874, 227874, 1024, 2048, 0xd055f448
+0, 228898, 228898, 1024, 2048, 0x0231086f
+0, 229922, 229922, 1024, 2048, 0x0e04e5c5
+0, 230946, 230946, 1024, 2048, 0x6ee9fbc5
+0, 231970, 231970, 1024, 2048, 0x1fe6008b
+0, 232994, 232994, 1024, 2048, 0x4582e8a2
+0, 234018, 234018, 1024, 2048, 0x11a603ff
+0, 235042, 235042, 1024, 2048, 0x20bef6f3
+0, 236066, 236066, 1024, 2048, 0x2b00f4e5
+0, 237090, 237090, 1024, 2048, 0x4c34f70f
+0, 238114, 238114, 1024, 2048, 0x6d44dc84
+0, 239138, 239138, 1024, 2048, 0x434d058d
+0, 240162, 240162, 1024, 2048, 0x301bf3cd
+0, 241186, 241186, 1024, 2048, 0xbf8efd3c
+0, 242210, 242210, 1024, 2048, 0x5e3f099f
+0, 243234, 243234, 1024, 2048, 0x30dae724
+0, 244258, 244258, 1024, 2048, 0x0362f4b5
+0, 245282, 245282, 1024, 2048, 0x4596f032
+0, 246306, 246306, 1024, 2048, 0x9593ec8d
+0, 247330, 247330, 1024, 2048, 0x882d05ef
+0, 248354, 248354, 1024, 2048, 0x83daead3
+0, 249378, 249378, 1024, 2048, 0x5c67fa0d
+0, 250402, 250402, 1024, 2048, 0xdaecf969
+0, 251426, 251426, 1024, 2048, 0xbb2af075
+0, 252450, 252450, 1024, 2048, 0x51aa06bd
+0, 253474, 253474, 1024, 2048, 0x466ee9c4
+0, 254498, 254498, 1024, 2048, 0x091bfc2f
+0, 255522, 255522, 1024, 2048, 0x174605be
+0, 256546, 256546, 1024, 2048, 0x3a9ce183
+0, 257570, 257570, 1024, 2048, 0x794651e0
+0, 258594, 258594, 1024, 2048, 0xf411f059
+0, 259618, 259618, 1024, 2048, 0xa70bfdc8
+0, 260642, 260642, 1024, 2048, 0x129c0423
+0, 261666, 261666, 1024, 2048, 0xe774effd
+0, 262690, 262690, 1024, 2048, 0xd32912a6
+0, 263714, 263714, 1024, 2048, 0x72a07316
diff --git a/tests/ref/fate/filter-aoverlay-default b/tests/ref/fate/filter-aoverlay-default
new file mode 100644
index 0000000000..ef5e1ec87c
--- /dev/null
+++ b/tests/ref/fate/filter-aoverlay-default
@@ -0,0 +1,259 @@
+#tb 0: 1/44100
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44100
+#channel_layout_name 0: mono
+0, 0, 0, 1024, 2048, 0x490ff760
+0, 1024, 1024, 1024, 2048, 0xc8a405cb
+0, 2048, 2048, 1024, 2048, 0xeed6fd45
+0, 3072, 3072, 1024, 2048, 0x8cabf8a0
+0, 4096, 4096, 1024, 2048, 0x4707f6c1
+0, 5120, 5120, 1024, 2048, 0xc1a50038
+0, 6144, 6144, 1024, 2048, 0x3e75fa60
+0, 7168, 7168, 1024, 2048, 0x988ffec2
+0, 8192, 8192, 1024, 2048, 0x0537f926
+0, 9216, 9216, 1024, 2048, 0x6919fd71
+0, 10240, 10240, 1024, 2048, 0xeef4f7d0
+0, 11264, 11264, 1024, 2048, 0xcf7a01c8
+0, 12288, 12288, 1024, 2048, 0x2cf70048
+0, 13312, 13312, 1024, 2048, 0x8a51fba6
+0, 14336, 14336, 1024, 2048, 0x311af181
+0, 15360, 15360, 1024, 2048, 0x8248009c
+0, 16384, 16384, 1024, 2048, 0x9aa4010b
+0, 17408, 17408, 1024, 2048, 0x1a2df2a0
+0, 18432, 18432, 1024, 2048, 0xf6e2fb18
+0, 19456, 19456, 1024, 2048, 0x548effbc
+0, 20480, 20480, 1024, 2048, 0x965a01a9
+0, 21504, 21504, 1024, 2048, 0x2554f834
+0, 22528, 22528, 1024, 2048, 0xa390fdfc
+0, 23552, 23552, 1024, 2048, 0x51d8f99b
+0, 24576, 24576, 1024, 2048, 0xed47fd39
+0, 25600, 25600, 1024, 2048, 0x79b8faeb
+0, 26624, 26624, 1024, 2048, 0xf6da009c
+0, 27648, 27648, 1024, 2048, 0x0ffbf6a2
+0, 28672, 28672, 1024, 2048, 0xb6a6f823
+0, 29696, 29696, 1024, 2048, 0x5cbefcb7
+0, 30720, 30720, 1024, 2048, 0xb0eb06ea
+0, 31744, 31744, 1024, 2048, 0x5edbf7ce
+0, 32768, 32768, 1024, 2048, 0x490ff760
+0, 33792, 33792, 1024, 2048, 0xc8a405cb
+0, 34816, 34816, 1024, 2048, 0xeed6fd45
+0, 35840, 35840, 1024, 2048, 0x8cabf8a0
+0, 36864, 36864, 1024, 2048, 0x4707f6c1
+0, 37888, 37888, 1024, 2048, 0xc1a50038
+0, 38912, 38912, 1024, 2048, 0x3e75fa60
+0, 39936, 39936, 1024, 2048, 0x988ffec2
+0, 40960, 40960, 1024, 2048, 0x0537f926
+0, 41984, 41984, 1024, 2048, 0x6919fd71
+0, 43008, 43008, 1024, 2048, 0xeef4f7d0
+0, 44032, 44032, 1024, 2048, 0xee07eb41
+0, 45056, 45056, 1024, 2048, 0xd8d9f658
+0, 46080, 46080, 1024, 2048, 0x9b30051b
+0, 47104, 47104, 1024, 2048, 0x5605f37f
+0, 48128, 48128, 1024, 2048, 0x6f6afd03
+0, 49152, 49152, 1024, 2048, 0x9ca8fd97
+0, 50176, 50176, 1024, 2048, 0x37f4fe98
+0, 51200, 51200, 1024, 2048, 0x8e66fb1f
+0, 52224, 52224, 1024, 2048, 0x3268f6cf
+0, 53248, 53248, 1024, 2048, 0x4636fb46
+0, 54272, 54272, 1024, 2048, 0xb413fbd5
+0, 55296, 55296, 1024, 2048, 0xabfd08c3
+0, 56320, 56320, 1024, 2048, 0x7810f6e4
+0, 57344, 57344, 1024, 2048, 0xb59f19b5
+0, 58368, 58368, 1024, 2048, 0xd8ea0714
+0, 59392, 59392, 1024, 2048, 0xd49a00e4
+0, 60416, 60416, 1024, 2048, 0xffed0128
+0, 61440, 61440, 1024, 2048, 0x50cbec23
+0, 62464, 62464, 1024, 2048, 0xe215f92b
+0, 63488, 63488, 1024, 2048, 0xa8bb00e1
+0, 64512, 64512, 1024, 2048, 0x2b55f854
+0, 65536, 65536, 1024, 2048, 0xca1cf07e
+0, 66560, 66560, 1024, 2048, 0xd059ff29
+0, 67584, 67584, 1024, 2048, 0xdd43fcd5
+0, 68608, 68608, 1024, 2048, 0x44edfacb
+0, 69632, 69632, 1024, 2048, 0xd7bc00c0
+0, 70656, 70656, 1024, 2048, 0x459ff45b
+0, 71680, 71680, 1024, 2048, 0x11f5fed5
+0, 72704, 72704, 1024, 2048, 0x2b670370
+0, 73728, 73728, 1024, 2048, 0xe785fa99
+0, 74752, 74752, 1024, 2048, 0xf8610009
+0, 75776, 75776, 1024, 2048, 0xb8f80489
+0, 76800, 76800, 1024, 2048, 0xa1cd0ec4
+0, 77824, 77824, 1024, 2048, 0xad05fdbe
+0, 78848, 78848, 1024, 2048, 0x7d630249
+0, 79872, 79872, 1024, 2048, 0xc112f3d4
+0, 80896, 80896, 1024, 2048, 0x6ed9fc34
+0, 81920, 81920, 1024, 2048, 0xf2c0168a
+0, 82944, 82944, 1024, 2048, 0x2fc416cd
+0, 83968, 83968, 1024, 2048, 0xea5dff83
+0, 84992, 84992, 710, 1420, 0xb52fc572
+0, 85702, 85702, 4410, 8820, 0x4d381731
+0, 90112, 90112, 1024, 2048, 0x8f07f6ee
+0, 91136, 91136, 1024, 2048, 0x50440744
+0, 92160, 92160, 1024, 2048, 0x473bf7f0
+0, 93184, 93184, 1024, 2048, 0x8c5cf82a
+0, 94208, 94208, 1024, 2048, 0xa53afdab
+0, 95232, 95232, 1024, 2048, 0x63fbfcd3
+0, 96256, 96256, 1024, 2048, 0xeb35fda7
+0, 97280, 97280, 1024, 2048, 0x4a1603a2
+0, 98304, 98304, 1024, 2048, 0xf18dfab6
+0, 99328, 99328, 1024, 2048, 0x6f99eef6
+0, 100352, 100352, 1024, 2048, 0x83840106
+0, 101376, 101376, 1024, 2048, 0x5e5a00c3
+0, 102400, 102400, 1024, 2048, 0x85d7fd23
+0, 103424, 103424, 1024, 2048, 0x0ee9f070
+0, 104448, 104448, 1024, 2048, 0xf600fb00
+0, 105472, 105472, 1024, 2048, 0x0fb80575
+0, 106496, 106496, 1024, 2048, 0x52c6017d
+0, 107520, 107520, 1024, 2048, 0x9419f127
+0, 108544, 108544, 1024, 2048, 0xa13a007d
+0, 109568, 109568, 1024, 2048, 0x717bfe33
+0, 110592, 110592, 1024, 2048, 0x44f1fab3
+0, 111616, 111616, 1024, 2048, 0x7d06fb89
+0, 112640, 112640, 1024, 2048, 0xf84dfab5
+0, 113664, 113664, 1024, 2048, 0x9899f4c9
+0, 114688, 114688, 1024, 2048, 0xf031fda6
+0, 115712, 115712, 1024, 2048, 0x74c40975
+0, 116736, 116736, 1024, 2048, 0x6495f766
+0, 117760, 117760, 1024, 2048, 0x7e85f7a7
+0, 118784, 118784, 1024, 2048, 0x589afb39
+0, 119808, 119808, 1024, 2048, 0xd21807fb
+0, 120832, 120832, 1024, 2048, 0xed82fd5c
+0, 121856, 121856, 1024, 2048, 0xd669f2f6
+0, 122880, 122880, 1024, 2048, 0x8f07f6ee
+0, 123904, 123904, 1024, 2048, 0x50440744
+0, 124928, 124928, 1024, 2048, 0x473bf7f0
+0, 125952, 125952, 1024, 2048, 0x8c5cf82a
+0, 126976, 126976, 1024, 2048, 0xa53afdab
+0, 128000, 128000, 1024, 2048, 0x63fbfcd3
+0, 129024, 129024, 1024, 2048, 0x41ac0a79
+0, 130048, 130048, 1024, 2048, 0x7569ddf3
+0, 131072, 131072, 1024, 2048, 0x7588f9c9
+0, 132096, 132096, 1024, 2048, 0x4bb4f2ad
+0, 133120, 133120, 1024, 2048, 0x0a29021d
+0, 134144, 134144, 4410, 8820, 0xaf4b51a4
+0, 138554, 138554, 1024, 2048, 0x2a940755
+0, 139578, 139578, 1024, 2048, 0xd9d20b41
+0, 140602, 140602, 1024, 2048, 0x23c2f62e
+0, 141626, 141626, 1024, 2048, 0x3bb5f531
+0, 142650, 142650, 1024, 2048, 0x57dffd27
+0, 143674, 143674, 1024, 2048, 0x48e2f322
+0, 144698, 144698, 1024, 2048, 0xd2c7f10a
+0, 145722, 145722, 1024, 2048, 0xe13afb8f
+0, 146746, 146746, 1024, 2048, 0x681a1844
+0, 147770, 147770, 1024, 2048, 0x556fea66
+0, 148794, 148794, 1024, 2048, 0xec880231
+0, 149818, 149818, 1024, 2048, 0xb826ed5a
+0, 150842, 150842, 1024, 2048, 0x43ad0045
+0, 151866, 151866, 1024, 2048, 0x469df6fc
+0, 152890, 152890, 1024, 2048, 0x6bc7eda5
+0, 153914, 153914, 1024, 2048, 0x4bf00baa
+0, 154938, 154938, 1024, 2048, 0xa14afe5a
+0, 155962, 155962, 1024, 2048, 0x4fa6eb3e
+0, 156986, 156986, 1024, 2048, 0x4080f71c
+0, 158010, 158010, 1024, 2048, 0x9478f217
+0, 159034, 159034, 1024, 2048, 0x24def107
+0, 160058, 160058, 1024, 2048, 0x11f2f63b
+0, 161082, 161082, 1024, 2048, 0xc47ffcd5
+0, 162106, 162106, 1024, 2048, 0xea590220
+0, 163130, 163130, 1024, 2048, 0xd98b0888
+0, 164154, 164154, 1024, 2048, 0x88c40856
+0, 165178, 165178, 1024, 2048, 0x817af922
+0, 166202, 166202, 1024, 2048, 0xe0100804
+0, 167226, 167226, 1024, 2048, 0xd7f3fb50
+0, 168250, 168250, 1024, 2048, 0x77e8fd45
+0, 169274, 169274, 1024, 2048, 0xe0cefaa1
+0, 170298, 170298, 1024, 2048, 0x20620151
+0, 171322, 171322, 1024, 2048, 0x97d2ff9b
+0, 172346, 172346, 1024, 2048, 0x08e2f5d4
+0, 173370, 173370, 1024, 2048, 0x0fa8fb60
+0, 174394, 174394, 1024, 2048, 0xf03fe8b5
+0, 175418, 175418, 1024, 2048, 0x39dcfcef
+0, 176442, 176442, 1024, 2048, 0x4a270176
+0, 177466, 177466, 1024, 2048, 0xbcfefdb0
+0, 178490, 178490, 1024, 2048, 0xbefdfcaa
+0, 179514, 179514, 1024, 2048, 0x4447e693
+0, 180538, 180538, 1024, 2048, 0x3e46f914
+0, 181562, 181562, 1024, 2048, 0x6182eddd
+0, 182586, 182586, 1024, 2048, 0xb73ef32e
+0, 183610, 183610, 1024, 2048, 0xf9a80887
+0, 184634, 184634, 1024, 2048, 0xf7d7e193
+0, 185658, 185658, 1024, 2048, 0xc6020158
+0, 186682, 186682, 1024, 2048, 0xc00cf907
+0, 187706, 187706, 1024, 2048, 0x9c67f01f
+0, 188730, 188730, 1024, 2048, 0x66c00433
+0, 189754, 189754, 1024, 2048, 0x7721ed3e
+0, 190778, 190778, 1024, 2048, 0x84c5009e
+0, 191802, 191802, 1024, 2048, 0x524e0255
+0, 192826, 192826, 1024, 2048, 0x954e6fc6
+0, 193850, 193850, 1024, 2048, 0x92ecc373
+0, 194874, 194874, 1024, 2048, 0xfa3ff0e2
+0, 195898, 195898, 1024, 2048, 0x28d4fd0f
+0, 196922, 196922, 1024, 2048, 0x499c036c
+0, 197946, 197946, 1024, 2048, 0x1b77f88f
+0, 198970, 198970, 1024, 2048, 0xd9920d25
+0, 199994, 199994, 1024, 2048, 0x217cf6a0
+0, 201018, 201018, 1024, 2048, 0x447dffb5
+0, 202042, 202042, 1024, 2048, 0xba7812c6
+0, 203066, 203066, 1024, 2048, 0xba09ecee
+0, 204090, 204090, 1024, 2048, 0xcdc0089d
+0, 205114, 205114, 1024, 2048, 0xed63068e
+0, 206138, 206138, 1024, 2048, 0x03b10426
+0, 207162, 207162, 1024, 2048, 0xf3e91165
+0, 208186, 208186, 1024, 2048, 0x9562f87b
+0, 209210, 209210, 1024, 2048, 0xe623fba7
+0, 210234, 210234, 1024, 2048, 0x224ffaab
+0, 211258, 211258, 1024, 2048, 0x24a8fbb2
+0, 212282, 212282, 1024, 2048, 0xa19611d8
+0, 213306, 213306, 1024, 2048, 0xa39bff48
+0, 214330, 214330, 1024, 2048, 0x8a4d0a90
+0, 215354, 215354, 1024, 2048, 0x28df053d
+0, 216378, 216378, 1024, 2048, 0xe8f6efe4
+0, 217402, 217402, 1024, 2048, 0xed9516d9
+0, 218426, 218426, 1024, 2048, 0x161bf712
+0, 219450, 219450, 1024, 2048, 0x236dff55
+0, 220474, 220474, 1024, 2048, 0x4a72084d
+0, 221498, 221498, 1024, 2048, 0x7af5f438
+0, 222522, 222522, 1024, 2048, 0x698c0b2d
+0, 223546, 223546, 1024, 2048, 0x631af7ce
+0, 224570, 224570, 1024, 2048, 0x908bf616
+0, 225594, 225594, 1024, 2048, 0xce976db2
+0, 226618, 226618, 1024, 2048, 0xa4a4bf5f
+0, 227642, 227642, 1024, 2048, 0xe8ff0789
+0, 228666, 228666, 1024, 2048, 0xbe1bfb4e
+0, 229690, 229690, 1024, 2048, 0x9bddf4ff
+0, 230714, 230714, 1024, 2048, 0xc8faffcd
+0, 231738, 231738, 1024, 2048, 0x0e63eb47
+0, 232762, 232762, 1024, 2048, 0xc13101cb
+0, 233786, 233786, 1024, 2048, 0x9d4ef8a7
+0, 234810, 234810, 1024, 2048, 0x2671e5a5
+0, 235834, 235834, 1024, 2048, 0x29700b7d
+0, 236858, 236858, 1024, 2048, 0x18edefcf
+0, 237882, 237882, 1024, 2048, 0xf591f1de
+0, 238906, 238906, 1024, 2048, 0xe094f445
+0, 239930, 239930, 1024, 2048, 0xec51e706
+0, 240954, 240954, 1024, 2048, 0x4d1fffe1
+0, 241978, 241978, 1024, 2048, 0xf853fcb5
+0, 243002, 243002, 1024, 2048, 0xbcfefdb0
+0, 244026, 244026, 1024, 2048, 0xbefdfcaa
+0, 245050, 245050, 1024, 2048, 0x4447e693
+0, 246074, 246074, 1024, 2048, 0x3e46f914
+0, 247098, 247098, 1024, 2048, 0x6182eddd
+0, 248122, 248122, 1024, 2048, 0xb73ef32e
+0, 249146, 249146, 1024, 2048, 0xf9a80887
+0, 250170, 250170, 1024, 2048, 0xf7d7e193
+0, 251194, 251194, 1024, 2048, 0xc6020158
+0, 252218, 252218, 1024, 2048, 0xc00cf907
+0, 253242, 253242, 1024, 2048, 0x9c67f01f
+0, 254266, 254266, 1024, 2048, 0x66c00433
+0, 255290, 255290, 1024, 2048, 0x7721ed3e
+0, 256314, 256314, 1024, 2048, 0x84c5009e
+0, 257338, 257338, 1024, 2048, 0x524e0255
+0, 258362, 258362, 1024, 2048, 0x954e6fc6
+0, 259386, 259386, 1024, 2048, 0x92ecc373
+0, 260410, 260410, 1024, 2048, 0xfa3ff0e2
+0, 261434, 261434, 1024, 2048, 0x28d4fd0f
+0, 262458, 262458, 1024, 2048, 0x499c036c
+0, 263482, 263482, 1024, 2048, 0x1b77f88f
+0, 264506, 264506, 1024, 2048, 0xd9920d25
+0, 265530, 265530, 1024, 2048, 0xe0e25c8d
diff --git a/tests/ref/fate/filter-aoverlay-timeline b/tests/ref/fate/filter-aoverlay-timeline
new file mode 100644
index 0000000000..e4113fd873
--- /dev/null
+++ b/tests/ref/fate/filter-aoverlay-timeline
@@ -0,0 +1,254 @@
+#tb 0: 1/44100
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44100
+#channel_layout_name 0: mono
+0, 0, 0, 1024, 2048, 0x490ff760
+0, 1024, 1024, 1024, 2048, 0xc8a405cb
+0, 2048, 2048, 1024, 2048, 0xeed6fd45
+0, 3072, 3072, 1024, 2048, 0x8cabf8a0
+0, 4096, 4096, 1024, 2048, 0x4707f6c1
+0, 5120, 5120, 1024, 2048, 0xc1a50038
+0, 6144, 6144, 1024, 2048, 0x3e75fa60
+0, 7168, 7168, 1024, 2048, 0x988ffec2
+0, 8192, 8192, 1024, 2048, 0x0537f926
+0, 9216, 9216, 1024, 2048, 0x6919fd71
+0, 10240, 10240, 1024, 2048, 0xeef4f7d0
+0, 11264, 11264, 1024, 2048, 0xcf7a01c8
+0, 12288, 12288, 1024, 2048, 0x2cf70048
+0, 13312, 13312, 1024, 2048, 0x8a51fba6
+0, 14336, 14336, 1024, 2048, 0x311af181
+0, 15360, 15360, 1024, 2048, 0x8248009c
+0, 16384, 16384, 1024, 2048, 0x9aa4010b
+0, 17408, 17408, 1024, 2048, 0x1a2df2a0
+0, 18432, 18432, 1024, 2048, 0xf6e2fb18
+0, 19456, 19456, 1024, 2048, 0x548effbc
+0, 20480, 20480, 1024, 2048, 0x965a01a9
+0, 21504, 21504, 1024, 2048, 0x2554f834
+0, 22528, 22528, 1024, 2048, 0xa390fdfc
+0, 23552, 23552, 1024, 2048, 0x51d8f99b
+0, 24576, 24576, 1024, 2048, 0xed47fd39
+0, 25600, 25600, 1024, 2048, 0x79b8faeb
+0, 26624, 26624, 1024, 2048, 0xf6da009c
+0, 27648, 27648, 1024, 2048, 0x0ffbf6a2
+0, 28672, 28672, 1024, 2048, 0xb6a6f823
+0, 29696, 29696, 1024, 2048, 0x5cbefcb7
+0, 30720, 30720, 1024, 2048, 0xb0eb06ea
+0, 31744, 31744, 1024, 2048, 0x5edbf7ce
+0, 32768, 32768, 1024, 2048, 0x490ff760
+0, 33792, 33792, 1024, 2048, 0xc8a405cb
+0, 34816, 34816, 1024, 2048, 0xeed6fd45
+0, 35840, 35840, 1024, 2048, 0x8cabf8a0
+0, 36864, 36864, 1024, 2048, 0x4707f6c1
+0, 37888, 37888, 1024, 2048, 0xc1a50038
+0, 38912, 38912, 1024, 2048, 0x3e75fa60
+0, 39936, 39936, 1024, 2048, 0x988ffec2
+0, 40960, 40960, 1024, 2048, 0x0537f926
+0, 41984, 41984, 1024, 2048, 0x6919fd71
+0, 43008, 43008, 1024, 2048, 0xeef4f7d0
+0, 44032, 44032, 1024, 2048, 0xee07eb41
+0, 45056, 45056, 1024, 2048, 0xd8d9f658
+0, 46080, 46080, 1024, 2048, 0x9b30051b
+0, 47104, 47104, 1024, 2048, 0x5605f37f
+0, 48128, 48128, 1024, 2048, 0x6f6afd03
+0, 49152, 49152, 1024, 2048, 0x9ca8fd97
+0, 50176, 50176, 1024, 2048, 0x37f4fe98
+0, 51200, 51200, 1024, 2048, 0x8e66fb1f
+0, 52224, 52224, 1024, 2048, 0x3268f6cf
+0, 53248, 53248, 1024, 2048, 0x4636fb46
+0, 54272, 54272, 1024, 2048, 0xb413fbd5
+0, 55296, 55296, 1024, 2048, 0xabfd08c3
+0, 56320, 56320, 1024, 2048, 0x7810f6e4
+0, 57344, 57344, 1024, 2048, 0xb59f19b5
+0, 58368, 58368, 1024, 2048, 0xd8ea0714
+0, 59392, 59392, 1024, 2048, 0xd49a00e4
+0, 60416, 60416, 1024, 2048, 0xffed0128
+0, 61440, 61440, 1024, 2048, 0x50cbec23
+0, 62464, 62464, 1024, 2048, 0xe215f92b
+0, 63488, 63488, 1024, 2048, 0xa8bb00e1
+0, 64512, 64512, 1024, 2048, 0x2b55f854
+0, 65536, 65536, 1024, 2048, 0xca1cf07e
+0, 66560, 66560, 1024, 2048, 0xd059ff29
+0, 67584, 67584, 1024, 2048, 0xdd43fcd5
+0, 68608, 68608, 1024, 2048, 0x44edfacb
+0, 69632, 69632, 1024, 2048, 0xd7bc00c0
+0, 70656, 70656, 1024, 2048, 0x459ff45b
+0, 71680, 71680, 1024, 2048, 0x11f5fed5
+0, 72704, 72704, 1024, 2048, 0x2b670370
+0, 73728, 73728, 1024, 2048, 0xe785fa99
+0, 74752, 74752, 1024, 2048, 0xf8610009
+0, 75776, 75776, 1024, 2048, 0xb8f80489
+0, 76800, 76800, 1024, 2048, 0xa1cd0ec4
+0, 77824, 77824, 1024, 2048, 0xad05fdbe
+0, 78848, 78848, 1024, 2048, 0x7d630249
+0, 79872, 79872, 1024, 2048, 0xc112f3d4
+0, 80896, 80896, 1024, 2048, 0x6ed9fc34
+0, 81920, 81920, 1024, 2048, 0xf2c0168a
+0, 82944, 82944, 1024, 2048, 0x2fc416cd
+0, 83968, 83968, 2915, 5830, 0xfb1b5d34
+0, 86883, 86883, 4410, 8820, 0xd6330e8a
+0, 91293, 91293, 1024, 2048, 0x8f07f6ee
+0, 92317, 92317, 1024, 2048, 0x50440744
+0, 93341, 93341, 1024, 2048, 0x473bf7f0
+0, 94365, 94365, 1024, 2048, 0x8c5cf82a
+0, 95389, 95389, 1024, 2048, 0xa53afdab
+0, 96413, 96413, 1024, 2048, 0x63fbfcd3
+0, 97437, 97437, 1024, 2048, 0xeb35fda7
+0, 98461, 98461, 1024, 2048, 0x4a1603a2
+0, 99485, 99485, 1024, 2048, 0xf18dfab6
+0, 100509, 100509, 1024, 2048, 0x6f99eef6
+0, 101533, 101533, 1024, 2048, 0x83840106
+0, 102557, 102557, 1024, 2048, 0x5e5a00c3
+0, 103581, 103581, 1024, 2048, 0x85d7fd23
+0, 104605, 104605, 1024, 2048, 0x0ee9f070
+0, 105629, 105629, 1024, 2048, 0xf600fb00
+0, 106653, 106653, 1024, 2048, 0x0fb80575
+0, 107677, 107677, 1024, 2048, 0x52c6017d
+0, 108701, 108701, 1024, 2048, 0x9419f127
+0, 109725, 109725, 1024, 2048, 0xa13a007d
+0, 110749, 110749, 1024, 2048, 0x717bfe33
+0, 111773, 111773, 1024, 2048, 0x44f1fab3
+0, 112797, 112797, 1024, 2048, 0x7d06fb89
+0, 113821, 113821, 1024, 2048, 0xf84dfab5
+0, 114845, 114845, 1024, 2048, 0x9899f4c9
+0, 115869, 115869, 1024, 2048, 0xf031fda6
+0, 116893, 116893, 1024, 2048, 0x74c40975
+0, 117917, 117917, 1024, 2048, 0x6495f766
+0, 118941, 118941, 1024, 2048, 0x7e85f7a7
+0, 119965, 119965, 1024, 2048, 0x589afb39
+0, 120989, 120989, 1024, 2048, 0xd21807fb
+0, 122013, 122013, 1024, 2048, 0xed82fd5c
+0, 123037, 123037, 1024, 2048, 0xd669f2f6
+0, 124061, 124061, 1024, 2048, 0x8f07f6ee
+0, 125085, 125085, 1024, 2048, 0x50440744
+0, 126109, 126109, 1024, 2048, 0x473bf7f0
+0, 127133, 127133, 1024, 2048, 0x8c5cf82a
+0, 128157, 128157, 2915, 5830, 0xf23734d4
+0, 131072, 131072, 4410, 8820, 0x84c16373
+0, 135482, 135482, 1024, 2048, 0x02adedee
+0, 136506, 136506, 1024, 2048, 0xda1e031d
+0, 137530, 137530, 1024, 2048, 0x2a940755
+0, 138554, 138554, 1024, 2048, 0xd9d20b41
+0, 139578, 139578, 1024, 2048, 0x23c2f62e
+0, 140602, 140602, 1024, 2048, 0x3bb5f531
+0, 141626, 141626, 1024, 2048, 0x57dffd27
+0, 142650, 142650, 1024, 2048, 0x48e2f322
+0, 143674, 143674, 1024, 2048, 0xd2c7f10a
+0, 144698, 144698, 1024, 2048, 0xe13afb8f
+0, 145722, 145722, 1024, 2048, 0x681a1844
+0, 146746, 146746, 1024, 2048, 0x556fea66
+0, 147770, 147770, 1024, 2048, 0xec880231
+0, 148794, 148794, 1024, 2048, 0xb826ed5a
+0, 149818, 149818, 1024, 2048, 0x43ad0045
+0, 150842, 150842, 1024, 2048, 0x469df6fc
+0, 151866, 151866, 1024, 2048, 0x6bc7eda5
+0, 152890, 152890, 1024, 2048, 0x4bf00baa
+0, 153914, 153914, 1024, 2048, 0xa14afe5a
+0, 154938, 154938, 1024, 2048, 0x4fa6eb3e
+0, 155962, 155962, 1024, 2048, 0x4080f71c
+0, 156986, 156986, 1024, 2048, 0x9478f217
+0, 158010, 158010, 1024, 2048, 0x24def107
+0, 159034, 159034, 1024, 2048, 0x11f2f63b
+0, 160058, 160058, 1024, 2048, 0xc47ffcd5
+0, 161082, 161082, 1024, 2048, 0xea590220
+0, 162106, 162106, 1024, 2048, 0xd98b0888
+0, 163130, 163130, 1024, 2048, 0x88c40856
+0, 164154, 164154, 1024, 2048, 0x817af922
+0, 165178, 165178, 1024, 2048, 0xe0100804
+0, 166202, 166202, 1024, 2048, 0xd7f3fb50
+0, 167226, 167226, 1024, 2048, 0x77e8fd45
+0, 168250, 168250, 1024, 2048, 0xe0cefaa1
+0, 169274, 169274, 1024, 2048, 0x20620151
+0, 170298, 170298, 1024, 2048, 0x97d2ff9b
+0, 171322, 171322, 1024, 2048, 0x08e2f5d4
+0, 172346, 172346, 1024, 2048, 0x0fa8fb60
+0, 173370, 173370, 1024, 2048, 0xf03fe8b5
+0, 174394, 174394, 1024, 2048, 0x39dcfcef
+0, 175418, 175418, 1024, 2048, 0x4a270176
+0, 176442, 176442, 1024, 2048, 0xbcfefdb0
+0, 177466, 177466, 1024, 2048, 0xbefdfcaa
+0, 178490, 178490, 1024, 2048, 0x4447e693
+0, 179514, 179514, 1024, 2048, 0x3e46f914
+0, 180538, 180538, 1024, 2048, 0x6182eddd
+0, 181562, 181562, 1024, 2048, 0xb73ef32e
+0, 182586, 182586, 1024, 2048, 0xf9a80887
+0, 183610, 183610, 1024, 2048, 0xf7d7e193
+0, 184634, 184634, 1024, 2048, 0xc6020158
+0, 185658, 185658, 1024, 2048, 0xc00cf907
+0, 186682, 186682, 1024, 2048, 0x9c67f01f
+0, 187706, 187706, 1024, 2048, 0x66c00433
+0, 188730, 188730, 1024, 2048, 0x7721ed3e
+0, 189754, 189754, 1024, 2048, 0x84c5009e
+0, 190778, 190778, 1024, 2048, 0x524e0255
+0, 191802, 191802, 1024, 2048, 0x954e6fc6
+0, 192826, 192826, 1024, 2048, 0x92ecc373
+0, 193850, 193850, 1024, 2048, 0xfa3ff0e2
+0, 194874, 194874, 1024, 2048, 0x28d4fd0f
+0, 195898, 195898, 1024, 2048, 0x499c036c
+0, 196922, 196922, 1024, 2048, 0x1b77f88f
+0, 197946, 197946, 1024, 2048, 0xd9920d25
+0, 198970, 198970, 1024, 2048, 0x217cf6a0
+0, 199994, 199994, 1024, 2048, 0x447dffb5
+0, 201018, 201018, 1024, 2048, 0xba7812c6
+0, 202042, 202042, 1024, 2048, 0xba09ecee
+0, 203066, 203066, 1024, 2048, 0xcdc0089d
+0, 204090, 204090, 1024, 2048, 0xed63068e
+0, 205114, 205114, 1024, 2048, 0x03b10426
+0, 206138, 206138, 1024, 2048, 0xf3e91165
+0, 207162, 207162, 1024, 2048, 0x9562f87b
+0, 208186, 208186, 1024, 2048, 0xe623fba7
+0, 209210, 209210, 1024, 2048, 0x224ffaab
+0, 210234, 210234, 1024, 2048, 0x24a8fbb2
+0, 211258, 211258, 1024, 2048, 0xa19611d8
+0, 212282, 212282, 1024, 2048, 0xa39bff48
+0, 213306, 213306, 1024, 2048, 0x8a4d0a90
+0, 214330, 214330, 1024, 2048, 0x28df053d
+0, 215354, 215354, 1024, 2048, 0xe8f6efe4
+0, 216378, 216378, 1024, 2048, 0xed9516d9
+0, 217402, 217402, 1024, 2048, 0x161bf712
+0, 218426, 218426, 1024, 2048, 0x236dff55
+0, 219450, 219450, 1024, 2048, 0x4a72084d
+0, 220474, 220474, 1024, 2048, 0x7af5f438
+0, 221498, 221498, 1024, 2048, 0x698c0b2d
+0, 222522, 222522, 1024, 2048, 0x631af7ce
+0, 223546, 223546, 1024, 2048, 0x908bf616
+0, 224570, 224570, 1024, 2048, 0xce976db2
+0, 225594, 225594, 1024, 2048, 0xa4a4bf5f
+0, 226618, 226618, 1024, 2048, 0xe8ff0789
+0, 227642, 227642, 1024, 2048, 0xbe1bfb4e
+0, 228666, 228666, 1024, 2048, 0x9bddf4ff
+0, 229690, 229690, 1024, 2048, 0xc8faffcd
+0, 230714, 230714, 1024, 2048, 0x0e63eb47
+0, 231738, 231738, 1024, 2048, 0xc13101cb
+0, 232762, 232762, 1024, 2048, 0x9d4ef8a7
+0, 233786, 233786, 1024, 2048, 0x2671e5a5
+0, 234810, 234810, 1024, 2048, 0x29700b7d
+0, 235834, 235834, 1024, 2048, 0x18edefcf
+0, 236858, 236858, 1024, 2048, 0xf591f1de
+0, 237882, 237882, 1024, 2048, 0xe094f445
+0, 238906, 238906, 1024, 2048, 0xec51e706
+0, 239930, 239930, 1024, 2048, 0x4d1fffe1
+0, 240954, 240954, 1024, 2048, 0xf853fcb5
+0, 241978, 241978, 1024, 2048, 0xbcfefdb0
+0, 243002, 243002, 1024, 2048, 0xbefdfcaa
+0, 244026, 244026, 1024, 2048, 0x4447e693
+0, 245050, 245050, 1024, 2048, 0x3e46f914
+0, 246074, 246074, 1024, 2048, 0x6182eddd
+0, 247098, 247098, 1024, 2048, 0xb73ef32e
+0, 248122, 248122, 1024, 2048, 0xf9a80887
+0, 249146, 249146, 1024, 2048, 0xf7d7e193
+0, 250170, 250170, 1024, 2048, 0xc6020158
+0, 251194, 251194, 1024, 2048, 0xc00cf907
+0, 252218, 252218, 1024, 2048, 0x9c67f01f
+0, 253242, 253242, 1024, 2048, 0x66c00433
+0, 254266, 254266, 1024, 2048, 0x7721ed3e
+0, 255290, 255290, 1024, 2048, 0x84c5009e
+0, 256314, 256314, 1024, 2048, 0x524e0255
+0, 257338, 257338, 1024, 2048, 0x954e6fc6
+0, 258362, 258362, 1024, 2048, 0x92ecc373
+0, 259386, 259386, 1024, 2048, 0xfa3ff0e2
+0, 260410, 260410, 1024, 2048, 0x28d4fd0f
+0, 261434, 261434, 1024, 2048, 0x499c036c
+0, 262458, 262458, 1024, 2048, 0x1b77f88f
+0, 263482, 263482, 1024, 2048, 0xd9920d25
+0, 264506, 264506, 1024, 2048, 0xe0e25c8d
--
2.39.3 (Apple Git-145)
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH v5 1/2] avfilter: add audio overlay filter
2024-02-01 13:01 ` [FFmpeg-devel] [PATCH v5 1/2] avfilter: add audio overlay filter Harshit Karwal
@ 2024-02-04 23:41 ` Stefano Sabatini
0 siblings, 0 replies; 4+ messages in thread
From: Stefano Sabatini @ 2024-02-04 23:41 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On date Thursday 2024-02-01 18:31:56 +0530, Harshit Karwal wrote:
> Co-authored-by: Paul B Mahol <onemda@gmail.com>
> Signed-off-by: Harshit Karwal <karwalharshit@gmail.com>
> ---
> doc/filters.texi | 40 +++
> libavfilter/Makefile | 1 +
> libavfilter/af_aoverlay.c | 548 ++++++++++++++++++++++++++++++++++++++
> libavfilter/allfilters.c | 1 +
> 4 files changed, 590 insertions(+)
> create mode 100644 libavfilter/af_aoverlay.c
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 20c91bab3a..f36ad9a2fd 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -2779,6 +2779,46 @@ This filter supports the same commands as options, excluding option @code{order}
>
> Pass the audio source unchanged to the output.
>
> +@section aoverlay
> +
> +Replace a specified section of an audio stream with another input audio stream.
> +
> +In case no @option{enable} for timeline editing is specified, the second audio stream will
> +be output at sections of the first stream which have a gap in PTS (Presentation TimeStamp) values
> +such that the output stream's PTS values are monotonous.
> +
> +This filter also supports linear cross fading when transitioning from one
> +input stream to another.
> +
> +The filter accepts the following options:
> +
> +@table @option
> +@item cf_duration
> +Set duration (in seconds) for cross fade between the inputs. Default value is @code{100} milliseconds.
> +@end table
> +
> +@subsection Examples
> +
> +@itemize
> +@item
> +Replace the first stream with the second stream from @code{t=10} seconds to @code{t=20} seconds:
> +@example
> +ffmpeg -i first.wav -i second.wav -filter_complex "aoverlay=enable='between(t,10,20)'" output.wav
> +@end example
> +
> +@item
> +Do the same as above, but with crossfading for @code{2} seconds between the streams:
> +@example
> +ffmpeg -i first.wav -i second.wav -filter_complex "aoverlay=cf_duration=2:enable='between(t,10,20)'" output.wav
> +@end example
> +
> +@item
> +Introduce a PTS gap from @code{t=4} seconds to @code{t=8} seconds in the first stream and output the second stream during this gap:
> +@example
> +ffmpeg -i first.wav -i second.wav -filter_complex "[0]aselect='not(between(t,4,8))'[temp];[temp][1]aoverlay[out]" -map "[out]" output.wav
> +@end example
> +@end itemize
> +
> @section apad
>
> Pad the end of an audio stream with silence.
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index bba0219876..0f2b403441 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -81,6 +81,7 @@ OBJS-$(CONFIG_ANLMDN_FILTER) += af_anlmdn.o
> OBJS-$(CONFIG_ANLMF_FILTER) += af_anlms.o
> OBJS-$(CONFIG_ANLMS_FILTER) += af_anlms.o
> OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o
> +OBJS-$(CONFIG_AOVERLAY_FILTER) += af_aoverlay.o
> OBJS-$(CONFIG_APAD_FILTER) += af_apad.o
> OBJS-$(CONFIG_APERMS_FILTER) += f_perms.o
> OBJS-$(CONFIG_APHASER_FILTER) += af_aphaser.o generate_wave_table.o
> diff --git a/libavfilter/af_aoverlay.c b/libavfilter/af_aoverlay.c
> new file mode 100644
> index 0000000000..8dd2d02951
> --- /dev/null
> +++ b/libavfilter/af_aoverlay.c
> @@ -0,0 +1,548 @@
> +/*
> + * Copyright (c) 2023 Harshit Karwal
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include "libavutil/opt.h"
> +#include "libavutil/audio_fifo.h"
> +
> +#include "audio.h"
> +#include "avfilter.h"
> +#include "filters.h"
> +#include "internal.h"
> +
> +typedef struct AOverlayContext {
> + const AVClass *class;
> + AVFrame *main_input;
> + AVFrame *overlay_input;
> + int64_t pts;
> + int main_eof;
> + int overlay_eof;
> +
> + int default_mode;
> + int previous_samples;
> + int64_t pts_gap;
> + int64_t previous_pts;
> + int64_t pts_gap_start;
> + int64_t pts_gap_end;
> +
> + int is_disabled;
> + int nb_channels;
> + int crossfade_ready;
> + AVAudioFifo *main_sample_buffers;
> + AVAudioFifo *overlay_sample_buffers;
> + int64_t cf_duration;
> + int64_t cf_samples;
> + void (*crossfade_samples)(uint8_t **dst, uint8_t * const *cf0,
> + uint8_t * const *cf1,
> + int nb_samples, int channels);
> +
> + int64_t transition_pts;
> + int64_t transition_pts2;
> +
> + uint8_t **cf0;
> + uint8_t **cf1;
> +} AOverlayContext;
> +
> +static const enum AVSampleFormat sample_fmts[] = {
> + AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_FLTP,
> + AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P,
> + AV_SAMPLE_FMT_NONE
> +};
> +
> +enum CrossfadeModes {
> + MODE_TIMELINE,
> + MODE_DEFAULT,
> + MODE_OVERLAY_EOF
> +};
> +
> +#define SEGMENT_SIZE 1024
> +#define OFFSET(x) offsetof(AOverlayContext, x)
> +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
> +
> +static const AVOption aoverlay_options[] = {
> + { "cf_duration", "set duration for cross fade between the inputs", OFFSET(cf_duration), AV_OPT_TYPE_DURATION, {.i64 = 100000}, 0, 60000000, FLAGS },
> + { NULL }
> +};
> +
> +AVFILTER_DEFINE_CLASS(aoverlay);
> +
> +#define CROSSFADE_PLANAR(name, type) \
> +static void crossfade_samples_## name ##p(uint8_t **dst, uint8_t * const *cf0, \
> + uint8_t * const *cf1, \
> + int nb_samples, int channels) \
> +{ \
> + for (int i = 0; i < nb_samples; i++) { \
> + double main_gain = av_clipd(1.0 * (nb_samples - 1 - i) / nb_samples, 0, 1.); \
> + double overlay_gain = av_clipd(1.0 * i / nb_samples, 0, 1.); \
> + for (int c = 0; c < channels; c++) { \
> + type *d = (type *)dst[c]; \
> + const type *s0 = (type *)cf0[c]; \
> + const type *s1 = (type *)cf1[c]; \
> + \
> + d[i] = s0[i] * main_gain + s1[i] * overlay_gain; \
> + } \
> + } \
> +}
> +
> +CROSSFADE_PLANAR(dbl, double)
> +CROSSFADE_PLANAR(flt, float)
> +CROSSFADE_PLANAR(s16, int16_t)
> +CROSSFADE_PLANAR(s32, int32_t)
> +
> +static av_cold int init(AVFilterContext *ctx)
> +{
> + AOverlayContext *s = ctx->priv;
> +
> + s->is_disabled = 1;
> + s->transition_pts = AV_NOPTS_VALUE;
> + s->transition_pts2 = AV_NOPTS_VALUE;
> +
> + return 0;
> +}
> +
> +static av_cold void uninit(AVFilterContext *ctx)
> +{
> + AOverlayContext *s = ctx->priv;
> +
> + av_audio_fifo_free(s->main_sample_buffers);
> + av_audio_fifo_free(s->overlay_sample_buffers);
> +
> + for (int i = 0; i < s->nb_channels; i++) {
> + if (s->cf0)
> + av_freep(&s->cf0[i]);
> + if (s->cf1)
> + av_freep(&s->cf1[i]);
> + }
> + av_freep(&s->cf0);
> + av_freep(&s->cf1);
> +
> + av_frame_free(&s->main_input);
> + av_frame_free(&s->overlay_input);
> +}
> +
> +static int crossfade_prepare(AOverlayContext *s, AVFilterLink *main_inlink, AVFilterLink *overlay_inlink, AVFilterLink *outlink,
> + int nb_samples, AVFrame **main_buffer, AVFrame **overlay_buffer, enum CrossfadeModes mode)
> +{
> + int ret;
> +
> + *main_buffer = ff_get_audio_buffer(outlink, nb_samples);
> + if (!(*main_buffer))
> + return AVERROR(ENOMEM);
> +
> + (*main_buffer)->pts = s->pts;
> + s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
> +
> + if ((ret = av_audio_fifo_read(s->main_sample_buffers, (void **)(*main_buffer)->extended_data, nb_samples)) < 0)
> + return ret;
> +
> + if (mode == MODE_DEFAULT) {
> + s->previous_samples = (*main_buffer)->nb_samples;
> + } else if (mode == MODE_OVERLAY_EOF || (mode == MODE_TIMELINE && s->is_disabled)) {
> + *overlay_buffer = ff_get_audio_buffer(outlink, nb_samples);
> + if (!(*overlay_buffer))
> + return AVERROR(ENOMEM);
> +
> + if ((ret = av_audio_fifo_read(s->overlay_sample_buffers, (void **)(*overlay_buffer)->extended_data, nb_samples)) < 0)
> + return ret;
> +
> + (*overlay_buffer)->pts = (*main_buffer)->pts;
> + }
> +
> + s->crossfade_ready = 1;
> +
> + return 0;
> +}
> +
> +static int crossfade_samples(AOverlayContext *s, AVFilterLink *main_inlink, AVFilterLink *overlay_inlink, AVFilterLink *outlink,
> + int nb_samples, AVFrame **out, enum CrossfadeModes mode)
> +{
> + int ret;
> +
> + *out = ff_get_audio_buffer(outlink, nb_samples);
> + if (!(*out))
> + return AVERROR(ENOMEM);
> +
> + if ((ret = av_audio_fifo_read(s->main_sample_buffers, (void **) s->cf0, nb_samples)) < 0)
> + return ret;
> +
> + if ((ret = av_audio_fifo_read(s->overlay_sample_buffers, (void **) s->cf1, nb_samples)) < 0)
> + return ret;
> +
> + if (mode == MODE_TIMELINE) {
> + s->is_disabled ? s->crossfade_samples((*out)->extended_data, s->cf1, s->cf0, nb_samples, (*out)->ch_layout.nb_channels)
> + : s->crossfade_samples((*out)->extended_data, s->cf0, s->cf1, nb_samples, (*out)->ch_layout.nb_channels);
> + } else if (mode == MODE_OVERLAY_EOF) {
> + s->crossfade_samples((*out)->extended_data, s->cf1, s->cf0, s->cf_samples, (*out)->ch_layout.nb_channels);
> + } else if (mode == MODE_DEFAULT) {
> + s->transition_pts2 != AV_NOPTS_VALUE ? s->crossfade_samples((*out)->extended_data, s->cf1, s->cf0, nb_samples, (*out)->ch_layout.nb_channels)
> + : s->crossfade_samples((*out)->extended_data, s->cf0, s->cf1, nb_samples, (*out)->ch_layout.nb_channels);
> + }
here you could split the code performing the check and the one running
the crossfade (at the end you have only two options):
int switch = (mode == MODE_TIMELINE && s->is_disabled) ||
mode == MODE_OVERLAY_EOF ||
(mode == MODE_DEFAULT && s->transition_pts2 != AV_NOPTS_VALUE);
s->crossfade_samples((*out)->extended_data,
switch ? c->cf1 : c->cf0,
switch ? c->cf0 : c->cf1,
nb_samples, (*out)->ch_layout.nb_channels);
> +
> + (*out)->pts = s->pts;
> + s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
> + s->transition_pts = AV_NOPTS_VALUE;
> + s->transition_pts2 = AV_NOPTS_VALUE;
> + s->crossfade_ready = 0;
> +
> + return 0;
> +}
> +
> +static int consume_samples(AOverlayContext *s, AVFilterLink *overlay_inlink, AVFilterLink *outlink)
> +{
> + int ret, status, nb_samples;
> + int64_t pts;
> +
> + nb_samples = FFMIN(SEGMENT_SIZE, av_audio_fifo_space(s->overlay_sample_buffers));
> +
> + ret = ff_inlink_consume_samples(overlay_inlink, nb_samples, nb_samples, &s->overlay_input);
> + if (ret < 0) {
> + return ret;
> + } else if (ff_inlink_acknowledge_status(overlay_inlink, &status, &pts)) {
> + s->overlay_eof = 1;
> + return 0;
> + } else if (!ret) {
> + if (ff_outlink_frame_wanted(outlink))
> + ff_inlink_request_frame(overlay_inlink);
> + return 0;
> + }
> +
> + ret = av_audio_fifo_write(s->overlay_sample_buffers, (void **)s->overlay_input->extended_data, nb_samples);
> + av_frame_free(&s->overlay_input);
> + if (ret < 0)
> + return ret;
> +
> + return 1;
> +}
> +
> +static int activate(AVFilterContext *ctx)
> +{
> + AOverlayContext *s = ctx->priv;
> + int status, ret, nb_samples;
> + int64_t pts;
> + AVFrame *out = NULL, *main_buffer = NULL, *overlay_buffer = NULL;
> +
> + AVFilterLink *main_inlink = ctx->inputs[0];
> + AVFilterLink *overlay_inlink = ctx->inputs[1];
> + AVFilterLink *outlink = ctx->outputs[0];
> +
> + FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);
> +
> + if (s->default_mode && (s->pts_gap_end - s->pts_gap_start <= 0 || s->overlay_eof)) {
> + s->default_mode = 0;
> + s->transition_pts2 = s->pts_gap_end;
> + }
> +
> + if (av_audio_fifo_space(s->main_sample_buffers) != 0 && !s->main_eof && !s->default_mode) {
> + nb_samples = FFMIN(SEGMENT_SIZE, av_audio_fifo_space(s->main_sample_buffers));
> +
> + ret = ff_inlink_consume_samples(main_inlink, nb_samples, nb_samples, &s->main_input);
> + if (ret > 0) {
> + if (ctx->enable_str && s->is_disabled != ctx->is_disabled && !s->overlay_eof) {
> + s->is_disabled = ctx->is_disabled;
> + s->transition_pts = s->main_input->pts;
> +
> + if (s->main_input->nb_samples < av_audio_fifo_space(s->main_sample_buffers))
> + s->crossfade_ready = 1;
> + if (av_audio_fifo_size(s->main_sample_buffers) == 0) {
> + s->transition_pts = AV_NOPTS_VALUE;
> + s->crossfade_ready = 0;
> + }
> + }
> + else if (!ctx->enable_str && !s->default_mode) {
> + if (s->previous_pts + av_rescale_q(s->previous_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base) >= s->main_input->pts) {
> + s->default_mode = 0;
> + s->previous_pts = s->main_input->pts;
> + s->previous_samples = s->main_input->nb_samples;
> + } else if (!s->overlay_eof) {
> + s->pts_gap_start = s->previous_pts;
> + if (s->pts > 0 || av_audio_fifo_size(s->main_sample_buffers) > 0)
> + s->transition_pts = s->pts_gap_start;
> + s->pts_gap_end = s->main_input->pts;
> + s->default_mode = 1;
> + }
> + }
> +
> + ret = av_audio_fifo_write(s->main_sample_buffers, (void **)s->main_input->extended_data, nb_samples);
> + av_frame_free(&s->main_input);
> + if (ret < 0)
> + return ret;
> + } else if (ret < 0) {
> + return ret;
> + } else if (ff_inlink_acknowledge_status(main_inlink, &status, &pts)) {
> + s->main_eof = 1;
> + s->crossfade_ready = 1;
> + } else if (!ret) {
> + if (ff_outlink_frame_wanted(outlink))
> + ff_inlink_request_frame(main_inlink);
> + return 0;
> + }
> + }
> +
> + if (s->main_eof && av_audio_fifo_size(s->main_sample_buffers) == 0 && ff_inlink_acknowledge_status(main_inlink, &status, &pts)) {
> + ff_outlink_set_status(outlink, status, pts);
> + return 0;
> + }
> +
> + if (av_audio_fifo_space(s->main_sample_buffers) > 0 &&
> + (s->transition_pts == AV_NOPTS_VALUE || av_audio_fifo_size(s->main_sample_buffers) != s->cf_samples) && !s->default_mode) {
> + if (ff_inlink_acknowledge_status(main_inlink, &status, &pts)) {
> + s->main_eof = 1;
> + s->crossfade_ready = 1;
> + } else {
> + ff_inlink_request_frame(main_inlink);
> + return 0;
> + }
> + }
> +
> + if (!s->overlay_eof) {
> + if (av_audio_fifo_space(s->overlay_sample_buffers) > 0) {
> + ret = consume_samples(s, overlay_inlink, outlink);
> + if (ret <= 0) {
> + if (!s->overlay_eof)
> + return ret;
nit: you can merge the two branches (if (ret <= 0 && !s->overlay_eof)...)
> + }
> + }
> +
> + if (av_audio_fifo_space(s->overlay_sample_buffers) > 0) {
> + if (ff_inlink_acknowledge_status(overlay_inlink, &status, &pts)) {
> + s->overlay_eof = 1;
> + s->transition_pts = s->pts + av_rescale_q(av_audio_fifo_size(s->overlay_sample_buffers) - (s->cf_samples / 2),
> + (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
> + s->is_disabled = 1;
> + } else {
> + ff_inlink_request_frame(overlay_inlink);
> + return 0;
> + }
> + }
> + }
> +
> + if (!ctx->enable_str) {
> + if (s->transition_pts != AV_NOPTS_VALUE && av_audio_fifo_size(s->main_sample_buffers) > s->cf_samples + SEGMENT_SIZE) {
> + nb_samples = av_audio_fifo_size(s->main_sample_buffers) + av_audio_fifo_space(s->main_sample_buffers) - s->cf_samples - SEGMENT_SIZE;
> +
> + if ((ret = crossfade_prepare(s, main_inlink, overlay_inlink, outlink, nb_samples, &main_buffer, &overlay_buffer, MODE_DEFAULT)) < 0)
> + return ret;
> +
> + return ff_filter_frame(outlink, main_buffer);
> + } else if (s->transition_pts != AV_NOPTS_VALUE || s->transition_pts2 != AV_NOPTS_VALUE) {
> + nb_samples = FFMIN(s->cf_samples, av_audio_fifo_size(s->main_sample_buffers) - SEGMENT_SIZE);
> +
> + if ((ret = crossfade_samples(s, main_inlink, overlay_inlink, outlink, nb_samples, &out, MODE_DEFAULT)) < 0)
> + return ret;
> +
> + av_log(ctx, AV_LOG_DEBUG, "PTS at stream transition: %lld\n", out->pts);
libavutil/timestamp.h to give a more friendly representation of a
timestamp, also it is not clear what this transition is about
From the point of view of the user you need to know: when the
crossfade starts, and when it finishes, when the overlay starts and
ends, and whether/when a timestamp gap was detected
> +
> + return ff_filter_frame(outlink, out);
> + } else if (!s->default_mode) {
> + nb_samples = FFMIN(av_audio_fifo_size(s->main_sample_buffers), SEGMENT_SIZE);
> +
> + main_buffer = ff_get_audio_buffer(outlink, nb_samples);
> + if (!main_buffer)
> + return AVERROR(ENOMEM);
> +
> + main_buffer->pts = s->pts;
> + s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
> +
> + if ((ret = av_audio_fifo_read(s->main_sample_buffers, (void **)main_buffer->extended_data, nb_samples)) < 0)
> + return ret;
> + }
> +
> + if (!s->default_mode || s->overlay_eof) {
> + s->previous_samples = main_buffer->nb_samples;
> + return ff_filter_frame(outlink, main_buffer);
> + }
> +
> + s->pts_gap = s->pts_gap_end - s->pts_gap_start;
> +
> + nb_samples = FFMIN(SEGMENT_SIZE, av_rescale_q(s->pts_gap, outlink->time_base, (AVRational){ 1, outlink->sample_rate }));
> +
> + overlay_buffer = ff_get_audio_buffer(outlink, nb_samples);
> + if (!overlay_buffer)
> + return AVERROR(ENOMEM);
> +
> + if ((ret = av_audio_fifo_read(s->overlay_sample_buffers, (void **)overlay_buffer->extended_data, nb_samples)) < 0)
> + return ret;
> +
> + s->previous_samples = nb_samples;
> + s->previous_pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
> + s->pts_gap_start += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
> +
> + overlay_buffer->pts = s->pts;
> + s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
the second hand is computed three times, store it in a variable and
reuse it
> +
> + av_frame_free(&main_buffer);
> +
> + return ff_filter_frame(outlink, overlay_buffer);
> + }
> +
> + if (s->overlay_eof && av_audio_fifo_size(s->overlay_sample_buffers) > 0) {
> + if (av_audio_fifo_size(s->overlay_sample_buffers) > s->cf_samples) {
> + nb_samples = av_audio_fifo_size(s->overlay_sample_buffers) - s->cf_samples;
> +
> + if ((ret = crossfade_prepare(s, main_inlink, overlay_inlink, outlink, nb_samples, &main_buffer, &overlay_buffer, MODE_OVERLAY_EOF)) < 0)
> + return ret;
> +
> + return ff_filter_frame(outlink, overlay_buffer);
> + } else if (av_audio_fifo_size(s->overlay_sample_buffers) >= s->cf_samples) {
> + if ((ret = crossfade_samples(s, main_inlink, overlay_inlink, outlink, s->cf_samples, &out, MODE_OVERLAY_EOF)) < 0)
> + return ret;
> +
> + av_log(ctx, AV_LOG_DEBUG, "PTS at stream transition: %lld\n", out->pts);
ditto
> +
> + return ff_filter_frame(outlink, out);
> + }
> + }
> +
> + if (s->transition_pts != AV_NOPTS_VALUE && !s->crossfade_ready) {
> + nb_samples = av_rescale_q(s->transition_pts - (s->cf_samples / 2) - s->pts, outlink->time_base, (AVRational) { 1, outlink->sample_rate });
> +
> + if ((ret = crossfade_prepare(s, main_inlink, overlay_inlink, outlink, nb_samples, &main_buffer, &overlay_buffer, MODE_TIMELINE)) < 0)
> + return ret;
> + } else if (s->transition_pts != AV_NOPTS_VALUE) {
> + nb_samples = s->main_eof ? av_audio_fifo_size(s->main_sample_buffers) : s->cf_samples;
> + if (s->transition_pts < av_rescale_q(s->cf_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base)) {
> + nb_samples = av_rescale_q(s->transition_pts, outlink->time_base, (AVRational){ 1, outlink->sample_rate });
> + }
> +
> + if ((ret = crossfade_samples(s, main_inlink, overlay_inlink, outlink, nb_samples, &out, MODE_TIMELINE)) < 0)
> + return ret;
> +
> + av_log(ctx, AV_LOG_DEBUG, "PTS at stream transition: %lld\n", out->pts);
ditto
> +
> + return ff_filter_frame(outlink, out);
> + } else {
> + nb_samples = FFMIN(av_audio_fifo_size(s->main_sample_buffers), SEGMENT_SIZE);
> + main_buffer = ff_get_audio_buffer(outlink, nb_samples);
> + if (!main_buffer)
> + return AVERROR(ENOMEM);
> +
> + main_buffer->pts = s->pts;
> + s->pts += av_rescale_q(nb_samples, (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
> +
> + if ((ret = av_audio_fifo_read(s->main_sample_buffers, (void **)main_buffer->extended_data, nb_samples)) < 0)
> + return ret;
> + }
> +
> + if (!ff_inlink_evaluate_timeline_at_frame(main_inlink, main_buffer) || (s->overlay_eof && av_audio_fifo_size(s->overlay_sample_buffers) == 0)) {
> + return ff_filter_frame(outlink, main_buffer);
> + } else {
> + if (s->transition_pts == AV_NOPTS_VALUE) {
> + nb_samples = FFMIN(av_audio_fifo_size(s->overlay_sample_buffers), SEGMENT_SIZE);
> + overlay_buffer = ff_get_audio_buffer(outlink, nb_samples);
> + if (!overlay_buffer)
> + return AVERROR(ENOMEM);
> +
> + if ((ret = av_audio_fifo_read(s->overlay_sample_buffers, (void **)overlay_buffer->extended_data, nb_samples)) < 0)
> + return ret;
> +
> + overlay_buffer->pts = main_buffer->pts;
> + }
> + av_frame_free(&main_buffer);
> + return ff_filter_frame(outlink, overlay_buffer);
> + }
> +}
I'm a bit concerned by the complexity of this function. I wonder if it
would make sense to split the filter in two separate ones, one for the
timeline editing and another one filling the PTS gaps. Or we might
have a "mode" option to enable one or the other behavior. It probably
does not make sense to mix the two. Would this help with simplifing
the logic?
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-02-04 23:41 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-01 13:01 [FFmpeg-devel] [PATCH v5 0/2] GSoC 2023: Add Audio Overlay Filter Harshit Karwal
2024-02-01 13:01 ` [FFmpeg-devel] [PATCH v5 1/2] avfilter: add audio overlay filter Harshit Karwal
2024-02-04 23:41 ` Stefano Sabatini
2024-02-01 13:01 ` [FFmpeg-devel] [PATCH v5 2/2] fate: Add tests for aoverlay filter Harshit Karwal
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git