Add support for 8 channel audio.

Where 8 channel support is non-trivial (e.g. ao_dsound), at least ensure we
fail gracefully.


git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29868 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
tack 2009-11-10 00:45:19 +00:00
parent 1d30062395
commit 3c2afd6786
10 changed files with 215 additions and 19 deletions

View File

@ -188,7 +188,7 @@
// force video/audio rate: // force video/audio rate:
{"fps", &force_fps, CONF_TYPE_DOUBLE, CONF_MIN, 0, 0, NULL}, {"fps", &force_fps, CONF_TYPE_DOUBLE, CONF_MIN, 0, 0, NULL},
{"srate", &force_srate, CONF_TYPE_INT, CONF_RANGE, 1000, 8*48000, NULL}, {"srate", &force_srate, CONF_TYPE_INT, CONF_RANGE, 1000, 8*48000, NULL},
{"channels", &audio_output_channels, CONF_TYPE_INT, CONF_RANGE, 1, 6, NULL}, {"channels", &audio_output_channels, CONF_TYPE_INT, CONF_RANGE, 1, 8, NULL},
{"format", &audio_output_format, CONF_TYPE_AFMT, 0, 0, 0, NULL}, {"format", &audio_output_format, CONF_TYPE_AFMT, 0, 0, 0, NULL},
{"speed", &playback_speed, CONF_TYPE_FLOAT, CONF_RANGE, 0.01, 100.0, NULL}, {"speed", &playback_speed, CONF_TYPE_FLOAT, CONF_RANGE, 0.01, 100.0, NULL},

View File

@ -39,7 +39,7 @@ struct af_instance_s;
// Number of channels // Number of channels
#ifndef AF_NCH #ifndef AF_NCH
#define AF_NCH 6 #define AF_NCH 8
#endif #endif
// Audio data chunk // Audio data chunk

View File

@ -20,7 +20,7 @@
/* This audio filter changes the volume of the sound, and can be used /* This audio filter changes the volume of the sound, and can be used
when the mixer doesn't support the PCM channel. It can handle when the mixer doesn't support the PCM channel. It can handle
between 1 and 6 channels. The volume can be adjusted between -60dB between 1 and AF_NCH channels. The volume can be adjusted between -60dB
to +20dB and is set on a per channels basis. The is accessed through to +20dB and is set on a per channels basis. The is accessed through
AF_CONTROL_VOLUME_LEVEL. AF_CONTROL_VOLUME_LEVEL.

View File

@ -189,6 +189,94 @@ static int reorder_copy_6ch(void *dest, const void *src,
return 1; return 1;
} }
#define REORDER_COPY_8(DEST,SRC,SAMPLES,S0,S1,S2,S3,S4,S5,S6,S7) \
for (i = 0; i < SAMPLES; i += 8) {\
DEST[i] = SRC[i+S0];\
DEST[i+1] = SRC[i+S1];\
DEST[i+2] = SRC[i+S2];\
DEST[i+3] = SRC[i+S3];\
DEST[i+4] = SRC[i+S4];\
DEST[i+5] = SRC[i+S5];\
DEST[i+6] = SRC[i+S6];\
DEST[i+7] = SRC[i+S7];\
}
static int reorder_copy_8ch(void *dest, const void *src,
unsigned int samples, uint8_t samplesize,
int s0, int s1, int s2, int s3,
int s4, int s5, int s6, int s7)
{
int i;
switch (samplesize) {
case 1:
{
int8_t *dest_8 = dest;
const int8_t *src_8 = src;
REORDER_COPY_8(dest_8,src_8,samples,s0,s1,s2,s3,s4,s5,s6,s7);
break;
}
case 2:
{
int16_t *dest_16 = dest;
const int16_t *src_16 = src;
REORDER_COPY_8(dest_16,src_16,samples,s0,s1,s2,s3,s4,s5,s6,s7);
break;
}
case 3:
{
int8_t *dest_8 = dest;
const int8_t *src_8 = src;
for (i = 0; i < samples; i += 24) {
dest_8[i] = src_8[i+s0*3];
dest_8[i+1] = src_8[i+s0*3+1];
dest_8[i+2] = src_8[i+s0*3+2];
dest_8[i+3] = src_8[i+s1*3];
dest_8[i+4] = src_8[i+s1*3+1];
dest_8[i+5] = src_8[i+s1*3+2];
dest_8[i+6] = src_8[i+s2*3];
dest_8[i+7] = src_8[i+s2*3+1];
dest_8[i+8] = src_8[i+s2*3+2];
dest_8[i+9] = src_8[i+s3*3];
dest_8[i+10] = src_8[i+s3*3+1];
dest_8[i+11] = src_8[i+s3*3+2];
dest_8[i+12] = src_8[i+s4*3];
dest_8[i+13] = src_8[i+s4*3+1];
dest_8[i+14] = src_8[i+s4*3+2];
dest_8[i+15] = src_8[i+s5*3];
dest_8[i+16] = src_8[i+s5*3+1];
dest_8[i+17] = src_8[i+s5*3+2];
dest_8[i+18] = src_8[i+s6*3];
dest_8[i+19] = src_8[i+s6*3+1];
dest_8[i+20] = src_8[i+s6*3+2];
dest_8[i+21] = src_8[i+s7*3];
dest_8[i+22] = src_8[i+s7*3+1];
dest_8[i+23] = src_8[i+s7*3+2];
}
break;
}
case 4:
{
int32_t *dest_32 = dest;
const int32_t *src_32 = src;
REORDER_COPY_8(dest_32,src_32,samples,s0,s1,s2,s3,s4,s5,s6,s7);
break;
}
case 8:
{
int64_t *dest_64 = dest;
const int64_t *src_64 = src;
REORDER_COPY_8(dest_64,src_64,samples,s0,s1,s2,s3,s4,s5,s6,s7);
break;
}
default:
mp_msg(MSGT_GLOBAL, MSGL_WARN,
"[reorder_ch] Unsupported sample size: %d, please "
"report this error on the MPlayer mailing list.\n",samplesize);
return 0;
}
return 1;
}
void reorder_channel_copy(void *src, void reorder_channel_copy(void *src,
int src_layout, int src_layout,
void *dest, void *dest,
@ -298,6 +386,16 @@ void reorder_channel_copy(void *src,
case AF_CHANNEL_LAYOUT_5_1_F << 16 | AF_CHANNEL_LAYOUT_5_1_B: case AF_CHANNEL_LAYOUT_5_1_F << 16 | AF_CHANNEL_LAYOUT_5_1_B:
reorder_copy_6ch(dest, src, samples, samplesize, 1, 2, 4, 5, 0, 3); reorder_copy_6ch(dest, src, samples, samplesize, 1, 2, 4, 5, 0, 3);
break; break;
// AF_CHANNEL_LAYOUT_7_1_A L R C LFE Ls Rs Rls Rrs
// AF_CHANNEL_LAYOUT_7_1_B L R Ls Rs C LFE Rls Rrs
// AF_CHANNEL_LAYOUT_7_1_D C L R Ls Rs Rls Rrs LFE
case AF_CHANNEL_LAYOUT_7_1_A << 16 | AF_CHANNEL_LAYOUT_7_1_B:
case AF_CHANNEL_LAYOUT_7_1_B << 16 | AF_CHANNEL_LAYOUT_7_1_A:
reorder_copy_8ch(dest, src, samples, samplesize, 0, 1, 4, 5, 2, 3, 6, 7);
break;
case AF_CHANNEL_LAYOUT_7_1_D << 16 | AF_CHANNEL_LAYOUT_7_1_B:
reorder_copy_8ch(dest, src, samples, samplesize, 1, 2, 3, 4, 0, 7, 5, 6);
break;
default: default:
mp_msg(MSGT_GLOBAL, MSGL_WARN, "[reorder_channel_copy] unsupport " mp_msg(MSGT_GLOBAL, MSGL_WARN, "[reorder_channel_copy] unsupport "
"from %x to %x, %d * %d\n", src_layout, dest_layout, "from %x to %x, %d * %d\n", src_layout, dest_layout,
@ -327,6 +425,9 @@ static int reorder_self_2(void *src, unsigned int samples,
if (chnum==6) { if (chnum==6) {
REORDER_SELF_SWAP_2(src_8,tmp,samples,6,s0,s1); REORDER_SELF_SWAP_2(src_8,tmp,samples,6,s0,s1);
} }
else if (chnum==8) {
REORDER_SELF_SWAP_2(src_8,tmp,samples,8,s0,s1);
}
else { else {
REORDER_SELF_SWAP_2(src_8,tmp,samples,5,s0,s1); REORDER_SELF_SWAP_2(src_8,tmp,samples,5,s0,s1);
} }
@ -342,6 +443,9 @@ static int reorder_self_2(void *src, unsigned int samples,
else if (chnum==3) { else if (chnum==3) {
REORDER_SELF_SWAP_2(src_16,tmp,samples,3,s0,s1); REORDER_SELF_SWAP_2(src_16,tmp,samples,3,s0,s1);
} }
else if (chnum==4) {
REORDER_SELF_SWAP_2(src_16,tmp,samples,3,s0,s1);
}
else { else {
REORDER_SELF_SWAP_2(src_16,tmp,samples,5,s0,s1); REORDER_SELF_SWAP_2(src_16,tmp,samples,5,s0,s1);
} }
@ -374,6 +478,9 @@ static int reorder_self_2(void *src, unsigned int samples,
else if (chnum==3) { else if (chnum==3) {
REORDER_SELF_SWAP_2(src_32,tmp,samples,3,s0,s1); REORDER_SELF_SWAP_2(src_32,tmp,samples,3,s0,s1);
} }
else if (chnum==4) {
REORDER_SELF_SWAP_2(src_32,tmp,samples,4,s0,s1);
}
else { else {
REORDER_SELF_SWAP_2(src_32,tmp,samples,5,s0,s1); REORDER_SELF_SWAP_2(src_32,tmp,samples,5,s0,s1);
} }
@ -389,6 +496,9 @@ static int reorder_self_2(void *src, unsigned int samples,
else if (chnum==3) { else if (chnum==3) {
REORDER_SELF_SWAP_2(src_64,tmp,samples,3,s0,s1); REORDER_SELF_SWAP_2(src_64,tmp,samples,3,s0,s1);
} }
else if (chnum==4) {
REORDER_SELF_SWAP_2(src_64,tmp,samples,4,s0,s1);
}
else { else {
REORDER_SELF_SWAP_2(src_64,tmp,samples,5,s0,s1); REORDER_SELF_SWAP_2(src_64,tmp,samples,5,s0,s1);
} }
@ -516,6 +626,9 @@ static int reorder_self_4_step_1(void *src, unsigned int samples,
if (chnum==6) { if (chnum==6) {
REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,6,s0,s1,s2,s3); REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,6,s0,s1,s2,s3);
} }
else if (chnum==8) {
REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,8,s0,s1,s2,s3);
}
else { else {
REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,5,s0,s1,s2,s3); REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,5,s0,s1,s2,s3);
} }
@ -528,6 +641,9 @@ static int reorder_self_4_step_1(void *src, unsigned int samples,
if (chnum==6) { if (chnum==6) {
REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,6,s0,s1,s2,s3); REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,6,s0,s1,s2,s3);
} }
else if (chnum==8) {
REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,8,s0,s1,s2,s3);
}
else { else {
REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,5,s0,s1,s2,s3); REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,5,s0,s1,s2,s3);
} }
@ -563,6 +679,9 @@ static int reorder_self_4_step_1(void *src, unsigned int samples,
if (chnum==6) { if (chnum==6) {
REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,6,s0,s1,s2,s3); REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,6,s0,s1,s2,s3);
} }
else if (chnum==8) {
REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,8,s0,s1,s2,s3);
}
else { else {
REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,5,s0,s1,s2,s3); REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,5,s0,s1,s2,s3);
} }
@ -575,6 +694,9 @@ static int reorder_self_4_step_1(void *src, unsigned int samples,
if (chnum==6) { if (chnum==6) {
REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,6,s0,s1,s2,s3); REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,6,s0,s1,s2,s3);
} }
else if (chnum==8) {
REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,8,s0,s1,s2,s3);
}
else { else {
REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,5,s0,s1,s2,s3); REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,5,s0,s1,s2,s3);
} }
@ -922,7 +1044,7 @@ for (i = 0; i < SAMPLES; i += CHNUM) {\
} }
static int reorder_self_2_4(void *src, unsigned int samples, static int reorder_self_2_4(void *src, unsigned int samples,
unsigned int samplesize, unsigned int samplesize, int chnum,
int s0, int s1, int s2, int s3, int s4, int s5) int s0, int s1, int s2, int s3, int s4, int s5)
{ {
int i; int i;
@ -931,21 +1053,29 @@ static int reorder_self_2_4(void *src, unsigned int samples,
{ {
int8_t *src_8 = src; int8_t *src_8 = src;
int8_t tmp; int8_t tmp;
REORDER_SELF_SWAP_2_4(src_8,tmp,samples,6,s0,s1,s2,s3,s4,s5); if (chnum==6) {
REORDER_SELF_SWAP_2_4(src_8,tmp,samples,6,s0,s1,s2,s3,s4,s5);
} else {
REORDER_SELF_SWAP_2_4(src_8,tmp,samples,8,s0,s1,s2,s3,s4,s5);
}
break; break;
} }
case 2: case 2:
{ {
int16_t *src_16 = src; int16_t *src_16 = src;
int16_t tmp; int16_t tmp;
REORDER_SELF_SWAP_2_4(src_16,tmp,samples,6,s0,s1,s2,s3,s4,s5); if (chnum==6) {
REORDER_SELF_SWAP_2_4(src_16,tmp,samples,6,s0,s1,s2,s3,s4,s5);
} else {
REORDER_SELF_SWAP_2_4(src_16,tmp,samples,8,s0,s1,s2,s3,s4,s5);
}
break; break;
} }
case 3: case 3:
{ {
int8_t *src_8 = src; int8_t *src_8 = src;
int8_t tmp0, tmp1, tmp2; int8_t tmp0, tmp1, tmp2;
for (i = 0; i < samples; i += 18) { for (i = 0; i < samples; i += 3*chnum) {
tmp0 = src_8[i+s0*3]; tmp0 = src_8[i+s0*3];
tmp1 = src_8[i+s0*3+1]; tmp1 = src_8[i+s0*3+1];
tmp2 = src_8[i+s0*3+2]; tmp2 = src_8[i+s0*3+2];
@ -977,14 +1107,22 @@ static int reorder_self_2_4(void *src, unsigned int samples,
{ {
int32_t *src_32 = src; int32_t *src_32 = src;
int32_t tmp; int32_t tmp;
REORDER_SELF_SWAP_2_4(src_32,tmp,samples,6,s0,s1,s2,s3,s4,s5); if (chnum==6) {
REORDER_SELF_SWAP_2_4(src_32,tmp,samples,6,s0,s1,s2,s3,s4,s5);
} else {
REORDER_SELF_SWAP_2_4(src_32,tmp,samples,8,s0,s1,s2,s3,s4,s5);
}
break; break;
} }
case 8: case 8:
{ {
int64_t *src_64 = src; int64_t *src_64 = src;
int64_t tmp; int64_t tmp;
REORDER_SELF_SWAP_2_4(src_64,tmp,samples,6,s0,s1,s2,s3,s4,s5); if (chnum==6) {
REORDER_SELF_SWAP_2_4(src_64,tmp,samples,6,s0,s1,s2,s3,s4,s5);
} else {
REORDER_SELF_SWAP_2_4(src_64,tmp,samples,8,s0,s1,s2,s3,s4,s5);
}
break; break;
} }
default: default:
@ -1083,7 +1221,7 @@ void reorder_channel(void *src,
reorder_self_5_step_1(src, samples, samplesize, 6, 4, 3, 2, 1, 0); reorder_self_5_step_1(src, samples, samplesize, 6, 4, 3, 2, 1, 0);
break; break;
case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_E: case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_E:
reorder_self_2_4(src, samples, samplesize, 2, 4, 5, 3, 1, 0); reorder_self_2_4(src, samples, samplesize, 6, 2, 4, 5, 3, 1, 0);
break; break;
case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_A: case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_A:
reorder_self_2_3(src, samples, samplesize, 1, 2, 5, 4, 3); reorder_self_2_3(src, samples, samplesize, 1, 2, 5, 4, 3);
@ -1104,10 +1242,27 @@ void reorder_channel(void *src,
reorder_self_2(src, samples, samplesize, 6, 0, 1); reorder_self_2(src, samples, samplesize, 6, 0, 1);
break; break;
case AF_CHANNEL_LAYOUT_5_1_E << 16 | AF_CHANNEL_LAYOUT_5_1_B: case AF_CHANNEL_LAYOUT_5_1_E << 16 | AF_CHANNEL_LAYOUT_5_1_B:
reorder_self_2_4(src, samples, samplesize, 2, 4, 0, 1, 3, 5); reorder_self_2_4(src, samples, samplesize, 6, 2, 4, 0, 1, 3, 5);
break; break;
case AF_CHANNEL_LAYOUT_5_1_F << 16 | AF_CHANNEL_LAYOUT_5_1_B: case AF_CHANNEL_LAYOUT_5_1_F << 16 | AF_CHANNEL_LAYOUT_5_1_B:
reorder_self_2_4(src, samples, samplesize, 3, 5, 0, 1, 2, 4); reorder_self_2_4(src, samples, samplesize, 6, 3, 5, 0, 1, 2, 4);
break;
// AF_CHANNEL_LAYOUT_7_1_A L R C LFE Ls Rs Rls Rrs
// AF_CHANNEL_LAYOUT_7_1_B L R Ls Rs C LFE Rls Rrs
// AF_CHANNEL_LAYOUT_7_1_C L C R Ls Rs LFE Rls Rrs
// AF_CHANNEL_LAYOUT_7_1_F C L R LFE Ls Rs Rls Rrs
case AF_CHANNEL_LAYOUT_7_1_A << 16 | AF_CHANNEL_LAYOUT_7_1_B:
case AF_CHANNEL_LAYOUT_7_1_B << 16 | AF_CHANNEL_LAYOUT_7_1_A:
if (samplesize != 3)
reorder_self_2(src, samples/2, samplesize*2, 4, 1, 2);
else
reorder_self_4_step_2(src, samples, samplesize, 8, 2, 3, 4, 5);
break;
case AF_CHANNEL_LAYOUT_7_1_C << 16 | AF_CHANNEL_LAYOUT_7_1_B:
reorder_self_4_step_1(src, samples, samplesize, 8, 1, 2, 3, 4);
break;
case AF_CHANNEL_LAYOUT_7_1_F << 16 | AF_CHANNEL_LAYOUT_7_1_B:
reorder_self_2_4(src, samples, samplesize, 8, 3, 5, 0, 1, 2, 4);
break; break;
default: default:
mp_msg(MSGT_GLOBAL, MSGL_WARN, mp_msg(MSGT_GLOBAL, MSGL_WARN,
@ -1133,6 +1288,14 @@ static int channel_layout_mapping_6ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
AF_CHANNEL_LAYOUT_VORBIS_6CH_DEFAULT, AF_CHANNEL_LAYOUT_VORBIS_6CH_DEFAULT,
}; };
static int channel_layout_mapping_8ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
AF_CHANNEL_LAYOUT_ALSA_8CH_DEFAULT,
AF_CHANNEL_LAYOUT_AAC_8CH_DEFAULT,
AF_CHANNEL_LAYOUT_WAVEEX_8CH_DEFAULT,
AF_CHANNEL_LAYOUT_LAVC_8CH_DEFAULT,
AF_CHANNEL_LAYOUT_VORBIS_8CH_DEFAULT,
};
void reorder_channel_copy_nch(void *src, void reorder_channel_copy_nch(void *src,
int src_layout, int src_layout,
void *dest, void *dest,
@ -1141,7 +1304,8 @@ void reorder_channel_copy_nch(void *src,
int samples, int samples,
int samplesize) int samplesize)
{ {
if (chnum < 5 || chnum > 6 || src_layout < 0 || dest_layout < 0 || if (chnum < 5 || chnum == 7 || chnum > 8 ||
src_layout < 0 || dest_layout < 0 ||
src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM || src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM) dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM)
fast_memcpy(dest, src, samples*samplesize); fast_memcpy(dest, src, samples*samplesize);
@ -1149,6 +1313,10 @@ void reorder_channel_copy_nch(void *src,
reorder_channel_copy(src, channel_layout_mapping_6ch[src_layout], reorder_channel_copy(src, channel_layout_mapping_6ch[src_layout],
dest, channel_layout_mapping_6ch[dest_layout], dest, channel_layout_mapping_6ch[dest_layout],
samples, samplesize); samples, samplesize);
else if (chnum == 8)
reorder_channel_copy(src, channel_layout_mapping_8ch[src_layout],
dest, channel_layout_mapping_8ch[dest_layout],
samples, samplesize);
else else
reorder_channel_copy(src, channel_layout_mapping_5ch[src_layout], reorder_channel_copy(src, channel_layout_mapping_5ch[src_layout],
dest, channel_layout_mapping_5ch[dest_layout], dest, channel_layout_mapping_5ch[dest_layout],
@ -1162,7 +1330,7 @@ void reorder_channel_nch(void *buf,
int samples, int samples,
int samplesize) int samplesize)
{ {
if (src_layout == dest_layout || chnum < 5 || chnum > 6 || if (src_layout == dest_layout || chnum < 5 || chnum == 7 || chnum > 8 ||
src_layout < 0 || dest_layout < 0 || src_layout < 0 || dest_layout < 0 ||
src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM || src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM || dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
@ -1172,6 +1340,10 @@ void reorder_channel_nch(void *buf,
reorder_channel(buf, channel_layout_mapping_6ch[src_layout], reorder_channel(buf, channel_layout_mapping_6ch[src_layout],
channel_layout_mapping_6ch[dest_layout], channel_layout_mapping_6ch[dest_layout],
samples, samplesize); samples, samplesize);
else if (chnum == 8)
reorder_channel(buf, channel_layout_mapping_8ch[src_layout],
channel_layout_mapping_8ch[dest_layout],
samples, samplesize);
else else
reorder_channel(buf, channel_layout_mapping_5ch[src_layout], reorder_channel(buf, channel_layout_mapping_5ch[src_layout],
channel_layout_mapping_5ch[dest_layout], channel_layout_mapping_5ch[dest_layout],

View File

@ -56,20 +56,30 @@
#define AF_CHANNEL_LAYOUT_5_1_F ((117<<8)|6|AF_LFE) // C L R LFE Ls Rs #define AF_CHANNEL_LAYOUT_5_1_F ((117<<8)|6|AF_LFE) // C L R LFE Ls Rs
#define AF_CHANNEL_LAYOUT_6_1_A ((118<<8)|7|AF_LFE) // L R C LFE Ls Rs Cs #define AF_CHANNEL_LAYOUT_6_1_A ((118<<8)|7|AF_LFE) // L R C LFE Ls Rs Cs
#define AF_CHANNEL_LAYOUT_7_1_A ((119<<8)|8|AF_LFE) // L R C LFE Ls Rs Rls Rrs #define AF_CHANNEL_LAYOUT_7_1_A ((119<<8)|8|AF_LFE) // L R C LFE Ls Rs Rls Rrs
#define AF_CHANNEL_LAYOUT_7_1_B ((120<<8)|8|AF_LFE) // L R Ls Rs C LFE Rls Rrs
#define AF_CHANNEL_LAYOUT_7_1_C ((121<<8)|8|AF_LFE) // L C R Ls Rs LFE Rls Rrs
#define AF_CHANNEL_LAYOUT_7_1_D ((122<<8)|8|AF_LFE) // C L R Ls Rs Rls Rrs LFE
#define AF_CHANNEL_LAYOUT_7_1_F ((123<<8)|8|AF_LFE) // C L R LFE Ls Rs Rls Rrs
#define AF_CHANNEL_LAYOUT_ALSA_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_B #define AF_CHANNEL_LAYOUT_ALSA_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_B
#define AF_CHANNEL_LAYOUT_ALSA_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_B #define AF_CHANNEL_LAYOUT_ALSA_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_B
#define AF_CHANNEL_LAYOUT_ALSA_8CH_DEFAULT AF_CHANNEL_LAYOUT_7_1_B
#define AF_CHANNEL_LAYOUT_MPLAYER_5CH_DEFAULT AF_CHANNEL_LAYOUT_ALSA_5CH_DEFAULT #define AF_CHANNEL_LAYOUT_MPLAYER_5CH_DEFAULT AF_CHANNEL_LAYOUT_ALSA_5CH_DEFAULT
#define AF_CHANNEL_LAYOUT_MPLAYER_6CH_DEFAULT AF_CHANNEL_LAYOUT_ALSA_6CH_DEFAULT #define AF_CHANNEL_LAYOUT_MPLAYER_6CH_DEFAULT AF_CHANNEL_LAYOUT_ALSA_6CH_DEFAULT
#define AF_CHANNEL_LAYOUT_MPLAYER_8CH_DEFAULT AF_CHANNEL_LAYOUT_ALSA_8CH_DEFAULT
#define AF_CHANNEL_LAYOUT_AAC_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_D #define AF_CHANNEL_LAYOUT_AAC_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_D
#define AF_CHANNEL_LAYOUT_AAC_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_D #define AF_CHANNEL_LAYOUT_AAC_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_D
#define AF_CHANNEL_LAYOUT_AAC_8CH_DEFAULT AF_CHANNEL_LAYOUT_7_1_D
#define AF_CHANNEL_LAYOUT_WAVEEX_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_A #define AF_CHANNEL_LAYOUT_WAVEEX_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_A
#define AF_CHANNEL_LAYOUT_WAVEEX_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_A #define AF_CHANNEL_LAYOUT_WAVEEX_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_A
#define AF_CHANNEL_LAYOUT_WAVEEX_8CH_DEFAULT AF_CHANNEL_LAYOUT_7_1_A
#define AF_CHANNEL_LAYOUT_LAVC_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_A #define AF_CHANNEL_LAYOUT_LAVC_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_A
#define AF_CHANNEL_LAYOUT_LAVC_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_A #define AF_CHANNEL_LAYOUT_LAVC_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_A
#define AF_CHANNEL_LAYOUT_LAVC_8CH_DEFAULT AF_CHANNEL_LAYOUT_7_1_A
#define AF_CHANNEL_LAYOUT_VORBIS_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_C #define AF_CHANNEL_LAYOUT_VORBIS_5CH_DEFAULT AF_CHANNEL_LAYOUT_5_0_C
#define AF_CHANNEL_LAYOUT_VORBIS_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_C #define AF_CHANNEL_LAYOUT_VORBIS_6CH_DEFAULT AF_CHANNEL_LAYOUT_5_1_C
#define AF_CHANNEL_LAYOUT_VORBIS_8CH_DEFAULT AF_CHANNEL_LAYOUT_7_1_C
#define AF_CHANNEL_MASK 0xFF #define AF_CHANNEL_MASK 0xFF
#define AF_GET_CH_NUM(A) ((A)&0x7F) #define AF_GET_CH_NUM(A) ((A)&0x7F)

View File

@ -457,6 +457,13 @@ static int init(int rate_hz, int channels, int format, int flags)
device.str = "surround51"; device.str = "surround51";
mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround51\n"); mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround51\n");
break; break;
case 8:
if (alsa_format == SND_PCM_FORMAT_FLOAT_LE)
device.str = "plug:surround71";
else
device.str = "surround71";
mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround71\n");
break;
default: default:
device.str = "default"; device.str = "default";
mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ChannelsNotSupported,channels); mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ChannelsNotSupported,channels);

View File

@ -426,7 +426,12 @@ static int init(int rate, int channels, int format, int flags)
DSBUFFERDESC dsbpridesc; DSBUFFERDESC dsbpridesc;
DSBUFFERDESC dsbdesc; DSBUFFERDESC dsbdesc;
//check if the format is supported in general //check if the channel count and format is supported in general
if (channels > 6) {
UninitDirectSound();
mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: 8 channel audio not yet supported\n");
return 0;
}
switch(format){ switch(format){
case AF_FORMAT_AC3: case AF_FORMAT_AC3:
case AF_FORMAT_S24_LE: case AF_FORMAT_S24_LE:

View File

@ -244,7 +244,7 @@ static int play(void* data,int len,int flags){
} }
#endif #endif
if (ao_data.channels == 6 || ao_data.channels == 5) { if (ao_data.channels == 5 || ao_data.channels == 6 || ao_data.channels == 8) {
int frame_size = le2me_16(wavhdr.bits) / 8; int frame_size = le2me_16(wavhdr.bits) / 8;
len -= len % (frame_size * ao_data.channels); len -= len % (frame_size * ao_data.channels);
reorder_channel_nch(data, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, reorder_channel_nch(data, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,

View File

@ -47,7 +47,7 @@ LIBAD_EXTERN(faad)
/* configure maximum supported channels, * /* configure maximum supported channels, *
* this is theoretically max. 64 chans */ * this is theoretically max. 64 chans */
#define FAAD_MAX_CHANNELS 6 #define FAAD_MAX_CHANNELS 8
#define FAAD_BUFFLEN (FAAD_MIN_STREAMSIZE*FAAD_MAX_CHANNELS) #define FAAD_BUFFLEN (FAAD_MIN_STREAMSIZE*FAAD_MAX_CHANNELS)
//#define AAC_DUMP_COMPRESSED //#define AAC_DUMP_COMPRESSED
@ -167,7 +167,8 @@ static int init(sh_audio_t *sh)
} else { } else {
mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug! mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug!
mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %ldHz channels: %d\n", faac_samplerate, faac_channels); mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %ldHz channels: %d\n", faac_samplerate, faac_channels);
sh->channels = faac_channels; // 8 channels is aac channel order #7.
sh->channels = faac_channels == 7 ? 8 : faac_channels;
if (audio_output_channels <= 2) sh->channels = faac_channels > 1 ? 2 : 1; if (audio_output_channels <= 2) sh->channels = faac_channels > 1 ? 2 : 1;
sh->samplerate = faac_samplerate; sh->samplerate = faac_samplerate;
sh->samplesize=2; sh->samplesize=2;

View File

@ -39,7 +39,8 @@ static int bind_pcm(audio_encoder_t *encoder, muxer_stream_t *mux_a)
static int encode_pcm(audio_encoder_t *encoder, uint8_t *dest, void *src, int nsamples, int max_size) static int encode_pcm(audio_encoder_t *encoder, uint8_t *dest, void *src, int nsamples, int max_size)
{ {
max_size = FFMIN(nsamples, max_size); max_size = FFMIN(nsamples, max_size);
if (encoder->params.channels == 6 || encoder->params.channels == 5) { if (encoder->params.channels == 5 || encoder->params.channels == 6 ||
encoder->params.channels == 8) {
max_size -= max_size % (encoder->params.channels * 2); max_size -= max_size % (encoder->params.channels * 2);
reorder_channel_copy_nch(src, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, reorder_channel_copy_nch(src, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
dest, AF_CHANNEL_LAYOUT_WAVEEX_DEFAULT, dest, AF_CHANNEL_LAYOUT_WAVEEX_DEFAULT,