mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/af_ladspa: fix pts compensation if number of samples per frame is lower than latency
This commit is contained in:
parent
4fbf3c828b
commit
55d414829c
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue