avfilter/af_ladspa: fix pts compensation if number of samples per frame is lower than latency

This commit is contained in:
Paul B Mahol 2022-04-07 09:35:57 +02:00
parent 4fbf3c828b
commit 55d414829c
1 changed files with 24 additions and 3 deletions

View File

@ -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,