summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-10 23:17:04 +0100
committerwm4 <wm4@nowhere>2013-11-12 23:16:31 +0100
commit45d1510e4e9fcaeb5781c78f7927555b569079cd (patch)
tree8f454ff63c856a4062c4f433071bd34b11fde4ff /audio
parentbf60281ffb6f47986fa6ef9ee559689be0075050 (diff)
downloadmpv-45d1510e4e9fcaeb5781c78f7927555b569079cd.tar.bz2
mpv-45d1510e4e9fcaeb5781c78f7927555b569079cd.tar.xz
af_lavrresample: add support for non-interleaved audio
Diffstat (limited to 'audio')
-rw-r--r--audio/filter/af_lavrresample.c72
1 files changed, 45 insertions, 27 deletions
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 <stdlib.h>
#include <string.h>
#include <inttypes.h>
+#include <assert.h>
+
#include <libavutil/opt.h>
#include <libavutil/audioconvert.h>
#include <libavutil/common.h>
@@ -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;
}