From c116a7b4369c264fc33ba2c0d48350d16537e0ae Mon Sep 17 00:00:00 2001 From: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com> Date: Thu, 22 Oct 2020 11:05:19 -0400 Subject: [PATCH] coreaudio: use queue to start/stop audio This patch add a queue to start/stop audio so it would not block execution thread. Change-Id: I4ca454a98395e71f00de38c511d18886d8ffbf1a --- src/media/audio/coreaudio/Makefile.am | 3 +- src/media/audio/coreaudio/ios/corelayer.h | 2 +- src/media/audio/coreaudio/ios/corelayer.mm | 72 ++++++++++--------- src/media/audio/coreaudio/osx/corelayer.h | 3 - .../osx/{corelayer.cpp => corelayer.mm} | 49 +++++++------ 5 files changed, 67 insertions(+), 62 deletions(-) rename src/media/audio/coreaudio/osx/{corelayer.cpp => corelayer.mm} (95%) diff --git a/src/media/audio/coreaudio/Makefile.am b/src/media/audio/coreaudio/Makefile.am index 10d07d47ea..655f144bb8 100644 --- a/src/media/audio/coreaudio/Makefile.am +++ b/src/media/audio/coreaudio/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/globals.mk if HAVE_OSX noinst_LTLIBRARIES = libcoreaudiolayer.la -libcoreaudiolayer_la_SOURCES = osx/corelayer.cpp osx/corelayer.h osx/audiodevice.cpp osx/audiodevice.h +libcoreaudiolayer_la_SOURCES = osx/corelayer.mm osx/corelayer.h osx/audiodevice.cpp osx/audiodevice.h endif if HAVE_IOS @@ -11,3 +11,4 @@ libcoreaudiolayer_la_SOURCES = ios/corelayer.mm ios/corelayer.h endif libcoreaudiolayer_la_CXXFLAGS = -I$(top_srcdir)/src +AM_OBJCXXFLAGS = -std=c++17 diff --git a/src/media/audio/coreaudio/ios/corelayer.h b/src/media/audio/coreaudio/ios/corelayer.h index 1155f94261..b1dbfb87ca 100644 --- a/src/media/audio/coreaudio/ios/corelayer.h +++ b/src/media/audio/coreaudio/ios/corelayer.h @@ -23,7 +23,6 @@ #define CORE_LAYER_H_ #include "audio/audiolayer.h" -#include "noncopyable.h" #include <AudioToolbox/AudioToolbox.h> #define checkErr(err) \ @@ -162,6 +161,7 @@ private: UInt32 outChannelsPerFrame_; std::condition_variable readyCv_ {}; + dispatch_queue_t audioConfigurationQueue; }; } // namespace jami diff --git a/src/media/audio/coreaudio/ios/corelayer.mm b/src/media/audio/coreaudio/ios/corelayer.mm index 54640bc66d..5552e783ce 100644 --- a/src/media/audio/coreaudio/ios/corelayer.mm +++ b/src/media/audio/coreaudio/ios/corelayer.mm @@ -21,20 +21,20 @@ #include "corelayer.h" #include "manager.h" -#include "noncopyable.h" -#include "audio/ringbufferpool.h" -#include "audio/ringbuffer.h" -#include "libav_utils.h" - #include <AVFoundation/AVAudioSession.h> -#include <cmath> -#include <vector> - #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" namespace jami { +dispatch_queue_t audioConfigurationQueueIOS() { + static dispatch_once_t queueCreationGuard; + static dispatch_queue_t queue; + dispatch_once(&queueCreationGuard, ^{ + queue = dispatch_queue_create("audioConfigurationQueueIOS", DISPATCH_QUEUE_SERIAL); + }); + return queue; +} // AudioLayer implementation. CoreLayer::CoreLayer(const AudioPreference &pref) @@ -43,11 +43,19 @@ CoreLayer::CoreLayer(const AudioPreference &pref) , indexOut_(pref.getAlsaCardout()) , indexRing_(pref.getAlsaCardring()) , playbackBuff_(0, audioFormat_) -{} +{ + audioConfigurationQueue = dispatch_queue_create("com.savoirfairelinux.audioConfigurationQueueIOS", DISPATCH_QUEUE_SERIAL); +} CoreLayer::~CoreLayer() { - stopStream(); + dispatch_sync(audioConfigurationQueueIOS(), ^{ + if (status_ != Status::Started) + return; + destroyAudioLayer(); + flushUrgent(); + flushMain(); + }); } std::vector<std::string> @@ -317,29 +325,25 @@ CoreLayer::bindCallbacks() { void CoreLayer::startStream(AudioDeviceType stream) { - std::lock_guard<std::mutex> lock(mutex_); - JAMI_DBG("iOS CoreLayer - Start Stream"); - auto currentCategoty = [[AVAudioSession sharedInstance] category]; + dispatch_async(audioConfigurationQueueIOS(), ^{ + JAMI_DBG("iOS CoreLayer - Start Stream"); + auto currentCategoty = [[AVAudioSession sharedInstance] category]; + + bool updateStream = currentCategoty == AVAudioSessionCategoryPlayback && (stream == AudioDeviceType::CAPTURE || stream == AudioDeviceType::ALL); + if (status_ == Status::Started) { + if (updateStream) + destroyAudioLayer(); + else + return; + } + status_ = Status::Started; - bool updateStream = currentCategoty == AVAudioSessionCategoryPlayback && (stream == AudioDeviceType::CAPTURE || stream == AudioDeviceType::ALL); - if (status_ == Status::Started) { - if (updateStream) + dcblocker_.reset(); + if (!initAudioLayerIO(stream) || AudioUnitInitialize(ioUnit_) || AudioOutputUnitStart(ioUnit_)) { destroyAudioLayer(); - else - return; - } - status_ = Status::Started; - - dcblocker_.reset(); - if (initAudioLayerIO(stream)) { - auto inputRes = AudioUnitInitialize(ioUnit_); - auto outputRes = AudioOutputUnitStart(ioUnit_); - if (!inputRes && !outputRes) { - return; + status_ = Status::Idle; } - } - destroyAudioLayer(); - status_ = Status::Idle; + }); } void @@ -354,15 +358,13 @@ CoreLayer::destroyAudioLayer() void CoreLayer::stopStream(AudioDeviceType stream) { - JAMI_DBG("iOS CoreLayer - Stop Stream"); - { - std::lock_guard<std::mutex> lock(mutex_); + dispatch_async(audioConfigurationQueueIOS(), ^{ + JAMI_DBG("iOS CoreLayer - Stop Stream"); if (status_ != Status::Started) return; status_ = Status::Idle; destroyAudioLayer(); - } - + }); /* Flush the ring buffers */ flushUrgent(); flushMain(); diff --git a/src/media/audio/coreaudio/osx/corelayer.h b/src/media/audio/coreaudio/osx/corelayer.h index 8409a49f1d..1428447524 100644 --- a/src/media/audio/coreaudio/osx/corelayer.h +++ b/src/media/audio/coreaudio/osx/corelayer.h @@ -22,10 +22,7 @@ #define CORE_LAYER_H_ #include "audio/audiolayer.h" -#include "noncopyable.h" -#include <CoreFoundation/CoreFoundation.h> #include <AudioToolbox/AudioToolbox.h> -#include <CoreAudio/AudioHardware.h> #define checkErr(err) \ if (err) { \ diff --git a/src/media/audio/coreaudio/osx/corelayer.cpp b/src/media/audio/coreaudio/osx/corelayer.mm similarity index 95% rename from src/media/audio/coreaudio/osx/corelayer.cpp rename to src/media/audio/coreaudio/osx/corelayer.mm index 823f516ec0..d6eb58a884 100644 --- a/src/media/audio/coreaudio/osx/corelayer.cpp +++ b/src/media/audio/coreaudio/osx/corelayer.mm @@ -20,17 +20,19 @@ #include "corelayer.h" #include "manager.h" -#include "noncopyable.h" -#include "audio/resampler.h" -#include "audio/ringbufferpool.h" -#include "audio/ringbuffer.h" #include "audiodevice.h" -#include <cmath> -#include <vector> - namespace jami { +dispatch_queue_t audioConfigurationQueueMacOS() { + static dispatch_once_t queueCreationGuard; + static dispatch_queue_t queue; + dispatch_once(&queueCreationGuard, ^{ + queue = dispatch_queue_create("audioConfigurationQueueMacOS", DISPATCH_QUEUE_SERIAL); + }); + return queue; +} + // AudioLayer implementation. CoreLayer::CoreLayer(const AudioPreference& pref) : AudioLayer(pref) @@ -42,7 +44,13 @@ CoreLayer::CoreLayer(const AudioPreference& pref) CoreLayer::~CoreLayer() { - stopStream(); + dispatch_sync(audioConfigurationQueueMacOS(), ^{ + if (status_ != Status::Started) + return; + destroyAudioLayer(); + flushUrgent(); + flushMain(); + }); } std::vector<std::string> @@ -294,10 +302,9 @@ CoreLayer::initAudioLayerIO(AudioDeviceType stream) void CoreLayer::startStream(AudioDeviceType stream) { - JAMI_DBG("START STREAM"); + dispatch_async(audioConfigurationQueueMacOS(), ^{ + JAMI_DBG("START STREAM"); - { - std::lock_guard<std::mutex> lock(mutex_); if (status_ != Status::Idle) return; status_ = Status::Started; @@ -306,13 +313,13 @@ CoreLayer::startStream(AudioDeviceType stream) initAudioLayerIO(stream); - auto inputRes = AudioUnitInitialize(ioUnit_); - auto outputRes = AudioOutputUnitStart(ioUnit_); - if (!inputRes && !outputRes) { - return; + auto inputError = AudioUnitInitialize(ioUnit_); + auto outputError = AudioOutputUnitStart(ioUnit_); + if (inputError || outputError) { + status_ = Status::Idle; + destroyAudioLayer(); } - } - stopStream(); + }); } void @@ -326,15 +333,13 @@ CoreLayer::destroyAudioLayer() void CoreLayer::stopStream(AudioDeviceType stream) { - JAMI_DBG("STOP STREAM"); - { - std::lock_guard<std::mutex> lock(mutex_); + dispatch_async(audioConfigurationQueueMacOS(), ^{ + JAMI_DBG("STOP STREAM"); if (status_ != Status::Started) return; status_ = Status::Idle; destroyAudioLayer(); - } - + }); /* Flush the ring buffers */ flushUrgent(); flushMain(); -- GitLab