[vlc-commits] auhal: fixed audio device configuration callback and added an additional callback to watch the used device 's health (close #4834)

Felix Paul Kühne git at videolan.org
Sat Sep 1 12:03:43 CEST 2012


vlc/vlc-2.0 | branch: master | Felix Paul Kühne <fkuehne at videolan.org> | Sat Sep  1 11:57:58 2012 +0200| [0401bdcdfec500db466fc875133e0890779190d2] | committer: Felix Paul Kühne

auhal: fixed audio device configuration callback and added an additional callback to watch the used device's health (close #4834)
(cherry picked from commit 8fbb1fd08399f3a29c0c4850bac2c03e40997099)

Conflicts:
	modules/audio_output/auhal.c

> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.0.git/?a=commit;h=0401bdcdfec500db466fc875133e0890779190d2
---

 NEWS                         |    2 ++
 modules/audio_output/auhal.c |   41 +++++++++++++++++++++++++++++++++--------
 2 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/NEWS b/NEWS
index bc605dc..e063a36 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,8 @@ Qt:
  * Fix media info dialog update
 
 Mac OS X:
+ * Fix audio output behavior when the output device is plugged or unplugged
+   during playback
  * Fix command-line options for the interface
  * Deactivate CoreAnimation effects on Leopard
  * Fix menus display and behaviour
diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c
index f308aad..d8bfc37 100644
--- a/modules/audio_output/auhal.c
+++ b/modules/audio_output/auhal.c
@@ -209,10 +209,9 @@ static int Open( vlc_object_t * p_this )
         msg_Dbg( p_aout, "audio device supports 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 */
     i_param_size = sizeof( b_alive );
     AudioObjectPropertyAddress audioDeviceAliveAddress = { kAudioDevicePropertyDeviceIsAlive,
-                                              kAudioDevicePropertyScopeOutput,
+                                              kAudioObjectPropertyScopeGlobal,
                                               kAudioObjectPropertyElementMaster };
     err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceAliveAddress, 0, NULL, &i_param_size, &b_alive );
 
@@ -230,6 +229,15 @@ static int Open( vlc_object_t * p_this )
         p_sys->i_selected_dev = p_sys->i_default_dev;
     }
 
+    /* add a callback to see if the device dies later on */
+    err = AudioObjectAddPropertyListener( p_sys->i_selected_dev, &audioDeviceAliveAddress, HardwareListener, (void *)p_aout );
+    if( err != noErr )
+    {
+        /* Be tolerant, only give a warning here */
+        msg_Warn( p_aout, "could not set alive check callback on device [0x%x]: %4.4s",
+                 (unsigned int)p_sys->i_selected_dev, (char *)&err );
+    }
+
     AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode,
                                   kAudioDevicePropertyScopeOutput,
                                   kAudioObjectPropertyElementMaster };
@@ -841,6 +849,13 @@ static void Close( vlc_object_t * p_this )
     OSStatus            err = noErr;
     UInt32              i_param_size = 0;
 
+    AudioObjectPropertyAddress deviceAliveAddress = { kAudioDevicePropertyDeviceIsAlive, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+    err = AudioObjectRemovePropertyListener( p_sys->i_selected_dev, &deviceAliveAddress, HardwareListener, NULL );
+    if( err != noErr )
+    {
+        msg_Err( p_aout, "failed to remove audio device life checker: [%4.4s]", (char *)&err );
+    }
+
     if( p_sys->au_unit )
     {
         verify_noerr( AudioOutputUnitStop( p_sys->au_unit ) );
@@ -894,7 +909,7 @@ static void Close( vlc_object_t * p_this )
         }
     }
 
-    AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
+    AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
     err = AudioObjectRemovePropertyListener( kAudioObjectSystemObject, &audioDevicesAddress, HardwareListener, NULL );
 
     if( err != noErr )
@@ -933,7 +948,7 @@ static void Probe( audio_output_t * p_aout )
     struct aout_sys_t   *p_sys = p_aout->sys;
 
     /* Get number of devices */
-    AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
+    AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
     err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &audioDevicesAddress, 0, NULL, &i_param_size);
     if( err != noErr )
     {
@@ -1040,14 +1055,17 @@ static void Probe( audio_output_t * p_aout )
     var_Get( p_aout->p_libvlc, "macosx-audio-device", &val );
     if( val.i_int > 0 )
     {
+        msg_Dbg( p_aout, "using preselected output device %#"PRIx64, val.i_int );
         var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL );
         var_Set( p_aout, "audio-device", val );
     }
 
     /* Attach a Listener so that we are notified of a change in the Device setup */
     err = AudioObjectAddPropertyListener( kAudioObjectSystemObject, &audioDevicesAddress, HardwareListener, (void *)p_aout );
-    if( err )
+    if( err != noErr ) {
+        msg_Warn( p_aout, "failed to add listener for audio device configuration (%i)", err );
         goto error;
+    }
 
     free( p_devices );
     return;
@@ -1339,9 +1357,9 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
         }
         else
         {
-             vlc_memset( (uint8_t *)ioData->mBuffers[0].mData +i_mData_bytes,
-                         0,ioData->mBuffers[0].mDataByteSize - i_mData_bytes );
-             i_mData_bytes += ioData->mBuffers[0].mDataByteSize - i_mData_bytes;
+            vlc_memset( (uint8_t *)ioData->mBuffers[0].mData +i_mData_bytes,
+                       0,ioData->mBuffers[0].mDataByteSize - i_mData_bytes );
+            i_mData_bytes += ioData->mBuffers[0].mDataByteSize - i_mData_bytes;
         }
     }
     return( noErr );
@@ -1413,6 +1431,13 @@ static OSStatus HardwareListener( AudioObjectID inObjectID,  UInt32 inNumberAddr
         {
             /* something changed in the list of devices */
             /* We trigger the audio-device's aout_ChannelsRestart callback */
+            msg_Warn( p_aout, "audio device configuration changed, resetting cache" );
+            var_TriggerCallback( p_aout, "audio-device" );
+            var_Destroy( p_aout, "audio-device" );
+        }
+        else if( inAddresses[i].mSelector == kAudioDevicePropertyDeviceIsAlive )
+        {
+            msg_Warn( p_aout, "audio device died, resetting aout" );
             var_TriggerCallback( p_aout, "audio-device" );
             var_Destroy( p_aout, "audio-device" );
         }



More information about the vlc-commits mailing list