[vlc-commits] auhal: better deregistration of deviceAlive and audioStreams callbacks
David Fuhrmann
git at videolan.org
Mon May 13 20:18:01 CEST 2013
vlc | branch: master | David Fuhrmann <david.fuhrmann at googlemail.com> | Mon May 13 20:06:44 2013 +0200| [de2b503862c24509f4702f3ac429b7536c23d830] | committer: David Fuhrmann
auhal: better deregistration of deviceAlive and audioStreams callbacks
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=de2b503862c24509f4702f3ac429b7536c23d830
---
modules/audio_output/auhal.c | 74 ++++++++++++++++++++++++++----------------
1 file changed, 46 insertions(+), 28 deletions(-)
diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c
index b25ff7e..c7af12d 100644
--- a/modules/audio_output/auhal.c
+++ b/modules/audio_output/auhal.c
@@ -147,7 +147,7 @@ static OSStatus RenderCallbackSPDIF (AudioDeviceID, const AudioTimeStamp *,
static OSStatus HardwareListener (AudioObjectID, UInt32, const AudioObjectPropertyAddress *, void *);
static OSStatus StreamListener (AudioObjectID, UInt32, const AudioObjectPropertyAddress *, void *);
-static int RegisterAudioStreamsCallback(audio_output_t *, AudioDeviceID);
+static int ManageAudioStreamsCallback(audio_output_t *p_aout, AudioDeviceID i_dev_id, bool b_register);
static int AudioDeviceHasOutput (AudioDeviceID);
static int AudioDeviceSupportsDigital(audio_output_t *, AudioDeviceID);
static int AudioStreamSupportsDigital(audio_output_t *, AudioStreamID);
@@ -226,19 +226,20 @@ static void Close(vlc_object_t *obj)
if (err != noErr)
msg_Err(p_aout, "AudioHardwareRemovePropertyListener failed [%4.4s]", (char *)&err);
-
- /* remove audio device alive callback */
- AudioObjectPropertyAddress deviceAliveAddress = { kAudioDevicePropertyDeviceIsAlive, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
- err = AudioObjectRemovePropertyListener(p_sys->i_selected_dev, &deviceAliveAddress, HardwareListener, (void *)p_aout);
- if (err != noErr)
- msg_Err(p_aout, "failed to remove audio device life checker [%4.4s]", (char *)&err);
-
- /* remove audio streams callback */
- if (p_sys->i_stream_id > 0) {
- AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 };
- err = AudioObjectRemovePropertyListener(p_sys->i_stream_id, &physicalFormatsAddress, HardwareListener, (void *)p_aout);
- if (err != noErr)
- msg_Err(p_aout, "failed to remove audio device property streams callback [%4.4s]", (char *)&err);
+ /* remove streams callbacks */
+ CFIndex count = CFArrayGetCount(p_sys->device_list);
+ if (count > 0) {
+ for (CFIndex x = 0; x < count; x++) {
+ AudioDeviceID deviceId = 0;
+ CFNumberRef cfn_device_id = CFArrayGetValueAtIndex(p_sys->device_list, x);
+ if (!cfn_device_id)
+ continue;
+
+ CFNumberGetValue(cfn_device_id, kCFNumberSInt32Type, &deviceId);
+ if (!(deviceId & AOUT_VAR_SPDIF_FLAG)) {
+ ManageAudioStreamsCallback(p_aout, deviceId, false);
+ }
+ }
}
config_PutPsz(p_aout, "auhal-audio-device", aout_DeviceGet(p_aout));
@@ -1058,6 +1059,16 @@ static void Stop(audio_output_t *p_aout)
msg_Err(p_aout, "Failed to release hogmode [%4.4s]", (char *)&err);
}
+ /* remove audio device alive callback */
+ AudioObjectPropertyAddress deviceAliveAddress = { kAudioDevicePropertyDeviceIsAlive, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+ err = AudioObjectRemovePropertyListener(p_sys->i_selected_dev, &deviceAliveAddress, HardwareListener, (void *)p_aout);
+ if (err != noErr) {
+ /* Be tolerant, only give a warning here */
+ msg_Warn(p_aout, "failed to remove audio device life checker [%4.4s]", (char *)&err);
+ }
+
+
+
p_sys->i_bytes_per_sample = 0;
p_sys->b_digital = false;
@@ -1169,7 +1180,7 @@ static void RebuildDeviceList(audio_output_t * p_aout)
}
// TODO: only register once for each device
- RegisterAudioStreamsCallback(p_aout, deviceIDs[i]);
+ ManageAudioStreamsCallback(p_aout, deviceIDs[i], true);
CFRelease(device_name_ref);
free(psz_name);
@@ -1469,8 +1480,6 @@ static OSStatus HardwareListener(AudioObjectID inObjectID, UInt32 inNumberAddre
OSStatus err = noErr;
audio_output_t *p_aout = (audio_output_t *)inClientData;
VLC_UNUSED(inObjectID);
- VLC_UNUSED(inNumberAddresses);
- VLC_UNUSED(inAddresses);
if (!p_aout)
return -1;
@@ -1524,7 +1533,7 @@ static OSStatus StreamListener(AudioObjectID inObjectID, UInt32 inNumberAddress
#pragma mark -
#pragma mark helpers
-static int RegisterAudioStreamsCallback(audio_output_t *p_aout, AudioDeviceID i_dev_id)
+static int ManageAudioStreamsCallback(audio_output_t *p_aout, AudioDeviceID i_dev_id, bool b_register)
{
OSStatus err = noErr;
UInt32 i_param_size = 0;
@@ -1535,7 +1544,7 @@ static int RegisterAudioStreamsCallback(audio_output_t *p_aout, AudioDeviceID i_
AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
err = AudioObjectGetPropertyDataSize(i_dev_id, &streamsAddress, 0, NULL, &i_param_size);
if (err != noErr) {
- msg_Err(p_aout, "could not get number of streams [%4.4s] (%i)", (char *)&err, (int32_t)err);
+ msg_Err(p_aout, "could not get number of streams for device id %i [%4.4s]", i_dev_id, (char *)&err);
return VLC_EGENERIC;
}
@@ -1553,17 +1562,26 @@ static int RegisterAudioStreamsCallback(audio_output_t *p_aout, AudioDeviceID i_
for (int i = 0; i < i_streams; i++) {
/* get notified when physical formats change */
AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 };
- err = AudioObjectAddPropertyListener(p_streams[i], &physicalFormatsAddress, HardwareListener, (void *)p_aout);
- if (err != noErr) {
- // nope just means that we already have a callback
- if (err == kAudioHardwareIllegalOperationError) {
- msg_Dbg(p_aout, "could not set audio stream formats property callback on stream id %i, callback already set? [%4.4s]", p_streams[i],
- (char *)&err);
- } else {
- msg_Warn(p_aout, "could not set audio stream formats property callback on stream id %i [%4.4s]", p_streams[i],
- (char *)&err);
+
+ if (b_register) {
+ err = AudioObjectAddPropertyListener(p_streams[i], &physicalFormatsAddress, HardwareListener, (void *)p_aout);
+ if (err != noErr) {
+ // nope just means that we already have a callback
+ if (err == kAudioHardwareIllegalOperationError) {
+ msg_Warn(p_aout, "could not set audio stream formats property callback on stream id %i, callback already set? [%4.4s]", p_streams[i],
+ (char *)&err);
+ } else {
+ msg_Err(p_aout, "could not set audio stream formats property callback on stream id %i [%4.4s]", p_streams[i],
+ (char *)&err);
+ }
}
+
+ } else { /* unregister callback */
+ err = AudioObjectRemovePropertyListener(p_streams[i], &physicalFormatsAddress, HardwareListener, (void *)p_aout);
+ if (err != noErr)
+ msg_Err(p_aout, "failed to remove audio device property streams callback [%4.4s]", (char *)&err);
}
+
}
free(p_streams);
More information about the vlc-commits
mailing list