summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rwxr-xr-xconfigure30
-rw-r--r--etc/codecs.conf10
-rw-r--r--libaf/af_format.c4
-rw-r--r--libaf/af_format.h9
-rw-r--r--libaf/af_lavcac3enc.c30
-rw-r--r--libaf/format.c7
-rw-r--r--libao2/ao_alsa.c22
-rw-r--r--libao2/ao_alsa5.c8
-rw-r--r--libao2/ao_coreaudio.c28
-rw-r--r--libao2/ao_dsound.c9
-rw-r--r--libao2/ao_dxr2.c2
-rw-r--r--libao2/ao_mpegpes.c7
-rw-r--r--libao2/ao_oss.c16
-rw-r--r--libao2/ao_pcm.c3
-rw-r--r--libao2/ao_win32.c6
-rw-r--r--libmpcodecs/ad.c2
-rw-r--r--libmpcodecs/ad_hwac3.c88
-rw-r--r--libmpdemux/demux_ts.c18
-rw-r--r--libmpeg2/motion_comp_mmx.c8
-rw-r--r--libvo/vo_directfb2.c3
-rw-r--r--loader/wine/winnt.h12
-rw-r--r--m_option.c4
-rw-r--r--stream/tv.c1
-rw-r--r--vidix/AsmMacros.h34
25 files changed, 178 insertions, 187 deletions
diff --git a/Makefile b/Makefile
index 3e2174d07f..f8d3982ac7 100644
--- a/Makefile
+++ b/Makefile
@@ -106,8 +106,7 @@ SRCS_COMMON-$(HAVE_POSIX_SELECT) += libmpcodecs/vf_bmovl.c
SRCS_COMMON-$(HAVE_SYS_MMAN_H) += libaf/af_export.c osdep/mmap_anon.c
SRCS_COMMON-$(JPEG) += libmpcodecs/vd_ijpg.c
SRCS_COMMON-$(LADSPA) += libaf/af_ladspa.c
-SRCS_COMMON-$(LIBA52) += libmpcodecs/ad_hwac3.c \
- libmpcodecs/ad_liba52.c
+SRCS_COMMON-$(LIBA52) += libmpcodecs/ad_liba52.c
SRCS_COMMON-$(LIBA52_INTERNAL) += liba52/crc.c \
liba52/resample.c \
liba52/bit_allocate.c \
@@ -375,6 +374,7 @@ SRCS_COMMON = asxparser.c \
libmpcodecs/ad_alaw.c \
libmpcodecs/ad_dk3adpcm.c \
libmpcodecs/ad_dvdpcm.c \
+ libmpcodecs/ad_hwac3.c \
libmpcodecs/ad_hwmpa.c \
libmpcodecs/ad_imaadpcm.c \
libmpcodecs/ad_msadpcm.c \
diff --git a/configure b/configure
index 8a09d5a79e..93bfd4d0d6 100755
--- a/configure
+++ b/configure
@@ -1467,7 +1467,7 @@ if test "$(basename $_cc)" = "icc" || test "$(basename $_cc)" = "ecc"; then
esac
echores "$cc_version"
else
- for _cc in "$_cc" cc gcc ; do
+ for _cc in "$_cc" gcc cc ; do
cc_name_tmp=$($_cc -v 2>&1 | tail -n 1 | cut -d ' ' -f 1)
if test "$cc_name_tmp" = "gcc"; then
cc_name=$cc_name_tmp
@@ -1487,6 +1487,15 @@ else
echores "$cc_version"
break
fi
+ cc_name_tmp=$($_cc -V 2>&1 | head -n 1 | cut -d ' ' -f 2,3)
+ if test "$cc_name_tmp" = "Sun C"; then
+ echocheck "$_cc version"
+ cc_vendor=sun
+ cc_version=$($_cc -V 2>&1 | head -n 1 | cut -d ' ' -f 4)
+ _res_comment="experimental support only"
+ echores "Sun C $cc_version"
+ break
+ fi
done
fi # icc
test "$cc_fail" = yes && die "unsupported compiler version"
@@ -1548,9 +1557,10 @@ if test "$_runtime_cpudetection" = no ; then
if test -r /proc/cpuinfo && ! cygwin; then
# Linux with /proc mounted, extract CPU information from it
_cpuinfo="cat /proc/cpuinfo"
-elif test -r /compat/linux/proc/cpuinfo && ! x86_32 ; then
+elif test -r /compat/linux/proc/cpuinfo && ! x86 ; then
# FreeBSD with Linux emulation /proc mounted,
# extract CPU information from it
+ # Don't use it on x86 though, it never reports 3Dnow
_cpuinfo="cat /compat/linux/proc/cpuinfo"
elif darwin && ! x86 ; then
# use hostinfo on Darwin
@@ -2315,7 +2325,8 @@ echocheck "assembler support of -pipe option"
cat > $TMPC << EOF
int main(void) { return 0; }
EOF
-cc_check -pipe && _pipe="-pipe" && echores "yes" || echores "no"
+# -I. helps to detect compilers that just misunderstand -pipe like Sun C
+cc_check -pipe -I. && _pipe="-pipe" && echores "yes" || echores "no"
echocheck "compiler support of named assembler arguments"
@@ -2356,6 +2367,8 @@ if test "$_profile" != "" || test "$_debug" != "" ; then
elif test -z "$CFLAGS" ; then
if test "$cc_vendor" = "intel" ; then
CFLAGS="-O2 $_march $_mcpu $_pipe -fomit-frame-pointer -wd167 -wd556 -wd144"
+ elif test "$cc_vendor" = "sun" ; then
+ CFLAGS="-O2 $_march $_mcpu $_pipe -xc99 -xregs=frameptr"
elif test "$cc_vendor" != "gnu" ; then
CFLAGS="-O2 $_march $_mcpu $_pipe"
else
@@ -2905,7 +2918,7 @@ if test "$_posix4" = yes ; then
fi
echores "$_posix4"
-for func in llrint log2 lrint lrintf round roundf truncf; do
+for func in exp2 exp2f llrint log2 log2f lrint lrintf round roundf truncf; do
echocheck $func
cat > $TMPC << EOF
#include <math.h>
@@ -4112,7 +4125,7 @@ echocheck "X11 headers presence"
fi
done
if test $_cross_compile = no; then
- for I in /usr/X11/include /usr/X11R7/include /usr/X11R6/include \
+ for I in /usr/X11/include /usr/X11R7/include /usr/local/include /usr/X11R6/include \
/usr/include/X11R6 /usr/openwin/include ; do
if test -f "$I/X11/Xlib.h" ; then
extra_cflags="$extra_cflags -I$I"
@@ -4132,8 +4145,8 @@ if test "$_x11" = auto && test "$_x11_headers" = yes ; then
#include <X11/Xutil.h>
int main(void) { (void) XCreateWindow(0,0,0,0,0,0,0,0,0,0,0,0); return 0; }
EOF
- for I in "" -L/usr/X11R7/lib -L/usr/X11R6/lib -L/usr/lib/X11R6 \
- -L/usr/X11/lib -L/usr/lib32 -L/usr/openwin/lib -L/usr/X11R6/lib64 \
+ for I in "" -L/usr/X11R7/lib -L/usr/local/lib -L/usr/X11R6/lib -L/usr/lib/X11R6 \
+ -L/usr/X11/lib -L/usr/lib32 -L/usr/openwin/lib -L/usr/local/lib64 -L/usr/X11R6/lib64 \
-L/usr/lib ; do
if netbsd; then
_ld_tmp="$I -lXext -lX11 $_ld_pthread -Wl,-R$(echo $I | sed s/^-L//)"
@@ -8124,12 +8137,15 @@ $def_winsock2_h
/* system functions */
+$def_exp2
+$def_exp2f
$def_gethostbyname2
$def_gettimeofday
$def_glob
$def_langinfo
$def_llrint
$def_log2
+$def_log2f
$def_lrint
$def_lrintf
$def_map_memalign
diff --git a/etc/codecs.conf b/etc/codecs.conf
index 3b065b7e05..0f821628d5 100644
--- a/etc/codecs.conf
+++ b/etc/codecs.conf
@@ -1999,7 +1999,7 @@ videocodec smv2vfw
videocodec cfhdvfw
status working
info "CineForm HD"
- comment "set registry keys for half-res decoding"
+ comment "windows only" ; set registry keys for half-res decoding
status working
fourcc CFHD
driver vfw
@@ -3488,6 +3488,14 @@ audiocodec ffatrc
driver ffmpeg
dll "atrac3"
+audiocodec ffsipr
+ info "FFmpeg Sipr/Acelp.net audio"
+ status buggy ; missing 16k support
+ format 0x72706973 ; "sipr"
+ format 0x130 ; acelp.net
+ driver ffmpeg
+ dll "sipr"
+
audiocodec ra144
info "RealAudio 1.0"
status working
diff --git a/libaf/af_format.c b/libaf/af_format.c
index 64acbbb9b6..3b9b907882 100644
--- a/libaf/af_format.c
+++ b/libaf/af_format.c
@@ -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;
diff --git a/libaf/af_format.h b/libaf/af_format.h
index e5e5c1cb05..5f194c1365 100644
--- a/libaf/af_format.h
+++ b/libaf/af_format.h
@@ -59,7 +59,7 @@
#define AF_FORMAT_MU_LAW (1<<6)
#define AF_FORMAT_A_LAW (2<<6)
#define AF_FORMAT_MPEG2 (3<<6) // MPEG(2) audio
-#define AF_FORMAT_AC3 ((4<<6)|AF_FORMAT_16BIT) // Dolby Digital AC3
+#define AF_FORMAT_AC3 (4<<6) // Dolby Digital AC3
#define AF_FORMAT_IMA_ADPCM (5<<6)
#define AF_FORMAT_SPECIAL_MASK (7<<6)
@@ -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,10 +103,13 @@
#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)
+#define AF_FORMAT_IS_AC3(fmt) (((fmt) & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_AC3)
+
int af_str2fmt(const char *str);
int af_str2fmt_short(const char *str);
int af_fmt2bits(int format);
diff --git a/libaf/af_lavcac3enc.c b/libaf/af_lavcac3enc.c
index 628c397002..a86b7fbdbd 100644
--- a/libaf/af_lavcac3enc.c
+++ b/libaf/af_lavcac3enc.c
@@ -32,6 +32,7 @@
#include "libavcodec/avcodec.h"
#include "libavcodec/ac3.h"
+#include "libavutil/intreadwrite.h"
// Data for specific instances of this filter
typedef struct af_ac3enc_s {
@@ -58,7 +59,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 +103,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_BE;
af->data->nch = 2;
return test_output_res;
case AF_CONTROL_COMMAND_LINE:
@@ -235,28 +236,13 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data)
len, s->pending_len);
if (s->add_iec61937_header) {
- int16_t *out = (int16_t *)buf;
int bsmod = dest[5] & 0x7;
-#if !HAVE_BIGENDIAN
- int i;
- char tmp;
- for (i = 0; i < len; i += 2) {
- tmp = dest[i];
- dest[i] = dest[i+1];
- dest[i+1] = tmp;
- }
- if (len & 1) {
- dest[len] = dest[len-1];
- dest[len-1] = 0;
- len++;
- }
-#endif
- out[0] = 0xF872; // iec 61937 syncword 1
- out[1] = 0x4E1F; // iec 61937 syncword 2
- out[2] = 0x0001; // data-type ac3
- out[2] |= bsmod << 8; // bsmod
- out[3] = len << 3; // number of bits in payload
+ AV_WB16(buf, 0xF872); // iec 61937 syncword 1
+ AV_WB16(buf + 2, 0x4E1F); // iec 61937 syncword 2
+ buf[4] = bsmod; // bsmod
+ buf[5] = 0x01; // data-type ac3
+ AV_WB16(buf + 6, len << 3); // number of bits in payload
memset(buf + 8 + len, 0, AC3_FRAME_SIZE * 2 * 2 - 8 - len);
len = AC3_FRAME_SIZE * 2 * 2;
diff --git a/libaf/format.c b/libaf/format.c
index 93dfdbbc31..8146899c7e 100644
--- a/libaf/format.c
+++ b/libaf/format.c
@@ -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;
@@ -74,6 +74,7 @@ int af_str2fmt(const char* str)
int af_fmt2bits(int format)
{
+ if (AF_FORMAT_IS_AC3(format)) return 16;
return (format & AF_FORMAT_BITS_MASK)+8;
// return (((format & AF_FORMAT_BITS_MASK)>>3)+1) * 8;
#if 0
@@ -157,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 },
diff --git a/libao2/ao_alsa.c b/libao2/ao_alsa.c
index 140b13a62a..92b8b64ea7 100644
--- a/libao2/ao_alsa.c
+++ b/libao2/ao_alsa.c
@@ -128,7 +128,7 @@ static int control(int cmd, void *arg)
long get_vol, set_vol;
float f_multi;
- if(ao_data.format == AF_FORMAT_AC3)
+ if(AF_FORMAT_IS_AC3(ao_data.format))
return CONTROL_TRUE;
if(mixer_channel) {
@@ -374,15 +374,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;
@@ -437,7 +433,7 @@ static int init(int rate_hz, int channels, int format, int flags)
* while opening the abstract alias for the spdif subdevice
* 'iec958'
*/
- if (format == AF_FORMAT_AC3) {
+ if (AF_FORMAT_IS_AC3(format)) {
device.str = "iec958";
mp_msg(MSGT_AO,MSGL_V,"alsa-spdif-init: playing AC3, %i channels\n", channels);
}
@@ -496,12 +492,13 @@ static int init(int rate_hz, int channels, int format, int flags)
}
if (!alsa_handler) {
+ int isac3 = AF_FORMAT_IS_AC3(format);
//modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC
- if ((err = try_open_device(alsa_device, open_mode, format == AF_FORMAT_AC3)) < 0)
+ if ((err = try_open_device(alsa_device, open_mode, isac3)) < 0)
{
if (err != -EBUSY && ao_noblock) {
mp_tmsg(MSGT_AO,MSGL_INFO,"[AO_ALSA] Open in nonblock-mode failed, trying to open in block-mode.\n");
- if ((err = try_open_device(alsa_device, 0, format == AF_FORMAT_AC3)) < 0) {
+ if ((err = try_open_device(alsa_device, 0, isac3)) < 0) {
mp_tmsg(MSGT_AO,MSGL_ERR,"[AO_ALSA] Playback open error: %s\n", snd_strerror(err));
return 0;
}
@@ -544,6 +541,9 @@ static int init(int rate_hz, int channels, int format, int flags)
mp_tmsg(MSGT_AO,MSGL_INFO,
"[AO_ALSA] Format %s is not supported by hardware, trying default.\n", 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;
}
@@ -583,7 +583,7 @@ static int init(int rate_hz, int channels, int format, int flags)
return 0;
}
- bytes_per_sample = snd_pcm_format_physical_width(alsa_format) / 8;
+ bytes_per_sample = af_fmt2bits(ao_data.format) / 8;
bytes_per_sample *= ao_data.channels;
ao_data.bps = ao_data.samplerate * bytes_per_sample;
diff --git a/libao2/ao_alsa5.c b/libao2/ao_alsa5.c
index 8843efb68a..ad17f5895f 100644
--- a/libao2/ao_alsa5.c
+++ b/libao2/ao_alsa5.c
@@ -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;
diff --git a/libao2/ao_coreaudio.c b/libao2/ao_coreaudio.c
index 130eee8f97..b60fb094e7 100644
--- a/libao2/ao_coreaudio.c
+++ b/libao2/ao_coreaudio.c
@@ -263,7 +263,7 @@ int b_alive;
ao->b_changed_mixing = 0;
/* Probe whether device support S/PDIF stream output if input is AC3 stream. */
- if ((format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_AC3)
+ if (AF_FORMAT_IS_AC3(format))
{
/* Find the ID of the default Device. */
i_param_size = sizeof(AudioDeviceID);
@@ -314,23 +314,7 @@ int b_alive;
inDesc.mSampleRate=rate;
inDesc.mFormatID=ao->b_supports_digital ? kAudioFormat60958AC3 : kAudioFormatLinearPCM;
inDesc.mChannelsPerFrame=channels;
- switch(format&AF_FORMAT_BITS_MASK){
- case AF_FORMAT_8BIT:
- inDesc.mBitsPerChannel=8;
- break;
- case AF_FORMAT_16BIT:
- inDesc.mBitsPerChannel=16;
- break;
- case AF_FORMAT_24BIT:
- inDesc.mBitsPerChannel=24;
- break;
- case AF_FORMAT_32BIT:
- inDesc.mBitsPerChannel=32;
- break;
- default:
- ao_msg(MSGT_AO, MSGL_WARN, "Unsupported format (0x%08x)\n", format);
- goto err_out;
- }
+ inDesc.mBitsPerChannel=af_fmt2bits(format);
if((format&AF_FORMAT_POINT_MASK)==AF_FORMAT_F) {
// float
@@ -344,13 +328,7 @@ int b_alive;
// unsigned int
inDesc.mFormatFlags = kAudioFormatFlagIsPacked;
}
- if ((format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_AC3) {
- // Currently ac3 input (comes from hwac3) is always in native byte-order.
-#if HAVE_BIGENDIAN
- inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian;
-#endif
- }
- else if ((format & AF_FORMAT_END_MASK) == AF_FORMAT_BE)
+ if ((format & AF_FORMAT_END_MASK) == AF_FORMAT_BE)
inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian;
inDesc.mFramesPerPacket = 1;
diff --git a/libao2/ao_dsound.c b/libao2/ao_dsound.c
index f66042a793..c53820638d 100644
--- a/libao2/ao_dsound.c
+++ b/libao2/ao_dsound.c
@@ -327,7 +327,7 @@ static int write_buffer(unsigned char *data, int len)
if (SUCCEEDED(res))
{
- if( (ao_data.channels == 6) && (ao_data.format!=AF_FORMAT_AC3) ) {
+ if( (ao_data.channels == 6) && !AF_FORMAT_IS_AC3(ao_data.format) ) {
// reorder channels while writing to pointers.
// it's this easy because buffer size and len are always
// aligned to multiples of channels*bytespersample
@@ -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:
@@ -456,7 +459,7 @@ static int init(int rate, int channels, int format, int flags)
wformat.Format.cbSize = (channels > 2) ? sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX) : 0;
wformat.Format.nChannels = channels;
wformat.Format.nSamplesPerSec = rate;
- if (format == AF_FORMAT_AC3) {
+ if (AF_FORMAT_IS_AC3(format)) {
wformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
wformat.Format.wBitsPerSample = 16;
wformat.Format.nBlockAlign = 4;
diff --git a/libao2/ao_dxr2.c b/libao2/ao_dxr2.c
index 4712f3341f..f9e31836d5 100644
--- a/libao2/ao_dxr2.c
+++ b/libao2/ao_dxr2.c
@@ -201,7 +201,7 @@ static int play(void* data,int len,int flags){
// MPEG and AC3 don't work :-(
if(ao_data.format==AF_FORMAT_MPEG2)
send_mpeg_ps_packet (data, len, 0xC0, ao_data.pts, 2, write_dxr2);
- else if(ao_data.format==AF_FORMAT_AC3)
+ else if(AF_FORMAT_IS_AC3(ao_data.format))
send_mpeg_ps_packet (data, len, 0x80, ao_data.pts, 2, write_dxr2);
else {
int i;
diff --git a/libao2/ao_mpegpes.c b/libao2/ao_mpegpes.c
index 47a75d7545..f6ab1c6aca 100644
--- a/libao2/ao_mpegpes.c
+++ b/libao2/ao_mpegpes.c
@@ -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;
}
@@ -331,8 +334,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;
diff --git a/libao2/ao_oss.c b/libao2/ao_oss.c
index 6872b15946..58d3b233cc 100644
--- a/libao2/ao_oss.c
+++ b/libao2/ao_oss.c
@@ -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_tmsg(MSGT_GLOBAL,MSGL_ERR,"[AO OSS] Unknown/Unsupported OSS format: %x.\n", format);
@@ -208,7 +208,7 @@ static int control(int cmd,void *arg){
return CONTROL_OK;
#endif
- if(ao_data.format == AF_FORMAT_AC3)
+ if(AF_FORMAT_IS_AC3(ao_data.format))
return CONTROL_TRUE;
if ((fd = open(oss_mixer_device, O_RDONLY)) > 0)
@@ -326,12 +326,14 @@ static int init(int rate,int channels,int format,int flags){
fcntl(audio_fd, F_SETFD, FD_CLOEXEC);
#endif
- if(format == AF_FORMAT_AC3) {
+ if(AF_FORMAT_IS_AC3(format)) {
ao_data.samplerate=rate;
ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate);
}
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) {
@@ -361,7 +363,7 @@ ac3_retry:
af_fmt2str_short(ao_data.format), af_fmt2str_short(format));
ao_data.channels = channels;
- if(format != AF_FORMAT_AC3) {
+ if(!AF_FORMAT_IS_AC3(format)) {
// We only use SNDCTL_DSP_CHANNELS for >2 channels, in case some drivers don't have it
if (ao_data.channels > 2) {
if ( ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &ao_data.channels) == -1 ||
@@ -476,10 +478,10 @@ static void reset(void){
#endif
oss_format = format2oss(ao_data.format);
- if(ao_data.format == AF_FORMAT_AC3)
+ if(AF_FORMAT_IS_AC3(ao_data.format))
ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate);
ioctl (audio_fd, SNDCTL_DSP_SETFMT, &oss_format);
- if(ao_data.format != AF_FORMAT_AC3) {
+ if(!AF_FORMAT_IS_AC3(ao_data.format)) {
if (ao_data.channels > 2)
ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &ao_data.channels);
else {
diff --git a/libao2/ao_pcm.c b/libao2/ao_pcm.c
index a03f41193e..5c418d0f5a 100644
--- a/libao2/ao_pcm.c
+++ b/libao2/ao_pcm.c
@@ -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:
diff --git a/libao2/ao_win32.c b/libao2/ao_win32.c
index a0475455ec..55ed17b457 100644
--- a/libao2/ao_win32.c
+++ b/libao2/ao_win32.c
@@ -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:
@@ -180,7 +182,7 @@ static int init(int rate,int channels,int format,int flags)
wformat.Format.cbSize = (channels>2)?sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX):0;
wformat.Format.nChannels = channels;
wformat.Format.nSamplesPerSec = rate;
- if(format == AF_FORMAT_AC3)
+ if(AF_FORMAT_IS_AC3(format))
{
wformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
wformat.Format.wBitsPerSample = 16;
diff --git a/libmpcodecs/ad.c b/libmpcodecs/ad.c
index c7e87cd92e..5843a49ae8 100644
--- a/libmpcodecs/ad.c
+++ b/libmpcodecs/ad.c
@@ -49,8 +49,8 @@ const ad_functions_t * const mpcodecs_ad_drivers[] =
#endif
#ifdef CONFIG_LIBA52
&mpcodecs_ad_liba52,
- &mpcodecs_ad_hwac3,
#endif
+ &mpcodecs_ad_hwac3,
&mpcodecs_ad_hwmpa,
#ifdef CONFIG_LIBAVCODEC
&mpcodecs_ad_ffmpeg,
diff --git a/libmpcodecs/ad_hwac3.c b/libmpcodecs/ad_hwac3.c
index 4dadf1723f..e6c7446631 100644
--- a/libmpcodecs/ad_hwac3.c
+++ b/libmpcodecs/ad_hwac3.c
@@ -15,15 +15,11 @@
#include "mp_msg.h"
#include "help_mp.h"
#include "mpbswap.h"
+#include "libavutil/common.h"
+#include "ffmpeg_files/intreadwrite.h"
#include "ad_internal.h"
-#ifdef CONFIG_LIBA52_INTERNAL
-#include "liba52/a52.h"
-#else
-#include <a52dec/a52.h>
-#endif
-
static int isdts = -1;
@@ -43,6 +39,44 @@ static int dts_syncinfo(uint8_t *indata_ptr, int *flags, int *sample_rate, int *
static int decode_audio_dts(unsigned char *indata_ptr, int len, unsigned char *buf);
+static int a52_syncinfo (uint8_t *buf, int *sample_rate, int *bit_rate)
+{
+ static const uint16_t rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320, 384, 448,
+ 512, 576, 640};
+ int frmsizecod;
+ int bitrate;
+ int half;
+
+ if (buf[0] != 0x0b || buf[1] != 0x77) /* syncword */
+ return 0;
+
+ if (buf[5] >= 0x60) /* bsid >= 12 */
+ return 0;
+ half = buf[5] >> 3;
+ half = FFMAX(half - 8, 0);
+
+ frmsizecod = buf[4] & 63;
+ if (frmsizecod >= 38)
+ return 0;
+ bitrate = rate[frmsizecod >> 1];
+ *bit_rate = (bitrate * 1000) >> half;
+
+ switch (buf[4] & 0xc0) {
+ case 0:
+ *sample_rate = 48000 >> half;
+ return 4 * bitrate;
+ case 0x40:
+ *sample_rate = 44100 >> half;
+ return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
+ case 0x80:
+ *sample_rate = 32000 >> half;
+ return 6 * bitrate;
+ default:
+ return 0;
+ }
+}
+
static int ac3dts_fillbuff(sh_audio_t *sh_audio)
{
int length = 0;
@@ -79,7 +113,7 @@ static int ac3dts_fillbuff(sh_audio_t *sh_audio)
}
else
{
- length = a52_syncinfo(sh_audio->a_in_buffer, &flags, &sample_rate, &bit_rate);
+ length = a52_syncinfo(sh_audio->a_in_buffer, &sample_rate, &bit_rate);
if(length >= 7 && length <= 3840)
{
if(isdts != 0)
@@ -101,12 +135,6 @@ static int ac3dts_fillbuff(sh_audio_t *sh_audio)
demux_read_data(sh_audio->ds, sh_audio->a_in_buffer + 12, length - 12);
sh_audio->a_in_buffer_len = length;
- // TODO: is DTS also checksummed?
-#ifdef CONFIG_LIBA52_INTERNAL
- if(isdts == 0 && crc16_block(sh_audio->a_in_buffer + 2, length - 2) != 0)
- mp_msg(MSGT_DECAUDIO, MSGL_STATUS, "a52: CRC check failed! \n");
-#endif
-
return length;
}
@@ -118,32 +146,26 @@ 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_BE;
+ // HACK for DTS where useless swapping can't easily be removed
+ if (sh->format == 0x2001)
+ sh->sample_format = AF_FORMAT_AC3_NE;
return 1;
}
static int init(sh_audio_t *sh_audio)
{
/* Dolby AC3 passthrough:*/
- a52_state_t *a52_state = a52_init(0);
- if(a52_state == NULL)
- {
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "A52 init failed\n");
- return 0;
- }
if(ac3dts_fillbuff(sh_audio) < 0)
{
- a52_free(a52_state);
mp_msg(MSGT_DECAUDIO, MSGL_ERR, "AC3/DTS sync failed\n");
return 0;
}
- sh_audio->context = a52_state;
return 1;
}
static void uninit(sh_audio_t *sh)
{
- a52_free(sh->context);
}
static int control(sh_audio_t *sh,int cmd,void* arg, ...)
@@ -174,22 +196,12 @@ static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int m
}
else if(isdts == 0)
{
- uint16_t *buf16 = (uint16_t *)buf;
- buf16[0] = 0xF872; // iec 61937 syncword 1
- buf16[1] = 0x4E1F; // iec 61937 syncword 2
- buf16[2] = 0x0001; // data-type ac3
- buf16[2] |= (sh_audio->a_in_buffer[5] & 0x7) << 8; // bsmod
- buf16[3] = len << 3; // number of bits in payload
-#if HAVE_BIGENDIAN
+ AV_WB16(buf, 0xF872); // iec 61937 syncword 1
+ AV_WB16(buf + 2, 0x4E1F); // iec 61937 syncword 2
+ buf[4] = sh_audio->a_in_buffer[5] & 0x7; // bsmod
+ buf[5] = 0x01; // data-type ac3
+ AV_WB16(buf + 6, len << 3); // number of bits in payload
memcpy(buf + 8, sh_audio->a_in_buffer, len);
-#else
- swab(sh_audio->a_in_buffer, buf + 8, len);
- if (len & 1) {
- buf[8+len-1] = 0;