X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_output%2Fauhal.c;h=999771a3b9f0c1f1becdf7423e2d26048d88a58b;hb=12dfb65e91cb460d1ac97dff6b5c0d2b1e431c51;hp=6e12887176dece6c5f5cce9a13f65edf8c2bb90f;hpb=97521497e5220d37c22fe92cadd3b43ad85a63cc;p=vlc diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c index 6e12887176..999771a3b9 100644 --- a/modules/audio_output/auhal.c +++ b/modules/audio_output/auhal.c @@ -18,47 +18,38 @@ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ + #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include - #include #include -#include -#include - -#include -#include -#include +#include // dialog_Fatal +#include // aout_* +#include // AudioUnit +#include // AudioDeviceID +#include // AudioFormatGetProperty #include #ifndef verify_noerr -#define verify_noerr(a) assert((a) == noErr) +# define verify_noerr(a) assert((a) == noErr) #endif #define STREAM_FORMAT_MSG( pre, sfm ) \ - pre "[%u][%4.4s][%u][%u][%u][%u][%u][%u]", \ - (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: [%u]\nFormatID: [%4.4s]\nFormatFlags: [%u]\nBypesPerPacket: [%u]\nFramesPerPacket: [%u]\nBytesPerFrame: [%u]\nChannelsPerFrame: [%u]\nBitsPerChannel[%u]", \ - (UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \ - sfm.mFormatFlags, sfm.mBytesPerPacket, \ - sfm.mFramesPerPacket, sfm.mBytesPerFrame, \ - sfm.mChannelsPerFrame, sfm.mBitsPerChannel + pre "[%f][%4.4s][%u][%u][%u][%u][%u][%u]", \ + sfm.mSampleRate, (char *)&sfm.mFormatID, \ + (unsigned int)sfm.mFormatFlags, (unsigned int)sfm.mBytesPerPacket, \ + (unsigned int)sfm.mFramesPerPacket, (unsigned int)sfm.mBytesPerFrame, \ + (unsigned int)sfm.mChannelsPerFrame, (unsigned int)sfm.mBitsPerChannel #define FRAMESIZE 2048 #define BUFSIZE (FRAMESIZE * 8) * 8 @@ -80,29 +71,28 @@ struct aout_sys_t { aout_packet_t packet; - AudioDeviceID i_default_dev; /* Keeps DeviceID of defaultOutputDevice */ - AudioDeviceID i_selected_dev; /* Keeps DeviceID of the selected device */ - AudioDeviceIOProcID i_procID; /* DeviceID of current device */ - UInt32 i_devices; /* Number of CoreAudio Devices */ - bool b_supports_digital;/* Does the currently selected device support digital mode? */ - bool b_digital; /* Are we running in digital mode? */ - mtime_t clock_diff; /* Difference between VLC clock and Device clock */ + AudioDeviceID i_default_dev; /* DeviceID of defaultOutputDevice */ + AudioDeviceID i_selected_dev; /* DeviceID of the selected device */ + AudioDeviceIOProcID i_procID; /* DeviceID of current device */ + UInt32 i_devices; /* Number of CoreAudio Devices */ + bool 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 */ + Component au_component; /* The Audiocomponent we use */ + AudioUnit au_unit; /* The AudioUnit we use */ uint8_t p_remainder_buffer[BUFSIZE]; uint32_t i_read_bytes; uint32_t i_total_bytes; /* 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 stream to */ - AudioStreamBasicDescription sfmt_revert; /* The original format of the stream */ - bool b_revert; /* Wether we need to revert the stream format */ - bool b_changed_mixing;/* Wether we need to set the mixing mode back */ + 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 stream to */ + AudioStreamBasicDescription sfmt_revert; /* The original format of the stream */ + bool b_revert; /* Wether we need to revert the stream format */ + bool b_changed_mixing; /* Wether we need to set the mixing mode back */ }; /***************************************************************************** @@ -113,7 +103,6 @@ static int OpenAnalog ( audio_output_t * ); static int OpenSPDIF ( audio_output_t * ); static void Close ( vlc_object_t * ); -static void Play ( audio_output_t *, block_t * ); static void Probe ( audio_output_t * ); static int AudioDeviceHasOutput ( AudioDeviceID ); @@ -131,7 +120,6 @@ static int AudioDeviceCallback ( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ); - /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -159,7 +147,7 @@ static int Open( vlc_object_t * p_this ) UInt32 i_param_size = 0; struct aout_sys_t *p_sys = NULL; vlc_value_t val; - audio_output_t *p_aout = (audio_output_t *)p_this; + audio_output_t *p_aout = (audio_output_t *)p_this; /* Use int here, to match kAudioDevicePropertyDeviceIsAlive * property size */ @@ -174,7 +162,6 @@ static int Open( vlc_object_t * p_this ) p_sys->i_default_dev = 0; p_sys->i_selected_dev = 0; p_sys->i_devices = 0; - p_sys->b_supports_digital = false; p_sys->b_digital = false; p_sys->au_component = NULL; p_sys->au_unit = NULL; @@ -214,11 +201,9 @@ static int Open( vlc_object_t * p_this ) } p_sys->i_selected_dev = val.i_int & ~AOUT_VAR_SPDIF_FLAG; /* remove SPDIF flag to get the true DeviceID */ - p_sys->b_supports_digital = ( val.i_int & AOUT_VAR_SPDIF_FLAG ) ? true : false; - if( p_sys->b_supports_digital ) + bool b_supports_digital = ( val.i_int & AOUT_VAR_SPDIF_FLAG ); + if( b_supports_digital ) msg_Dbg( p_aout, "audio device supports digital output" ); - else - msg_Dbg( p_aout, "audio device does not support digital output" ); /* Check if the desired device is alive and usable */ /* TODO: add a callback to the device to alert us if the device dies */ @@ -231,7 +216,8 @@ static int Open( vlc_object_t * p_this ) if( err != noErr ) { /* Be tolerant, only give a warning here */ - msg_Warn( p_aout, "could not check whether device [0x%x] is alive: %4.4s", (unsigned int)p_sys->i_selected_dev, (char *)&err ); + msg_Warn( p_aout, "could not check whether device [0x%x] is alive: %4.4s", + (unsigned int)p_sys->i_selected_dev, (char *)&err ); b_alive = false; } @@ -264,7 +250,7 @@ static int Open( vlc_object_t * p_this ) } /* Check for Digital mode or Analog output mode */ - if( AOUT_FMT_NON_LINEAR( &p_aout->format ) && p_sys->b_supports_digital ) + if( AOUT_FMT_SPDIF( &p_aout->format ) && b_supports_digital ) { if( OpenSPDIF( p_aout ) ) { @@ -633,23 +619,27 @@ static int OpenSPDIF( audio_output_t * p_aout ) return false; } - /* Set mixable to false if we are allowed to */ - AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; - err = AudioObjectIsPropertySettable( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, &b_writeable ); - err = AudioObjectGetPropertyDataSize( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size ); - err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size, &b_mix ); + AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; - if( !err && b_writeable ) + if (AudioObjectHasProperty(p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress)) { - b_mix = 0; - err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, i_param_size, &b_mix ); - p_sys->b_changed_mixing = true; - } + /* Set mixable to false if we are allowed to */ + err = AudioObjectIsPropertySettable( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, &b_writeable ); + err = AudioObjectGetPropertyDataSize( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size ); + err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size, &b_mix ); - if( err != noErr ) - { - msg_Err( p_aout, "failed to set mixmode: [%4.4s]", (char *)&err ); - return false; + if( err == noErr && b_writeable ) + { + b_mix = 0; + err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, i_param_size, &b_mix ); + p_sys->b_changed_mixing = true; + } + + if( err != noErr ) + { + msg_Err( p_aout, "failed to set mixmode: [%4.4s]", (char *)&err ); + return false; + } } /* Get a list of all the streams on this device */ @@ -676,18 +666,18 @@ static int OpenSPDIF( audio_output_t * p_aout ) } AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 }; - for( int i = 0; i < i_streams && p_sys->i_stream_index < 0 ; i++ ) + for( unsigned i = 0; i < i_streams && p_sys->i_stream_index < 0 ; i++ ) { /* Find a stream with a cac3 stream */ AudioStreamRangedDescription *p_format_list = NULL; - int i_formats = 0; - bool b_digital = false; + int i_formats = 0; + bool b_digital = false; /* Retrieve all the stream formats supported by each output stream */ err = AudioObjectGetPropertyDataSize( p_streams[i], &physicalFormatsAddress, 0, NULL, &i_param_size ); if( err != noErr ) { - msg_Err( p_aout, "OpenSPDIF: could not get number of streamformats: [%s] (%i)", (char *)&err, err ); + msg_Err( p_aout, "OpenSPDIF: could not get number of streamformats: [%s] (%i)", (char *)&err, (int32_t)err ); continue; } @@ -708,7 +698,9 @@ static int OpenSPDIF( audio_output_t * p_aout ) for( int j = 0; j < i_formats; j++ ) { if( p_format_list[j].mFormat.mFormatID == 'IAC3' || - p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 ) + p_format_list[j].mFormat.mFormatID == 'iac3' || + p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || + p_format_list[j].mFormat.mFormatID == kAudioFormatAC3 ) { b_digital = true; break; @@ -727,9 +719,10 @@ static int OpenSPDIF( audio_output_t * p_aout ) if( !p_sys->b_revert ) { + AudioObjectPropertyAddress currentPhysicalFormatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; /* Retrieve the original format of this stream first if not done so already */ i_param_size = sizeof( p_sys->sfmt_revert ); - err = AudioObjectGetPropertyData( p_sys->i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size, &p_sys->sfmt_revert ); + err = AudioObjectGetPropertyData( p_sys->i_stream_id, ¤tPhysicalFormatAddress, 0, NULL, &i_param_size, &p_sys->sfmt_revert ); if( err != noErr ) { msg_Err( p_aout, "could not retrieve the original streamformat: [%4.4s]", (char *)&err ); @@ -741,7 +734,9 @@ static int OpenSPDIF( audio_output_t * p_aout ) for( int j = 0; j < i_formats; j++ ) { if( p_format_list[j].mFormat.mFormatID == 'IAC3' || - p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 ) + p_format_list[j].mFormat.mFormatID == 'iac3' || + p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || + p_format_list[j].mFormat.mFormatID == kAudioFormatAC3 ) { if( p_format_list[j].mFormat.mSampleRate == p_aout->format.i_rate ) { @@ -868,13 +863,13 @@ static void Close( vlc_object_t * p_this ) if( p_sys->b_changed_mixing && p_sys->sfmt_revert.mFormatID != kAudioFormat60958AC3 ) { int b_mix; - Boolean b_writeable; + Boolean b_writeable = false; /* Revert mixable to true if we are allowed to */ AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; err = AudioObjectIsPropertySettable( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, &b_writeable ); err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size, &b_mix ); - if( !err && b_writeable ) + if( err == noErr && b_writeable ) { msg_Dbg( p_aout, "mixable is: %d", b_mix ); b_mix = 1; @@ -907,6 +902,8 @@ static void Close( vlc_object_t * p_this ) if( err != noErr ) msg_Err( p_aout, "Could not release hogmode: [%4.4s]", (char *)&err ); } + var_DelCallback( p_aout, "audio-device", AudioDeviceCallback, NULL ); + aout_PacketDestroy( p_aout ); free( p_sys ); } @@ -940,7 +937,7 @@ static void Probe( audio_output_t * p_aout ) msg_Err( p_aout, "No audio output devices were found." ); goto error; } - msg_Dbg( p_aout, "found %u audio device(s)", p_sys->i_devices ); + msg_Dbg( p_aout, "found %u audio device(s)", (unsigned)p_sys->i_devices ); /* Allocate DeviceID array */ p_devices = (AudioDeviceID*)malloc( sizeof(AudioDeviceID) * p_sys->i_devices ); @@ -986,7 +983,7 @@ static void Probe( audio_output_t * p_aout ) err = AudioObjectGetPropertyData( p_devices[i], &deviceNameAddress, 0, NULL, &i_param_size, psz_name ); if( err ) goto error; - msg_Dbg( p_aout, "DevID: %u DevName: %s", p_devices[i], psz_name ); + msg_Dbg( p_aout, "DevID: %u DevName: %s", (unsigned)p_devices[i], psz_name ); if( !AudioDeviceHasOutput( p_devices[i]) ) { @@ -1083,7 +1080,7 @@ static int AudioDeviceSupportsDigital( audio_output_t *p_aout, AudioDeviceID i_d err = AudioObjectGetPropertyDataSize( i_dev_id, &streamsAddress, 0, NULL, &i_param_size ); if( err != noErr ) { - msg_Err( p_aout, "could not get number of streams: [%s] (%i)", (char *)&err, err ); + msg_Err( p_aout, "could not get number of streams: [%s] (%i)", (char *)&err, (int32_t)err ); return false; } @@ -1125,7 +1122,7 @@ static int AudioStreamSupportsDigital( audio_output_t *p_aout, AudioStreamID i_s err = AudioObjectGetPropertyDataSize( i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size ); if( err != noErr ) { - msg_Err( p_aout, "could not get number of streamformats: [%s] (%i)", (char *)&err, err ); + msg_Err( p_aout, "could not get number of streamformats: [%s] (%i)", (char *)&err, (int32_t)err ); return false; } @@ -1150,7 +1147,9 @@ static int AudioStreamSupportsDigital( audio_output_t *p_aout, AudioStreamID i_s msg_Dbg( p_aout, STREAM_FORMAT_MSG( "supported format: ", p_format_list[i].mFormat ) ); if( p_format_list[i].mFormat.mFormatID == 'IAC3' || - p_format_list[i].mFormat.mFormatID == kAudioFormat60958AC3 ) + p_format_list[i].mFormat.mFormatID == 'iac3' || + p_format_list[i].mFormat.mFormatID == kAudioFormat60958AC3 || + p_format_list[i].mFormat.mFormatID == kAudioFormatAC3 ) { b_return = true; } @@ -1168,7 +1167,7 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre OSStatus err = noErr; UInt32 i_param_size = 0; - AudioObjectPropertyAddress physicalFormatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + AudioObjectPropertyAddress physicalFormatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; struct { vlc_mutex_t lock; vlc_cond_t cond; } w; @@ -1225,7 +1224,7 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre } /* Removing the property listener */ - err = AudioObjectRemovePropertyListener( i_stream_id, &physicalFormatAddress, StreamListener, NULL ); + err = AudioObjectRemovePropertyListener( i_stream_id, &physicalFormatAddress, StreamListener, (void *)&w ); if( err != noErr ) { msg_Err( p_aout, "AudioStreamRemovePropertyListener failed: [%4.4s]", (char *)&err ); @@ -1424,13 +1423,14 @@ static OSStatus StreamListener( AudioObjectID inObjectID, UInt32 inNumberAddres VLC_UNUSED(inObjectID); - for ( unsigned int i = 0; i < inNumberAddresses; i++ ) + for( unsigned int i = 0; i < inNumberAddresses; i++ ) { if( inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat ) { vlc_mutex_lock( &w->lock ); vlc_cond_signal( &w->cond ); vlc_mutex_unlock( &w->lock ); + break; } } return( err );