summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-04-05 20:39:52 +0200
committerwm4 <wm4@nowhere>2013-05-12 21:24:54 +0200
commit7971bb87cb46f90152913de6ac673ae3bd1637a3 (patch)
tree7929e829c5960425270f4f0c017d84c37872ac5b /audio
parentf7a427676c0fe3c12509e3d9a243301f93626b0a (diff)
downloadmpv-7971bb87cb46f90152913de6ac673ae3bd1637a3.tar.bz2
mpv-7971bb87cb46f90152913de6ac673ae3bd1637a3.tar.xz
af: use mp_chmap for mp_audio, include channel map in format negotiation
Now af_lavrresample pretends to reorder the channels, although it doesn't yet, and nothing sets non-standard layouts either.
Diffstat (limited to 'audio')
-rw-r--r--audio/audio.c22
-rw-r--r--audio/audio.h6
-rw-r--r--audio/filter/af.c15
-rw-r--r--audio/filter/af_center.c2
-rw-r--r--audio/filter/af_channels.c15
-rw-r--r--audio/filter/af_format.c2
-rw-r--r--audio/filter/af_hrtf.c12
-rw-r--r--audio/filter/af_lavcac3enc.c6
-rw-r--r--audio/filter/af_lavrresample.c33
-rw-r--r--audio/filter/af_sub.c2
-rw-r--r--audio/filter/af_surround.c4
-rw-r--r--audio/filter/af_tools.c2
12 files changed, 64 insertions, 57 deletions
diff --git a/audio/audio.c b/audio/audio.c
index 04ebe390b8..549553184d 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -27,12 +27,30 @@ void mp_audio_set_format(struct mp_audio *mpa, int format)
void mp_audio_set_num_channels(struct mp_audio *mpa, int num_channels)
{
- mpa->nch = num_channels;
+ struct mp_chmap map;
+ mp_chmap_from_channels(&map, num_channels);
+ mp_audio_set_channels(mpa, &map);
+}
+
+// Use old MPlayer/ALSA channel layout.
+void mp_audio_set_channels_old(struct mp_audio *mpa, int num_channels)
+{
+ struct mp_chmap map;
+ mp_chmap_from_channels(&map, num_channels);
+ mp_chmap_reorder_to_alsa(&map);
+ mp_audio_set_channels(mpa, &map);
+}
+
+void mp_audio_set_channels(struct mp_audio *mpa, const struct mp_chmap *chmap)
+{
+ assert(mp_chmap_is_empty(chmap) || mp_chmap_is_valid(chmap));
+ mpa->channels = *chmap;
+ mpa->nch = mpa->channels.num;
}
void mp_audio_copy_config(struct mp_audio *dst, const struct mp_audio *src)
{
mp_audio_set_format(dst, src->format);
- mp_audio_set_num_channels(dst, src->nch);
+ mp_audio_set_channels(dst, &src->channels);
dst->rate = src->rate;
}
diff --git a/audio/audio.h b/audio/audio.h
index f39069cf73..902b5a1b40 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -19,20 +19,24 @@
#define MP_AUDIO_H
#include "format.h"
+#include "chmap.h"
// Audio data chunk
struct mp_audio {
void *audio; // data buffer
int len; // buffer length (in bytes)
int rate; // sample rate
- int nch; // number of channels, use mp_audio_set_channels() to set
+ struct mp_chmap channels; // channel layout, use mp_audio_set_*() to set
int format; // format (AF_FORMAT_...), use mp_audio_set_format() to set
// Redundant fields, for convenience
+ int nch; // number of channels (redundant with chmap)
int bps; // bytes per sample (redundant with format)
};
void mp_audio_set_format(struct mp_audio *mpa, int format);
void mp_audio_set_num_channels(struct mp_audio *mpa, int num_channels);
+void mp_audio_set_channels_old(struct mp_audio *mpa, int num_channels);
+void mp_audio_set_channels(struct mp_audio *mpa, const struct mp_chmap *chmap);
void mp_audio_copy_config(struct mp_audio *dst, const struct mp_audio *src);
#endif
diff --git a/audio/filter/af.c b/audio/filter/af.c
index 4d2e5e3ac3..3bc9ae764d 100644
--- a/audio/filter/af.c
+++ b/audio/filter/af.c
@@ -84,7 +84,7 @@ static struct af_info* filter_list[] = {
static bool af_config_equals(struct mp_audio *a, struct mp_audio *b)
{
return a->format == b->format
- && a->nch == b->nch
+ && mp_chmap_equals(&a->channels, &b->channels)
&& a->rate == b->rate;
}
@@ -93,7 +93,7 @@ static void af_copy_unset_fields(struct mp_audio *dst, struct mp_audio *src)
if (dst->format == AF_FORMAT_UNKNOWN)
mp_audio_set_format(dst, src->format);
if (dst->nch == 0)
- dst->nch = src->nch;
+ mp_audio_set_channels(dst, &src->channels);
if (dst->rate == 0)
dst->rate = src->rate;
}
@@ -304,8 +304,11 @@ repeat:
static void print_fmt(struct mp_audio *d)
{
if (d) {
- mp_msg(MSGT_AFILTER, MSGL_V, "%dHz/%dch/%s", d->rate, d->nch,
+ char *chstr = mp_chmap_to_str(&d->channels);
+ mp_msg(MSGT_AFILTER, MSGL_V, "%dHz/%s(%dch)/%s", d->rate,
+ chstr ? chstr : "?", d->nch,
af_fmt2str_short(d->format));
+ talloc_free(chstr);
} else
mp_msg(MSGT_AFILTER, MSGL_V, "(?)");
}
@@ -386,9 +389,9 @@ static int af_fix_channels(struct af_stream *s, struct af_instance **p_af,
struct af_instance *af = *p_af;
struct af_instance *prev = af->prev;
struct mp_audio actual = *prev->data;
- if (actual.nch == in.nch)
+ if (mp_chmap_equals(&actual.channels, &in.channels))
return AF_FALSE;
- if (prev->control(prev, AF_CONTROL_CHANNELS, &in.nch) == AF_OK) {
+ if (prev->control(prev, AF_CONTROL_CHANNELS, &in.channels) == AF_OK) {
*p_af = prev;
return AF_OK;
}
@@ -397,7 +400,7 @@ static int af_fix_channels(struct af_stream *s, struct af_instance **p_af,
if (new == NULL)
return AF_ERROR;
new->auto_inserted = true;
- if (AF_OK != (rv = new->control(new, AF_CONTROL_CHANNELS, &in.nch)))
+ if (AF_OK != (rv = new->control(new, AF_CONTROL_CHANNELS, &in.channels)))
return rv;
*p_af = new;
return AF_OK;
diff --git a/audio/filter/af_center.c b/audio/filter/af_center.c
index f92cefd335..42571eea35 100644
--- a/audio/filter/af_center.c
+++ b/audio/filter/af_center.c
@@ -48,7 +48,7 @@ static int control(struct af_instance* af, int cmd, void* arg)
if(!arg) return AF_ERROR;
af->data->rate = ((struct mp_audio*)arg)->rate;
- mp_audio_set_num_channels(af->data, max(s->ch+1,((struct mp_audio*)arg)->nch));
+ mp_audio_set_channels_old(af->data, max(s->ch+1,((struct mp_audio*)arg)->nch));
mp_audio_set_format(af->data, AF_FORMAT_FLOAT_NE);
return af_test_output(af,(struct mp_audio*)arg);
diff --git a/audio/filter/af_channels.c b/audio/filter/af_channels.c
index f6369936d6..7955018ec0 100644
--- a/audio/filter/af_channels.c
+++ b/audio/filter/af_channels.c
@@ -193,21 +193,16 @@ static int control(struct af_instance* af, int cmd, void* arg)
}
}
- if(AF_OK != af->control(af,AF_CONTROL_CHANNELS | AF_CONTROL_SET ,&nch))
+ struct mp_chmap chmap;
+ mp_chmap_from_channels(&chmap, nch);
+ if (AF_OK != af->control(af, AF_CONTROL_CHANNELS | AF_CONTROL_SET, &chmap))
return AF_ERROR;
return AF_OK;
}
case AF_CONTROL_CHANNELS | AF_CONTROL_SET:
// Reinit must be called after this function has been called
- // Sanity check
- if(((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH){
- mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] The number of output channels must be"
- " between 1 and %i. Current value is %i\n",AF_NCH,((int*)arg)[0]);
- return AF_ERROR;
- }
-
- mp_audio_set_num_channels(af->data, ((int*)arg)[0]);
+ mp_audio_set_channels(af->data, (struct mp_chmap *)arg);
if(!s->router)
mp_msg(MSGT_AFILTER, MSGL_V, "[channels] Changing number of channels"
" to %i\n",af->data->nch);
@@ -247,7 +242,7 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data)
// Set output data
c->audio = l->audio;
c->len = c->len / c->nch * l->nch;
- mp_audio_set_num_channels(c, l->nch);
+ mp_audio_set_channels(c, &l->channels);
return c;
}
diff --git a/audio/filter/af_format.c b/audio/filter/af_format.c
index 5988d25118..616bc9e494 100644
--- a/audio/filter/af_format.c
+++ b/audio/filter/af_format.c
@@ -120,7 +120,7 @@ static int control(struct af_instance* af, int cmd, void* arg)
buf1, buf2);
af->data->rate = data->rate;
- mp_audio_set_num_channels(af->data, data->nch);
+ mp_audio_set_channels(af->data, &data->channels);
af->mul = (double)af->data->bps / data->bps;
af->play = play; // set default
diff --git a/audio/filter/af_hrtf.c b/audio/filter/af_hrtf.c
index 1e3244e2eb..85e6477b31 100644
--- a/audio/filter/af_hrtf.c
+++ b/audio/filter/af_hrtf.c
@@ -31,8 +31,6 @@
#include "af.h"
#include "dsp.h"
-#include "audio/reorder_ch.h"
-
/* HRTF filter coefficients and adjustable parameters */
#include "af_hrtf.h"
@@ -301,7 +299,7 @@ static int control(struct af_instance *af, int cmd, void* arg)
af->data->rate);
return AF_ERROR;
}
- mp_audio_set_num_channels(af->data, ((struct mp_audio*)arg)->nch);
+ mp_audio_set_channels_old(af->data, ((struct mp_audio*)arg)->nch);
if(af->data->nch == 2) {
/* 2 channel input */
if(s->decode_mode != HRTF_MIX_MATRIX2CH) {
@@ -310,7 +308,7 @@ static int control(struct af_instance *af, int cmd, void* arg)
}
}
else if (af->data->nch < 5)
- mp_audio_set_num_channels(af->data, 5);
+ mp_audio_set_channels_old(af->data, 5);
mp_audio_set_format(af->data, AF_FORMAT_S16_NE);
test_output_res = af_test_output(af, (struct mp_audio*)arg);
af->mul = 2.0 / af->data->nch;
@@ -391,12 +389,6 @@ static struct mp_audio* play(struct af_instance *af, struct mp_audio *data)
float common, left, right, diff, left_b, right_b;
const int dblen = s->dlbuflen, hlen = s->hrflen, blen = s->basslen;
- // This was written against the old mplayer channel order, which was ALSA.
- // Feel free to fix the otuput code below to output proper order.
- reorder_channel_nch(data->audio, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
- AF_CHANNEL_LAYOUT_ALSA_DEFAULT,
- data->nch, data->len / data->bps, data->bps);
-
if(AF_OK != RESIZE_LOCAL_BUFFER(af, data))
return NULL;
diff --git a/audio/filter/af_lavcac3enc.c b/audio/filter/af_lavcac3enc.c
index 5be8df2b51..b4b4fd4a1d 100644
--- a/audio/filter/af_lavcac3enc.c
+++ b/audio/filter/af_lavcac3enc.c
@@ -83,7 +83,8 @@ static int control(struct af_instance *af, int cmd, void *arg)
if (data->nch > AC3_MAX_CHANNELS)
mp_audio_set_num_channels(af->data, AC3_MAX_CHANNELS);
else
- mp_audio_set_num_channels(af->data, data->nch);
+ mp_audio_set_channels(af->data, &data->channels);
+ mp_chmap_reorder_to_lavc(&af->data->channels);
test_output_res = af_test_output(af, data);
s->pending_len = 0;
@@ -107,8 +108,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
// Put sample parameters
s->lavc_actx->channels = af->data->nch;
- s->lavc_actx->channel_layout =
- av_get_default_channel_layout(af->data->nch);
+ s->lavc_actx->channel_layout = mp_chmap_to_lavc(&af->data->channels);
s->lavc_actx->sample_rate = af->data->rate;
s->lavc_actx->bit_rate = bit_rate;
diff --git a/audio/filter/af_lavrresample.c b/audio/filter/af_lavrresample.c
index 1f142792df..b5c5a089fd 100644
--- a/audio/filter/af_lavrresample.c
+++ b/audio/filter/af_lavrresample.c
@@ -60,10 +60,10 @@ struct af_resample_opts {
int in_rate;
int in_format;
- int in_channels;
+ struct mp_chmap in_channels;
int out_rate;
int out_format;
- int out_channels;
+ struct mp_chmap out_channels;
};
struct af_resample {
@@ -96,10 +96,10 @@ static bool needs_lavrctx_reconfigure(struct af_resample *s,
{
return s->ctx.in_rate != in->rate ||
s->ctx.in_format != in->format ||
- s->ctx.in_channels != in->nch ||
+ !mp_chmap_equals(&s->ctx.in_channels, &in->channels) ||
s->ctx.out_rate != out->rate ||
s->ctx.out_format != out->format ||
- s->ctx.out_channels!= out->nch ||
+ !mp_chmap_equals(&s->ctx.out_channels, &out->channels) ||
s->ctx.filter_size != s->opts.filter_size ||
s->ctx.phase_shift != s->opts.phase_shift ||
s->ctx.linear != s->opts.linear ||
@@ -128,16 +128,15 @@ static int control(struct af_instance *af, int cmd, void *arg)
if (((out->rate == in->rate) || (out->rate == 0)) &&
(out->format == in->format) &&
- (out->bps == in->bps) &&
- ((out->nch == in->nch) || out->nch == 0) &&
+ (mp_chmap_equals(&out->channels, &in->channels) || out->nch == 0) &&
s->allow_detach)
return AF_DETACH;
if (out->rate == 0)
out->rate = in->rate;
- if (out->nch == 0)
- mp_audio_set_num_channels(out, in->nch);
+ if (mp_chmap_is_empty(&out->channels))
+ mp_audio_set_channels(out, &in->channels);
enum AVSampleFormat in_samplefmt = af_to_avformat(in->format);
if (in_samplefmt == AV_SAMPLE_FMT_NONE) {
@@ -161,15 +160,16 @@ static int control(struct af_instance *af, int cmd, void *arg)
s->ctx.in_rate = in->rate;
s->ctx.out_format = out->format;
s->ctx.in_format = in->format;
- s->ctx.out_channels= out->nch;
- s->ctx.in_channels = in->nch;
+ s->ctx.out_channels= out->channels;
+ s->ctx.in_channels = in->channels;
s->ctx.filter_size = s->opts.filter_size;
s->ctx.phase_shift = s->opts.phase_shift;
s->ctx.linear = s->opts.linear;
s->ctx.cutoff = s->opts.cutoff;
- int in_ch_layout = av_get_default_channel_layout(in->nch);
- int out_ch_layout = av_get_default_channel_layout(out->nch);
+ // 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);
ctx_opt_set_int("in_channel_layout", in_ch_layout);
ctx_opt_set_int("out_channel_layout", out_ch_layout);
@@ -194,7 +194,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
}
return ((in->format == orig_in.format) &&
- (in->nch == orig_in.nch))
+ mp_chmap_equals(&in->channels, &orig_in.channels))
? AF_OK : AF_FALSE;
}
case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET: {
@@ -205,12 +205,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
return AF_OK;
}
case AF_CONTROL_CHANNELS | AF_CONTROL_SET: {
- int nch = *(int *)arg;
-
- if (nch < 1 || nch > AF_NCH)
- return AF_ERROR;
-
- mp_audio_set_num_channels(af->data, nch);
+ mp_audio_set_channels(af->data, (struct mp_chmap *)arg);
return AF_OK;
}
case AF_CONTROL_COMMAND_LINE: {
diff --git a/audio/filter/af_sub.c b/audio/filter/af_sub.c
index 1ae65a0d11..a985ac2a05 100644
--- a/audio/filter/af_sub.c
+++ b/audio/filter/af_sub.c
@@ -70,7 +70,7 @@ static int control(struct af_instance* af, int cmd, void* arg)
if(!arg) return AF_ERROR;
af->data->rate = ((struct mp_audio*)arg)->rate;
- mp_audio_set_num_channels(af->data, max(s->ch+1,((struct mp_audio*)arg)->nch));
+ mp_audio_set_channels_old(af->data, max(s->ch+1,((struct mp_audio*)arg)->nch));
mp_audio_set_format(af->data, AF_FORMAT_FLOAT_NE);
// Design low-pass filter
diff --git a/audio/filter/af_surround.c b/audio/filter/af_surround.c
index c63105481f..c04a039d65 100644
--- a/audio/filter/af_surround.c
+++ b/audio/filter/af_surround.c
@@ -93,7 +93,7 @@ static int control(struct af_instance* af, int cmd, void* arg)
case AF_CONTROL_REINIT:{
float fc;
mp_audio_copy_config(af->data, (struct mp_audio*)arg);
- mp_audio_set_num_channels(af->data, ((struct mp_audio*)arg)->nch*2);
+ mp_audio_set_channels_old(af->data, ((struct mp_audio*)arg)->nch*2);
mp_audio_set_format(af->data, AF_FORMAT_FLOAT_NE);
if (af->data->nch != 4){
@@ -242,7 +242,7 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data){
// Set output data
data->audio = af->data->audio;
data->len *= 2;
- mp_audio_set_num_channels(data, af->data->nch);
+ mp_audio_set_channels_old(data, af->data->nch);
return data;
}
diff --git a/audio/filter/af_tools.c b/audio/filter/af_tools.c
index 22534cda8d..77fdad55f2 100644
--- a/audio/filter/af_tools.c
+++ b/audio/filter/af_tools.c
@@ -90,7 +90,7 @@ int af_test_output(struct af_instance* af, struct mp_audio* out)
if((af->data->format != out->format) ||
(af->data->bps != out->bps) ||
(af->data->rate != out->rate) ||
- (af->data->nch != out->nch)){
+ !mp_chmap_equals(&af->data->channels, &out->channels)){
*out = *af->data;
return AF_FALSE;
}