summaryrefslogtreecommitdiff
path: root/media/libcubeb/uplift-system-listener-patch.patch
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2021-08-22 17:39:55 +0000
committerMoonchild <moonchild@palemoon.org>2021-08-22 17:39:55 +0000
commitee498381734bdf31ea38b2f5ea4cac3130ae58e3 (patch)
tree97ff8ce2e72b017abb9f529283812c56ae10b9c5 /media/libcubeb/uplift-system-listener-patch.patch
parenta725c0fe3d75512ee64f7fff5f8d5c216c13ecea (diff)
downloaduxp-ee498381734bdf31ea38b2f5ea4cac3130ae58e3.tar.gz
Revert "Issue #1806 - Update libcubeb"
This reverts commit 741fd8b61ccc5b3a01ccf8ff154ccb8ce80ecc38.
Diffstat (limited to 'media/libcubeb/uplift-system-listener-patch.patch')
-rw-r--r--media/libcubeb/uplift-system-listener-patch.patch402
1 files changed, 402 insertions, 0 deletions
diff --git a/media/libcubeb/uplift-system-listener-patch.patch b/media/libcubeb/uplift-system-listener-patch.patch
new file mode 100644
index 0000000000..5064d7fb35
--- /dev/null
+++ b/media/libcubeb/uplift-system-listener-patch.patch
@@ -0,0 +1,402 @@
+diff --git a/media/libcubeb/src/cubeb_audiounit.cpp b/media/libcubeb/src/cubeb_audiounit.cpp
+--- a/media/libcubeb/src/cubeb_audiounit.cpp
++++ b/media/libcubeb/src/cubeb_audiounit.cpp
+@@ -594,20 +594,20 @@ audiounit_get_input_device_id(AudioDevic
+
+ return CUBEB_OK;
+ }
+
+ static int audiounit_stream_get_volume(cubeb_stream * stm, float * volume);
+ static int audiounit_stream_set_volume(cubeb_stream * stm, float volume);
+
+ static int
+-audiounit_reinit_stream(cubeb_stream * stm, bool is_started)
++audiounit_reinit_stream(cubeb_stream * stm)
+ {
+ auto_lock context_lock(stm->context->mutex);
+- if (is_started) {
++ if (!stm->shutdown) {
+ audiounit_stream_stop_internal(stm);
+ }
+
+ {
+ auto_lock lock(stm->mutex);
+ float volume = 0.0;
+ int vol_rv = audiounit_stream_get_volume(stm, &volume);
+
+@@ -622,32 +622,30 @@ audiounit_reinit_stream(cubeb_stream * s
+ audiounit_stream_set_volume(stm, volume);
+ }
+
+ // Reset input frames to force new stream pre-buffer
+ // silence if needed, check `is_extra_input_needed()`
+ stm->frames_read = 0;
+
+ // If the stream was running, start it again.
+- if (is_started) {
++ if (!stm->shutdown) {
+ audiounit_stream_start_internal(stm);
+ }
+ }
+ return CUBEB_OK;
+ }
+
+ static OSStatus
+ audiounit_property_listener_callback(AudioObjectID /* id */, UInt32 address_count,
+ const AudioObjectPropertyAddress * addresses,
+ void * user)
+ {
+ cubeb_stream * stm = (cubeb_stream*) user;
+ stm->switching_device = true;
+- // Note if the stream was running or not
+- bool was_running = !stm->shutdown;
+
+ LOG("(%p) Audio device changed, %d events.", stm, address_count);
+ for (UInt32 i = 0; i < address_count; i++) {
+ switch(addresses[i].mSelector) {
+ case kAudioHardwarePropertyDefaultOutputDevice: {
+ LOG("Event[%d] - mSelector == kAudioHardwarePropertyDefaultOutputDevice", i);
+ // Allow restart to choose the new default
+ stm->output_device = nullptr;
+@@ -666,19 +664,20 @@ audiounit_property_listener_callback(Aud
+ if (stm->is_default_input) {
+ LOG("It's the default input device, ignore the event");
+ return noErr;
+ }
+ // Allow restart to choose the new default. Event register only for input.
+ stm->input_device = nullptr;
+ }
+ break;
+- case kAudioDevicePropertyDataSource:
+- LOG("Event[%d] - mSelector == kAudioHardwarePropertyDataSource", i);
+- break;
++ case kAudioDevicePropertyDataSource: {
++ LOG("Event[%d] - mSelector == kAudioHardwarePropertyDataSource", i);
++ return noErr;
++ }
+ }
+ }
+
+ for (UInt32 i = 0; i < address_count; i++) {
+ switch(addresses[i].mSelector) {
+ case kAudioHardwarePropertyDefaultOutputDevice:
+ case kAudioHardwarePropertyDefaultInputDevice:
+ case kAudioDevicePropertyDeviceIsAlive:
+@@ -691,17 +690,17 @@ audiounit_property_listener_callback(Aud
+ break;
+ }
+ }
+ }
+
+ // Use a new thread, through the queue, to avoid deadlock when calling
+ // Get/SetProperties method from inside notify callback
+ dispatch_async(stm->context->serial_queue, ^() {
+- if (audiounit_reinit_stream(stm, was_running) != CUBEB_OK) {
++ if (audiounit_reinit_stream(stm) != CUBEB_OK) {
+ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
+ LOG("(%p) Could not reopen the stream after switching.", stm);
+ }
+ stm->switching_device = false;
+ });
+
+ return noErr;
+ }
+@@ -752,27 +751,16 @@ audiounit_install_device_changed_callbac
+ }
+
+ r = audiounit_add_listener(stm, output_dev_id, kAudioDevicePropertyDataSource,
+ kAudioDevicePropertyScopeOutput, &audiounit_property_listener_callback);
+ if (r != noErr) {
+ PRINT_ERROR_CODE("AudioObjectAddPropertyListener/output/kAudioDevicePropertyDataSource", r);
+ return CUBEB_ERROR;
+ }
+-
+- /* This event will notify us when the default audio device changes,
+- * for example when the user plugs in a USB headset and the system chooses it
+- * automatically as the default, or when another device is chosen in the
+- * dropdown list. */
+- r = audiounit_add_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultOutputDevice,
+- kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+- if (r != noErr) {
+- PRINT_ERROR_CODE("AudioObjectAddPropertyListener/output/kAudioHardwarePropertyDefaultOutputDevice", r);
+- return CUBEB_ERROR;
+- }
+ }
+
+ if (stm->input_unit) {
+ /* This event will notify us when the data source on the input device changes. */
+ AudioDeviceID input_dev_id;
+ r = audiounit_get_input_device_id(&input_dev_id);
+ if (r != noErr) {
+ return CUBEB_ERROR;
+@@ -780,78 +768,112 @@ audiounit_install_device_changed_callbac
+
+ r = audiounit_add_listener(stm, input_dev_id, kAudioDevicePropertyDataSource,
+ kAudioDevicePropertyScopeInput, &audiounit_property_listener_callback);
+ if (r != noErr) {
+ PRINT_ERROR_CODE("AudioObjectAddPropertyListener/input/kAudioDevicePropertyDataSource", r);
+ return CUBEB_ERROR;
+ }
+
+- /* This event will notify us when the default input device changes. */
+- r = audiounit_add_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultInputDevice,
+- kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+- if (r != noErr) {
+- PRINT_ERROR_CODE("AudioObjectAddPropertyListener/input/kAudioHardwarePropertyDefaultInputDevice", r);
+- return CUBEB_ERROR;
+- }
+-
+ /* Event to notify when the input is going away. */
+ AudioDeviceID dev = stm->input_device ? reinterpret_cast<intptr_t>(stm->input_device) :
+ audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT);
+ r = audiounit_add_listener(stm, dev, kAudioDevicePropertyDeviceIsAlive,
+ kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+ if (r != noErr) {
+ PRINT_ERROR_CODE("AudioObjectAddPropertyListener/input/kAudioDevicePropertyDeviceIsAlive", r);
+ return CUBEB_ERROR;
+ }
+ }
+
+ return CUBEB_OK;
+ }
+
+ static int
++audiounit_install_system_changed_callback(cubeb_stream * stm)
++{
++ OSStatus r;
++
++ if (stm->output_unit) {
++ /* This event will notify us when the default audio device changes,
++ * for example when the user plugs in a USB headset and the system chooses it
++ * automatically as the default, or when another device is chosen in the
++ * dropdown list. */
++ r = audiounit_add_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultOutputDevice,
++ kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
++ if (r != noErr) {
++ LOG("AudioObjectAddPropertyListener/output/kAudioHardwarePropertyDefaultOutputDevice rv=%d", r);
++ return CUBEB_ERROR;
++ }
++ }
++
++ if (stm->input_unit) {
++ /* This event will notify us when the default input device changes. */
++ r = audiounit_add_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultInputDevice,
++ kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
++ if (r != noErr) {
++ LOG("AudioObjectAddPropertyListener/input/kAudioHardwarePropertyDefaultInputDevice rv=%d", r);
++ return CUBEB_ERROR;
++ }
++ }
++
++ return CUBEB_OK;
++}
++
++static int
+ audiounit_uninstall_device_changed_callback(cubeb_stream * stm)
+ {
+ OSStatus r;
+
+ if (stm->output_unit) {
+ AudioDeviceID output_dev_id;
+ r = audiounit_get_output_device_id(&output_dev_id);
+ if (r != noErr) {
+ return CUBEB_ERROR;
+ }
+
+ r = audiounit_remove_listener(stm, output_dev_id, kAudioDevicePropertyDataSource,
+ kAudioDevicePropertyScopeOutput, &audiounit_property_listener_callback);
+ if (r != noErr) {
+ return CUBEB_ERROR;
+ }
+-
+- r = audiounit_remove_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultOutputDevice,
+- kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+- if (r != noErr) {
+- return CUBEB_ERROR;
+- }
+ }
+
+ if (stm->input_unit) {
+ AudioDeviceID input_dev_id;
+ r = audiounit_get_input_device_id(&input_dev_id);
+ if (r != noErr) {
+ return CUBEB_ERROR;
+ }
+
+ r = audiounit_remove_listener(stm, input_dev_id, kAudioDevicePropertyDataSource,
+ kAudioDevicePropertyScopeInput, &audiounit_property_listener_callback);
+ if (r != noErr) {
+ return CUBEB_ERROR;
+ }
+-
++ }
++ return CUBEB_OK;
++}
++
++static int
++audiounit_uninstall_system_changed_callback(cubeb_stream * stm)
++{
++ OSStatus r;
++
++ if (stm->output_unit) {
++ r = audiounit_remove_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultOutputDevice,
++ kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
++ if (r != noErr) {
++ return CUBEB_ERROR;
++ }
++ }
++
++ if (stm->input_unit) {
+ r = audiounit_remove_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultInputDevice,
+- kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
++ kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+ if (r != noErr) {
+ return CUBEB_ERROR;
+ }
+ }
+ return CUBEB_OK;
+ }
+
+ /* Get the acceptable buffer size (in frames) that this device can work with. */
+@@ -1764,16 +1786,22 @@ audiounit_setup_stream(cubeb_stream * st
+
+ if (stm->input_unit && stm->output_unit) {
+ // According to the I/O hardware rate it is expected a specific pattern of callbacks
+ // for example is input is 44100 and output is 48000 we expected no more than 2
+ // out callback in a row.
+ stm->expected_output_callbacks_in_a_row = ceilf(stm->output_hw_rate / stm->input_hw_rate);
+ }
+
++ r = audiounit_install_device_changed_callback(stm);
++ if (r != CUBEB_OK) {
++ LOG("(%p) Could not install the device change callback.", stm);
++ return r;
++ }
++
+ return CUBEB_OK;
+ }
+
+ static int
+ audiounit_stream_init(cubeb * context,
+ cubeb_stream ** stream,
+ char const * /* stream_name */,
+ cubeb_devid input_device,
+@@ -1838,31 +1866,37 @@ audiounit_stream_init(cubeb * context,
+ }
+
+ if (r != CUBEB_OK) {
+ LOG("(%p) Could not setup the audiounit stream.", stm);
+ audiounit_stream_destroy(stm);
+ return r;
+ }
+
+- r = audiounit_install_device_changed_callback(stm);
++ r = audiounit_install_system_changed_callback(stm);
+ if (r != CUBEB_OK) {
+ LOG("(%p) Could not install the device change callback.", stm);
+ return r;
+ }
+
+ *stream = stm;
+ LOG("Cubeb stream (%p) init successful.", stm);
+ return CUBEB_OK;
+ }
+
+ static void
+ audiounit_close_stream(cubeb_stream *stm)
+ {
+ stm->mutex.assert_current_thread_owns();
++
++ int r = audiounit_uninstall_device_changed_callback(stm);
++ if (r != CUBEB_OK) {
++ LOG("(%p) Could not uninstall the device changed callback", stm);
++ }
++
+ if (stm->input_unit) {
+ AudioUnitUninitialize(stm->input_unit);
+ AudioComponentInstanceDispose(stm->input_unit);
+ }
+
+ audiounit_destroy_input_linear_buffer(stm);
+
+ if (stm->output_unit) {
+@@ -1873,31 +1907,29 @@ audiounit_close_stream(cubeb_stream *stm
+ cubeb_resampler_destroy(stm->resampler);
+ }
+
+ static void
+ audiounit_stream_destroy(cubeb_stream * stm)
+ {
+ stm->shutdown = true;
+
++ int r = audiounit_uninstall_system_changed_callback(stm);
++ if (r != CUBEB_OK) {
++ LOG("(%p) Could not uninstall the device changed callback", stm);
++ }
++
+ auto_lock context_lock(stm->context->mutex);
+ audiounit_stream_stop_internal(stm);
+
+ {
+ auto_lock lock(stm->mutex);
+ audiounit_close_stream(stm);
+ }
+
+-#if !TARGET_OS_IPHONE
+- int r = audiounit_uninstall_device_changed_callback(stm);
+- if (r != CUBEB_OK) {
+- LOG("(%p) Could not uninstall the device changed callback", stm);
+- }
+-#endif
+-
+ assert(stm->context->active_streams >= 1);
+ stm->context->active_streams -= 1;
+
+ LOG("Cubeb stream (%p) destroyed successful.", stm);
+
+ stm->~cubeb_stream();
+ free(stm);
+ }
+@@ -1914,20 +1946,20 @@ audiounit_stream_start_internal(cubeb_st
+ r = AudioOutputUnitStart(stm->output_unit);
+ assert(r == 0);
+ }
+ }
+
+ static int
+ audiounit_stream_start(cubeb_stream * stm)
+ {
++ auto_lock context_lock(stm->context->mutex);
+ stm->shutdown = false;
+ stm->draining = false;
+
+- auto_lock context_lock(stm->context->mutex);
+ audiounit_stream_start_internal(stm);
+
+ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STARTED);
+
+ LOG("Cubeb stream (%p) started successfully.", stm);
+ return CUBEB_OK;
+ }
+
+@@ -1943,19 +1975,19 @@ audiounit_stream_stop_internal(cubeb_str
+ r = AudioOutputUnitStop(stm->output_unit);
+ assert(r == 0);
+ }
+ }
+
+ static int
+ audiounit_stream_stop(cubeb_stream * stm)
+ {
++ auto_lock context_lock(stm->context->mutex);
+ stm->shutdown = true;
+
+- auto_lock context_lock(stm->context->mutex);
+ audiounit_stream_stop_internal(stm);
+
+ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
+
+ LOG("Cubeb stream (%p) stopped successfully.", stm);
+ return CUBEB_OK;
+ }
+