From: Stefano Sabatini <stefasab@gmail.com> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: Re: [FFmpeg-devel] [PATCH v4 1/2] avfilter: add audio overlay filter Date: Mon, 22 Jan 2024 02:20:06 +0100 Message-ID: <Za3CxtBpECST8Y5X@mariano> (raw) In-Reply-To: <20240116121643.74916-2-karwalharshit@gmail.com> On date Tuesday 2024-01-16 17:46:42 +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 | 538 ++++++++++++++++++++++++++++++++++++++ > libavfilter/allfilters.c | 1 + > 4 files changed, 580 insertions(+) > create mode 100644 libavfilter/af_aoverlay.c > > diff --git a/doc/filters.texi b/doc/filters.texi > index 20c91bab3a..79eb600ae3 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 enable option for timeline editing is specified, the second audio stream will nit: @option{enable} > +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 option: nit: options in case we add more > + > +@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..f7ac00dda1 > --- /dev/null > +++ b/libavfilter/af_aoverlay.c [...] > +static int crossfade_prepare(AOverlayContext *s, AVFilterLink *main_inlink, AVFilterLink *overlay_inlink, AVFilterLink *outlink, > + int nb_samples, AVFrame **main_buffer, AVFrame **overlay_buffer, int 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 == 1) { > + s->previous_samples = (*main_buffer)->nb_samples; > + } else if (mode == -1 || (mode == 0 && s->is_disabled)) { it would help to use an enum to describe the mode value Also would help to introduce some debug log messages to aid troubleshooting/debugging. For instance, it would be very useful to show the exact time when the overlay stream is inserted. [...] > +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; > + } > + } > + if (!ctx->enable_str && !s->default_mode) { nit: else if to avoid this evaluation in case the first block is executed [...] > + > +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); > + else > + s->cf_samples = av_rescale(100000, outlink->sample_rate, AV_TIME_BASE); is this needed? shouldn't the duration be set also for the default case? [...] Thanks _______________________________________________ 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".
next prev parent reply other threads:[~2024-01-22 1:20 UTC|newest] Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-01-16 12:16 [FFmpeg-devel] [PATCH v4 0/2] GSoC 2023: Add Audio Overlay Filter Harshit Karwal 2024-01-16 12:16 ` [FFmpeg-devel] [PATCH v4 1/2] avfilter: add audio overlay filter Harshit Karwal 2024-01-22 1:20 ` Stefano Sabatini [this message] 2024-01-16 12:16 ` [FFmpeg-devel] [PATCH v4 2/2] fate: Add tests for aoverlay filter Harshit Karwal 2024-01-21 16:44 ` [FFmpeg-devel] [PATCH v4 0/2] GSoC 2023: Add Audio Overlay Filter Harshit Karwal
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=Za3CxtBpECST8Y5X@mariano \ --to=stefasab@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
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