summaryrefslogtreecommitdiffstats
path: root/audio/filter/af_lavfi.c
diff options
context:
space:
mode:
Diffstat (limited to 'audio/filter/af_lavfi.c')
-rw-r--r--audio/filter/af_lavfi.c66
1 files changed, 28 insertions, 38 deletions
diff --git a/audio/filter/af_lavfi.c b/audio/filter/af_lavfi.c
index 3c6d981f1d..24ff8c5985 100644
--- a/audio/filter/af_lavfi.c
+++ b/audio/filter/af_lavfi.c
@@ -58,14 +58,7 @@ struct priv {
AVFilterContext *in;
AVFilterContext *out;
- // Guarantee that the data stays valid until next filter call
- char *out_buffer;
-
- struct mp_audio data;
- struct mp_audio temp;
-
- int64_t bytes_in;
- int64_t bytes_out;
+ int64_t samples_in;
AVRational timebase_out;
@@ -129,6 +122,8 @@ static bool recreate_graph(struct af_instance *af, struct mp_audio *config)
static const enum AVSampleFormat sample_fmts[] = {
AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL,
+ AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P,
+ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP,
AV_SAMPLE_FMT_NONE
};
r = av_opt_set_int_list(out, "sample_fmts", sample_fmts,
@@ -202,7 +197,8 @@ static int control(struct af_instance *af, int cmd, void *arg)
p->timebase_out = l_out->time_base;
- af->mul = (double) (out->rate * out->nch) / (in->rate * in->nch);
+ // Blatantly incorrect; we don't know what the filters do.
+ af->mul = out->rate / (double)in->rate;
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
}
@@ -218,28 +214,25 @@ static int control(struct af_instance *af, int cmd, void *arg)
static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
{
struct priv *p = af->priv;
+ struct mp_audio *r = af->data;
AVFilterLink *l_in = p->in->outputs[0];
- struct mp_audio *r = &p->temp;
- *r = *af->data;
-
- int in_frame_size = data->bps * data->channels.num;
- int out_frame_size = r->bps * r->channels.num;
-
AVFrame *frame = av_frame_alloc();
- frame->nb_samples = data->len / in_frame_size;
+ frame->nb_samples = data->samples;
frame->format = l_in->format;
// Timebase is 1/sample_rate
- frame->pts = p->bytes_in / in_frame_size;
+ frame->pts = p->samples_in;
av_frame_set_channels(frame, l_in->channels);
av_frame_set_channel_layout(frame, l_in->channel_layout);
av_frame_set_sample_rate(frame, l_in->sample_rate);
- frame->data[0] = data->audio;
frame->extended_data = frame->data;
+ for (int n = 0; n < data->num_planes; n++)
+ frame->data[n] = data->planes[n];
+ frame->linesize[0] = frame->nb_samples * data->sstride;
if (av_buffersrc_add_frame(p->in, frame) < 0) {
av_frame_free(&frame);
@@ -248,7 +241,7 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
av_frame_free(&frame);
int64_t out_pts = AV_NOPTS_VALUE;
- size_t out_len = 0;
+ r->samples = 0;
for (;;) {
frame = av_frame_alloc();
if (av_buffersink_get_frame(p->out, frame) < 0) {
@@ -257,36 +250,32 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
break;
}
- size_t new_len = out_len + frame->nb_samples * out_frame_size;
- if (new_len > talloc_get_size(p->out_buffer))
- p->out_buffer = talloc_realloc(p, p->out_buffer, char, new_len);
- memcpy(p->out_buffer + out_len, frame->data[0], new_len - out_len);
- out_len = new_len;
+ mp_audio_realloc_min(r, r->samples + frame->nb_samples);
+ for (int n = 0; n < r->num_planes; n++) {
+ memcpy((char *)r->planes[n] + r->samples * r->sstride,
+ frame->extended_data[n], frame->nb_samples * r->sstride);
+ }
+ r->samples += frame->nb_samples;
+
if (out_pts == AV_NOPTS_VALUE)
out_pts = frame->pts;
av_frame_free(&frame);
}
- r->audio = p->out_buffer;
- r->len = out_len;
-
- p->bytes_in += data->len;
- p->bytes_out += r->len;
+ p->samples_in += data->samples;
if (out_pts != AV_NOPTS_VALUE) {
- int64_t num_in_frames = p->bytes_in / in_frame_size;
- double in_time = num_in_frames / (double)data->rate;
-
+ double in_time = p->samples_in / (double)data->rate;
double out_time = out_pts * av_q2d(p->timebase_out);
// Need pts past the last output sample.
- int out_frames = r->len / out_frame_size;
- out_time += out_frames / (double)r->rate;
+ out_time += r->samples / (double)r->rate;
- af->delay = (in_time - out_time) * r->rate * out_frame_size;
+ af->delay = in_time - out_time;
}
- return r;
+ *data = *r;
+ return data;
}
static void uninit(struct af_instance *af)
@@ -298,9 +287,10 @@ static int af_open(struct af_instance *af)
af->control = control;
af->uninit = uninit;
af->play = play;
- af->mul = 1;
struct priv *priv = af->priv;
- af->data = &priv->data;
+ af->data = talloc_zero(priv, struct mp_audio),
+ // Removing this requires fixing AVFrame.data vs. AVFrame.extended_data
+ assert(MP_NUM_CHANNELS <= AV_NUM_DATA_POINTERS);
return AF_OK;
}