Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
fb397dc0
Commit
fb397dc0
authored
Dec 10, 2005
by
Derk-Jan Hartman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* Backport of the Mac OS X audio fixes to 0.8.4a (fixes #456)
parent
b759e185
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
947 additions
and
528 deletions
+947
-528
Makefile.am
Makefile.am
+0
-4
configure.ac
configure.ac
+6
-6
include/audio_output.h
include/audio_output.h
+3
-0
modules/audio_filter/converter/a52tospdif.c
modules/audio_filter/converter/a52tospdif.c
+34
-27
modules/audio_filter/converter/dtstospdif.c
modules/audio_filter/converter/dtstospdif.c
+30
-16
modules/audio_filter/resampler/Modules.am
modules/audio_filter/resampler/Modules.am
+0
-1
modules/audio_filter/resampler/coreaudio.c
modules/audio_filter/resampler/coreaudio.c
+0
-298
modules/audio_output/Modules.am
modules/audio_output/Modules.am
+0
-1
modules/audio_output/auhal.c
modules/audio_output/auhal.c
+738
-136
modules/audio_output/coreaudio.c
modules/audio_output/coreaudio.c
+135
-39
src/audio_output/common.c
src/audio_output/common.c
+1
-0
No files found.
Makefile.am
View file @
fb397dc0
...
...
@@ -577,8 +577,6 @@ VLC-release.app: vlc
cp
"
$(srcdir)
/
$$
i"
$(top_builddir)
/tmp
;
\
done
mkdir
-p
$(top_builddir)
/tmp/modules/audio_output
cp
$(srcdir)
/modules/audio_output/coreaudio.c
\
$(top_builddir)
/tmp/modules/audio_output/coreaudio.c
mkdir
-p
$(top_builddir)
/tmp/modules/gui/macosx
for
i
in
\
about.h
\
...
...
@@ -691,8 +689,6 @@ VLC.app: vlc
cp
"
$(srcdir)
/
$$
i"
$(top_builddir)
/tmp
;
\
done
mkdir
-p
$(top_builddir)
/tmp/modules/audio_output
cp
$(srcdir)
/modules/audio_output/coreaudio.c
\
$(top_builddir)
/tmp/modules/audio_output/coreaudio.c
mkdir
-p
$(top_builddir)
/tmp/modules/gui/macosx
for
i
in
\
about.h
\
...
...
configure.ac
View file @
fb397dc0
...
...
@@ -3627,14 +3627,14 @@ fi
dnl
dnl CoreAudio plugin
dnl
AC_ARG_ENABLE(
core
audio,
[ --enable-
coreaudio CoreA
udio module (default enabled on MacOS X)])
if test "${enable_
core
audio}" != "no" &&
(test "${SYS}" = "darwin" || test "${enable_
core
audio}" = "yes")
AC_ARG_ENABLE(
macosx-
audio,
[ --enable-
macosx-audio Mac OS X a
udio module (default enabled on MacOS X)])
if test "${enable_
macosx-
audio}" != "no" &&
(test "${SYS}" = "darwin" || test "${enable_
macosx-
audio}" = "yes")
then
AC_CHECK_HEADERS(CoreAudio/CoreAudio.h,
[ VLC_ADD_BUILTINS([
coreaudio
auhal])
VLC_ADD_LDFLAGS([
coreaudio
auhal],[-framework CoreAudio -framework AudioUnit -framework AudioToolbox])
[ VLC_ADD_BUILTINS([auhal])
VLC_ADD_LDFLAGS([auhal],[-framework CoreAudio -framework AudioUnit -framework AudioToolbox])
], [ AC_MSG_ERROR([cannot find CoreAudio headers]) ])
fi
...
...
include/audio_output.h
View file @
fb397dc0
...
...
@@ -41,14 +41,17 @@
# define AOUT_FMT_S16_NE VLC_FOURCC('s','1','6','b')
# define AOUT_FMT_U16_NE VLC_FOURCC('u','1','6','b')
# define AOUT_FMT_S24_NE VLC_FOURCC('s','2','4','b')
# define AOUT_FMT_SPDIF_NE VLC_FOURCC('s','p','d','b')
#else
# define AOUT_FMT_S16_NE VLC_FOURCC('s','1','6','l')
# define AOUT_FMT_U16_NE VLC_FOURCC('u','1','6','l')
# define AOUT_FMT_S24_NE VLC_FOURCC('s','2','4','l')
# define AOUT_FMT_SPDIF_NE VLC_FOURCC('s','p','d','i')
#endif
#define AOUT_FMT_NON_LINEAR( p_format ) \
( ((p_format)->i_format == VLC_FOURCC('s','p','d','i')) \
|| ((p_format)->i_format == VLC_FOURCC('s','p','d','b')) \
|| ((p_format)->i_format == VLC_FOURCC('a','5','2',' ')) \
|| ((p_format)->i_format == VLC_FOURCC('d','t','s',' ')) )
...
...
modules/audio_filter/converter/a52tospdif.c
View file @
fb397dc0
...
...
@@ -62,8 +62,9 @@ static int Create( vlc_object_t *p_this )
{
aout_filter_t
*
p_filter
=
(
aout_filter_t
*
)
p_this
;
if
(
p_filter
->
input
.
i_format
!=
VLC_FOURCC
(
'a'
,
'5'
,
'2'
,
' '
)
||
p_filter
->
output
.
i_format
!=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
)
)
if
(
p_filter
->
input
.
i_format
!=
VLC_FOURCC
(
'a'
,
'5'
,
'2'
,
' '
)
||
(
p_filter
->
output
.
i_format
!=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'b'
)
&&
p_filter
->
output
.
i_format
!=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
)
)
)
{
return
-
1
;
}
...
...
@@ -80,43 +81,49 @@ static int Create( vlc_object_t *p_this )
static
void
DoWork
(
aout_instance_t
*
p_aout
,
aout_filter_t
*
p_filter
,
aout_buffer_t
*
p_in_buf
,
aout_buffer_t
*
p_out_buf
)
{
/* It is not entirely clear which endianness the AC3 stream should have.
* I have been told endianness does not matter, AC3 can be both endian.
* But then, I could not get it to work on Mac OS X and a JVC RX-6000R
* decoder without using little endian. So right now, I convert to little
* endian.
/* AC3 is natively big endian. Most SPDIF devices have the native
* endianness of the computersystem.
* On MAc OS X however, little endian devices are also common.
*/
static
const
uint8_t
p_sync
[
6
]
=
{
0x72
,
0xF8
,
0x1F
,
0x4E
,
0x01
,
0x00
};
static
const
uint8_t
p_sync_le
[
6
]
=
{
0x72
,
0xF8
,
0x1F
,
0x4E
,
0x01
,
0x00
};
static
const
uint8_t
p_sync
_be
[
6
]
=
{
0xF8
,
0x72
,
0x4E
,
0x1F
,
0x00
,
0x01
};
#ifndef HAVE_SWAB
byte_t
*
p_tmp
;
uint16_t
i
;
#endif
uint16_t
i_length
=
p_in_buf
->
i_nb_bytes
;
uint8_t
*
pi_length
;
uint16_t
i_frame_size
=
p_in_buf
->
i_nb_bytes
/
2
;
byte_t
*
p_in
=
p_in_buf
->
p_buffer
;
byte_t
*
p_out
=
p_out_buf
->
p_buffer
;
/* Copy the S/PDIF headers. */
memcpy
(
p_out
,
p_sync
,
6
);
pi_length
=
(
p_out
+
6
);
*
pi_length
=
(
i_length
*
8
)
&
0xff
;
*
(
pi_length
+
1
)
=
(
i_length
*
8
)
>>
8
;
#ifdef HAVE_SWAB
swab
(
p_in
,
p_out
+
8
,
i_length
);
#else
p_tmp
=
p_out
+
8
;
for
(
i
=
i_length
/
2
;
i
--
;
)
if
(
p_filter
->
output
.
i_format
==
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'b'
)
)
{
p_tmp
[
0
]
=
p_in
[
1
];
p_tmp
[
1
]
=
p_in
[
0
];
p_tmp
+=
2
;
p_in
+=
2
;
p_filter
->
p_vlc
->
pf_memcpy
(
p_out
,
p_sync_be
,
6
);
p_out
[
4
]
=
p_in
[
5
]
&
0x7
;
/* bsmod */
p_out
[
6
]
=
(
i_frame_size
>>
4
)
&
0xff
;
p_out
[
7
]
=
(
i_frame_size
<<
4
)
&
0xff
;
p_filter
->
p_vlc
->
pf_memcpy
(
&
p_out
[
8
],
p_in
,
i_frame_size
*
2
);
}
else
{
p_filter
->
p_vlc
->
pf_memcpy
(
p_out
,
p_sync_le
,
6
);
p_out
[
5
]
=
p_in
[
5
]
&
0x7
;
/* bsmod */
p_out
[
6
]
=
(
i_frame_size
<<
4
)
&
0xff
;
p_out
[
7
]
=
(
i_frame_size
>>
4
)
&
0xff
;
#ifdef HAVE_SWAB
swab
(
p_in
,
&
p_out
[
8
],
i_frame_size
*
2
);
#else
p_tmp
=
&
p_out
[
8
];
for
(
i
=
i_frame_size
;
i
--
;
)
{
p_tmp
[
0
]
=
p_in
[
1
];
p_tmp
[
1
]
=
p_in
[
0
];
p_tmp
+=
2
;
p_in
+=
2
;
}
#endif
p_filter
->
p_vlc
->
pf_memset
(
p_out
+
8
+
i_
length
,
0
,
AOUT_SPDIF_SIZE
-
i_length
-
8
);
}
p_filter
->
p_vlc
->
pf_memset
(
p_out
+
8
+
i_
frame_size
*
2
,
0
,
AOUT_SPDIF_SIZE
-
i_frame_size
*
2
-
8
);
p_out_buf
->
i_nb_samples
=
p_in_buf
->
i_nb_samples
;
p_out_buf
->
i_nb_bytes
=
AOUT_SPDIF_SIZE
;
...
...
modules/audio_filter/converter/dtstospdif.c
View file @
fb397dc0
...
...
@@ -79,8 +79,9 @@ static int Create( vlc_object_t *p_this )
{
aout_filter_t
*
p_filter
=
(
aout_filter_t
*
)
p_this
;
if
(
p_filter
->
input
.
i_format
!=
VLC_FOURCC
(
'd'
,
't'
,
's'
,
' '
)
||
p_filter
->
output
.
i_format
!=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
)
)
if
(
p_filter
->
input
.
i_format
!=
VLC_FOURCC
(
'd'
,
't'
,
's'
,
' '
)
||
(
p_filter
->
output
.
i_format
!=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
)
&&
p_filter
->
output
.
i_format
!=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'b'
)
)
)
{
return
-
1
;
}
...
...
@@ -117,9 +118,11 @@ static void Close( vlc_object_t * p_this )
static
void
DoWork
(
aout_instance_t
*
p_aout
,
aout_filter_t
*
p_filter
,
aout_buffer_t
*
p_in_buf
,
aout_buffer_t
*
p_out_buf
)
{
uint32_t
i_ac5_spdif_type
=
0
;
uint16_t
i_fz
=
p_in_buf
->
i_nb_samples
*
4
;
uint16_t
i_frame
,
i_length
=
p_in_buf
->
i_nb_bytes
;
static
const
uint8_t
p_sync
[
6
]
=
{
0x72
,
0xF8
,
0x1F
,
0x4E
,
0x00
,
0x00
};
static
const
uint8_t
p_sync_le
[
6
]
=
{
0x72
,
0xF8
,
0x1F
,
0x4E
,
0x00
,
0x00
};
static
const
uint8_t
p_sync_be
[
6
]
=
{
0xF8
,
0x72
,
0x4E
,
0x1F
,
0x00
,
0x00
};
if
(
p_in_buf
->
i_nb_bytes
!=
p_filter
->
p_sys
->
i_frame_size
)
{
...
...
@@ -156,23 +159,35 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
byte_t
*
p_out
=
p_out_buf
->
p_buffer
+
(
i_frame
*
i_fz
);
byte_t
*
p_in
=
p_filter
->
p_sys
->
p_buf
+
(
i_frame
*
i_length
);
/* Copy the S/PDIF headers. */
memcpy
(
p_out
,
p_sync
,
6
);
switch
(
p_in_buf
->
i_nb_samples
)
{
case
512
:
*
(
p_out
+
4
)
=
0x0B
;
break
;
case
1024
:
*
(
p_out
+
4
)
=
0x0C
;
break
;
case
2048
:
*
(
p_out
+
4
)
=
0x0D
;
break
;
case
512
:
i_ac5_spdif_type
=
0x0B
;
break
;
case
1024
:
i_ac5_spdif_type
=
0x0C
;
break
;
case
2048
:
i_ac5_spdif_type
=
0x0D
;
break
;
}
*
(
p_out
+
6
)
=
(
i_length
*
8
)
&
0xff
;
*
(
p_out
+
7
)
=
(
i_length
*
8
)
>>
8
;
/* Copy the S/PDIF headers. */
if
(
p_filter
->
output
.
i_format
==
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'b'
)
)
{
p_filter
->
p_vlc
->
pf_memcpy
(
p_out
,
p_sync_be
,
6
);
p_out
[
5
]
=
i_ac5_spdif_type
;
p_out
[
6
]
=
((
i_length
)
>>
5
)
&
0xFF
;
p_out
[
7
]
=
(
i_length
<<
3
)
&
0xFF
;
}
else
{
p_filter
->
p_vlc
->
pf_memcpy
(
p_out
,
p_sync_le
,
6
);
p_out
[
4
]
=
i_ac5_spdif_type
;
p_out
[
6
]
=
(
i_length
<<
3
)
&
0xFF
;
p_out
[
7
]
=
((
i_length
)
>>
5
)
&
0xFF
;
}
if
(
p_in
[
0
]
==
0x1f
||
p_in
[
0
]
==
0x7f
)
if
(
(
(
p_in
[
0
]
==
0x1F
||
p_in
[
0
]
==
0x7F
)
&&
p_filter
->
output
.
i_format
==
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
)
)
||
(
(
p_in
[
0
]
==
0xFF
||
p_in
[
0
]
==
0xFE
)
&&
p_filter
->
output
.
i_format
==
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'b'
)
)
)
{
/* We are dealing with a big endian bitstream.
* Convert to little endian */
/* We are dealing with a big endian bitstream and a little endian output
* or a little endian bitstream and a big endian output.
* Byteswap the stream */
#ifdef HAVE_SWAB
swab
(
p_in
,
p_out
+
8
,
i_length
);
#else
...
...
@@ -190,8 +205,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
}
else
{
/* Little endian */
memcpy
(
p_out
+
8
,
p_in
,
i_length
);
p_filter
->
p_vlc
->
pf_memcpy
(
p_out
+
8
,
p_in
,
i_length
);
}
if
(
i_fz
>
i_length
+
8
)
...
...
modules/audio_filter/resampler/Modules.am
View file @
fb397dc0
...
...
@@ -2,4 +2,3 @@ SOURCES_trivial_resampler = trivial.c
SOURCES_ugly_resampler = ugly.c
SOURCES_linear_resampler = linear.c
SOURCES_bandlimited_resampler = bandlimited.c bandlimited.h
SOURCES_coreaudio_resampler = coreaudio.c
modules/audio_filter/resampler/coreaudio.c
deleted
100644 → 0
View file @
b759e185
/*****************************************************************************
* coreaudio.c resampler based on CoreAudio's AudioConverter
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Jon Lech Johansen <jon-vl@nanocrew.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
/* malloc(), free() */
#include <string.h>
#include <AudioToolbox/AudioConverter.h>
#include <vlc/vlc.h>
#include "audio_output.h"
#include "aout_internal.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
DoWork
(
aout_instance_t
*
,
aout_filter_t
*
,
aout_buffer_t
*
,
aout_buffer_t
*
);
/*****************************************************************************
* Local structures
*****************************************************************************/
struct
aout_filter_sys_t
{
aout_filter_t
*
p_secondary_resampler
;
aout_alloc_t
alloc
;
AudioStreamBasicDescription
s_src_stream_format
;
AudioStreamBasicDescription
s_dst_stream_format
;
AudioConverterRef
s_converter
;
unsigned
int
i_remainder
;
unsigned
int
i_first_rate
;
};
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin
();
set_description
(
_
(
"audio filter using CoreAudio for resampling"
)
);
set_category
(
CAT_AUDIO
);
set_subcategory
(
SUBCAT_AUDIO_MISC
);
set_capability
(
"audio filter"
,
40
);
set_callbacks
(
Create
,
Close
);
vlc_module_end
();
/*****************************************************************************
* Create: allocate resampler
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
p_this
)
{
aout_filter_t
*
p_filter
=
(
aout_filter_t
*
)
p_this
;
struct
aout_filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
unsigned
int
i_nb_channels
;
OSStatus
err
;
uint32_t
i_prop
;
unsigned
int
i_first_rate
;
if
(
p_filter
->
input
.
i_rate
==
p_filter
->
output
.
i_rate
||
p_filter
->
input
.
i_format
!=
p_filter
->
output
.
i_format
||
p_filter
->
input
.
i_physical_channels
!=
p_filter
->
output
.
i_physical_channels
||
p_filter
->
input
.
i_original_channels
!=
p_filter
->
output
.
i_original_channels
||
p_filter
->
input
.
i_format
!=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
)
)
{
return
VLC_EGENERIC
;
}
if
(
p_filter
->
input
.
i_rate
>=
48000
*
(
100
+
AOUT_MAX_RESAMPLING
)
/
100
)
i_first_rate
=
48000
;
else
i_first_rate
=
44100
;
if
(
p_filter
->
output
.
i_rate
==
i_first_rate
)
{
return
VLC_EGENERIC
;
}
i_nb_channels
=
aout_FormatNbChannels
(
&
p_filter
->
input
);
/* Allocate the memory needed to store the module's structure */
p_sys
=
p_filter
->
p_sys
=
malloc
(
sizeof
(
struct
aout_filter_sys_t
)
);
if
(
p_filter
->
p_sys
==
NULL
)
{
msg_Err
(
p_filter
,
"out of memory"
);
return
VLC_ENOMEM
;
}
memset
(
p_filter
->
p_sys
,
0
,
sizeof
(
struct
aout_filter_sys_t
)
);
p_sys
->
i_first_rate
=
i_first_rate
;
p_sys
->
i_remainder
=
0
;
p_sys
->
s_src_stream_format
.
mFormatID
=
kAudioFormatLinearPCM
;
p_sys
->
s_src_stream_format
.
mFormatFlags
=
kLinearPCMFormatFlagIsFloat
|
kAudioFormatFlagsNativeEndian
|
kAudioFormatFlagIsPacked
;
p_sys
->
s_src_stream_format
.
mBytesPerPacket
=
i_nb_channels
*
4
;
p_sys
->
s_src_stream_format
.
mFramesPerPacket
=
1
;
p_sys
->
s_src_stream_format
.
mBytesPerFrame
=
i_nb_channels
*
4
;
p_sys
->
s_src_stream_format
.
mChannelsPerFrame
=
i_nb_channels
;
p_sys
->
s_src_stream_format
.
mBitsPerChannel
=
32
;
memcpy
(
&
p_sys
->
s_dst_stream_format
,
&
p_sys
->
s_src_stream_format
,
sizeof
(
AudioStreamBasicDescription
)
);
p_sys
->
s_src_stream_format
.
mSampleRate
=
p_sys
->
i_first_rate
;
p_sys
->
s_dst_stream_format
.
mSampleRate
=
p_filter
->
output
.
i_rate
;
err
=
AudioConverterNew
(
&
p_sys
->
s_src_stream_format
,
&
p_sys
->
s_dst_stream_format
,
&
p_sys
->
s_converter
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_filter
,
"AudioConverterNew failed: [%4.4s]"
,
(
char
*
)
&
err
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
i_prop
=
kConverterPrimeMethod_None
;
err
=
AudioConverterSetProperty
(
p_sys
->
s_converter
,
kAudioConverterPrimeMethod
,
sizeof
(
i_prop
),
&
i_prop
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_filter
,
"AudioConverterSetProperty failed: [%4.4s]"
,
(
char
*
)
&
err
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
/* Allocate a secondary resampler for the remainder. */
p_sys
->
p_secondary_resampler
=
vlc_object_create
(
p_filter
,
sizeof
(
aout_filter_t
)
);
if
(
p_sys
->
p_secondary_resampler
==
NULL
)
{
free
(
p_sys
);
return
VLC_EGENERIC
;
}
vlc_object_attach
(
p_sys
->
p_secondary_resampler
,
p_filter
);
memcpy
(
&
p_sys
->
p_secondary_resampler
->
input
,
&
p_filter
->
input
,
sizeof
(
audio_sample_format_t
)
);
memcpy
(
&
p_sys
->
p_secondary_resampler
->
output
,
&
p_filter
->
output
,
sizeof
(
audio_sample_format_t
)
);
p_sys
->
p_secondary_resampler
->
p_module
=
module_Need
(
p_sys
->
p_secondary_resampler
,
"audio filter"
,
"ugly_resampler"
,
VLC_TRUE
);
if
(
p_sys
->
p_secondary_resampler
->
p_module
==
NULL
)
{
vlc_object_detach
(
p_sys
->
p_secondary_resampler
);
vlc_object_destroy
(
p_sys
->
p_secondary_resampler
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
p_sys
->
p_secondary_resampler
->
b_continuity
=
VLC_FALSE
;
p_sys
->
alloc
.
i_alloc_type
=
AOUT_ALLOC_STACK
;
p_sys
->
alloc
.
i_bytes_per_sec
=
p_filter
->
output
.
i_bytes_per_frame
*
p_filter
->
output
.
i_rate
/
p_filter
->
output
.
i_frame_length
;
p_filter
->
pf_do_work
=
DoWork
;
/* We don't want a new buffer to be created because we're not sure we'll
* actually need to resample anything. */
p_filter
->
b_in_place
=
VLC_FALSE
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close: free our resources
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
{
aout_filter_t
*
p_filter
=
(
aout_filter_t
*
)
p_this
;
struct
aout_filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
OSErr
err
;
module_Unneed
(
p_sys
->
p_secondary_resampler
,
p_sys
->
p_secondary_resampler
->
p_module
);
vlc_object_detach
(
p_sys
->
p_secondary_resampler
);
vlc_object_destroy
(
p_sys
->
p_secondary_resampler
);
/* Destroy the AudioConverter */
err
=
AudioConverterDispose
(
p_sys
->
s_converter
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_this
,
"AudioConverterDispose failed: %u"
,
err
);
}
free
(
p_filter
->
p_sys
);
}
/*****************************************************************************
* DoWork: convert a buffer
*****************************************************************************/
static
void
DoWork
(
aout_instance_t
*
p_aout
,
aout_filter_t
*
p_filter
,
aout_buffer_t
*
p_in_buf
,
aout_buffer_t
*
p_out_buf
)
{
struct
aout_filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
int32_t
*
p_in
=
(
int32_t
*
)
p_in_buf
->
p_buffer
;
int32_t
*
p_out
;
UInt32
i_output_size
;
unsigned
int
i_out_nb
,
i_wanted_nb
,
i_new_rate
;
OSErr
err
;
aout_buffer_t
*
p_middle_buf
;
unsigned
int
i_nb_channels
=
aout_FormatNbChannels
(
&
p_filter
->
input
);
#if 1
if
(
!
p_filter
->
b_continuity
)
{
err
=
AudioConverterReset
(
p_sys
->
s_converter
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_filter
,
"AudioConverterReset failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
p_filter
->
b_continuity
=
VLC_TRUE
;
p_sys
->
i_remainder
=
0
;
}
#endif
i_out_nb
=
(
p_in_buf
->
i_nb_samples
*
p_filter
->
output
.
i_rate
+
p_sys
->
i_remainder
)
/
p_sys
->
i_first_rate
;
p_sys
->
i_remainder
=
(
p_in_buf
->
i_nb_samples
*
p_filter
->
output
.
i_rate
+
p_sys
->
i_remainder
)
%
p_sys
->
i_first_rate
;
i_output_size
=
i_out_nb
*
4
*
i_nb_channels
;
if
(
i_output_size
>
p_out_buf
->
i_size
)
{
aout_BufferAlloc
(
&
p_sys
->
alloc
,
i_out_nb
*
1000000
/
p_filter
->
output
.
i_rate
,
NULL
,
p_middle_buf
);
}
else
{
p_middle_buf
=
p_out_buf
;
}
p_out
=
(
int32_t
*
)
p_middle_buf
->
p_buffer
;
err
=
AudioConverterConvertBuffer
(
p_sys
->
s_converter
,
p_in_buf
->
i_nb_samples
*
4
*
i_nb_channels
,
p_in
,
&
i_output_size
,
p_out
);
if
(
err
!=
noErr
)
{
msg_Warn
(
p_filter
,
"AudioConverterConvertBuffer failed: [%4.4s] (%u:%u)"
,
(
char
*
)
&
err
,
i_out_nb
*
4
*
i_nb_channels
,
i_output_size
);
i_output_size
=
i_out_nb
*
4
*
i_nb_channels
;
memset
(
p_out
,
0
,
i_output_size
);
}
p_middle_buf
->
i_nb_samples
=
i_output_size
/
4
/
i_nb_channels
;
p_middle_buf
->
i_nb_bytes
=
i_output_size
;
p_middle_buf
->
start_date
=
p_in_buf
->
start_date
;
p_middle_buf
->
end_date
=
p_middle_buf
->
start_date
+
p_middle_buf
->
i_nb_samples
*
1000000
/
p_filter
->
output
.
i_rate
;
i_wanted_nb
=
p_in_buf
->
i_nb_samples
*
p_filter
->
output
.
i_rate
/
p_filter
->
input
.
i_rate
;
i_new_rate
=
p_middle_buf
->
i_nb_samples
*
p_filter
->
output
.
i_rate
/
i_wanted_nb
;
p_sys
->
p_secondary_resampler
->
input
.
i_rate
=
i_new_rate
;
p_sys
->
p_secondary_resampler
->
pf_do_work
(
p_aout
,
p_sys
->
p_secondary_resampler
,
p_middle_buf
,
p_out_buf
);
if
(
p_middle_buf
!=
p_out_buf
)
{
aout_BufferFree
(
p_middle_buf
);
}
}
modules/audio_output/Modules.am
View file @
fb397dc0
SOURCES_alsa = alsa.c
SOURCES_arts = arts.c
SOURCES_coreaudio = coreaudio.c
SOURCES_aout_directx = directx.c
SOURCES_esd = esd.c
SOURCES_aout_file = file.c
...
...
modules/audio_output/auhal.c
View file @
fb397dc0
...
...
@@ -40,6 +40,13 @@
#include <AudioToolbox/AudioFormat.h>
#define STREAM_FORMAT_MSG( pre, sfm ) \
pre "[%ld][%4.4s][%ld][%ld][%ld][%ld][%ld][%ld]", \
(UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \
sfm.mFormatFlags, sfm.mBytesPerPacket, \
sfm.mFramesPerPacket, sfm.mBytesPerFrame, \
sfm.mChannelsPerFrame, sfm.mBitsPerChannel
#define STREAM_FORMAT_MSG_FULL( pre, sfm ) \
pre ":\nsamplerate: [%ld]\nFormatID: [%4.4s]\nFormatFlags: [%ld]\nBypesPerPacket: [%ld]\nFramesPerPacket: [%ld]\nBytesPerFrame: [%ld]\nChannelsPerFrame: [%ld]\nBitsPerChannel[%ld]", \
(UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \
sfm.mFormatFlags, sfm.mBytesPerPacket, \
...
...
@@ -47,6 +54,7 @@
sfm.mChannelsPerFrame, sfm.mBitsPerChannel
#define BUFSIZE 0xffffff
#define AOUT_VAR_SPDIF_FLAG 0xf00000
/*****************************************************************************
* aout_sys_t: private audio output method descriptor
...
...
@@ -61,33 +69,48 @@ struct aout_sys_t
UInt32
i_devices
;
/* Number of CoreAudio Devices */
vlc_bool_t
b_supports_digital
;
/* Does the currently selected device support digital mode? */
vlc_bool_t
b_digital
;
/* Are we running in digital mode? */
mtime_t
clock_diff
;
/* Difference between VLC clock and Device clock */
/* AUHAL specific */
Component
au_component
;
/* The Audiocomponent we use */
AudioUnit
au_unit
;
/* The AudioUnit we use */
mtime_t
clock_diff
;
uint8_t
p_remainder_buffer
[
BUFSIZE
];
uint8_t
p_remainder_buffer
[
BUFSIZE
];
uint32_t
i_read_bytes
;
uint32_t
i_total_bytes
;
audio_date_t
end_date_t
;
/* CoreAudio SPDIF mode specific */
pid_t
i_hog_pid
;
/* The keep the pid of our hog status */
AudioStreamID
i_stream_id
;
/* The StreamID that has a cac3 streamformat */
int
i_stream_index
;
/* The index of i_stream_id in an AudioBufferList */
AudioStreamBasicDescription
stream_format
;
/* The format we changed the to */
AudioStreamBasicDescription
sfmt_revert
;
/* The original format of the stream */
vlc_bool_t
b_revert
;
/* Wether we need to revert the stream format */
vlc_bool_t
b_changed_mixing
;
/* Wether we need to set the mixing mode back */
};
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
int
OpenAnalog
(
aout_instance_t
*
);
static
int
OpenSPDIF
(
aout_instance_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
Play
(
aout_instance_t
*
);
static
void
Play
(
aout_instance_t
*
);
static
void
Probe
(
aout_instance_t
*
);
static
int
Probe
(
aout_instance_t
*
);
static
int
DeviceDigitalMode
(
aout_instance_t
*
,
AudioDeviceID
);
int
AudioDeviceHasOutput
(
AudioDeviceID
);
static
int
DigitalInit
(
aout_instance_t
*
);
static
int
AudioDeviceHasOutput
(
AudioDeviceID
);
static
int
AudioDeviceSupportsDigital
(
aout_instance_t
*
,
AudioDeviceID
);
static
int
AudioStreamSupportsDigital
(
aout_instance_t
*
,
AudioStreamID
);
static
OSStatus
RenderCallbackAnalog
(
vlc_object_t
*
,
AudioUnitRenderActionFlags
*
,
const
AudioTimeStamp
*
,
unsigned
int
,
unsigned
int
,
AudioBufferList
*
);
static
OSStatus
RenderCallbackSPDIF
(
AudioDeviceID
,
const
AudioTimeStamp
*
,
const
void
*
,
const
AudioTimeStamp
*
,
AudioBufferList
*
,
const
AudioTimeStamp
*
,
void
*
);
static
OSStatus
HardwareListener
(
AudioHardwarePropertyID
,
void
*
);
static
OSStatus
StreamListener
(
AudioStreamID
,
UInt32
,
AudioDevicePropertyID
,
void
*
);
static
int
AudioDeviceCallback
(
vlc_object_t
*
,
const
char
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
/*****************************************************************************
* Module descriptor
...
...
@@ -104,82 +127,148 @@ vlc_module_begin();
set_category
(
CAT_AUDIO
);
set_subcategory
(
SUBCAT_AUDIO_AOUT
);
set_callbacks
(
Open
,
Close
);
//add_integer( "coreaudio-dev", -1
, NULL, ADEV_TEXT, ADEV_LONGTEXT, VLC_FALSE );
add_integer
(
"macosx-audio-device"
,
0
,
NULL
,
ADEV_TEXT
,
ADEV_LONGTEXT
,
VLC_FALSE
);
vlc_module_end
();
/*****************************************************************************
* Open: open
a HAL AudioUni
t
* Open: open
macosx audio outpu
t
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
{
OSStatus
err
=
noErr
;
ComponentDescription
desc
;
UInt32
i_param_size
,
i
;
struct
aout_sys_t
*
p_sys
;
UInt32
i_param_size
=
0
;
struct
aout_sys_t
*
p_sys
=
NULL
;
vlc_bool_t
b_alive
=
VLC_FALSE
;
vlc_value_t
val
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_this
;
/* Allocate structure */
p_
sys
=
(
struct
aout_sys_t
*
)
malloc
(
sizeof
(
struct
aout_sys_t
)
);
if
(
p_sys
==
NULL
)
p_
aout
->
output
.
p_sys
=
malloc
(
sizeof
(
aout_sys_t
)
);
if
(
p_
aout
->
output
.
p_
sys
==
NULL
)
{
msg_Err
(
p_aout
,
"out of memory"
);
return
(
VLC_ENOMEM
);
}
memset
(
p_sys
,
0
,
sizeof
(
struct
aout_sys_t
)
);
p_sys
->
b_digital
=
VLC_FALSE
;
/* We assume we are not digital */
p_sys
=
p_aout
->
output
.
p_sys
;
p_sys
->
i_default_dev
=
0
;
p_sys
->
i_selected_dev
=
0
;
p_sys
->
i_devices
=
0
;
p_sys
->
b_supports_digital
=
VLC_FALSE
;
p_sys
->
b_digital
=
VLC_FALSE
;
p_sys
->
au_component
=
NULL
;
p_sys
->
au_unit
=
NULL
;
p_sys
->
clock_diff
=
(
mtime_t
)
0
;
p_sys
->
i_read_bytes
=
0
;
p_sys
->
i_total_bytes
=
0
;
p_sys
->
i_hog_pid
=
-
1
;
p_sys
->
i_stream_id
=
0
;
p_sys
->
i_stream_index
=
0
;
p_sys
->
b_revert
=
VLC_FALSE
;
p_sys
->
b_changed_mixing
=
VLC_FALSE
;
memset
(
p_sys
->
p_remainder_buffer
,
0
,
sizeof
(
uint8_t
)
*
BUFSIZE
);
p_aout
->
output
.
p_sys
=
p_sys
;
p_aout
->
output
.
pf_play
=
Play
;
aout_FormatPrint
(
p_aout
,
"VLC is looking for:
\n
"
,
(
audio_sample_format_t
*
)
&
p_aout
->
output
.
output
);
aout_FormatPrint
(
p_aout
,
"VLC is looking for:"
,
(
audio_sample_format_t
*
)
&
p_aout
->
output
.
output
);
/* Persistent device variable */
if
(
var_Type
(
p_aout
->
p_vlc
,
"macosx-audio-device"
)
==
0
)
{
msg_Dbg
(
p_aout
,
"create macosx-audio-device"
);
var_Create
(
p_aout
->
p_vlc
,
"macosx-audio-device"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
}
/* Build a list of devices */
if
(
var_Type
(
p_aout
,
"audio-device"
)
==
0
)
{
Probe
(
p_aout
);
/*if( Probe( p_aout ) != VLC_SUCCESS );
{
msg_Err( p_aout, "Probe failed" );
free( p_sys );
return VLC_EGENERIC;
}*/
}
/* What device do we want? */
if
(
var_Get
(
p_aout
,
"audio-device"
,
&
val
)
<
0
)
{
msg_Err
(
p_aout
,
"audio-device var does not exist"
);
msg_Err
(
p_aout
,
"audio-device var does not exist
. device probe failed.
"
);
free
(
p_sys
);
return
(
VLC_ENOVAR
);
}
p_sys
->
i_selected_dev
=
val
.
i_int
;
/* what is vlc format? if digital, take digital route else AUHAL route */
DeviceDigitalMode
(
p_aout
,
p_sys
->
i_selected_dev
);
/*if( DeviceDigitalMode( p_aout, p_sys->i_selected_dev ) != VLC_SUCCESS );
p_sys
->
i_selected_dev
=
val
.
i_int
&
~
AOUT_VAR_SPDIF_FLAG
;
p_sys
->
b_supports_digital
=
(
val
.
i_int
&
AOUT_VAR_SPDIF_FLAG
)
?
VLC_TRUE
:
VLC_FALSE
;
/* Check if the desired device is alive and usable */
i_param_size
=
sizeof
(
b_alive
);
err
=
AudioDeviceGetProperty
(
p_sys
->
i_selected_dev
,
0
,
FALSE
,
kAudioDevicePropertyDeviceIsAlive
,
&
i_param_size
,
&
b_alive
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not check whether device is alive: %4.4s"
,
(
char
*
)
&
err
);
return
VLC_EGENERIC
;
}
if
(
b_alive
==
VLC_FALSE
)
{
msg_Err
(
p_aout
,
"Selected audio device is not alive switching to default device"
);
p_sys
->
i_selected_dev
=
p_sys
->
i_default_dev
;
}
i_param_size
=
sizeof
(
p_sys
->
i_hog_pid
);
err
=
AudioDeviceGetProperty
(
p_sys
->
i_selected_dev
,
0
,
FALSE
,
kAudioDevicePropertyHogMode
,
&
i_param_size
,
&
p_sys
->
i_hog_pid
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not check whether device is hogged: %4.4s"
,
(
char
*
)
&
err
);
return
VLC_EGENERIC
;
}
if
(
p_sys
->
i_hog_pid
!=
-
1
&&
p_sys
->
i_hog_pid
!=
getpid
()
)
{
msg_Err( p_aout, "DeviceDigitalMode failed" );
msg_Err
(
p_aout
,
"Selected audio device is exclusively in use by another program"
);
var_Destroy
(
p_aout
,
"audio-device"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
*/
/* Check for Digital mode or Analog output mode */
if
(
AOUT_FMT_NON_LINEAR
(
&
p_aout
->
output
.
output
)
&&
p_sys
->
b_supports_digital
)
{
p_sys
->
b_digital
=
VLC_TRUE
;
p_aout
->
output
.
output
.
i_format
=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
);
msg_Dbg
(
p_aout
,
"we found a digital stream, and we WANT a digital stream"
);
if
(
OpenSPDIF
(
p_aout
)
)
return
VLC_SUCCESS
;
}
else
if
(
AOUT_FMT_NON_LINEAR
(
&
p_aout
->
output
.
output
)
&&
!
p_sys
->
b_supports_digital
)
else
{
if
(
OpenAnalog
(
p_aout
)
)
return
VLC_SUCCESS
;
}
/* If we reach this, the Open* failed */
var_Destroy
(
p_aout
,
"audio-device"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
/*****************************************************************************
* Open: open and setup a HAL AudioUnit
*****************************************************************************/
static
int
OpenAnalog
(
aout_instance_t
*
p_aout
)
{
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
OSStatus
err
=
noErr
;
UInt32
i_param_size
=
0
,
i
=
0
;
ComponentDescription
desc
;
if
(
AOUT_FMT_NON_LINEAR
(
&
p_aout
->
output
.
output
)
&&
!
p_sys
->
b_supports_digital
)
{
msg_Dbg
(
p_aout
,
"we had requested a digital stream, but it's not possible for this device"
);
}
/* If analog only start setting up AUHAL */
/* If analog only start setting up AUHAL */
/* Lets go find our Component */
desc
.
componentType
=
kAudioUnitType_Output
;
desc
.
componentSubType
=
kAudioUnitSubType_HALOutput
;
...
...
@@ -191,20 +280,18 @@ static int Open( vlc_object_t * p_this )
if
(
p_sys
->
au_component
==
NULL
)
{
msg_Err
(
p_aout
,
"we cannot find our HAL component"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
return
VLC_FALSE
;
}
err
=
OpenAComponent
(
p_sys
->
au_component
,
&
p_sys
->
au_unit
);
if
(
err
)
{
msg_Err
(
p_aout
,
"we cannot find our HAL component"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
return
VLC_FALSE
;
}
/* Enable IO for the component */
msg_Dbg
(
p_aout
,
"Device: %#x"
,
(
int
)
p_sys
->
i_selected_dev
);
/* Set the device */
verify_noerr
(
AudioUnitSetProperty
(
p_sys
->
au_unit
,
...
...
@@ -212,7 +299,7 @@ static int Open( vlc_object_t * p_this )
kAudioUnitScope_Global
,
0
,
&
p_sys
->
i_selected_dev
,
sizeof
(
p_sys
->
i_selected_dev
)));
sizeof
(
AudioDeviceID
)));
/* Get the current format */
AudioStreamBasicDescription
DeviceFormat
;
...
...
@@ -226,7 +313,7 @@ static int Open( vlc_object_t * p_this )
&
DeviceFormat
,
&
i_param_size
));
msg_Dbg
(
p_aout
,
STREAM_FORMAT_MSG
(
"current format is "
,
DeviceFormat
)
);
msg_Dbg
(
p_aout
,
STREAM_FORMAT_MSG
(
"current format is
:
"
,
DeviceFormat
)
);
/* Get the channel layout */
AudioChannelLayout
*
layout
;
...
...
@@ -442,13 +529,10 @@ static int Open( vlc_object_t * p_this )
p_aout
->
output
.
i_nb_samples
=
2048
;
aout_VolumeSoftInit
(
p_aout
);
/*
Let's pray for the following operation to be atomic...
*/
/*
Find the difference between device clock and mdate clock
*/
p_sys
->
clock_diff
=
-
(
mtime_t
)
AudioConvertHostTimeToNanos
(
AudioGetCurrentHostTime
()
)
/
1000
;
p_sys
->
clock_diff
+=
mdate
();
p_sys
->
i_read_bytes
=
0
;
p_sys
->
i_total_bytes
=
0
;
/* set the IOproc callback */
AURenderCallbackStruct
input
;
...
...
@@ -473,9 +557,268 @@ static int Open( vlc_object_t * p_this )
verify_noerr
(
AudioUnitInitialize
(
p_sys
->
au_unit
)
);
verify_noerr
(
AudioOutputUnitStart
(
p_sys
->
au_unit
)
);
return
(
VLC_SUCCESS
);
return
VLC_TRUE
;
}
/*****************************************************************************
* Setup a encoded digital stream (SPDIF)
*****************************************************************************/
static
int
OpenSPDIF
(
aout_instance_t
*
p_aout
)
{
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
OSStatus
err
=
noErr
;
UInt32
i_param_size
=
0
,
b_mix
=
0
;
Boolean
b_writeable
=
VLC_FALSE
;
AudioStreamID
*
p_streams
=
NULL
;
int
i
=
0
,
i_streams
=
0
;
struct
timeval
now
;
struct
timespec
timeout
;
struct
{
vlc_mutex_t
lock
;
vlc_cond_t
cond
;
}
w
;
/* Start doing the SPDIF setup proces */
p_sys
->
b_digital
=
VLC_TRUE
;
msg_Dbg
(
p_aout
,
"opening in SPDIF mode"
);
/* Hog the device */
i_param_size
=
sizeof
(
p_sys
->
i_hog_pid
);
p_sys
->
i_hog_pid
=
getpid
()
;
err
=
AudioDeviceSetProperty
(
p_sys
->
i_selected_dev
,
0
,
0
,
FALSE
,
kAudioDevicePropertyHogMode
,
i_param_size
,
&
p_sys
->
i_hog_pid
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"failed to set hogmode: : [%4.4s]"
,
(
char
*
)
&
err
);
return
VLC_FALSE
;
}
/* Set mixable to false if we are allowed to */
err
=
AudioDeviceGetPropertyInfo
(
p_sys
->
i_selected_dev
,
0
,
FALSE
,
kAudioDevicePropertySupportsMixing
,
&
i_param_size
,
&
b_writeable
);
err
=
AudioDeviceGetProperty
(
p_sys
->
i_selected_dev
,
0
,
FALSE
,
kAudioDevicePropertySupportsMixing
,
&
i_param_size
,
&
b_mix
);
if
(
!
err
&&
b_writeable
)
{
b_mix
=
0
;
err
=
AudioDeviceSetProperty
(
p_sys
->
i_selected_dev
,
0
,
0
,
FALSE
,
kAudioDevicePropertySupportsMixing
,
i_param_size
,
&
b_mix
);
p_sys
->
b_changed_mixing
=
VLC_TRUE
;
}
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"failed to set mixmode: [%4.4s]"
,
(
char
*
)
&
err
);
return
VLC_FALSE
;
}
// Find stream_id of selected device with a cac3 stream
err
=
AudioDeviceGetPropertyInfo
(
p_sys
->
i_selected_dev
,
0
,
FALSE
,
kAudioDevicePropertyStreams
,
&
i_param_size
,
NULL
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get number of streams: [%4.4s]"
,
(
char
*
)
&
err
);
return
VLC_FALSE
;
}
i_streams
=
i_param_size
/
sizeof
(
AudioStreamID
);
p_streams
=
(
AudioStreamID
*
)
malloc
(
i_param_size
);
if
(
p_streams
==
NULL
)
{
msg_Err
(
p_aout
,
"Out of memory"
);
return
VLC_FALSE
;
}
err
=
AudioDeviceGetProperty
(
p_sys
->
i_selected_dev
,
0
,
FALSE
,
kAudioDevicePropertyStreams
,
&
i_param_size
,
p_streams
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get number of streams: [%4.4s]"
,
(
char
*
)
&
err
);
if
(
p_streams
)
free
(
p_streams
);
return
VLC_FALSE
;
}
for
(
i
=
0
;
i
<
i_streams
;
i
++
)
{
// Find a stream with a cac3 stream
AudioStreamBasicDescription
*
p_format_list
=
NULL
;
int
i_formats
=
0
,
j
=
0
;
/* Retrieve all the stream formats supported by each output stream */
err
=
AudioStreamGetPropertyInfo
(
p_streams
[
i
],
0
,
kAudioStreamPropertyPhysicalFormats
,
&
i_param_size
,
NULL
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get number of streamformats: [%4.4s]"
,
(
char
*
)
&
err
);
continue
;
}
i_formats
=
i_param_size
/
sizeof
(
AudioStreamBasicDescription
);
p_format_list
=
(
AudioStreamBasicDescription
*
)
malloc
(
i_param_size
);
if
(
p_format_list
==
NULL
)
{
msg_Err
(
p_aout
,
"Could not malloc the memory"
);
continue
;
}
err
=
AudioStreamGetProperty
(
p_streams
[
i
],
0
,
kAudioStreamPropertyPhysicalFormats
,
&
i_param_size
,
p_format_list
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get the list of streamformats: [%4.4s]"
,
(
char
*
)
&
err
);
if
(
p_format_list
)
free
(
p_format_list
);
continue
;
}
for
(
j
=
0
;
j
<
i_formats
;
j
++
)
{
if
(
p_format_list
[
j
].
mFormatID
==
'
IAC3
'
||
p_format_list
[
j
].
mFormatID
==
kAudioFormat60958AC3
)
{
// found a cac3 format
p_sys
->
i_stream_id
=
p_streams
[
i
];
p_sys
->
i_stream_index
=
i
;
if
(
p_sys
->
b_revert
==
VLC_FALSE
)
{
i_param_size
=
sizeof
(
p_sys
->
sfmt_revert
);
err
=
AudioStreamGetProperty
(
p_sys
->
i_stream_id
,
0
,
kAudioStreamPropertyPhysicalFormat
,
&
i_param_size
,
&
p_sys
->
sfmt_revert
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not retrieve the original streamformat: [%4.4s]"
,
(
char
*
)
&
err
);
continue
;
}
p_sys
->
b_revert
=
VLC_TRUE
;
}
if
(
p_format_list
[
j
].
mSampleRate
==
p_sys
->
sfmt_revert
.
mSampleRate
)
{
p_sys
->
stream_format
=
p_format_list
[
j
];
}
}
}
if
(
p_format_list
)
free
(
p_format_list
);
}
if
(
p_streams
)
free
(
p_streams
);
msg_Dbg
(
p_aout
,
STREAM_FORMAT_MSG
(
"original stream format: "
,
p_sys
->
sfmt_revert
)
);
msg_Dbg
(
p_aout
,
STREAM_FORMAT_MSG
(
"setting stream format: "
,
p_sys
->
stream_format
)
);
/* Install the callback */
err
=
AudioStreamAddPropertyListener
(
p_sys
->
i_stream_id
,
0
,
kAudioStreamPropertyPhysicalFormat
,
StreamListener
,
(
void
*
)
&
w
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioStreamAddPropertyListener failed: [%4.4s]"
,
(
char
*
)
&
err
);
return
VLC_FALSE
;
}
/* Condition because SetProperty is asynchronious */
vlc_cond_init
(
p_aout
,
&
w
.
cond
);
vlc_mutex_init
(
p_aout
,
&
w
.
lock
);
vlc_mutex_lock
(
&
w
.
lock
);
/* change the format */
err
=
AudioStreamSetProperty
(
p_sys
->
i_stream_id
,
0
,
0
,
kAudioStreamPropertyPhysicalFormat
,
sizeof
(
AudioStreamBasicDescription
),
&
p_sys
->
stream_format
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not set the stream format: [%4.4s]"
,
(
char
*
)
&
err
);
vlc_mutex_unlock
(
&
w
.
lock
);
vlc_mutex_destroy
(
&
w
.
lock
);
vlc_cond_destroy
(
&
w
.
cond
);
return
VLC_FALSE
;
}
gettimeofday
(
&
now
,
NULL
);
timeout
.
tv_sec
=
now
.
tv_sec
;
timeout
.
tv_nsec
=
(
now
.
tv_usec
+
900000
)
*
1000
;
pthread_cond_timedwait
(
&
w
.
cond
.
cond
,
&
w
.
lock
.
mutex
,
&
timeout
);
vlc_mutex_unlock
(
&
w
.
lock
);
err
=
AudioStreamRemovePropertyListener
(
p_sys
->
i_stream_id
,
0
,
kAudioStreamPropertyPhysicalFormat
,
StreamListener
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioStreamRemovePropertyListener failed: [%4.4s]"
,
(
char
*
)
&
err
);
vlc_mutex_destroy
(
&
w
.
lock
);
vlc_cond_destroy
(
&
w
.
cond
);
return
VLC_FALSE
;
}
vlc_mutex_destroy
(
&
w
.
lock
);
vlc_cond_destroy
(
&
w
.
cond
);
i_param_size
=
sizeof
(
AudioStreamBasicDescription
);
err
=
AudioStreamGetProperty
(
p_sys
->
i_stream_id
,
0
,
kAudioStreamPropertyPhysicalFormat
,
&
i_param_size
,
&
p_sys
->
stream_format
);
msg_Dbg
(
p_aout
,
STREAM_FORMAT_MSG
(
"actual format in use: "
,
p_sys
->
stream_format
)
);
/* set the format flags */
if
(
p_sys
->
stream_format
.
mFormatFlags
&
kAudioFormatFlagIsBigEndian
)
p_aout
->
output
.
output
.
i_format
=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'b'
);
else
p_aout
->
output
.
output
.
i_format
=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
);
p_aout
->
output
.
output
.
i_bytes_per_frame
=
AOUT_SPDIF_SIZE
;
p_aout
->
output
.
output
.
i_frame_length
=
A52_FRAME_NB
;
p_aout
->
output
.
i_nb_samples
=
p_aout
->
output
.
output
.
i_frame_length
;
p_aout
->
output
.
output
.
i_rate
=
(
unsigned
int
)
p_sys
->
stream_format
.
mSampleRate
;
aout_VolumeNoneInit
(
p_aout
);
/* Add IOProc callback */
err
=
AudioDeviceAddIOProc
(
p_sys
->
i_selected_dev
,
(
AudioDeviceIOProc
)
RenderCallbackSPDIF
,
(
void
*
)
p_aout
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioDeviceAddIOProc failed: [%4.4s]"
,
(
char
*
)
&
err
);
return
VLC_FALSE
;
}
/* Check for the difference between the Device clock and mdate */
p_sys
->
clock_diff
=
-
(
mtime_t
)
AudioConvertHostTimeToNanos
(
AudioGetCurrentHostTime
()
)
/
1000
;
p_sys
->
clock_diff
+=
mdate
();
/* Start device */
err
=
AudioDeviceStart
(
p_sys
->
i_selected_dev
,
(
AudioDeviceIOProc
)
RenderCallbackSPDIF
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioDeviceStart failed: [%4.4s]"
,
(
char
*
)
&
err
);
err
=
AudioDeviceRemoveIOProc
(
p_sys
->
i_selected_dev
,
(
AudioDeviceIOProc
)
RenderCallbackSPDIF
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioDeviceRemoveIOProc failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
return
VLC_FALSE
;
}
return
VLC_TRUE
;
}
/*****************************************************************************
* Close: Close HAL AudioUnit
*****************************************************************************/
...
...
@@ -483,6 +826,8 @@ static void Close( vlc_object_t * p_this )
{
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_this
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
OSStatus
err
=
noErr
;
UInt32
i_param_size
=
0
;
if
(
p_sys
->
au_unit
)
{
...
...
@@ -490,7 +835,127 @@ static void Close( vlc_object_t * p_this )
verify_noerr
(
AudioUnitUninitialize
(
p_sys
->
au_unit
)
);
verify_noerr
(
CloseComponent
(
p_sys
->
au_unit
)
);
}
free
(
p_sys
);
if
(
p_sys
->
b_digital
)
{
/* Stop device */
err
=
AudioDeviceStop
(
p_sys
->
i_selected_dev
,
(
AudioDeviceIOProc
)
RenderCallbackSPDIF
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioDeviceStop failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
/* Remove callback */
err
=
AudioDeviceRemoveIOProc
(
p_sys
->
i_selected_dev
,
(
AudioDeviceIOProc
)
RenderCallbackSPDIF
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioDeviceRemoveIOProc failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
if
(
p_sys
->
b_revert
)
{
struct
timeval
now
;
struct
timespec
timeout
;
struct
{
vlc_mutex_t
lock
;
vlc_cond_t
cond
;
}
w
;
/* Install the callback */
err
=
AudioStreamAddPropertyListener
(
p_sys
->
i_stream_id
,
0
,
kAudioStreamPropertyPhysicalFormat
,
StreamListener
,
(
void
*
)
&
w
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioStreamAddPropertyListener failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
/* Condition because SetProperty is asynchronious */
vlc_cond_init
(
p_aout
,
&
w
.
cond
);
vlc_mutex_init
(
p_aout
,
&
w
.
lock
);
vlc_mutex_lock
(
&
w
.
lock
);
msg_Dbg
(
p_aout
,
STREAM_FORMAT_MSG
(
"setting stream format: "
,
p_sys
->
sfmt_revert
)
);
err
=
AudioStreamSetProperty
(
p_sys
->
i_stream_id
,
NULL
,
0
,
kAudioStreamPropertyPhysicalFormat
,
sizeof
(
AudioStreamBasicDescription
),
&
p_sys
->
sfmt_revert
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"Streamformat reverse failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
gettimeofday
(
&
now
,
NULL
);
timeout
.
tv_sec
=
now
.
tv_sec
;
timeout
.
tv_nsec
=
(
now
.
tv_usec
+
900000
)
*
1000
;
pthread_cond_timedwait
(
&
w
.
cond
.
cond
,
&
w
.
lock
.
mutex
,
&
timeout
);
vlc_mutex_unlock
(
&
w
.
lock
);
err
=
AudioStreamRemovePropertyListener
(
p_sys
->
i_stream_id
,
0
,
kAudioStreamPropertyPhysicalFormat
,
StreamListener
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioStreamRemovePropertyListener failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
vlc_mutex_destroy
(
&
w
.
lock
);
vlc_cond_destroy
(
&
w
.
cond
);
i_param_size
=
sizeof
(
AudioStreamBasicDescription
);
err
=
AudioStreamGetProperty
(
p_sys
->
i_stream_id
,
0
,
kAudioStreamPropertyPhysicalFormat
,
&
i_param_size
,
&
p_sys
->
stream_format
);
msg_Dbg
(
p_aout
,
STREAM_FORMAT_MSG
(
"actual format in use: "
,
p_sys
->
stream_format
)
);
}
if
(
p_sys
->
b_changed_mixing
&&
p_sys
->
sfmt_revert
.
mFormatID
!=
kAudioFormat60958AC3
)
{
int
b_mix
;
Boolean
b_writeable
;
/* Revert mixable to true if we are allowed to */
err
=
AudioDeviceGetPropertyInfo
(
p_sys
->
i_selected_dev
,
0
,
FALSE
,
kAudioDevicePropertySupportsMixing
,
&
i_param_size
,
&
b_writeable
);
err
=
AudioDeviceGetProperty
(
p_sys
->
i_selected_dev
,
0
,
FALSE
,
kAudioDevicePropertySupportsMixing
,
&
i_param_size
,
&
b_mix
);
if
(
!
err
&&
b_writeable
)
{
msg_Dbg
(
p_aout
,
"mixable is: %d"
,
b_mix
);
b_mix
=
1
;
err
=
AudioDeviceSetProperty
(
p_sys
->
i_selected_dev
,
0
,
0
,
FALSE
,
kAudioDevicePropertySupportsMixing
,
i_param_size
,
&
b_mix
);
}
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"failed to set mixmode: [%4.4s]"
,
(
char
*
)
&
err
);
}
}
}
err
=
AudioHardwareRemovePropertyListener
(
kAudioHardwarePropertyDevices
,
HardwareListener
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"AudioHardwareRemovePropertyListener failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
if
(
p_sys
->
i_hog_pid
==
getpid
()
)
{
p_sys
->
i_hog_pid
=
-
1
;
i_param_size
=
sizeof
(
p_sys
->
i_hog_pid
);
err
=
AudioDeviceSetProperty
(
p_sys
->
i_selected_dev
,
0
,
0
,
FALSE
,
kAudioDevicePropertyHogMode
,
i_param_size
,
&
p_sys
->
i_hog_pid
);
if
(
err
!=
noErr
)
msg_Err
(
p_aout
,
"Could not release hogmode: [%4.4s]"
,
(
char
*
)
&
err
);
}
if
(
p_sys
)
free
(
p_sys
);
}
/*****************************************************************************
...
...
@@ -504,11 +969,11 @@ static void Play( aout_instance_t * p_aout )
/*****************************************************************************
* Probe
*****************************************************************************/
static
int
Probe
(
aout_instance_t
*
p_aout
)
static
void
Probe
(
aout_instance_t
*
p_aout
)
{
OSStatus
err
=
noErr
;
UInt32
i
,
i_param_size
;
AudioDeviceID
devid_def
;
UInt32
i
=
0
,
i_param_size
=
0
;
AudioDeviceID
devid_def
=
0
;
AudioDeviceID
*
p_devices
=
NULL
;
vlc_value_t
val
,
text
;
...
...
@@ -534,7 +999,7 @@ static int Probe( aout_instance_t * p_aout )
msg_Dbg
(
p_aout
,
"system has [%ld] device(s)"
,
p_sys
->
i_devices
);
/* Allocate DeviceID array */
p_devices
=
(
AudioDeviceID
*
)
malloc
(
i_param_size
);
p_devices
=
(
AudioDeviceID
*
)
malloc
(
sizeof
(
AudioDeviceID
)
*
p_sys
->
i_devices
);
if
(
p_devices
==
NULL
)
{
msg_Err
(
p_aout
,
"out of memory"
);
...
...
@@ -543,7 +1008,7 @@ static int Probe( aout_instance_t * p_aout )
/* Populate DeviceID array */
err
=
AudioHardwareGetProperty
(
kAudioHardwarePropertyDevices
,
&
i_param_size
,
(
void
*
)
p_devices
);
&
i_param_size
,
p_devices
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get the device ID's: [%4.4s]"
,
(
char
*
)
&
err
);
...
...
@@ -553,7 +1018,7 @@ static int Probe( aout_instance_t * p_aout )
/* Find the ID of the default Device */
i_param_size
=
sizeof
(
AudioDeviceID
);
err
=
AudioHardwareGetProperty
(
kAudioHardwarePropertyDefaultOutputDevice
,
&
i_param_size
,
(
void
*
)
&
devid_def
);
&
i_param_size
,
&
devid_def
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get default audio device: [%4.4s]"
,
(
char
*
)
&
err
);
...
...
@@ -567,29 +1032,25 @@ static int Probe( aout_instance_t * p_aout )
for
(
i
=
0
;
i
<
p_sys
->
i_devices
;
i
++
)
{
char
psz_devuid
[
1024
];
char
psz_name
[
1024
];
CFStringRef
devUID
;
char
*
psz_name
;
i_param_size
=
0
;
i_param_size
=
sizeof
psz_name
;
err
=
AudioDeviceGetProperty
(
/* Retrieve the length of the device name */
err
=
AudioDeviceGetProperty
Info
(
p_devices
[
i
],
0
,
VLC_FALSE
,
kAudioDevicePropertyDeviceName
,
&
i_param_size
,
psz_name
);
if
(
err
)
goto
error
;
&
i_param_size
,
NULL
);
if
(
err
)
goto
error
;
i_param_size
=
sizeof
(
CFStringRef
);
/* Retrieve the name of the device */
psz_name
=
(
char
*
)
malloc
(
i_param_size
);
err
=
AudioDeviceGetProperty
(
p_devices
[
i
],
0
,
VLC_FALSE
,
kAudioDevicePropertyDeviceUID
,
&
i_param_size
,
&
devUID
);
if
(
err
)
goto
error
;
kAudioDevicePropertyDeviceName
,
&
i_param_size
,
psz_name
);
if
(
err
)
goto
error
;
CFStringGetCString
(
devUID
,
psz_devuid
,
sizeof
psz_devuid
,
CFStringGetSystemEncoding
()
);
msg_Dbg
(
p_aout
,
"DevID: %lu DevName: %s DevUID: %s"
,
p_devices
[
i
],
psz_name
,
psz_devuid
);
CFRelease
(
devUID
);
msg_Dbg
(
p_aout
,
"DevID: %lu DevName: %s"
,
p_devices
[
i
],
psz_name
);
if
(
!
AudioDeviceHasOutput
(
p_devices
[
i
])
)
{
...
...
@@ -597,70 +1058,160 @@ static int Probe( aout_instance_t * p_aout )
continue
;
}
val
.
i_int
=
(
int
)
p_devices
[
i
];
text
.
psz_string
=
psz_name
;
val
.
i_int
=
(
int
)
p_devices
[
i
];
text
.
psz_string
=
strdup
(
psz_name
)
;
var_Change
(
p_aout
,
"audio-device"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
if
(
devid_def
==
p_devices
[
i
]
)
if
(
p_sys
->
i_default_dev
==
p_devices
[
i
]
)
{
var_Change
(
p_aout
,
"audio-device"
,
VLC_VAR_SETDEFAULT
,
&
val
,
NULL
);
var_Set
(
p_aout
,
"audio-device"
,
val
);
}
if
(
AudioDeviceSupportsDigital
(
p_aout
,
p_devices
[
i
]
)
)
{
val
.
i_int
=
(
int
)
p_devices
[
i
]
|
AOUT_VAR_SPDIF_FLAG
;
asprintf
(
&
text
.
psz_string
,
"%s (Encoded Output)"
,
psz_name
);
var_Change
(
p_aout
,
"audio-device"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
if
(
p_sys
->
i_default_dev
==
p_devices
[
i
]
&&
config_GetInt
(
p_aout
,
"spdif"
)
)
{
var_Change
(
p_aout
,
"audio-device"
,
VLC_VAR_SETDEFAULT
,
&
val
,
NULL
);
var_Set
(
p_aout
,
"audio-device"
,
val
);
}
}
free
(
psz_name
);
}
var_AddCallback
(
p_aout
,
"audio-device"
,
aout_ChannelsRestart
,
NULL
);
var_Get
(
p_aout
->
p_vlc
,
"macosx-audio-device"
,
&
val
);
msg_Dbg
(
p_aout
,
"device value override1: %#x"
,
val
.
i_int
);
if
(
val
.
i_int
>
0
)
{
msg_Dbg
(
p_aout
,
"device value override2: %#x"
,
val
.
i_int
);
var_Change
(
p_aout
,
"audio-device"
,
VLC_VAR_SETDEFAULT
,
&
val
,
NULL
);
var_Set
(
p_aout
,
"audio-device"
,
val
);
}
var_AddCallback
(
p_aout
,
"audio-device"
,
AudioDeviceCallback
,
NULL
);
/* attach a Listener so that we are notified of a change in the Device setup */
/*
err = AudioHardwareAddPropertyListener( kAudioHardwarePropertyDevices,
err
=
AudioHardwareAddPropertyListener
(
kAudioHardwarePropertyDevices
,
HardwareListener
,
(
void
*
)
p_aout
);
if
(
err
)
goto error;
*/
goto
error
;
msg_Dbg
(
p_aout
,
"succesful finish of deviceslist"
);
if
(
p_devices
)
free
(
p_devices
);
return
(
VLC_SUCCESS
)
;
return
;
error:
var_Destroy
(
p_aout
,
"audio-device"
);
if
(
p_devices
)
free
(
p_devices
);
return
VLC_EGENERIC
;
return
;
}
/*****************************************************************************
*
DeviceDigitalMode: Check i_dev_id for digital stream support.
*
AudioDeviceHasOutput: Checks if the Device actually provides any outputs at all
*****************************************************************************/
static
int
DeviceDigitalMode
(
aout_instance_t
*
p_aout
,
AudioDeviceID
i_dev_id
)
static
int
AudioDeviceHasOutput
(
AudioDeviceID
i_dev_id
)
{
OSStatus
err
=
noErr
;
UInt32
i_param_siz
e
;
AudioStreamBasicDescription
*
p_format_list
;
int
i
,
i_formats
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
UInt32
dataSize
;
Boolean
isWritabl
e
;
verify_noerr
(
AudioDeviceGetPropertyInfo
(
i_dev_id
,
0
,
FALSE
,
kAudioDevicePropertyStreams
,
&
dataSize
,
&
isWritable
)
)
;
if
(
dataSize
==
0
)
return
FALSE
;
p_sys
->
b_supports_digital
=
VLC_FALSE
;
return
TRUE
;
}
/*****************************************************************************
* AudioDeviceSupportsDigital: Check i_dev_id for digital stream support.
*****************************************************************************/
static
int
AudioDeviceSupportsDigital
(
aout_instance_t
*
p_aout
,
AudioDeviceID
i_dev_id
)
{
OSStatus
err
=
noErr
;
UInt32
i_param_size
=
0
;
AudioStreamID
*
p_streams
=
NULL
;
int
i
=
0
,
i_streams
=
0
;
vlc_bool_t
b_return
=
VLC_FALSE
;
/* Retrieve all the output streams */
err
=
AudioDeviceGetPropertyInfo
(
i_dev_id
,
0
,
FALSE
,
kAudioDevicePropertyStream
Format
s
,
kAudioDevicePropertyStreams
,
&
i_param_size
,
NULL
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get number of streamsformats: [%4.4s]"
,
(
char
*
)
&
err
);
return
(
VLC_EGENERIC
);
msg_Err
(
p_aout
,
"could not get number of streams: [%4.4s]"
,
(
char
*
)
&
err
);
return
VLC_FALSE
;
}
i_streams
=
i_param_size
/
sizeof
(
AudioStreamID
);
p_streams
=
(
AudioStreamID
*
)
malloc
(
i_param_size
);
if
(
p_streams
==
NULL
)
{
msg_Err
(
p_aout
,
"Out of memory"
);
return
VLC_ENOMEM
;
}
err
=
AudioDeviceGetProperty
(
i_dev_id
,
0
,
FALSE
,
kAudioDevicePropertyStreams
,
&
i_param_size
,
p_streams
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get number of streams: [%4.4s]"
,
(
char
*
)
&
err
);
return
VLC_FALSE
;
}
for
(
i
=
0
;
i
<
i_streams
;
i
++
)
{
if
(
AudioStreamSupportsDigital
(
p_aout
,
p_streams
[
i
]
)
)
b_return
=
VLC_TRUE
;
}
if
(
p_streams
)
free
(
p_streams
);
return
b_return
;
}
/*****************************************************************************
* AudioStreamSupportsDigital: Check i_stream_id for digital stream support.
*****************************************************************************/
static
int
AudioStreamSupportsDigital
(
aout_instance_t
*
p_aout
,
AudioStreamID
i_stream_id
)
{
OSStatus
err
=
noErr
;
UInt32
i_param_size
=
0
;
AudioStreamBasicDescription
*
p_format_list
=
NULL
;
int
i
=
0
,
i_formats
=
0
;
vlc_bool_t
b_return
=
VLC_FALSE
;
/* Retrieve all the stream formats supported by each output stream */
err
=
AudioStreamGetPropertyInfo
(
i_stream_id
,
0
,
kAudioStreamPropertyPhysicalFormats
,
&
i_param_size
,
NULL
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get number of streamformats: [%4.4s]"
,
(
char
*
)
&
err
);
return
VLC_FALSE
;
}
i_formats
=
i_param_size
/
sizeof
(
AudioStreamBasicDescription
);
msg_Dbg
(
p_aout
,
"number of formats: %d"
,
i_formats
);
p_format_list
=
(
AudioStreamBasicDescription
*
)
malloc
(
i_param_size
);
if
(
p_format_list
==
NULL
)
{
return
(
VLC_ENOMEM
);
msg_Err
(
p_aout
,
"Could not malloc the memory"
);
return
VLC_FALSE
;
}
err
=
Audio
DeviceGetProperty
(
i_dev_id
,
0
,
FALSE
,
kAudio
DevicePropertyStream
Formats
,
&
i_param_size
,
(
void
*
)
p_format_list
);
err
=
Audio
StreamGetProperty
(
i_stream_id
,
0
,
kAudio
StreamPropertyPhysical
Formats
,
&
i_param_size
,
p_format_list
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"could not get the list of formats: [%4.4s]"
,
(
char
*
)
&
err
);
return
(
VLC_EGENERIC
);
msg_Err
(
p_aout
,
"could not get the list of streamformats: [%4.4s]"
,
(
char
*
)
&
err
);
free
(
p_format_list
);
p_format_list
=
NULL
;
return
VLC_FALSE
;
}
for
(
i
=
0
;
i
<
i_formats
;
i
++
)
...
...
@@ -670,14 +1221,12 @@ static int DeviceDigitalMode( aout_instance_t *p_aout, AudioDeviceID i_dev_id )
if
(
p_format_list
[
i
].
mFormatID
==
'
IAC3
'
||
p_format_list
[
i
].
mFormatID
==
kAudioFormat60958AC3
)
{
p_sys
->
b_supports_digital
=
VLC_TRUE
;
msg_Dbg
(
p_aout
,
"this device supports a digital stream"
);
break
;
b_return
=
VLC_TRUE
;
}
}
free
(
(
void
*
)
p_format_list
);
return
VLC_SUCCESS
;
if
(
p_format_list
)
free
(
p_format_list
);
return
b_return
;
}
/*****************************************************************************
...
...
@@ -703,12 +1252,14 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
host_time
.
mFlags
=
kAudioTimeStampHostTimeValid
;
AudioDeviceTranslateTime
(
p_sys
->
i_selected_dev
,
inTimeStamp
,
&
host_time
);
/* Check for the difference between the Device clock and mdate */
p_sys
->
clock_diff
=
-
(
mtime_t
)
AudioConvertHostTimeToNanos
(
AudioGetCurrentHostTime
()
)
/
1000
;
p_sys
->
clock_diff
+=
mdate
();
current_date
=
p_sys
->
clock_diff
+
AudioConvertHostTimeToNanos
(
host_time
.
mHostTime
)
/
1000
;
//- ((mtime_t) 1000000 / p_aout->output.output.i_rate * 31 ); // 31 = Latency in Frames. retrieve somewhere
if
(
ioData
==
NULL
&&
ioData
->
mNumberBuffers
<
1
)
{
...
...
@@ -766,39 +1317,53 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
return
(
noErr
);
}
/*****************************************************************************
*
Setup a digital stream
*
RenderCallbackSPDIF: callback for SPDIF audio output
*****************************************************************************/
static
int
DigitalInit
(
aout_instance_t
*
p_aout
)
static
OSStatus
RenderCallbackSPDIF
(
AudioDeviceID
inDevice
,
const
AudioTimeStamp
*
inNow
,
const
void
*
inInputData
,
const
AudioTimeStamp
*
inInputTime
,
AudioBufferList
*
outOutputData
,
const
AudioTimeStamp
*
inOutputTime
,
void
*
threadGlobals
)
{
OSStatus
err
=
noErr
;
UInt32
i
,
i_param_size
;
AudioDeviceID
devid_def
;
AudioDeviceID
*
p_devices
=
NULL
;
vlc_value_t
val
,
text
;
aout_buffer_t
*
p_buffer
;
mtime_t
current_date
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
threadGlobals
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
return
(
VLC_SUCCESS
);
/* Check for the difference between the Device clock and mdate */
p_sys
->
clock_diff
=
-
(
mtime_t
)
AudioConvertHostTimeToNanos
(
inNow
->
mHostTime
)
/
1000
;
p_sys
->
clock_diff
+=
mdate
();
error:
return
VLC_EGENERIC
;
}
current_date
=
p_sys
->
clock_diff
+
AudioConvertHostTimeToNanos
(
inOutputTime
->
mHostTime
)
/
1000
;
//- ((mtime_t) 1000000 / p_aout->output.output.i_rate * 31 ); // 31 = Latency in Frames. retrieve somewhere
int
AudioDeviceHasOutput
(
AudioDeviceID
i_dev_id
)
{
UInt32
dataSize
;
Boolean
isWritable
;
verify_noerr
(
AudioDeviceGetPropertyInfo
(
i_dev_id
,
0
,
FALSE
,
kAudioDevicePropertyStreams
,
&
dataSize
,
&
isWritable
)
);
if
(
dataSize
==
0
)
return
FALSE
;
return
TRUE
;
}
p_buffer
=
aout_OutputNextBuffer
(
p_aout
,
current_date
,
VLC_TRUE
);
#define BUFFER outOutputData->mBuffers[p_sys->i_stream_index]
if
(
p_buffer
!=
NULL
)
{
if
(
(
int
)
BUFFER
.
mDataByteSize
!=
(
int
)
p_buffer
->
i_nb_bytes
)
msg_Warn
(
p_aout
,
"bytesize: %d nb_bytes: %d"
,
(
int
)
BUFFER
.
mDataByteSize
,
(
int
)
p_buffer
->
i_nb_bytes
);
/* move data into output data buffer */
p_aout
->
p_vlc
->
pf_memcpy
(
BUFFER
.
mData
,
p_buffer
->
p_buffer
,
p_buffer
->
i_nb_bytes
);
aout_BufferFree
(
p_buffer
);
}
else
{
p_aout
->
p_vlc
->
pf_memset
(
BUFFER
.
mData
,
0
,
BUFFER
.
mDataByteSize
);
}
#undef BUFFER
return
(
noErr
);
}
/*****************************************************************************
* HardwareListener: Warns us of changes in the list of registered devices
...
...
@@ -807,9 +1372,7 @@ static OSStatus HardwareListener( AudioHardwarePropertyID inPropertyID,
void
*
inClientData
)
{
OSStatus
err
=
noErr
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
inClientData
;
/* struct aout_sys_t *p_sys = p_aout->output.p_sys; */
switch
(
inPropertyID
)
{
...
...
@@ -818,9 +1381,48 @@ static OSStatus HardwareListener( AudioHardwarePropertyID inPropertyID,
/* something changed in the list of devices */
/* We trigger the audio-device's aout_ChannelsRestart callback */
var_Change
(
p_aout
,
"audio-device"
,
VLC_VAR_TRIGGER_CALLBACKS
,
NULL
,
NULL
);
var_Destroy
(
p_aout
,
"audio-device"
);
}
break
;
}
return
(
err
);
}
/*****************************************************************************
* StreamListener
*****************************************************************************/
static
OSStatus
StreamListener
(
AudioStreamID
inStream
,
UInt32
inChannel
,
AudioDevicePropertyID
inPropertyID
,
void
*
inClientData
)
{
OSStatus
err
=
noErr
;
struct
{
vlc_mutex_t
lock
;
vlc_cond_t
cond
;
}
*
w
=
inClientData
;
switch
(
inPropertyID
)
{
case
kAudioStreamPropertyPhysicalFormat
:
vlc_mutex_lock
(
&
w
->
lock
);
vlc_cond_signal
(
&
w
->
cond
);
vlc_mutex_unlock
(
&
w
->
lock
);
break
;
default:
break
;
}
return
(
err
);
}
/*****************************************************************************
* AudioDeviceCallback: Callback triggered when the audio-device variable is changed
*****************************************************************************/
static
int
AudioDeviceCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_variable
,
vlc_value_t
old_val
,
vlc_value_t
new_val
,
void
*
param
)
{
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
p_this
;
var_Set
(
p_aout
->
p_vlc
,
"macosx-audio-device"
,
new_val
);
msg_Dbg
(
p_aout
,
"Set Device: %#x"
,
new_val
.
i_int
);
return
aout_ChannelsRestart
(
p_this
,
psz_variable
,
old_val
,
new_val
,
param
);
}
modules/audio_output/coreaudio.c
View file @
fb397dc0
...
...
@@ -158,6 +158,7 @@ struct aout_sys_t
UInt32
i_stream_index
;
AudioStreamBasicDescription
stream_format
;
UInt32
b_dev_alive
;
pid_t
i_hog_pid
;
vlc_bool_t
b_revert_sfmt
;
AudioStreamBasicDescription
sfmt_revert
;
...
...
@@ -253,6 +254,7 @@ static int Open( vlc_object_t * p_this )
p_aout
->
output
.
p_sys
=
p_sys
;
p_aout
->
output
.
pf_play
=
Play
;
p_sys
->
i_hog_pid
=
-
1
;
vlc_mutex_init
(
p_aout
,
&
p_sys
->
lock
);
...
...
@@ -281,7 +283,6 @@ static int Open( vlc_object_t * p_this )
/* get starting channel for the selected stream */
p_option
=
&
p_sys
->
p_options
[
p_sys
->
i_sel_opt
];
i_param_size
=
sizeof
(
UInt32
);
err
=
AudioStreamGetProperty
(
p_option
->
i_sid
,
0
,
kAudioStreamPropertyStartingChannel
,
...
...
@@ -337,34 +338,34 @@ static int Open( vlc_object_t * p_this )
free
(
(
void
*
)
p_sys
);
return
(
VLC_EGENERIC
);
}
msg_Dbg
(
p_aout
,
"device bufframe size: [%ld]"
,
p_sys
->
i_bufframe_size
);
msg_Dbg
(
p_aout
,
"device buffer index: [%ld]"
,
p_sys
->
i_stream_index
);
/* If we do AC3 over SPDIF, set buffer size to one AC3 frame */
if
(
(
p_sys
->
stream_format
.
mFormatID
==
kAudioFormat60958AC3
||
p_sys
->
stream_format
.
mFormatID
==
'
IAC3
'
)
&&
p_sys
->
i_bufframe_size
!=
A52_FRAME_NB
)
{
p_sys
->
i_bufframe_size
=
A52_FRAME_NB
;
i_param_size
=
sizeof
(
p_sys
->
i_bufframe_size
);
err
=
AudioDeviceSetProperty
(
p_sys
->
devid
,
0
,
0
,
FALSE
,
kAudioDevicePropertyBufferFrameSize
,
i_param_size
,
&
p_sys
->
i_bufframe_size
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"failed to set bufframe size (%ld): [%4.4s]"
,
p_sys
->
i_bufframe_size
,
(
char
*
)
&
err
);
FreeDevice
(
p_aout
);
FreeHardwareInfo
(
p_aout
);
vlc_mutex_destroy
(
&
p_sys
->
lock
);
free
(
(
void
*
)
p_sys
);
return
(
VLC_EGENERIC
);
}
msg_Dbg
(
p_aout
,
"device bufframe size set to: [%ld]"
,
p_sys
->
i_bufframe_size
);
}
/* If we do AC3 over SPDIF, set buffer size to one AC3 frame */
if
(
(
p_sys
->
stream_format
.
mFormatID
==
kAudioFormat60958AC3
||
p_sys
->
stream_format
.
mFormatID
==
'
IAC3
'
)
&&
p_sys
->
i_bufframe_size
!=
A52_FRAME_NB
)
{
p_sys
->
i_bufframe_size
=
A52_FRAME_NB
;
i_param_size
=
sizeof
(
p_sys
->
i_bufframe_size
);
err
=
AudioDeviceSetProperty
(
p_sys
->
devid
,
0
,
0
,
FALSE
,
kAudioDevicePropertyBufferFrameSize
,
i_param_size
,
&
p_sys
->
i_bufframe_size
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"failed to set bufframe size (%ld): [%4.4s]"
,
p_sys
->
i_bufframe_size
,
(
char
*
)
&
err
);
FreeDevice
(
p_aout
);
FreeHardwareInfo
(
p_aout
);
vlc_mutex_destroy
(
&
p_sys
->
lock
);
free
(
(
void
*
)
p_sys
);
return
(
VLC_EGENERIC
);
}
msg_Dbg
(
p_aout
,
"device bufframe size set to: [%ld]"
,
p_sys
->
i_bufframe_size
);
}
switch
(
p_sys
->
stream_format
.
mFormatID
)
{
...
...
@@ -420,7 +421,10 @@ static int Open( vlc_object_t * p_this )
case
'
IAC3
'
:
case
kAudioFormat60958AC3
:
p_aout
->
output
.
output
.
i_format
=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
);
if
(
p_sys
->
stream_format
.
mFormatFlags
&
kAudioFormatFlagIsBigEndian
)
p_aout
->
output
.
output
.
i_format
=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'b'
);
else
p_aout
->
output
.
output
.
i_format
=
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
);
p_aout
->
output
.
output
.
i_bytes_per_frame
=
AOUT_SPDIF_SIZE
;
p_aout
->
output
.
output
.
i_frame_length
=
A52_FRAME_NB
;
p_aout
->
output
.
i_nb_samples
=
p_aout
->
output
.
output
.
i_frame_length
;
...
...
@@ -584,35 +588,30 @@ static OSStatus IOCallback( AudioDeviceID inDevice,
void
*
threadGlobals
)
{
aout_buffer_t
*
p_buffer
;
AudioTimeStamp
host_time
;
mtime_t
current_date
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
threadGlobals
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
host_time
.
mFlags
=
kAudioTimeStampHostTimeValid
;
AudioDeviceTranslateTime
(
inDevice
,
inOutputTime
,
&
host_time
);
#if 1
p_sys
->
clock_diff
=
-
(
mtime_t
)
AudioConvertHostTimeToNanos
(
AudioGetCurrentHostTime
()
)
/
1000
;
AudioConvertHostTimeToNanos
(
inNow
->
mHostTime
)
/
1000
;
p_sys
->
clock_diff
+=
mdate
();
#endif
current_date
=
p_sys
->
clock_diff
+
AudioConvertHostTimeToNanos
(
host_time
.
mHostTime
)
/
1000
;
AudioConvertHostTimeToNanos
(
inOutputTime
->
mHostTime
)
/
1000
;
#define B_SPDI (p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i'))
#define B_SPDI (p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i')
|| p_aout->output.output.i_format == VLC_FOURCC('s','p','d','b')
)
p_buffer
=
aout_OutputNextBuffer
(
p_aout
,
current_date
,
B_SPDI
);
#undef B_SPDI
#define BUFFER outOutputData->mBuffers[
p_sys->i_stream_index
]
#define BUFFER outOutputData->mBuffers[
p_sys->i_stream_index
]
if
(
p_buffer
!=
NULL
)
{
/* move data into output data buffer */
p_aout
->
p_vlc
->
pf_memcpy
(
BUFFER
.
mData
,
p_buffer
->
p_buffer
,
p_buffer
->
i_nb_bytes
);
aout_BufferFree
(
p_buffer
);
}
else
...
...
@@ -993,7 +992,6 @@ static int InitStreamInfo( UInt32 i_dev, aout_instance_t * p_aout,
msg_Err
(
p_aout
,
"GetStreamID(%ld, %ld) failed"
,
i_dev
,
i_idx
);
return
(
VLC_EGENERIC
);
}
err
=
AudioStreamGetPropertyInfo
(
i_sid
,
0
,
kAudioStreamPropertyPhysicalFormats
,
&
i_param_size
,
NULL
);
...
...
@@ -1214,6 +1212,81 @@ static int InitDevice( aout_instance_t * p_aout )
vlc_mutex_lock
(
&
w
.
lock
);
/* If we do AC3 over SPDIF, take hog mode and non mixable mode */
if
(
P_STREAMS
[
i_stream
].
mFormatID
==
kAudioFormat60958AC3
||
P_STREAMS
[
i_stream
].
mFormatID
==
'
IAC3
'
)
{
UInt32
b_mix
;
i_param_size
=
sizeof
(
p_sys
->
i_hog_pid
);
err
=
AudioDeviceGetProperty
(
p_dev
->
devid
,
0
,
FALSE
,
kAudioDevicePropertyHogMode
,
&
i_param_size
,
&
p_sys
->
i_hog_pid
);
if
(
!
err
)
{
msg_Dbg
(
p_aout
,
"Current status of hog mode: pid=%d vlc pid=%d
\n
"
,
(
int
)
p_sys
->
i_hog_pid
,
(
int
)
getpid
()
);
if
(
p_sys
->
i_hog_pid
!=
getpid
()
)
{
p_sys
->
i_hog_pid
=
getpid
()
;
err
=
AudioDeviceSetProperty
(
p_dev
->
devid
,
0
,
0
,
FALSE
,
kAudioDevicePropertyHogMode
,
i_param_size
,
&
p_sys
->
i_hog_pid
);
if
(
!
err
)
{
msg_Dbg
(
p_aout
,
"Successfully set hog mode - new pid=%d!
\n
"
,
(
int
)
p_sys
->
i_hog_pid
);
err
=
AudioDeviceGetProperty
(
p_dev
->
devid
,
0
,
FALSE
,
kAudioDevicePropertyHogMode
,
&
i_param_size
,
&
p_sys
->
i_hog_pid
);
if
(
!
err
)
{
msg_Dbg
(
p_aout
,
"Checking new status of hog mode: pid=%d vlc pid=%d
\n
"
,
(
int
)
p_sys
->
i_hog_pid
,
(
int
)
getpid
()
);
}
}
}
}
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"failed to set hogmode: : [%4.4s]"
,
(
char
*
)
&
err
);
FreeDevice
(
p_aout
);
FreeHardwareInfo
(
p_aout
);
vlc_mutex_destroy
(
&
p_sys
->
lock
);
free
(
(
void
*
)
p_sys
);
return
(
VLC_EGENERIC
);
}
/*
i_param_size = sizeof( b_mix );
err = AudioDeviceGetProperty( p_dev->devid, 0, FALSE, kAudioDevicePropertySupportsMixing,
&i_param_size, &b_mix );
if( !err )
{
msg_Dbg( p_aout, "Current status of mix mode: %i\n", (int)b_mix );
b_mix = 0;
err = AudioDeviceSetProperty( p_dev->devid, 0, 0, FALSE,
kAudioDevicePropertySupportsMixing, i_param_size, &b_mix );
if( !err )
{
msg_Dbg( p_aout, "Successfully set mix mode - new mix=%d!\n", (int)b_mix );
err = AudioDeviceGetProperty( p_dev->devid, 0, FALSE,
kAudioDevicePropertySupportsMixing, &i_param_size, &b_mix );
if( !err )
{
msg_Dbg( p_aout, "Checking new status of mix mode: %d\n", (int)b_mix );
}
}
}
if( err != noErr )
{
msg_Err( p_aout, "failed to set mixmode: : [%4.4s]", (char *)&err );
FreeDevice( p_aout );
FreeHardwareInfo( p_aout );
vlc_mutex_destroy( &p_sys->lock );
free( (void *)p_sys );
return( VLC_EGENERIC );
}*/
}
msg_Dbg
(
p_aout
,
STREAM_FORMAT_MSG
(
"setting format"
,
P_STREAMS
[
i_stream
]
)
);
...
...
@@ -1325,6 +1398,29 @@ static void FreeDevice( aout_instance_t * p_aout )
msg_Err
(
p_aout
,
"AudioStreamSetProperty revert format failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
}
if
(
(
int
)
p_sys
->
i_hog_pid
!=
-
1
)
{
/*UInt32 b_mix = 1;
err = AudioDeviceSetProperty( p_sys->devid, 0, 0, FALSE,
kAudioDevicePropertySupportsMixing, sizeof(b_mix), &b_mix );
if( err != noErr )
{
msg_Err( p_aout, "Resetting mix mode failed: [%4.4s]",
(char *)&err );
}
*/
p_sys
->
i_hog_pid
=
(
pid_t
)
-
1
;
err
=
AudioDeviceSetProperty
(
p_sys
->
devid
,
0
,
0
,
FALSE
,
kAudioDevicePropertyHogMode
,
sizeof
(
p_sys
->
i_hog_pid
),
&
p_sys
->
i_hog_pid
);
if
(
err
!=
noErr
)
{
msg_Err
(
p_aout
,
"Releasing hog mode failed: [%4.4s]"
,
(
char
*
)
&
err
);
}
}
}
...
...
@@ -1440,8 +1536,9 @@ static OSStatus StreamListener( AudioStreamID inStream,
void
*
inClientData
)
{
OSStatus
err
=
noErr
;
struct
{
vlc_mutex_t
lock
;
vlc_cond_t
cond
;
}
*
w
=
inClientData
;
aout_instance_t
*
p_aout
=
(
aout_instance_t
*
)
inClientData
;
struct
aout_sys_t
*
p_sys
=
p_aout
->
output
.
p_sys
;
switch
(
inPropertyID
)
{
...
...
@@ -1454,7 +1551,6 @@ static OSStatus StreamListener( AudioStreamID inStream,
default:
break
;
}
return
(
err
);
}
...
...
src/audio_output/common.c
View file @
fb397dc0
...
...
@@ -142,6 +142,7 @@ void aout_FormatPrepare( audio_sample_format_t * p_format )
break
;
case
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'i'
):
case
VLC_FOURCC
(
's'
,
'p'
,
'd'
,
'b'
):
/* Big endian spdif output */
case
VLC_FOURCC
(
'a'
,
'5'
,
'2'
,
' '
):
case
VLC_FOURCC
(
'd'
,
't'
,
's'
,
' '
):
case
VLC_FOURCC
(
'm'
,
'p'
,
'g'
,
'a'
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment