From 45d1510e4e9fcaeb5781c78f7927555b569079cd Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 10 Nov 2013 23:17:04 +0100 Subject: af_lavrresample: add support for non-interleaved audio --- audio/filter/af_lavrresample.c | 72 ++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 27 deletions(-) (limited to 'audio') diff --git a/audio/filter/af_lavrresample.c b/audio/filter/af_lavrresample.c index a6abd32aed..8c7a7543fa 100644 --- a/audio/filter/af_lavrresample.c +++ b/audio/filter/af_lavrresample.c @@ -24,6 +24,8 @@ #include #include #include +#include + #include #include #include @@ -244,10 +246,8 @@ static int control(struct af_instance *af, int cmd, void *arg) if (af_to_avformat(in->format) == AV_SAMPLE_FMT_NONE) mp_audio_set_format(in, AF_FORMAT_FLOAT_NE); - mp_audio_force_interleaved_format(in); if (af_to_avformat(out->format) == AV_SAMPLE_FMT_NONE) mp_audio_set_format(out, in->format); - mp_audio_force_interleaved_format(out); af->mul = (double) (out->rate * out->nch) / (in->rate * in->nch); af->delay = out->nch * s->opts.filter_size / FFMIN(af->mul, 1); @@ -301,38 +301,51 @@ static bool needs_reorder(int *reorder, int num_ch) return false; } +static void reorder_planes(struct mp_audio *mpa, int *reorder) +{ + struct mp_audio prev = *mpa; + for (int n = 0; n < mpa->num_planes; n++) { + assert(reorder[n] >= 0 && reorder[n] < mpa->num_planes); + mpa->planes[n] = prev.planes[reorder[n]]; + } +} + +#if !USE_SET_CHANNEL_MAPPING +static void do_reorder(struct mp_audio *mpa, int *reorder) +{ + if (af_fmt_is_planar(mpa->format)) { + reorder_planes(mpa, reorder); + } else { + reorder_channels(mpa->planes[0], reorder, mpa->bps, mpa->nch, mpa->samples); + } +} +#endif + static struct mp_audio *play(struct af_instance *af, struct mp_audio *data) { struct af_resample *s = af->priv; struct mp_audio *in = data; struct mp_audio *out = af->data; - - int in_samples = data->samples; - int in_size = data->samples * data->sstride; - int out_samples = avresample_available(s->avrctx) + - av_rescale_rnd(get_delay(s) + in_samples, + out->samples = avresample_available(s->avrctx) + + av_rescale_rnd(get_delay(s) + in->samples, s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP); - int out_size = out_samples * out->sstride; - if (talloc_get_size(out->planes[0]) < out_size) - out->planes[0] = talloc_realloc_size(out, out->planes[0], out_size); + mp_audio_realloc_min(out, out->samples); af->delay = out->bps * av_rescale_rnd(get_delay(s), s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP); -#if USE_SET_CHANNEL_MAPPING - (void)in_size; -#else - reorder_channels(data->planes[0], s->reorder_in, data->bps, data->nch, in_samples); +#if !USE_SET_CHANNEL_MAPPING + do_reorder(in, s->reorder_in); #endif - if (out_samples) { - out_samples = avresample_convert(s->avrctx, - (uint8_t **) out->planes, out_size, out_samples, - (uint8_t **) in->planes, in_size, in_samples); - if (out_samples < 0) + if (out->samples) { + out->samples = avresample_convert(s->avrctx, + (uint8_t **) out->planes, out->samples * out->sstride, out->samples, + (uint8_t **) in->planes, in->samples * in->sstride, in->samples); + if (out->samples < 0) return NULL; // error } @@ -340,18 +353,23 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data) #if USE_SET_CHANNEL_MAPPING if (needs_reorder(s->reorder_out, out->nch)) { - if (talloc_get_size(s->reorder_buffer) < out_size) - s->reorder_buffer = talloc_realloc_size(s, s->reorder_buffer, out_size); - data->planes[0] = s->reorder_buffer; - out_samples = avresample_convert(s->avrctx_out, - (uint8_t **) data->planes, out_size, out_samples, - (uint8_t **) out->planes, out_size, out_samples); + if (af_fmt_is_planar(out->format)) { + reorder_planes(data, s->reorder_out); + } else { + int out_size = out->samples * out->sstride; + if (talloc_get_size(s->reorder_buffer) < out_size) + s->reorder_buffer = talloc_realloc_size(s, s->reorder_buffer, out_size); + data->planes[0] = s->reorder_buffer; + int out_samples = avresample_convert(s->avrctx_out, + (uint8_t **) data->planes, out_size, out->samples, + (uint8_t **) out->planes, out_size, out->samples); + assert(out_samples == data->samples); + } } #else - reorder_channels(data->planes[0], s->reorder_out, out->bps, out->nch, out_samples); + do_reorder(data, s->reorder_out); #endif - data->samples = out_samples; return data; } -- cgit v1.2.3