diff options
-rw-r--r-- | audio/decode/dec_audio.c | 7 | ||||
-rw-r--r-- | audio/decode/dec_audio.h | 4 | ||||
-rw-r--r-- | audio/mixer.c | 2 | ||||
-rw-r--r-- | audio/out/ao.c | 2 | ||||
-rw-r--r-- | audio/out/ao.h | 5 | ||||
-rw-r--r-- | audio/out/ao_alsa.c | 31 | ||||
-rw-r--r-- | audio/out/ao_coreaudio.c | 15 | ||||
-rw-r--r-- | audio/out/ao_dsound.c | 83 | ||||
-rw-r--r-- | audio/out/ao_jack.c | 17 | ||||
-rw-r--r-- | audio/out/ao_lavc.c | 86 | ||||
-rw-r--r-- | audio/out/ao_null.c | 4 | ||||
-rw-r--r-- | audio/out/ao_openal.c | 43 | ||||
-rw-r--r-- | audio/out/ao_oss.c | 32 | ||||
-rw-r--r-- | audio/out/ao_pcm.c | 34 | ||||
-rw-r--r-- | audio/out/ao_portaudio.c | 6 | ||||
-rw-r--r-- | audio/out/ao_pulse.c | 6 | ||||
-rw-r--r-- | audio/out/ao_rsound.c | 6 | ||||
-rw-r--r-- | audio/out/ao_sdl.c | 7 | ||||
-rw-r--r-- | audio/out/audio_out_internal.h | 3 | ||||
-rw-r--r-- | core/mplayer.c | 8 |
20 files changed, 162 insertions, 239 deletions
diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index 6c8804eec9..11232f9271 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -199,7 +199,8 @@ void uninit_audio(sh_audio_t *sh_audio) int init_audio_filters(sh_audio_t *sh_audio, int in_samplerate, - int *out_samplerate, int *out_channels, int *out_format) + int *out_samplerate, struct mp_chmap *out_channels, + int *out_format) { struct af_stream *afs = sh_audio->afilter; if (!afs) @@ -211,7 +212,7 @@ int init_audio_filters(sh_audio_t *sh_audio, int in_samplerate, // output format: same as ao driver's input format (if missing, fallback to input) afs->output.rate = *out_samplerate; - mp_audio_set_num_channels(&afs->output, *out_channels); + mp_audio_set_channels(&afs->output, out_channels); mp_audio_set_format(&afs->output, *out_format); // filter config: @@ -231,7 +232,7 @@ int init_audio_filters(sh_audio_t *sh_audio, int in_samplerate, } *out_samplerate = afs->output.rate; - *out_channels = afs->output.nch; + *out_channels = afs->output.channels; *out_format = afs->output.format; // ok! diff --git a/audio/decode/dec_audio.h b/audio/decode/dec_audio.h index 9fa6aad8dd..b46f4282fb 100644 --- a/audio/decode/dec_audio.h +++ b/audio/decode/dec_audio.h @@ -19,6 +19,7 @@ #ifndef MPLAYER_DEC_AUDIO_H #define MPLAYER_DEC_AUDIO_H +#include "audio/chmap.h" #include "demux/stheader.h" struct bstr; @@ -33,6 +34,7 @@ void skip_audio_frame(sh_audio_t *sh_audio); void uninit_audio(sh_audio_t *sh_audio); int init_audio_filters(sh_audio_t *sh_audio, int in_samplerate, - int *out_samplerate, int *out_channels, int *out_format); + int *out_samplerate, struct mp_chmap *out_channels, + int *out_format); #endif /* MPLAYER_DEC_AUDIO_H */ diff --git a/audio/mixer.c b/audio/mixer.c index b67e548a3c..0f1a7871d6 100644 --- a/audio/mixer.c +++ b/audio/mixer.c @@ -217,7 +217,7 @@ void mixer_setbalance(mixer_t *mixer, float val) AF_CONTROL_PAN_BALANCE | AF_CONTROL_SET, &val)) return; - if (val == 0 || mixer->ao->channels < 2) + if (val == 0 || mixer->ao->channels.num < 2) return; if (!(af_pan_balance = af_add(mixer->afilter, "pan"))) { diff --git a/audio/out/ao.c b/audio/out/ao.c index 9fb201a333..bf9b47a14e 100644 --- a/audio/out/ao.c +++ b/audio/out/ao.c @@ -257,7 +257,7 @@ int old_ao_init(struct ao *ao, char *params) assert(!global_ao); global_ao = ao; ao_subdevice = params ? talloc_strdup(ao, params) : NULL; - if (ao->driver->old_functions->init(ao->samplerate, ao->channels, + if (ao->driver->old_functions->init(ao->samplerate, &ao->channels, ao->format, 0) == 0) { global_ao = NULL; return -1; diff --git a/audio/out/ao.h b/audio/out/ao.h index e57fff7a95..465bcf6197 100644 --- a/audio/out/ao.h +++ b/audio/out/ao.h @@ -23,6 +23,7 @@ #include "core/bstr.h" #include "core/mp_common.h" +#include "audio/chmap.h" enum aocontrol { // _VOLUME commands take struct ao_control_vol pointer for input/output. @@ -55,7 +56,7 @@ typedef struct ao_info { /* interface towards mplayer and */ typedef struct ao_old_functions { int (*control)(int cmd, void *arg); - int (*init)(int rate, int channels, int format, int flags); + int (*init)(int rate, const struct mp_chmap *channels, int format, int flags); void (*uninit)(int immed); void (*reset)(void); int (*get_space)(void); @@ -86,7 +87,7 @@ struct ao_driver { /* global data used by mplayer and plugins */ struct ao { int samplerate; - int channels; + struct mp_chmap channels; int format; int bps; // bytes per second int outburst; diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c index 3682e76aa3..a194ce0478 100644 --- a/audio/out/ao_alsa.c +++ b/audio/out/ao_alsa.c @@ -332,7 +332,8 @@ static int try_open_device(const char *device, int open_mode, int try_ac3) open & setup audio device return: 1=success 0=fail */ -static int init(int rate_hz, int channels, int format, int flags) +static int init(int rate_hz, const struct mp_chmap *channels, int format, + int flags) { int err; int block; @@ -351,7 +352,7 @@ static int init(int rate_hz, int channels, int format, int flags) memset(alsa_device, 0, ALSA_DEVICE_SIZE + 1); mp_msg(MSGT_AO,MSGL_V,"alsa-init: requested format: %d Hz, %d channels, %x\n", rate_hz, - channels, format); + ao_data.channels.num, format); alsa_handler = NULL; mp_msg(MSGT_AO,MSGL_V,"alsa-init: using ALSA %s\n", snd_asoundlib_version()); @@ -360,10 +361,6 @@ static int init(int rate_hz, int channels, int format, int flags) snd_lib_error_set_handler(alsa_error_handler); - ao_data.samplerate = rate_hz; - ao_data.format = format; - ao_data.channels = channels; - switch (format) { case AF_FORMAT_S8: @@ -435,13 +432,13 @@ static int init(int rate_hz, int channels, int format, int flags) */ if (AF_FORMAT_IS_IEC61937(format)) { device.str = "iec958"; - mp_msg(MSGT_AO,MSGL_V,"alsa-spdif-init: playing AC3/iec61937/iec958, %i channels\n", channels); + mp_msg(MSGT_AO,MSGL_V,"alsa-spdif-init: playing AC3/iec61937/iec958, %i channels\n", ao_data.channels.num); } else /* in any case for multichannel playback we should select * appropriate device */ - switch (channels) { + switch (ao_data.channels.num) { case 1: case 2: device.str = "default"; @@ -471,7 +468,8 @@ static int init(int rate_hz, int channels, int format, int flags) break; default: device.str = "default"; - mp_tmsg(MSGT_AO,MSGL_ERR,"[AO_ALSA] %d channels are not supported.\n",channels); + mp_tmsg(MSGT_AO,MSGL_ERR,"[AO_ALSA] %d channels are not supported.\n", + ao_data.channels.num); } device.len = strlen(device.str); if (subopt_parse(ao_subdevice, subopts) != 0) { @@ -554,13 +552,17 @@ static int init(int rate_hz, int channels, int format, int flags) return 0; } + int num_channels = ao_data.channels.num; if ((err = snd_pcm_hw_params_set_channels_near(alsa_handler, alsa_hwparams, - &ao_data.channels)) < 0) + &num_channels)) < 0) { mp_tmsg(MSGT_AO,MSGL_ERR,"[AO_ALSA] Unable to set channels: %s\n", snd_strerror(err)); return 0; } + mp_chmap_from_channels(&ao_data.channels, num_channels); + if (!AF_FORMAT_IS_IEC61937(format)) + mp_chmap_reorder_to_alsa(&ao_data.channels); /* workaround for buggy rate plugin (should be fixed in ALSA 1.0.11) prefer our own resampler, since that allows users to choose the resampler, @@ -582,7 +584,7 @@ static int init(int rate_hz, int channels, int format, int flags) } bytes_per_sample = af_fmt2bits(ao_data.format) / 8; - bytes_per_sample *= ao_data.channels; + bytes_per_sample *= ao_data.channels.num; ao_data.bps = ao_data.samplerate * bytes_per_sample; if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, @@ -668,7 +670,7 @@ static int init(int rate_hz, int channels, int format, int flags) alsa_can_pause = snd_pcm_hw_params_can_pause(alsa_hwparams); mp_msg(MSGT_AO,MSGL_V,"alsa: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n", - ao_data.samplerate, ao_data.channels, (int)bytes_per_sample, ao_data.buffersize, + ao_data.samplerate, ao_data.channels.num, (int)bytes_per_sample, ao_data.buffersize, snd_pcm_format_description(alsa_format)); } // end switch alsa_handler (spdif) @@ -791,11 +793,6 @@ static int play(void* data, int len, int flags) len = len / ao_data.outburst * ao_data.outburst; num_frames = len / bytes_per_sample; - int bps = af_fmt2bits(ao_data.format) / 8; - reorder_channel_nch(data, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, - AF_CHANNEL_LAYOUT_ALSA_DEFAULT, - ao_data.channels, len / bps, bps); - //mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: frames=%i, len=%i\n",num_frames,len); if (!alsa_handler) { diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index 7993eac910..98b9f9adeb 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -412,7 +412,7 @@ static void print_help(void) free(devids); } -static int init(int rate,int channels,int format,int flags) +static int init(int rate,const struct mp_chmap *channels,int format,int flags) { AudioStreamBasicDescription inDesc; AudioComponentDescription desc; @@ -439,7 +439,7 @@ int device_id, display_help = 0; return 0; } - ao_msg(MSGT_AO,MSGL_V, "init([%dHz][%dch][%s][%d])\n", rate, channels, af_fmt2str_short(format), flags); + ao_msg(MSGT_AO,MSGL_V, "init([%dHz][%dch][%s][%d])\n", rate, ao_data.channels.num, af_fmt2str_short(format), flags); ao = calloc(1, sizeof(ao_coreaudio_t)); @@ -502,7 +502,7 @@ int device_id, display_help = 0; // Build Description for the input format inDesc.mSampleRate=rate; inDesc.mFormatID=ao->b_supports_digital ? kAudioFormat60958AC3 : kAudioFormatLinearPCM; - inDesc.mChannelsPerFrame=channels; + inDesc.mChannelsPerFrame=ao_data.channels.num; inDesc.mBitsPerChannel=af_fmt2bits(format); if((format&AF_FORMAT_POINT_MASK)==AF_FORMAT_F) { @@ -521,7 +521,7 @@ int device_id, display_help = 0; inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian; inDesc.mFramesPerPacket = 1; - ao->packetSize = inDesc.mBytesPerPacket = inDesc.mBytesPerFrame = inDesc.mFramesPerPacket*channels*(inDesc.mBitsPerChannel/8); + ao->packetSize = inDesc.mBytesPerPacket = inDesc.mBytesPerFrame = inDesc.mFramesPerPacket*ao_data.channels.num*(inDesc.mBitsPerChannel/8); print_format(MSGL_V, "source:",&inDesc); if (ao->b_supports_digital) @@ -605,7 +605,9 @@ int device_id, display_help = 0; ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame; ao_data.samplerate = inDesc.mSampleRate; - ao_data.channels = inDesc.mChannelsPerFrame; + mp_chmap_from_channels(&ao_data.channels, inDesc.mChannelsPerFrame); + // Most likely wrong, but that's what it has been set to. + mp_chmap_reorder_to_alsa(&ao_data.channels); ao_data.bps = ao_data.samplerate * inDesc.mBytesPerFrame; ao_data.outburst = ao->chunk_size; ao_data.buffersize = ao_data.bps; @@ -837,7 +839,8 @@ static int OpenSPDIF(void) ao->chunk_size = ao->stream_format.mBytesPerPacket; ao_data.samplerate = ao->stream_format.mSampleRate; - ao_data.channels = ao->stream_format.mChannelsPerFrame; + // Applies default ordering; ok becazse AC3 data is always in mpv internal channel order + mp_chmap_from_channels(&ao_data.channels, ao->stream_format.mChannelsPerFrame); ao_data.bps = ao_data.samplerate * (ao->stream_format.mBytesPerPacket/ao->stream_format.mFramesPerPacket); ao_data.outburst = ao->chunk_size; ao_data.buffersize = ao_data.bps; diff --git a/audio/out/ao_dsound.c b/audio/out/ao_dsound.c index 9ad27306bd..b096dd28db 100644 --- a/audio/out/ao_dsound.c +++ b/audio/out/ao_dsound.c @@ -64,26 +64,6 @@ LIBAO_EXTERN(dsound) static const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x1,0x0000,0x0010, {0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}; -#define SPEAKER_FRONT_LEFT 0x1 -#define SPEAKER_FRONT_RIGHT 0x2 -#define SPEAKER_FRONT_CENTER 0x4 -#define SPEAKER_LOW_FREQUENCY 0x8 -#define SPEAKER_BACK_LEFT 0x10 -#define SPEAKER_BACK_RIGHT 0x20 -#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 -#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 -#define SPEAKER_BACK_CENTER 0x100 -#define SPEAKER_SIDE_LEFT 0x200 -#define SPEAKER_SIDE_RIGHT 0x400 -#define SPEAKER_TOP_CENTER 0x800 -#define SPEAKER_TOP_FRONT_LEFT 0x1000 -#define SPEAKER_TOP_FRONT_CENTER 0x2000 -#define SPEAKER_TOP_FRONT_RIGHT 0x4000 -#define SPEAKER_TOP_BACK_LEFT 0x8000 -#define SPEAKER_TOP_BACK_CENTER 0x10000 -#define SPEAKER_TOP_BACK_RIGHT 0x20000 -#define SPEAKER_RESERVED 0x80000000 - #if 0 #define DSSPEAKER_HEADPHONE 0x00000001 #define DSSPEAKER_MONO 0x00000002 @@ -107,28 +87,6 @@ typedef struct { } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; #endif -static const int channel_mask[] = { - /* 1 */ SPEAKER_FRONT_CENTER, - /* 2 */ SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT, - /* 3 */ SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT - | SPEAKER_LOW_FREQUENCY, - /* 4 */ SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT - | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT, - /* 5 */ SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT - | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT - | SPEAKER_LOW_FREQUENCY, - /* 6 */ SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT - | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT - | SPEAKER_LOW_FREQUENCY, - /* 7 */ SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT - | SPEAKER_BACK_LEFT | SPEAKER_BACK_CENTER | SPEAKER_BACK_RIGHT - | SPEAKER_LOW_FREQUENCY, - /* 8 */ SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT - | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT - | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT - | SPEAKER_LOW_FREQUENCY, -}; - static HINSTANCE hdsound_dll = NULL; ///handle to the dll static LPDIRECTSOUND hds = NULL; ///direct sound object static LPDIRECTSOUNDBUFFER hdspribuf = NULL; ///primary direct sound buffer @@ -349,22 +307,9 @@ static int write_buffer(unsigned char *data, int len) if (SUCCEEDED(res)) { if (!AF_FORMAT_IS_AC3(ao_data.format)) { - int sampsize = af_fmt2bits(ao_data.format) / 8; - reorder_channel_copy_nch(data, - AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, - lpvPtr1, - AF_CHANNEL_LAYOUT_WAVEEX_DEFAULT, - ao_data.channels, - dwBytes1 / sampsize, - sampsize); + memcpy(lpvPtr1, data, dwBytes1); if (lpvPtr2 != NULL) - reorder_channel_copy_nch(data + dwBytes1, - AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, - lpvPtr2, - AF_CHANNEL_LAYOUT_WAVEEX_DEFAULT, - ao_data.channels, - dwBytes2 / sampsize, - sampsize); + memcpy(lpvPtr2, (char *)data + dwBytes1, dwBytes2); write_offset+=dwBytes1+dwBytes2; if(write_offset>=buffer_size) @@ -432,7 +377,7 @@ static int control(int cmd, void *arg) \param flags unused \return 1=success 0=fail */ -static int init(int rate, int channels, int format, int flags) +static int init(int rate, const struct mp_chmap *channels, int format, int flags) { int res; if (!InitDirectSound()) return 0; @@ -446,14 +391,17 @@ static int init(int rate, int channels, int format, int flags) DSBUFFERDESC dsbdesc; //check if the channel count and format is supported in general - if (channels > FF_ARRAY_ELEMS(channel_mask)) { + if (ao_data.channels.num > 8) { + // More than 8 channels might just work, but needs testing UninitDirectSound(); - mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: 8 channel audio not yet supported\n"); + mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: > 8 channel audio not yet supported\n"); return 0; } if (AF_FORMAT_IS_AC3(format)) format = AF_FORMAT_AC3_NE; + else + mp_chmap_reorder_to_waveext(&ao_data.channels); switch(format){ case AF_FORMAT_AC3_NE: case AF_FORMAT_S24_LE: @@ -465,25 +413,24 @@ static int init(int rate, int channels, int format, int flags) format=AF_FORMAT_S16_LE; } //fill global ao_data - ao_data.channels = channels; ao_data.samplerate = rate; ao_data.format = format; - ao_data.bps = channels * rate * (af_fmt2bits(format)>>3); + ao_data.bps = ao_data.channels.num * rate * (af_fmt2bits(format)>>3); if(ao_data.buffersize==-1) ao_data.buffersize = ao_data.bps; // space for 1 sec - mp_msg(MSGT_AO, MSGL_V,"ao_dsound: Samplerate:%iHz Channels:%i Format:%s\n", rate, channels, af_fmt2str_short(format)); + mp_msg(MSGT_AO, MSGL_V,"ao_dsound: Samplerate:%iHz Channels:%i Format:%s\n", rate, ao_data.channels.num, af_fmt2str_short(format)); mp_msg(MSGT_AO, MSGL_V,"ao_dsound: Buffersize:%d bytes (%d msec)\n", ao_data.buffersize, ao_data.buffersize / ao_data.bps * 1000); //fill waveformatex ZeroMemory(&wformat, sizeof(WAVEFORMATEXTENSIBLE)); - wformat.Format.cbSize = (channels > 2) ? sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX) : 0; - wformat.Format.nChannels = channels; + wformat.Format.cbSize = (ao_data.channels.num > 2) ? sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX) : 0; + wformat.Format.nChannels = ao_data.channels.num; wformat.Format.nSamplesPerSec = rate; if (AF_FORMAT_IS_AC3(format)) { wformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF; wformat.Format.wBitsPerSample = 16; wformat.Format.nBlockAlign = 4; } else { - wformat.Format.wFormatTag = (channels > 2) ? WAVE_FORMAT_EXTENSIBLE : WAVE_FORMAT_PCM; + wformat.Format.wFormatTag = (ao_data.channels.num > 2) ? WAVE_FORMAT_EXTENSIBLE : WAVE_FORMAT_PCM; wformat.Format.wBitsPerSample = af_fmt2bits(format); wformat.Format.nBlockAlign = wformat.Format.nChannels * (wformat.Format.wBitsPerSample >> 3); } @@ -503,8 +450,8 @@ static int init(int rate, int channels, int format, int flags) | DSBCAPS_GLOBALFOCUS /** Allows background playing */ | DSBCAPS_CTRLVOLUME; /** volume control enabled */ - if (channels > 2) { - wformat.dwChannelMask = channel_mask[channels - 1]; + if (ao_data.channels.num > 2) { + wformat.dwChannelMask = mp_chmap_to_waveext(&ao_data.channels); wformat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; wformat.Samples.wValidBitsPerSample = wformat.Format.wBitsPerSample; // Needed for 5.1 on emu101k - shit soundblaster diff --git a/audio/out/ao_jack.c b/audio/out/ao_jack.c index b75122dc17..aea64ee02c 100644 --- a/audio/out/ao_jack.c +++ b/audio/out/ao_jack.c @@ -202,7 +202,8 @@ static void print_help (void) ); } -static int init(int rate, int channels, int format, int flags) { +static int init(int rate, const struct mp_chmap *channels, int format, int flags) +{ const char **matching_ports = NULL; char *port_name = NULL; char *client_name = NULL; @@ -222,8 +223,9 @@ static int init(int rate, int channels, int format, int flags) { print_help(); return 0; } - if (channels > MAX_CHANS) { - mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] Invalid number of channels: %i\n", channels); + if (ao_data.channels.num > MAX_CHANS) { + mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] Invalid number of channels: %i\n", + ao_data.channels.num); goto err_out; } if (!client_name) { @@ -249,9 +251,9 @@ static int init(int rate, int channels, int format, int flags) { goto err_out; } i = 1; + num_ports = ao_data.channels.num; while (matching_ports[i]) i++; - if (channels > i) channels = i; - num_ports = channels; + if (num_ports > i) num_ports = i; // create out output ports for (i = 0; i < num_ports; i++) { @@ -281,10 +283,11 @@ static int init(int rate, int channels, int format, int flags) { / (float)rate; callback_interval = 0; - ao_data.channels = channels; + mp_chmap_from_channels(&ao_data.channels, num_ports); + mp_chmap_reorder_to_alsa(&ao_data.channels); // what order does hack use? ao_data.samplerate = rate; ao_data.format = AF_FORMAT_FLOAT_NE; - ao_data.bps = channels * rate * sizeof(float); + ao_data.bps = ao_data.channels.num * rate * sizeof(float); ao_data.buffersize = CHUNK_SIZE * NUM_CHUNKS; ao_data.outburst = CHUNK_SIZE; free(matching_ports); diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c index 062d1b928b..0b989224c4 100644 --- a/audio/out/ao_lavc.c +++ b/audio/out/ao_lavc.c @@ -101,7 +101,10 @@ static int init(struct ao *ao, char *params) ac->stream->codec->time_base.den = ao->samplerate; ac->stream->codec->sample_rate = ao->samplerate; - ac->stream->codec->channels = ao->channels; + + mp_chmap_reorder_to_lavc(&ao->channels); + ac->stream->codec->channels = ao->channels.num; + ac->stream->codec->channel_layout = mp_chmap_to_lavc(&ao->channels); ac->stream->codec->sample_fmt = AV_SAMPLE_FMT_NONE; @@ -243,36 +246,6 @@ out_takefirst: ac->stream->codec->bits_per_raw_sample = ac->sample_size * 8; - switch (ao->channels) { - case 1: - ac->stream->codec->channel_layout = AV_CH_LAYOUT_MONO; - break; - case 2: - ac->stream->codec->channel_layout = AV_CH_LAYOUT_STEREO; - break; - /* someone please check if these are what mplayer normally assumes - case 3: - ac->stream->codec->channel_layout = AV_CH_LAYOUT_SURROUND; - break; - case 4: - ac->stream->codec->channel_layout = AV_CH_LAYOUT_2_2; - break; - */ - case 5: - ac->stream->codec->channel_layout = AV_CH_LAYOUT_5POINT0; - break; - case 6: - ac->stream->codec->channel_layout = AV_CH_LAYOUT_5POINT1; - break; - case 8: - ac->stream->codec->channel_layout = AV_CH_LAYOUT_7POINT1; - break; - default: - mp_msg(MSGT_ENCODE, MSGL_ERR, - "ao-lavc: unknown channel layout; hoping for the best\n"); - break; - } - if (encode_lavc_open_codec(ao->encode_lavc_ctx, ac->stream) < 0) return -1; @@ -282,11 +255,12 @@ out_takefirst: if (ac->pcmhack) { ac->aframesize = 16384; // "enough" - ac->buffer_size = ac->aframesize * ac->pcmhack * ao->channels * 2 + 200; + ac->buffer_size = + ac->aframesize * ac->pcmhack * ao->channels.num * 2 + 200; } else { ac->aframesize = ac->stream->codec->frame_size; - ac->buffer_size = ac->aframesize * ac->sample_size * ao->channels * 2 + - 200; + ac->buffer_size = + ac->aframesize * ac->sample_size * ao->channels.num * 2 + 200; } if (ac->buffer_size < FF_MIN_BUFFER_SIZE) ac->buffer_size = FF_MIN_BUFFER_SIZE; @@ -304,10 +278,10 @@ out_takefirst: ac->offset_left = ac->offset; //fill_ao_data: - ao->outburst = ac->aframesize * ac->sample_size * ao->channels * - ac->framecount; + ao->outburst = + ac->aframesize * ac->sample_size * ao->channels.num * ac->framecount; ao->buffersize = ao->outburst * 2; - ao->bps = ao->channels * ao->samplerate * ac->sample_size; + ao->bps = ao->channels.num * ao->samplerate * ac->sample_size; ao->untimed = true; ao->priv = ac; @@ -346,12 +320,12 @@ static void uninit(struct ao *ao, bool cut_audio) double pts = ao->pts + ac->offset / (double) ao->samplerate; if (ao->buffer.len > 0) { void *paddingbuf = talloc_size(ao, - ac->aframesize * ao->channels * ac->sample_size); + ac->aframesize * ao->channels.num * ac->sample_size); memcpy(paddingbuf, ao->buffer.start, ao->buffer.len); fill_with_padding((char *) paddingbuf + ao->buffer.len, - (ac->aframesize * ao->channels * ac->sample_size - - ao->buffer.len) / ac->sample_size, - ac->sample_size, ac->sample_padding); + (ac->aframesize * ao->channels.num * ac->sample_size - + ao->buffer.len) / ac->sample_size, + ac->sample_size, ac->sample_padding); encode(ao, pts, paddingbuf); pts += ac->aframesize / (double) ao->samplerate; talloc_free(paddingbuf); @@ -381,12 +355,6 @@ static int encode(struct ao *ao, double apts, void *data) int status, gotpacket; ac->aframecount++; - if (data && (ao->channels == 5 || ao->channels == 6 || ao->channels == 8)) { - reorder_channel_nch(data, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, - AF_CHANNEL_LAYOUT_LAVC_DEFAULT, - ao->channels, - ac->aframesize * ao->channels, ac->sample_size); - } if (data) ectx->audio_pts_offset = realapts - apts; @@ -400,12 +368,18 @@ static int encode(struct ao *ao, double apts, void *data) frame->nb_samples = ac->aframesize; if (ac->planarize) { - void *data2 = talloc_size(ao, ac->aframesize * ao->channels * ac->sample_size); - reorder_to_planar(data2, data, ac->sample_size, ao->channels, ac->aframesize); + void *data2 = talloc_size(ao, ac->aframesize * ao->channels.num * + ac->sample_size); + reorder_to_planar(data2, data, ac->sample_size, ao->channels.num, + ac->aframesize); data = data2; } - if (avcodec_fill_audio_frame(frame, ao->channels, ac->stream->codec->sample_fmt, data, ac->aframesize * ao->channels * ac->sample_size, 1)) { + size_t audiolen = ac->aframesize * ao->channels.num * ac->sample_size; + if (avcodec_fill_audio_frame(frame, ao->channels.num, + ac->stream->codec->sample_fmt, data, + audiolen, 1)) + { mp_msg(MSGT_ENCODE, MSGL_ERR, "ao-lavc: error filling\n"); return -1; } @@ -512,7 +486,7 @@ static int play(struct ao *ao, void *data, int len, int flags) double pts = ao->pts; double outpts; - len /= ac->sample_size * ao->channels; + len /= ac->sample_size * ao->channels.num; if (!encode_lavc_start(ectx)) { mp_msg(MSGT_ENCODE, MSGL_WARN, @@ -581,7 +555,7 @@ static int play(struct ao *ao, void *data, int len, int flags) if (ac->offset_left <= -len) { // skip whole frame ac->offset_left += len; - return len * ac->sample_size * ao->channels; + return len * ac->sample_size * ao->channels.num; } else { // skip part of this frame, buffer/encode the rest bufpos -= ac->offset_left; @@ -592,11 +566,11 @@ static int play(struct ao *ao, void *data, int len, int flags) // make a temporary buffer, filled with zeroes at the start // (don't worry, only happens once) - paddingbuf = talloc_size(ac, ac->sample_size * ao->channels * + paddingbuf = talloc_size(ac, ac->sample_size * ao->channels.num * (ac->offset_left + len)); fill_with_padding(paddingbuf, ac->offset_left, ac->sample_size, ac->sample_padding); - data = (char *) paddingbuf + ac->sample_size * ao->channels * + data = (char *) paddingbuf + ac->sample_size * ao->channels.num * ac->offset_left; bufpos -= ac->offset_left; // yes, negative! ptsoffset += ac->offset_left; @@ -639,7 +613,7 @@ static int play(struct ao *ao, void *data, int len, int flags) while (len - bufpos >= ac->aframesize) { encode(ao, outpts + (bufpos + ptsoffset) / (double) ao->samplerate + encode_lavc_getoffset(ectx, ac->stream), - (char *) data + ac->sample_size * bufpos * ao->channels); + (char *) data + ac->sample_size * bufpos * ao->channels.num); bufpos += ac->aframesize; } @@ -655,7 +629,7 @@ static int play(struct ao *ao, void *data, int len, int flags) ectx->next_in_pts = nextpts; } - return bufpos * ac->sample_size * ao->channels; + return bufpos * ac->sample_size * ao->channels.num; } const struct ao_driver audio_out_lavc = { diff --git a/audio/out/ao_null.c b/audio/out/ao_null.c index 102f0a7013..f6d7bb0c5f 100644 --- a/audio/out/ao_null.c +++ b/audio/out/ao_null.c @@ -49,10 +49,10 @@ static int init(struct ao *ao, char *params) struct priv *priv = talloc_zero(ao, struct priv); ao->priv = priv; int samplesize = af_fmt2bits(ao->format) / 8; - ao->outburst = 256 * ao->channels * samplesize; + ao->outburst = 256 * ao->channels.num * samplesize; // A "buffer" for about 0.2 seconds of audio ao->buffersize = (int)(ao->samplerate * 0.2 / 256 + 1) * ao->outburst; - ao->bps = ao->channels * ao->samplerate * samplesize; + ao->bps = ao->channels.num * ao->samplerate * samplesize; priv->last_time = GetTimer(); return 0; diff --git a/audio/out/ao_openal.c b/audio/out/ao_openal.c index 157cf93ac4..e6e1369a2f 100644 --- a/audio/out/ao_openal.c +++ b/audio/out/ao_openal.c @@ -109,7 +109,9 @@ static void list_devices(void) { } } -static int init(int rate, int channels, int format, int flags) { +static int init(int rate, const struct mp_chmap *channels, int format, + int flags) +{ float position[3] = {0, 0, 0}; float direction[6] = {0, 0, 1, 0, -1, 0}; float sppos[MAX_CHANS][3] = { @@ -137,8 +139,9 @@ static int init(int rate, int channels, int format, int flags) { list_devices(); goto err_out; } - if (channels > MAX_CHANS) { - mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] Invalid number of channels: %i\n", channels); + if (ao_data.channels.num > MAX_CHANS) { + mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] Invalid number of channels: %i\n", + ao_data.channels.num); goto err_out; } dev = alcOpenDevice(device); @@ -150,25 +153,25 @@ static int init(int rate, int channels, int format, int flags) { alcMakeContextCurrent(ctx); alListenerfv(AL_POSITION, position); alListenerfv(AL_ORIENTATION, direction); - alGenSources(channels, sources); - for (i = 0; i < channels; i++) { + alGenSources(ao_data.channels.num, sources); + for (i = 0; i < ao_data.channels.num; i++) { cur_buf[i] = 0; unqueue_buf[i] = 0; alGenBuffers(NUM_BUF, buffers[i]); alSourcefv(sources[i], AL_POSITION, sppos[i]); alSource3f(sources[i], AL_VELOCITY, 0, 0, 0); } - if (channels == 1) + if (ao_data.channels.num == 1) alSource3f(sources[0], AL_POSITION, 0, 0, 1); - ao_data.channels = channels; alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq); if (alcGetError(dev) == ALC_NO_ERROR && freq) rate = freq; ao_data.samplerate = rate; ao_data.format = AF_FORMAT_S16_NE; - ao_data.bps = channels * rate * 2; + ao_data.bps = ao_data.channels.num * rate * 2; ao_data.buffersize = CHUNK_SIZE * NUM_BUF; - ao_data.outburst = channels * CHUNK_SIZE; + ao_data.outburst = ao_data.channels.num * CHUNK_SIZE; + mp_chmap_reorder_to_alsa(&ao_data.channels); // sppos[][] matrix is for ALSA tmpbuf = malloc( |