From 55d414829c601ec5482be61aa327c22f0f602fe1 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 7 Apr 2022 09:35:57 +0200 Subject: [PATCH] avfilter/af_ladspa: fix pts compensation if number of samples per frame is lower than latency --- libavfilter/af_ladspa.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/libavfilter/af_ladspa.c b/libavfilter/af_ladspa.c index bf51b372ff..1c3ede2ee2 100644 --- a/libavfilter/af_ladspa.c +++ b/libavfilter/af_ladspa.c @@ -29,11 +29,17 @@ #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/channel_layout.h" +#include "libavutil/fifo.h" #include "libavutil/opt.h" #include "audio.h" #include "avfilter.h" #include "internal.h" +typedef struct MetaItem { + int64_t pts; + int nb_samples; +} MetaItem; + typedef struct LADSPAContext { const AVClass *class; char *dl_name; @@ -69,6 +75,8 @@ typedef struct LADSPAContext { int in_trim; int out_pad; int latency; + + AVFifo *fifo; } LADSPAContext; #define OFFSET(x) offsetof(LADSPAContext, x) @@ -169,6 +177,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) int64_t out_duration; int64_t in_duration; int64_t in_pts; + MetaItem meta; av_assert0(in->ch_layout.nb_channels == (s->nb_inputs * s->nb_handles)); @@ -210,8 +219,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) for (i = 0; i < s->nb_outputcontrols; i++) print_ctl_info(ctx, AV_LOG_VERBOSE, s, i, s->ocmap, s->octlv, 1); - in_duration = av_rescale_q(in->nb_samples, inlink->time_base, av_make_q(1, in->sample_rate)); - in_pts = in->pts; + meta = (MetaItem){ in->pts, in->nb_samples }; + av_fifo_write(s->fifo, &meta, 1); + if (out != in) av_frame_free(&in); @@ -235,9 +245,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) out->nb_samples = new_out_samples; } + av_fifo_read(s->fifo, &meta, 1); + out_duration = av_rescale_q(out->nb_samples, inlink->time_base, av_make_q(1, out->sample_rate)); + in_duration = av_rescale_q(meta.nb_samples, inlink->time_base, av_make_q(1, out->sample_rate)); + in_pts = meta.pts; + if (s->next_out_pts != AV_NOPTS_VALUE && out->pts != s->next_out_pts && - s->next_in_pts != AV_NOPTS_VALUE && out->pts == s->next_in_pts) { + s->next_in_pts != AV_NOPTS_VALUE && in_pts == s->next_in_pts) { out->pts = s->next_out_pts; } else { out->pts = in_pts; @@ -676,6 +691,10 @@ static av_cold int init(AVFilterContext *ctx) s->next_out_pts = AV_NOPTS_VALUE; s->next_in_pts = AV_NOPTS_VALUE; + s->fifo = av_fifo_alloc2(8, sizeof(MetaItem), AV_FIFO_FLAG_AUTO_GROW); + if (!s->fifo) + return AVERROR(ENOMEM); + return 0; } @@ -775,6 +794,8 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&s->octlv); av_freep(&s->handles); av_freep(&s->ctl_needs_value); + + av_fifo_freep2(&s->fifo); } static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,