summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-05-09 14:15:26 +0200
committerwm4 <wm4@nowhere>2013-05-12 21:24:56 +0200
commit5c0c141a55b1c2928119cb1cfc604ca77013725d (patch)
tree409ad44384a369d83278b38dfb98a43403c83db6 /audio
parent9d1f5e8e9f16737b732918a8924c23ee70886db5 (diff)
downloadmpv-5c0c141a55b1c2928119cb1cfc604ca77013725d.tar.bz2
mpv-5c0c141a55b1c2928119cb1cfc604ca77013725d.tar.xz
af_lavrresample: avoid channel reordering with unknown layouts
If one of the input or output is an unknown layout, but the other is known, it can still happen that channels are remixed randomly. Avoid this by forcing default layouts in this case. (Doesn't work if the channel counts are different.)
Diffstat (limited to 'audio')
-rw-r--r--audio/filter/af_lavrresample.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/audio/filter/af_lavrresample.c b/audio/filter/af_lavrresample.c
index 3fc2b46fb1..4372100ea0 100644
--- a/audio/filter/af_lavrresample.c
+++ b/audio/filter/af_lavrresample.c
@@ -76,7 +76,6 @@ struct af_resample {
// At least libswresample keeps a pointer around for this:
int reorder_in[MP_NUM_CHANNELS];
int reorder_out[MP_NUM_CHANNELS];
- bool need_reorder_out;
uint8_t *reorder_buffer;
};
@@ -174,9 +173,18 @@ static int control(struct af_instance *af, int cmd, void *arg)
s->ctx.linear = s->opts.linear;
s->ctx.cutoff = s->opts.cutoff;
- // unchecked: don't take channel reordering into account
- uint64_t in_ch_layout = mp_chmap_to_lavc_unchecked(&in->channels);
- uint64_t out_ch_layout = mp_chmap_to_lavc_unchecked(&out->channels);
+ struct mp_chmap map_in = in->channels;
+ struct mp_chmap map_out = out->channels;
+
+ // Try not to do any remixing if at least one is "unknown".
+ if (mp_chmap_is_unknown(&map_in) || mp_chmap_is_unknown(&map_out)) {
+ mp_chmap_set_unknown(&map_in, map_in.num);
+ mp_chmap_set_unknown(&map_out, map_out.num);
+ }
+
+ // unchecked: don't take any channel reordering into account
+ uint64_t in_ch_layout = mp_chmap_to_lavc_unchecked(&map_in);
+ uint64_t out_ch_layout = mp_chmap_to_lavc_unchecked(&map_out);
ctx_opt_set_int("in_channel_layout", in_ch_layout);
ctx_opt_set_int("out_channel_layout", out_ch_layout);
@@ -195,12 +203,11 @@ static int control(struct af_instance *af, int cmd, void *arg)
struct mp_chmap in_lavc;
mp_chmap_from_lavc(&in_lavc, in_ch_layout);
- mp_chmap_get_reorder(s->reorder_in, &in->channels, &in_lavc);
+ mp_chmap_get_reorder(s->reorder_in, &map_in, &in_lavc);
struct mp_chmap out_lavc;
mp_chmap_from_lavc(&out_lavc, out_ch_layout);
- mp_chmap_get_reorder(s->reorder_out, &out_lavc, &out->channels);
- s->need_reorder_out = !mp_chmap_equals(&out_lavc, &out->channels);
+ mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out);
// Same configuration; we just reorder.
av_opt_set_int(s->avrctx_out, "in_channel_layout", out_ch_layout, 0);
@@ -285,6 +292,15 @@ static void uninit(struct af_instance *af)
}
}
+static bool needs_reorder(int *reorder, int num_ch)
+{
+ for (int n = 0; n < num_ch; n++) {
+ if (reorder[n] != n)
+ return true;
+ }
+ return false;
+}
+
static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
{
struct af_resample *s = af->setup;
@@ -312,7 +328,7 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
*data = *out;
- if (s->need_reorder_out) {
+ 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->audio = s->reorder_buffer;