mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
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/avassert.h"
|
||||||
#include "libavutil/avstring.h"
|
#include "libavutil/avstring.h"
|
||||||
#include "libavutil/channel_layout.h"
|
#include "libavutil/channel_layout.h"
|
||||||
|
#include "libavutil/fifo.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "avfilter.h"
|
#include "avfilter.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
typedef struct MetaItem {
|
||||||
|
int64_t pts;
|
||||||
|
int nb_samples;
|
||||||
|
} MetaItem;
|
||||||
|
|
||||||
typedef struct LADSPAContext {
|
typedef struct LADSPAContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
char *dl_name;
|
char *dl_name;
|
||||||
@ -69,6 +75,8 @@ typedef struct LADSPAContext {
|
|||||||
int in_trim;
|
int in_trim;
|
||||||
int out_pad;
|
int out_pad;
|
||||||
int latency;
|
int latency;
|
||||||
|
|
||||||
|
AVFifo *fifo;
|
||||||
} LADSPAContext;
|
} LADSPAContext;
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(LADSPAContext, x)
|
#define OFFSET(x) offsetof(LADSPAContext, x)
|
||||||
@ -169,6 +177,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
|||||||
int64_t out_duration;
|
int64_t out_duration;
|
||||||
int64_t in_duration;
|
int64_t in_duration;
|
||||||
int64_t in_pts;
|
int64_t in_pts;
|
||||||
|
MetaItem meta;
|
||||||
|
|
||||||
av_assert0(in->ch_layout.nb_channels == (s->nb_inputs * s->nb_handles));
|
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++)
|
for (i = 0; i < s->nb_outputcontrols; i++)
|
||||||
print_ctl_info(ctx, AV_LOG_VERBOSE, s, i, s->ocmap, s->octlv, 1);
|
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));
|
meta = (MetaItem){ in->pts, in->nb_samples };
|
||||||
in_pts = in->pts;
|
av_fifo_write(s->fifo, &meta, 1);
|
||||||
|
|
||||||
if (out != in)
|
if (out != in)
|
||||||
av_frame_free(&in);
|
av_frame_free(&in);
|
||||||
|
|
||||||
@ -235,9 +245,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
|||||||
out->nb_samples = new_out_samples;
|
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));
|
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 &&
|
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;
|
out->pts = s->next_out_pts;
|
||||||
} else {
|
} else {
|
||||||
out->pts = in_pts;
|
out->pts = in_pts;
|
||||||
@ -676,6 +691,10 @@ static av_cold int init(AVFilterContext *ctx)
|
|||||||
s->next_out_pts = AV_NOPTS_VALUE;
|
s->next_out_pts = AV_NOPTS_VALUE;
|
||||||
s->next_in_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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,6 +794,8 @@ static av_cold void uninit(AVFilterContext *ctx)
|
|||||||
av_freep(&s->octlv);
|
av_freep(&s->octlv);
|
||||||
av_freep(&s->handles);
|
av_freep(&s->handles);
|
||||||
av_freep(&s->ctl_needs_value);
|
av_freep(&s->ctl_needs_value);
|
||||||
|
|
||||||
|
av_fifo_freep2(&s->fifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
|
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user