From 838fa07376e3b6c34c2a75535d9f29b9eb1b0db5 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Wed, 26 Jun 2013 08:16:34 +0200 Subject: ao_coreaudio: move AudioStreamChangeFormat to common file and refactor --- audio/out/ao_coreaudio.c | 86 ----------------------------------------- audio/out/ao_coreaudio_common.c | 74 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 86 deletions(-) (limited to 'audio') diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index a633849aca..4d11f40d51 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -38,7 +38,6 @@ #include "ao.h" #include "audio/format.h" -#include "osdep/timer.h" #include "core/subopt-helper.h" #include "core/mp_ring.h" @@ -583,91 +582,6 @@ coreaudio_error: return CONTROL_FALSE; } -/***************************************************************************** -* AudioStreamChangeFormat: Change i_stream_id to change_format -*****************************************************************************/ -static int AudioStreamChangeFormat(AudioStreamID i_stream_id, - AudioStreamBasicDescription change_format) -{ - OSStatus err = noErr; - int i; - AudioObjectPropertyAddress p_addr; - - static volatile int stream_format_changed; - stream_format_changed = 0; - - ca_print_asbd("setting stream format:", &change_format); - - /* Install the callback. */ - p_addr.mSelector = kAudioStreamPropertyPhysicalFormat; - p_addr.mScope = kAudioObjectPropertyScopeGlobal; - p_addr.mElement = kAudioObjectPropertyElementMaster; - - err = AudioObjectAddPropertyListener(i_stream_id, - &p_addr, - ca_stream_listener, - (void *)&stream_format_changed); - if (err != noErr) { - ca_msg(MSGL_WARN, - "AudioStreamAddPropertyListener failed: [%4.4s]\n", - (char *)&err); - return CONTROL_FALSE; - } - - /* Change the format. */ - err = SetAudioProperty(i_stream_id, - kAudioStreamPropertyPhysicalFormat, - sizeof(AudioStreamBasicDescription), &change_format); - if (err != noErr) { - ca_msg(MSGL_WARN, "could not set the stream format: [%4.4s]\n", - (char *)&err); - return CONTROL_FALSE; - } - - /* The AudioStreamSetProperty is not only asynchronious, - * it is also not Atomic, in its behaviour. - * Therefore we check 5 times before we really give up. - * FIXME: failing isn't actually implemented yet. */ - for (i = 0; i < 5; ++i) { - AudioStreamBasicDescription actual_format; - int j; - for (j = 0; !stream_format_changed && j < 50; ++j) - mp_sleep_us(10000); - if (stream_format_changed) - stream_format_changed = 0; - else - ca_msg(MSGL_V, "reached timeout\n"); - - err = GetAudioProperty(i_stream_id, - kAudioStreamPropertyPhysicalFormat, - sizeof(AudioStreamBasicDescription), - &actual_format); - - ca_print_asbd("actual format in use:", &actual_format); - if (actual_format.mSampleRate == change_format.mSampleRate && - actual_format.mFormatID == change_format.mFormatID && - actual_format.mFramesPerPacket == change_format.mFramesPerPacket) { - /* The right format is now active. */ - break; - } - /* We need to check again. */ - } - - /* Removing the property listener. */ - err = AudioObjectRemovePropertyListener(i_stream_id, - &p_addr, - ca_stream_listener, - (void *)&stream_format_changed); - if (err != noErr) { - ca_msg(MSGL_WARN, - "AudioStreamRemovePropertyListener failed: [%4.4s]\n", - (char *)&err); - return CONTROL_FALSE; - } - - return CONTROL_TRUE; -} - static int play(struct ao *ao, void *output_samples, int num_bytes, int flags) { struct priv *p = ao->priv; diff --git a/audio/out/ao_coreaudio_common.c b/audio/out/ao_coreaudio_common.c index 289fa93b64..c6c56c0323 100644 --- a/audio/out/ao_coreaudio_common.c +++ b/audio/out/ao_coreaudio_common.c @@ -26,6 +26,7 @@ #include #include #include +#include "osdep/timer.h" #include "core/mp_msg.h" #define ca_msg(a, b ...) mp_msg(MSGT_AO, a, "AO: [coreaudio] " b) @@ -329,3 +330,76 @@ static OSStatus ca_unlock_device(AudioDeviceID device, pid_t *pid) { } return noErr; } + +static int AudioStreamChangeFormat(AudioStreamID i_stream_id, + AudioStreamBasicDescription change_format) +{ + OSStatus err = noErr; + AudioObjectPropertyAddress p_addr; + volatile int stream_format_changed = 0; + + ca_print_asbd("setting stream format:", &change_format); + + /* Install the callback. */ + p_addr = (AudioObjectPropertyAddress) { + .mSelector = kAudioStreamPropertyPhysicalFormat, + .mScope = kAudioObjectPropertyScopeGlobal, + .mElement = kAudioObjectPropertyElementMaster, + }; + + err = AudioObjectAddPropertyListener(i_stream_id, + &p_addr, + ca_stream_listener, + (void *)&stream_format_changed); + if (!CHECK_CA_WARN("can't add property listener during format change")) { + return CONTROL_FALSE; + } + + /* Change the format. */ + err = SetAudioProperty(i_stream_id, + kAudioStreamPropertyPhysicalFormat, + sizeof(AudioStreamBasicDescription), &change_format); + if (!CHECK_CA_WARN("error changing physical format")) { + return CONTROL_FALSE; + } + + /* The AudioStreamSetProperty is not only asynchronious, + * it is also not Atomic, in its behaviour. + * Therefore we check 5 times before we really give up. */ + bool format_set = CONTROL_FALSE; + for (int i = 0; !format_set && i < 5; ++i) { + for (int j = 0; !stream_format_changed && j < 50; ++j) + mp_sleep_us(10000); + + if (stream_format_changed) { + stream_format_changed = 0; + } else { + ca_msg(MSGL_V, "reached timeout\n"); + } + + AudioStreamBasicDescription actual_format; + err = GetAudioProperty(i_stream_id, + kAudioStreamPropertyPhysicalFormat, + sizeof(AudioStreamBasicDescription), + &actual_format); + + ca_print_asbd("actual format in use:", &actual_format); + if (actual_format.mSampleRate == change_format.mSampleRate && + actual_format.mFormatID == change_format.mFormatID && + actual_format.mFramesPerPacket == change_format.mFramesPerPacket) { + format_set = CONTROL_TRUE; + } + } + + err = AudioObjectRemovePropertyListener(i_stream_id, + &p_addr, + ca_stream_listener, + (void *)&stream_format_changed); + + if (!CHECK_CA_WARN("can't remove property listener")) { + return CONTROL_FALSE; + } + + return format_set; +} + -- cgit v1.2.3