From 79445eadcc7a004333beac0148407d0607805ff6 Mon Sep 17 00:00:00 2001 From: henrika Date: Tue, 29 May 2018 16:04:16 +0200 Subject: [PATCH] Thread checker fails when switching to/from bluetooth headset. Made some minor changes to resolve the issue. Only affects Debug builds. NOTRY=TRUE Bug: webrtc:9310 Change-Id: Ieeeb57d24b559282b2eefd4d8785f7cfe4f44e40 Reviewed-on: https://webrtc-review.googlesource.com/79624 Commit-Queue: Henrik Andreassson Reviewed-by: Peter Hanspers Cr-Commit-Position: refs/heads/master@{#23434} --- modules/audio_device/ios/audio_device_ios.h | 3 +++ modules/audio_device/ios/audio_device_ios.mm | 26 ++++++++++++------- .../Native/src/audio/audio_device_ios.h | 3 +++ .../Native/src/audio/audio_device_ios.mm | 26 ++++++++++++------- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/modules/audio_device/ios/audio_device_ios.h b/modules/audio_device/ios/audio_device_ios.h index c51a9799da..b1d40537af 100644 --- a/modules/audio_device/ios/audio_device_ios.h +++ b/modules/audio_device/ios/audio_device_ios.h @@ -195,6 +195,9 @@ class AudioDeviceIOS : public AudioDeviceGeneric, // Closes and deletes the voice-processing I/O unit. void ShutdownPlayOrRecord(); + // Resets thread-checkers before a call is restarted. + void PrepareForNewStart(); + // Ensures that methods are called from the same thread as this object is // created on. rtc::ThreadChecker thread_checker_; diff --git a/modules/audio_device/ios/audio_device_ios.mm b/modules/audio_device/ios/audio_device_ios.mm index 36da53819f..f8aae2efe6 100644 --- a/modules/audio_device/ios/audio_device_ios.mm +++ b/modules/audio_device/ios/audio_device_ios.mm @@ -491,15 +491,7 @@ void AudioDeviceIOS::HandleInterruptionBegin() { if (!audio_unit_->Stop()) { RTCLogError(@"Failed to stop the audio unit for interruption begin."); } else { - // The audio unit has been stopped but will be restarted when the - // interruption ends in HandleInterruptionEnd(). It will result in audio - // callbacks from a new native I/O thread which means that we must detach - // thread checkers here to be prepared for an upcoming new audio stream. - io_thread_checker_.DetachFromThread(); - // The audio device buffer must also be informed about the interrupted - // state so it can detach its thread checkers as well. - audio_device_buffer_->NativeAudioPlayoutInterrupted(); - audio_device_buffer_->NativeAudioRecordingInterrupted(); + PrepareForNewStart(); } } is_interrupted_ = true; @@ -581,6 +573,7 @@ void AudioDeviceIOS::HandleSampleRateChange(float sample_rate) { if (audio_unit_->GetState() == VoiceProcessingAudioUnit::kStarted) { audio_unit_->Stop(); restart_audio_unit = true; + PrepareForNewStart(); } if (audio_unit_->GetState() == VoiceProcessingAudioUnit::kInitialized) { audio_unit_->Uninitialize(); @@ -901,4 +894,19 @@ void AudioDeviceIOS::ShutdownPlayOrRecord() { [session unlockForConfiguration]; } +void AudioDeviceIOS::PrepareForNewStart() { + LOGI() << "PrepareForNewStart"; + // The audio unit has been stopped and preparations are needed for an upcoming + // restart. It will result in audio callbacks from a new native I/O thread + // which means that we must detach thread checkers here to be prepared for an + // upcoming new audio stream. + io_thread_checker_.DetachFromThread(); + // The audio device buffer must also be informed about the interrupted + // state so it can detach its thread checkers as well. + if (audio_device_buffer_) { + audio_device_buffer_->NativeAudioPlayoutInterrupted(); + audio_device_buffer_->NativeAudioRecordingInterrupted(); + } +} + } // namespace webrtc diff --git a/sdk/objc/Framework/Native/src/audio/audio_device_ios.h b/sdk/objc/Framework/Native/src/audio/audio_device_ios.h index 250826de18..4001f49055 100644 --- a/sdk/objc/Framework/Native/src/audio/audio_device_ios.h +++ b/sdk/objc/Framework/Native/src/audio/audio_device_ios.h @@ -198,6 +198,9 @@ class AudioDeviceIOS : public AudioDeviceGeneric, // Closes and deletes the voice-processing I/O unit. void ShutdownPlayOrRecord(); + // Resets thread-checkers before a call is restarted. + void PrepareForNewStart(); + // Ensures that methods are called from the same thread as this object is // created on. rtc::ThreadChecker thread_checker_; diff --git a/sdk/objc/Framework/Native/src/audio/audio_device_ios.mm b/sdk/objc/Framework/Native/src/audio/audio_device_ios.mm index cf254869c0..3779c2552e 100644 --- a/sdk/objc/Framework/Native/src/audio/audio_device_ios.mm +++ b/sdk/objc/Framework/Native/src/audio/audio_device_ios.mm @@ -497,15 +497,7 @@ void AudioDeviceIOS::HandleInterruptionBegin() { if (!audio_unit_->Stop()) { RTCLogError(@"Failed to stop the audio unit for interruption begin."); } else { - // The audio unit has been stopped but will be restarted when the - // interruption ends in HandleInterruptionEnd(). It will result in audio - // callbacks from a new native I/O thread which means that we must detach - // thread checkers here to be prepared for an upcoming new audio stream. - io_thread_checker_.DetachFromThread(); - // The audio device buffer must also be informed about the interrupted - // state so it can detach its thread checkers as well. - audio_device_buffer_->NativeAudioPlayoutInterrupted(); - audio_device_buffer_->NativeAudioRecordingInterrupted(); + PrepareForNewStart(); } } is_interrupted_ = true; @@ -587,6 +579,7 @@ void AudioDeviceIOS::HandleSampleRateChange(float sample_rate) { if (audio_unit_->GetState() == VoiceProcessingAudioUnit::kStarted) { audio_unit_->Stop(); restart_audio_unit = true; + PrepareForNewStart(); } if (audio_unit_->GetState() == VoiceProcessingAudioUnit::kInitialized) { audio_unit_->Uninitialize(); @@ -907,6 +900,21 @@ void AudioDeviceIOS::ShutdownPlayOrRecord() { [session unlockForConfiguration]; } +void AudioDeviceIOS::PrepareForNewStart() { + LOGI() << "PrepareForNewStart"; + // The audio unit has been stopped and preparations are needed for an upcoming + // restart. It will result in audio callbacks from a new native I/O thread + // which means that we must detach thread checkers here to be prepared for an + // upcoming new audio stream. + io_thread_checker_.DetachFromThread(); + // The audio device buffer must also be informed about the interrupted + // state so it can detach its thread checkers as well. + if (audio_device_buffer_) { + audio_device_buffer_->NativeAudioPlayoutInterrupted(); + audio_device_buffer_->NativeAudioRecordingInterrupted(); + } +} + bool AudioDeviceIOS::IsInterrupted() { return is_interrupted_; }