From 09a76193f5fa87bfacefd2ea15249338792aad1d Mon Sep 17 00:00:00 2001 From: henrika Date: Wed, 23 Aug 2017 15:04:40 +0200 Subject: [PATCH] Resolves threading issues when audio is interrupted on iOS. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this change we could crash in Debug when WebRTC audio was first interrupted and then resumed again. The reason was that the new audio stream stems from a new native I/O thread and that triggered thread checkers. With this change, failing thread checkers are detached when audio is interrupted to ensure that they don't fail when audio is restarted. NOTRY=TRUE Bug: webrtc:8126 Change-Id: Ib36ff6bc942477730aba60066f049ed0c43d3901 Reviewed-on: https://chromium-review.googlesource.com/628716 Commit-Queue: Henrik Andreasson Reviewed-by: Per Ã…hgren Cr-Commit-Position: refs/heads/master@{#19465} --- webrtc/modules/audio_device/audio_device_buffer.cc | 6 ++++++ webrtc/modules/audio_device/audio_device_buffer.h | 6 ++++++ webrtc/modules/audio_device/ios/audio_device_ios.mm | 9 +++++++++ 3 files changed, 21 insertions(+) diff --git a/webrtc/modules/audio_device/audio_device_buffer.cc b/webrtc/modules/audio_device/audio_device_buffer.cc index 8227d5b077..905c69681f 100644 --- a/webrtc/modules/audio_device/audio_device_buffer.cc +++ b/webrtc/modules/audio_device/audio_device_buffer.cc @@ -260,6 +260,12 @@ int32_t AudioDeviceBuffer::SetTypingStatus(bool typing_status) { return 0; } +void AudioDeviceBuffer::NativeAudioInterrupted() { + RTC_DCHECK(main_thread_checker_.CalledOnValidThread()); + playout_thread_checker_.DetachFromThread(); + recording_thread_checker_.DetachFromThread(); +} + uint32_t AudioDeviceBuffer::NewMicLevel() const { RTC_DCHECK_RUN_ON(&recording_thread_checker_); return new_mic_level_; diff --git a/webrtc/modules/audio_device/audio_device_buffer.h b/webrtc/modules/audio_device/audio_device_buffer.h index 04e1be8687..2a5a84b22f 100644 --- a/webrtc/modules/audio_device/audio_device_buffer.h +++ b/webrtc/modules/audio_device/audio_device_buffer.h @@ -118,6 +118,12 @@ class AudioDeviceBuffer { int32_t SetTypingStatus(bool typing_status); + // Called on iOS where the native audio layer can be interrupted by other + // audio applications. This method can then be used to reset internal + // states and detach thread checkers to allow for a new audio session where + // native callbacks may come from a new set of I/O threads. + void NativeAudioInterrupted(); + private: // Starts/stops periodic logging of audio stats. void StartPeriodicLogging(); diff --git a/webrtc/modules/audio_device/ios/audio_device_ios.mm b/webrtc/modules/audio_device/ios/audio_device_ios.mm index 1d59aff467..fb2f65d339 100644 --- a/webrtc/modules/audio_device/ios/audio_device_ios.mm +++ b/webrtc/modules/audio_device/ios/audio_device_ios.mm @@ -554,6 +554,15 @@ void AudioDeviceIOS::HandleInterruptionBegin() { RTCLog(@"Stopping the audio unit due to interruption begin."); 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_->NativeAudioInterrupted(); } } is_interrupted_ = true;