mirror of
https://github.com/mpv-player/mpv
synced 2024-08-24 07:21:49 +02:00
Add support for distinguishing between little- and big-endian SPDIF AC3
and converting between both. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30283 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
d3ae3611ce
commit
33bc71f10d
@ -98,6 +98,8 @@ static int control(struct af_instance_s* af, int cmd, void* arg)
|
||||
af->data->bps == data->bps)
|
||||
return AF_DETACH;
|
||||
|
||||
// Allow trivial AC3-endianness conversion
|
||||
if (!AF_FORMAT_IS_AC3(af->data->format) || !AF_FORMAT_IS_AC3(data->format))
|
||||
// Check for errors in configuration
|
||||
if((AF_OK != check_bps(data->bps)) ||
|
||||
(AF_OK != check_format(data->format)) ||
|
||||
@ -152,7 +154,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg)
|
||||
}
|
||||
case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET:{
|
||||
// Check for errors in configuration
|
||||
if(AF_OK != check_format(*(int*)arg))
|
||||
if(!AF_FORMAT_IS_AC3(*(int*)arg) && AF_OK != check_format(*(int*)arg))
|
||||
return AF_ERROR;
|
||||
|
||||
af->data->format = *(int*)arg;
|
||||
|
@ -83,6 +83,9 @@
|
||||
#define AF_FORMAT_FLOAT_LE (AF_FORMAT_F|AF_FORMAT_32BIT|AF_FORMAT_LE)
|
||||
#define AF_FORMAT_FLOAT_BE (AF_FORMAT_F|AF_FORMAT_32BIT|AF_FORMAT_BE)
|
||||
|
||||
#define AF_FORMAT_AC3_LE (AF_FORMAT_AC3|AF_FORMAT_16BIT|AF_FORMAT_LE)
|
||||
#define AF_FORMAT_AC3_BE (AF_FORMAT_AC3|AF_FORMAT_16BIT|AF_FORMAT_BE)
|
||||
|
||||
#if HAVE_BIGENDIAN
|
||||
#define AF_FORMAT_U16_NE AF_FORMAT_U16_BE
|
||||
#define AF_FORMAT_S16_NE AF_FORMAT_S16_BE
|
||||
@ -91,6 +94,7 @@
|
||||
#define AF_FORMAT_U32_NE AF_FORMAT_U32_BE
|
||||
#define AF_FORMAT_S32_NE AF_FORMAT_S32_BE
|
||||
#define AF_FORMAT_FLOAT_NE AF_FORMAT_FLOAT_BE
|
||||
#define AF_FORMAT_AC3_NE AF_FORMAT_AC3_BE
|
||||
#else
|
||||
#define AF_FORMAT_U16_NE AF_FORMAT_U16_LE
|
||||
#define AF_FORMAT_S16_NE AF_FORMAT_S16_LE
|
||||
@ -99,6 +103,7 @@
|
||||
#define AF_FORMAT_U32_NE AF_FORMAT_U32_LE
|
||||
#define AF_FORMAT_S32_NE AF_FORMAT_S32_LE
|
||||
#define AF_FORMAT_FLOAT_NE AF_FORMAT_FLOAT_LE
|
||||
#define AF_FORMAT_AC3_NE AF_FORMAT_AC3_LE
|
||||
#endif
|
||||
|
||||
#define AF_FORMAT_UNKNOWN (-1)
|
||||
|
@ -58,7 +58,7 @@ static int control(struct af_instance_s *af, int cmd, void *arg)
|
||||
|
||||
switch (cmd){
|
||||
case AF_CONTROL_REINIT:
|
||||
if (data->format == AF_FORMAT_AC3 || data->nch < s->min_channel_num)
|
||||
if (AF_FORMAT_IS_AC3(data->format) || data->nch < s->min_channel_num)
|
||||
return AF_DETACH;
|
||||
|
||||
s->pending_len = 0;
|
||||
@ -102,7 +102,7 @@ static int control(struct af_instance_s *af, int cmd, void *arg)
|
||||
return AF_ERROR;
|
||||
}
|
||||
}
|
||||
af->data->format = AF_FORMAT_AC3;
|
||||
af->data->format = AF_FORMAT_AC3_NE;
|
||||
af->data->nch = 2;
|
||||
return test_output_res;
|
||||
case AF_CONTROL_COMMAND_LINE:
|
||||
|
@ -47,7 +47,7 @@ int af_str2fmt(const char* str)
|
||||
format |= AF_FORMAT_A_LAW; return format;
|
||||
}
|
||||
if(strstr(str,"ac3") || strstr(str,"AC3")){
|
||||
format |= AF_FORMAT_AC3; return format;
|
||||
format |= AF_FORMAT_AC3 | AF_FORMAT_16BIT; return format;
|
||||
}
|
||||
if(strstr(str,"mpeg2") || strstr(str,"MPEG2")){
|
||||
format |= AF_FORMAT_MPEG2; return format;
|
||||
@ -158,7 +158,9 @@ static struct {
|
||||
{ "mulaw", AF_FORMAT_MU_LAW },
|
||||
{ "alaw", AF_FORMAT_A_LAW },
|
||||
{ "mpeg2", AF_FORMAT_MPEG2 },
|
||||
{ "ac3", AF_FORMAT_AC3 },
|
||||
{ "ac3le", AF_FORMAT_AC3_LE },
|
||||
{ "ac3be", AF_FORMAT_AC3_BE },
|
||||
{ "ac3ne", AF_FORMAT_AC3_NE },
|
||||
{ "imaadpcm", AF_FORMAT_IMA_ADPCM },
|
||||
|
||||
{ "u8", AF_FORMAT_U8 },
|
||||
|
@ -364,15 +364,11 @@ static int init(int rate_hz, int channels, int format, int flags)
|
||||
case AF_FORMAT_U16_BE:
|
||||
alsa_format = SND_PCM_FORMAT_U16_BE;
|
||||
break;
|
||||
#if !HAVE_BIGENDIAN
|
||||
case AF_FORMAT_AC3:
|
||||
#endif
|
||||
case AF_FORMAT_AC3_LE:
|
||||
case AF_FORMAT_S16_LE:
|
||||
alsa_format = SND_PCM_FORMAT_S16_LE;
|
||||
break;
|
||||
#if HAVE_BIGENDIAN
|
||||
case AF_FORMAT_AC3:
|
||||
#endif
|
||||
case AF_FORMAT_AC3_BE:
|
||||
case AF_FORMAT_S16_BE:
|
||||
alsa_format = SND_PCM_FORMAT_S16_BE;
|
||||
break;
|
||||
@ -535,6 +531,9 @@ static int init(int rate_hz, int channels, int format, int flags)
|
||||
mp_msg(MSGT_AO,MSGL_INFO,
|
||||
MSGTR_AO_ALSA_FormatNotSupportedByHardware, af_fmt2str_short(format));
|
||||
alsa_format = SND_PCM_FORMAT_S16_LE;
|
||||
if (AF_FORMAT_IS_AC3(ao_data.format))
|
||||
ao_data.format = AF_FORMAT_AC3_LE;
|
||||
else
|
||||
ao_data.format = AF_FORMAT_S16_LE;
|
||||
}
|
||||
|
||||
|
@ -101,15 +101,11 @@ static int init(int rate_hz, int channels, int format, int flags)
|
||||
case AF_FORMAT_U16_BE:
|
||||
alsa_format.format = SND_PCM_SFMT_U16_BE;
|
||||
break;
|
||||
#if !HAVE_BIGENDIAN
|
||||
case AF_FORMAT_AC3:
|
||||
#endif
|
||||
case AF_FORMAT_AC3_LE:
|
||||
case AF_FORMAT_S16_LE:
|
||||
alsa_format.format = SND_PCM_SFMT_S16_LE;
|
||||
break;
|
||||
#if HAVE_BIGENDIAN
|
||||
case AF_FORMAT_AC3:
|
||||
#endif
|
||||
case AF_FORMAT_AC3_BE:
|
||||
case AF_FORMAT_S16_BE:
|
||||
alsa_format.format = SND_PCM_SFMT_S16_BE;
|
||||
break;
|
||||
|
@ -432,8 +432,11 @@ static int init(int rate, int channels, int format, int flags)
|
||||
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;
|
||||
switch(format){
|
||||
case AF_FORMAT_AC3:
|
||||
case AF_FORMAT_AC3_NE:
|
||||
case AF_FORMAT_S24_LE:
|
||||
case AF_FORMAT_S16_LE:
|
||||
case AF_FORMAT_U8:
|
||||
|
@ -250,9 +250,12 @@ static int init(int rate,int channels,int format,int flags){
|
||||
switch(format){
|
||||
case AF_FORMAT_S16_BE:
|
||||
case AF_FORMAT_MPEG2:
|
||||
case AF_FORMAT_AC3:
|
||||
case AF_FORMAT_AC3_BE:
|
||||
ao_data.format=format;
|
||||
break;
|
||||
case AF_FORMAT_AC3_LE:
|
||||
ao_data.format=AF_FORMAT_AC3_BE;
|
||||
break;
|
||||
default:
|
||||
ao_data.format=AF_FORMAT_S16_BE;
|
||||
}
|
||||
@ -333,8 +336,6 @@ static int play(void* data,int len,int flags){
|
||||
unsigned short *s=data;
|
||||
// if(len>2000) len=2000;
|
||||
// printf("ao_mpegpes: len=%d \n",len);
|
||||
if(ao_data.format==AF_FORMAT_AC3)
|
||||
for(i=0;i<len/2;i++) s[i]=(s[i]>>8)|(s[i]<<8); // le<->be
|
||||
send_mpeg_lpcm_packet(data, len, 0xA0, ao_data.pts, freq_id, my_ao_write);
|
||||
}
|
||||
return len;
|
||||
|
@ -96,7 +96,7 @@ static int format2oss(int format)
|
||||
case AF_FORMAT_MPEG2: return AFMT_MPEG;
|
||||
#endif
|
||||
#ifdef AFMT_AC3
|
||||
case AF_FORMAT_AC3: return AFMT_AC3;
|
||||
case AF_FORMAT_AC3_NE: return AFMT_AC3;
|
||||
#endif
|
||||
}
|
||||
mp_msg(MSGT_AO, MSGL_V, "OSS: Unknown/not supported internal format: %s\n", af_fmt2str_short(format));
|
||||
@ -139,7 +139,7 @@ static int oss2format(int format)
|
||||
case AFMT_MPEG: return AF_FORMAT_MPEG2;
|
||||
#endif
|
||||
#ifdef AFMT_AC3
|
||||
case AFMT_AC3: return AF_FORMAT_AC3;
|
||||
case AFMT_AC3: return AF_FORMAT_AC3_NE;
|
||||
#endif
|
||||
}
|
||||
mp_msg(MSGT_GLOBAL,MSGL_ERR,MSGTR_AO_OSS_UnknownUnsupportedFormat, format);
|
||||
@ -303,6 +303,8 @@ static int init(int rate,int channels,int format,int flags){
|
||||
}
|
||||
|
||||
ac3_retry:
|
||||
if (AF_FORMAT_IS_AC3(format))
|
||||
format = AF_FORMAT_AC3_NE;
|
||||
ao_data.format=format;
|
||||
oss_format=format2oss(format);
|
||||
if (oss_format == -1) {
|
||||
|
@ -127,7 +127,8 @@ static int init(int rate,int channels,int format,int flags){
|
||||
format=AF_FORMAT_U8;
|
||||
case AF_FORMAT_U8:
|
||||
break;
|
||||
case AF_FORMAT_AC3:
|
||||
case AF_FORMAT_AC3_BE:
|
||||
case AF_FORMAT_AC3_LE:
|
||||
bits=16;
|
||||
break;
|
||||
default:
|
||||
|
@ -143,8 +143,10 @@ static int init(int rate,int channels,int format,int flags)
|
||||
unsigned char* buffer;
|
||||
int i;
|
||||
|
||||
if (AF_FORMAT_IS_AC3(format))
|
||||
format = AF_FORMAT_AC3_NE;
|
||||
switch(format){
|
||||
case AF_FORMAT_AC3:
|
||||
case AF_FORMAT_AC3_NE:
|
||||
case AF_FORMAT_S24_LE:
|
||||
case AF_FORMAT_S16_LE:
|
||||
case AF_FORMAT_U8:
|
||||
|
@ -151,7 +151,7 @@ static int preinit(sh_audio_t *sh)
|
||||
sh->audio_in_minsize = 8192;
|
||||
sh->channels = 2;
|
||||
sh->samplesize = 2;
|
||||
sh->sample_format = AF_FORMAT_AC3;
|
||||
sh->sample_format = AF_FORMAT_AC3_NE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1146,7 +1146,9 @@ static struct {
|
||||
{"mulaw", AF_FORMAT_MU_LAW},
|
||||
{"alaw", AF_FORMAT_A_LAW},
|
||||
{"mpeg2", AF_FORMAT_MPEG2},
|
||||
{"ac3", AF_FORMAT_AC3},
|
||||
{"ac3le", AF_FORMAT_AC3_LE},
|
||||
{"ac3be", AF_FORMAT_AC3_BE},
|
||||
{"ac3ne", AF_FORMAT_AC3_NE},
|
||||
{"imaadpcm", AF_FORMAT_IMA_ADPCM},
|
||||
// ORIDNARY
|
||||
{"u8", AF_FORMAT_U8},
|
||||
|
@ -760,7 +760,6 @@ static demuxer_t* demux_open_tv(demuxer_t *demuxer)
|
||||
case AF_FORMAT_MU_LAW:
|
||||
case AF_FORMAT_A_LAW:
|
||||
case AF_FORMAT_MPEG2:
|
||||
case AF_FORMAT_AC3:
|
||||
default:
|
||||
mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_UnsupportedAudioType,
|
||||
af_fmt2str(audio_format, buf, 128), audio_format);
|
||||
|
Loading…
Reference in New Issue
Block a user