Update ios AudioDevice away from rtc::MessageHandler
Align thread checkers with the class comment, i.e. ensure AudioDevice is used and destroyed on the same thread it was constructed on, not just the same thread AudioDevice::Init was called. Bug: webrtc:9702 Change-Id: Ib905978cc8173266151adf26e1b7317f1d3852bc Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/274164 Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Auto-Submit: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Kári Helgason <kthelgason@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38018}
This commit is contained in:
committed by
WebRTC LUCI CQ
parent
7faf7171b0
commit
4a29edca7d
@ -270,9 +270,11 @@ if (is_ios || is_mac) {
|
|||||||
":audio_session_observer",
|
":audio_session_observer",
|
||||||
":base_objc",
|
":base_objc",
|
||||||
"../api:array_view",
|
"../api:array_view",
|
||||||
|
"../api:scoped_refptr",
|
||||||
"../api:sequence_checker",
|
"../api:sequence_checker",
|
||||||
"../api/task_queue",
|
"../api/task_queue",
|
||||||
"../api/task_queue:default_task_queue_factory",
|
"../api/task_queue:default_task_queue_factory",
|
||||||
|
"../api/task_queue:pending_task_safety_flag",
|
||||||
"../modules/audio_device:audio_device_api",
|
"../modules/audio_device:audio_device_api",
|
||||||
"../modules/audio_device:audio_device_buffer",
|
"../modules/audio_device:audio_device_buffer",
|
||||||
"../modules/audio_device:audio_device_generic",
|
"../modules/audio_device:audio_device_generic",
|
||||||
|
|||||||
@ -14,7 +14,9 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "api/scoped_refptr.h"
|
||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
|
#include "api/task_queue/pending_task_safety_flag.h"
|
||||||
#include "audio_session_observer.h"
|
#include "audio_session_observer.h"
|
||||||
#include "modules/audio_device/audio_device_generic.h"
|
#include "modules/audio_device/audio_device_generic.h"
|
||||||
#include "rtc_base/buffer.h"
|
#include "rtc_base/buffer.h"
|
||||||
@ -46,8 +48,7 @@ namespace ios_adm {
|
|||||||
// same thread.
|
// same thread.
|
||||||
class AudioDeviceIOS : public AudioDeviceGeneric,
|
class AudioDeviceIOS : public AudioDeviceGeneric,
|
||||||
public AudioSessionObserver,
|
public AudioSessionObserver,
|
||||||
public VoiceProcessingAudioUnitObserver,
|
public VoiceProcessingAudioUnitObserver {
|
||||||
public rtc::MessageHandler {
|
|
||||||
public:
|
public:
|
||||||
explicit AudioDeviceIOS(bool bypass_voice_processing);
|
explicit AudioDeviceIOS(bool bypass_voice_processing);
|
||||||
~AudioDeviceIOS() override;
|
~AudioDeviceIOS() override;
|
||||||
@ -159,9 +160,6 @@ class AudioDeviceIOS : public AudioDeviceGeneric,
|
|||||||
UInt32 num_frames,
|
UInt32 num_frames,
|
||||||
AudioBufferList* io_data) override;
|
AudioBufferList* io_data) override;
|
||||||
|
|
||||||
// Handles messages from posts.
|
|
||||||
void OnMessage(rtc::Message* msg) override;
|
|
||||||
|
|
||||||
bool IsInterrupted();
|
bool IsInterrupted();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -213,10 +211,6 @@ class AudioDeviceIOS : public AudioDeviceGeneric,
|
|||||||
// Determines whether voice processing should be enabled or disabled.
|
// Determines whether voice processing should be enabled or disabled.
|
||||||
const bool bypass_voice_processing_;
|
const bool bypass_voice_processing_;
|
||||||
|
|
||||||
// Ensures that methods are called from the same thread as this object is
|
|
||||||
// created on.
|
|
||||||
SequenceChecker thread_checker_;
|
|
||||||
|
|
||||||
// Native I/O audio thread checker.
|
// Native I/O audio thread checker.
|
||||||
SequenceChecker io_thread_checker_;
|
SequenceChecker io_thread_checker_;
|
||||||
|
|
||||||
@ -273,7 +267,7 @@ class AudioDeviceIOS : public AudioDeviceGeneric,
|
|||||||
std::atomic<int> playing_;
|
std::atomic<int> playing_;
|
||||||
|
|
||||||
// Set to true after successful call to Init(), false otherwise.
|
// Set to true after successful call to Init(), false otherwise.
|
||||||
bool initialized_ RTC_GUARDED_BY(thread_checker_);
|
bool initialized_ RTC_GUARDED_BY(thread_);
|
||||||
|
|
||||||
// Set to true after successful call to InitRecording() or InitPlayout(),
|
// Set to true after successful call to InitRecording() or InitPlayout(),
|
||||||
// false otherwise.
|
// false otherwise.
|
||||||
@ -284,23 +278,27 @@ class AudioDeviceIOS : public AudioDeviceGeneric,
|
|||||||
|
|
||||||
// Audio interruption observer instance.
|
// Audio interruption observer instance.
|
||||||
RTCNativeAudioSessionDelegateAdapter* audio_session_observer_
|
RTCNativeAudioSessionDelegateAdapter* audio_session_observer_
|
||||||
RTC_GUARDED_BY(thread_checker_);
|
RTC_GUARDED_BY(thread_);
|
||||||
|
|
||||||
// Set to true if we've activated the audio session.
|
// Set to true if we've activated the audio session.
|
||||||
bool has_configured_session_ RTC_GUARDED_BY(thread_checker_);
|
bool has_configured_session_ RTC_GUARDED_BY(thread_);
|
||||||
|
|
||||||
// Counts number of detected audio glitches on the playout side.
|
// Counts number of detected audio glitches on the playout side.
|
||||||
int64_t num_detected_playout_glitches_ RTC_GUARDED_BY(thread_checker_);
|
int64_t num_detected_playout_glitches_ RTC_GUARDED_BY(thread_);
|
||||||
int64_t last_playout_time_ RTC_GUARDED_BY(io_thread_checker_);
|
int64_t last_playout_time_ RTC_GUARDED_BY(io_thread_checker_);
|
||||||
|
|
||||||
// Counts number of playout callbacks per call.
|
// Counts number of playout callbacks per call.
|
||||||
// The value isupdated on the native I/O thread and later read on the
|
// The value is updated on the native I/O thread and later read on the
|
||||||
// creating thread (see thread_checker_) but at this stage no audio is
|
// creating `thread_` but at this stage no audio is active.
|
||||||
// active. Hence, it is a "thread safe" design and no lock is needed.
|
// Hence, it is a "thread safe" design and no lock is needed.
|
||||||
int64_t num_playout_callbacks_;
|
int64_t num_playout_callbacks_;
|
||||||
|
|
||||||
// Contains the time for when the last output volume change was detected.
|
// Contains the time for when the last output volume change was detected.
|
||||||
int64_t last_output_volume_change_time_ RTC_GUARDED_BY(thread_checker_);
|
int64_t last_output_volume_change_time_ RTC_GUARDED_BY(thread_);
|
||||||
|
|
||||||
|
// Avoids running pending task after `this` is Terminated.
|
||||||
|
rtc::scoped_refptr<PendingTaskSafetyFlag> safety_ =
|
||||||
|
PendingTaskSafetyFlag::Create();
|
||||||
};
|
};
|
||||||
} // namespace ios_adm
|
} // namespace ios_adm
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
|
#include "api/task_queue/pending_task_safety_flag.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "modules/audio_device/fine_audio_buffer.h"
|
#include "modules/audio_device/fine_audio_buffer.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
@ -60,15 +61,6 @@ namespace ios_adm {
|
|||||||
const UInt16 kFixedPlayoutDelayEstimate = 30;
|
const UInt16 kFixedPlayoutDelayEstimate = 30;
|
||||||
const UInt16 kFixedRecordDelayEstimate = 30;
|
const UInt16 kFixedRecordDelayEstimate = 30;
|
||||||
|
|
||||||
enum AudioDeviceMessageType : uint32_t {
|
|
||||||
kMessageTypeInterruptionBegin,
|
|
||||||
kMessageTypeInterruptionEnd,
|
|
||||||
kMessageTypeValidRouteChange,
|
|
||||||
kMessageTypeCanPlayOrRecordChange,
|
|
||||||
kMessageTypePlayoutGlitchDetected,
|
|
||||||
kMessageOutputVolumeChange,
|
|
||||||
};
|
|
||||||
|
|
||||||
using ios::CheckAndLogError;
|
using ios::CheckAndLogError;
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
@ -115,16 +107,15 @@ AudioDeviceIOS::AudioDeviceIOS(bool bypass_voice_processing)
|
|||||||
LOGI() << "ctor" << ios::GetCurrentThreadDescription()
|
LOGI() << "ctor" << ios::GetCurrentThreadDescription()
|
||||||
<< ",bypass_voice_processing=" << bypass_voice_processing_;
|
<< ",bypass_voice_processing=" << bypass_voice_processing_;
|
||||||
io_thread_checker_.Detach();
|
io_thread_checker_.Detach();
|
||||||
thread_checker_.Detach();
|
|
||||||
thread_ = rtc::Thread::Current();
|
thread_ = rtc::Thread::Current();
|
||||||
|
|
||||||
audio_session_observer_ = [[RTCNativeAudioSessionDelegateAdapter alloc] initWithObserver:this];
|
audio_session_observer_ = [[RTCNativeAudioSessionDelegateAdapter alloc] initWithObserver:this];
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDeviceIOS::~AudioDeviceIOS() {
|
AudioDeviceIOS::~AudioDeviceIOS() {
|
||||||
RTC_DCHECK(thread_checker_.IsCurrent());
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
LOGI() << "~dtor" << ios::GetCurrentThreadDescription();
|
LOGI() << "~dtor" << ios::GetCurrentThreadDescription();
|
||||||
thread_->Clear(this);
|
safety_->SetNotAlive();
|
||||||
Terminate();
|
Terminate();
|
||||||
audio_session_observer_ = nil;
|
audio_session_observer_ = nil;
|
||||||
}
|
}
|
||||||
@ -132,16 +123,15 @@ AudioDeviceIOS::~AudioDeviceIOS() {
|
|||||||
void AudioDeviceIOS::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
|
void AudioDeviceIOS::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
|
||||||
LOGI() << "AttachAudioBuffer";
|
LOGI() << "AttachAudioBuffer";
|
||||||
RTC_DCHECK(audioBuffer);
|
RTC_DCHECK(audioBuffer);
|
||||||
RTC_DCHECK(thread_checker_.IsCurrent());
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
audio_device_buffer_ = audioBuffer;
|
audio_device_buffer_ = audioBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDeviceGeneric::InitStatus AudioDeviceIOS::Init() {
|
AudioDeviceGeneric::InitStatus AudioDeviceIOS::Init() {
|
||||||
LOGI() << "Init";
|
LOGI() << "Init";
|
||||||
io_thread_checker_.Detach();
|
io_thread_checker_.Detach();
|
||||||
thread_checker_.Detach();
|
|
||||||
|
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
if (initialized_) {
|
if (initialized_) {
|
||||||
return InitStatus::OK;
|
return InitStatus::OK;
|
||||||
}
|
}
|
||||||
@ -167,7 +157,7 @@ AudioDeviceGeneric::InitStatus AudioDeviceIOS::Init() {
|
|||||||
|
|
||||||
int32_t AudioDeviceIOS::Terminate() {
|
int32_t AudioDeviceIOS::Terminate() {
|
||||||
LOGI() << "Terminate";
|
LOGI() << "Terminate";
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
if (!initialized_) {
|
if (!initialized_) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -178,13 +168,13 @@ int32_t AudioDeviceIOS::Terminate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AudioDeviceIOS::Initialized() const {
|
bool AudioDeviceIOS::Initialized() const {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
return initialized_;
|
return initialized_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AudioDeviceIOS::InitPlayout() {
|
int32_t AudioDeviceIOS::InitPlayout() {
|
||||||
LOGI() << "InitPlayout";
|
LOGI() << "InitPlayout";
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTC_DCHECK(initialized_);
|
RTC_DCHECK(initialized_);
|
||||||
RTC_DCHECK(!audio_is_initialized_);
|
RTC_DCHECK(!audio_is_initialized_);
|
||||||
RTC_DCHECK(!playing_.load());
|
RTC_DCHECK(!playing_.load());
|
||||||
@ -199,18 +189,18 @@ int32_t AudioDeviceIOS::InitPlayout() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AudioDeviceIOS::PlayoutIsInitialized() const {
|
bool AudioDeviceIOS::PlayoutIsInitialized() const {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
return audio_is_initialized_;
|
return audio_is_initialized_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioDeviceIOS::RecordingIsInitialized() const {
|
bool AudioDeviceIOS::RecordingIsInitialized() const {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
return audio_is_initialized_;
|
return audio_is_initialized_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AudioDeviceIOS::InitRecording() {
|
int32_t AudioDeviceIOS::InitRecording() {
|
||||||
LOGI() << "InitRecording";
|
LOGI() << "InitRecording";
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTC_DCHECK(initialized_);
|
RTC_DCHECK(initialized_);
|
||||||
RTC_DCHECK(!audio_is_initialized_);
|
RTC_DCHECK(!audio_is_initialized_);
|
||||||
RTC_DCHECK(!recording_.load());
|
RTC_DCHECK(!recording_.load());
|
||||||
@ -226,7 +216,7 @@ int32_t AudioDeviceIOS::InitRecording() {
|
|||||||
|
|
||||||
int32_t AudioDeviceIOS::StartPlayout() {
|
int32_t AudioDeviceIOS::StartPlayout() {
|
||||||
LOGI() << "StartPlayout";
|
LOGI() << "StartPlayout";
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTC_DCHECK(audio_is_initialized_);
|
RTC_DCHECK(audio_is_initialized_);
|
||||||
RTC_DCHECK(!playing_.load());
|
RTC_DCHECK(!playing_.load());
|
||||||
RTC_DCHECK(audio_unit_);
|
RTC_DCHECK(audio_unit_);
|
||||||
@ -251,7 +241,7 @@ int32_t AudioDeviceIOS::StartPlayout() {
|
|||||||
|
|
||||||
int32_t AudioDeviceIOS::StopPlayout() {
|
int32_t AudioDeviceIOS::StopPlayout() {
|
||||||
LOGI() << "StopPlayout";
|
LOGI() << "StopPlayout";
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
if (!audio_is_initialized_ || !playing_.load()) {
|
if (!audio_is_initialized_ || !playing_.load()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -282,7 +272,7 @@ bool AudioDeviceIOS::Playing() const {
|
|||||||
|
|
||||||
int32_t AudioDeviceIOS::StartRecording() {
|
int32_t AudioDeviceIOS::StartRecording() {
|
||||||
LOGI() << "StartRecording";
|
LOGI() << "StartRecording";
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTC_DCHECK(audio_is_initialized_);
|
RTC_DCHECK(audio_is_initialized_);
|
||||||
RTC_DCHECK(!recording_.load());
|
RTC_DCHECK(!recording_.load());
|
||||||
RTC_DCHECK(audio_unit_);
|
RTC_DCHECK(audio_unit_);
|
||||||
@ -305,7 +295,7 @@ int32_t AudioDeviceIOS::StartRecording() {
|
|||||||
|
|
||||||
int32_t AudioDeviceIOS::StopRecording() {
|
int32_t AudioDeviceIOS::StopRecording() {
|
||||||
LOGI() << "StopRecording";
|
LOGI() << "StopRecording";
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
if (!audio_is_initialized_ || !recording_.load()) {
|
if (!audio_is_initialized_ || !recording_.load()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -329,7 +319,7 @@ int32_t AudioDeviceIOS::PlayoutDelay(uint16_t& delayMS) const {
|
|||||||
int AudioDeviceIOS::GetPlayoutAudioParameters(AudioParameters* params) const {
|
int AudioDeviceIOS::GetPlayoutAudioParameters(AudioParameters* params) const {
|
||||||
LOGI() << "GetPlayoutAudioParameters";
|
LOGI() << "GetPlayoutAudioParameters";
|
||||||
RTC_DCHECK(playout_parameters_.is_valid());
|
RTC_DCHECK(playout_parameters_.is_valid());
|
||||||
RTC_DCHECK(thread_checker_.IsCurrent());
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
*params = playout_parameters_;
|
*params = playout_parameters_;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -337,7 +327,7 @@ int AudioDeviceIOS::GetPlayoutAudioParameters(AudioParameters* params) const {
|
|||||||
int AudioDeviceIOS::GetRecordAudioParameters(AudioParameters* params) const {
|
int AudioDeviceIOS::GetRecordAudioParameters(AudioParameters* params) const {
|
||||||
LOGI() << "GetRecordAudioParameters";
|
LOGI() << "GetRecordAudioParameters";
|
||||||
RTC_DCHECK(record_parameters_.is_valid());
|
RTC_DCHECK(record_parameters_.is_valid());
|
||||||
RTC_DCHECK(thread_checker_.IsCurrent());
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
*params = record_parameters_;
|
*params = record_parameters_;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -345,31 +335,29 @@ int AudioDeviceIOS::GetRecordAudioParameters(AudioParameters* params) const {
|
|||||||
void AudioDeviceIOS::OnInterruptionBegin() {
|
void AudioDeviceIOS::OnInterruptionBegin() {
|
||||||
RTC_DCHECK(thread_);
|
RTC_DCHECK(thread_);
|
||||||
LOGI() << "OnInterruptionBegin";
|
LOGI() << "OnInterruptionBegin";
|
||||||
thread_->Post(RTC_FROM_HERE, this, kMessageTypeInterruptionBegin);
|
thread_->PostTask(SafeTask(safety_, [this] { HandleInterruptionBegin(); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::OnInterruptionEnd() {
|
void AudioDeviceIOS::OnInterruptionEnd() {
|
||||||
RTC_DCHECK(thread_);
|
RTC_DCHECK(thread_);
|
||||||
LOGI() << "OnInterruptionEnd";
|
LOGI() << "OnInterruptionEnd";
|
||||||
thread_->Post(RTC_FROM_HERE, this, kMessageTypeInterruptionEnd);
|
thread_->PostTask(SafeTask(safety_, [this] { HandleInterruptionEnd(); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::OnValidRouteChange() {
|
void AudioDeviceIOS::OnValidRouteChange() {
|
||||||
RTC_DCHECK(thread_);
|
RTC_DCHECK(thread_);
|
||||||
thread_->Post(RTC_FROM_HERE, this, kMessageTypeValidRouteChange);
|
thread_->PostTask(SafeTask(safety_, [this] { HandleValidRouteChange(); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::OnCanPlayOrRecordChange(bool can_play_or_record) {
|
void AudioDeviceIOS::OnCanPlayOrRecordChange(bool can_play_or_record) {
|
||||||
RTC_DCHECK(thread_);
|
RTC_DCHECK(thread_);
|
||||||
thread_->Post(RTC_FROM_HERE,
|
thread_->PostTask(SafeTask(
|
||||||
this,
|
safety_, [this, can_play_or_record] { HandleCanPlayOrRecordChange(can_play_or_record); }));
|
||||||
kMessageTypeCanPlayOrRecordChange,
|
|
||||||
new rtc::TypedMessageData<bool>(can_play_or_record));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::OnChangedOutputVolume() {
|
void AudioDeviceIOS::OnChangedOutputVolume() {
|
||||||
RTC_DCHECK(thread_);
|
RTC_DCHECK(thread_);
|
||||||
thread_->Post(RTC_FROM_HERE, this, kMessageOutputVolumeChange);
|
thread_->PostTask(SafeTask(safety_, [this] { HandleOutputVolumeChange(); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
OSStatus AudioDeviceIOS::OnDeliverRecordedData(AudioUnitRenderActionFlags* flags,
|
OSStatus AudioDeviceIOS::OnDeliverRecordedData(AudioUnitRenderActionFlags* flags,
|
||||||
@ -464,7 +452,7 @@ OSStatus AudioDeviceIOS::OnGetPlayoutData(AudioUnitRenderActionFlags* flags,
|
|||||||
if (glitch_threshold < 120 && delta_time > 120) {
|
if (glitch_threshold < 120 && delta_time > 120) {
|
||||||
RTCLog(@"Glitch warning is ignored. Probably caused by device switch.");
|
RTCLog(@"Glitch warning is ignored. Probably caused by device switch.");
|
||||||
} else {
|
} else {
|
||||||
thread_->Post(RTC_FROM_HERE, this, kMessageTypePlayoutGlitchDetected);
|
thread_->PostTask(SafeTask(safety_, [this] { HandlePlayoutGlitchDetected(); }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -479,34 +467,8 @@ OSStatus AudioDeviceIOS::OnGetPlayoutData(AudioUnitRenderActionFlags* flags,
|
|||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::OnMessage(rtc::Message* msg) {
|
|
||||||
switch (msg->message_id) {
|
|
||||||
case kMessageTypeInterruptionBegin:
|
|
||||||
HandleInterruptionBegin();
|
|
||||||
break;
|
|
||||||
case kMessageTypeInterruptionEnd:
|
|
||||||
HandleInterruptionEnd();
|
|
||||||
break;
|
|
||||||
case kMessageTypeValidRouteChange:
|
|
||||||
HandleValidRouteChange();
|
|
||||||
break;
|
|
||||||
case kMessageTypeCanPlayOrRecordChange: {
|
|
||||||
rtc::TypedMessageData<bool>* data = static_cast<rtc::TypedMessageData<bool>*>(msg->pdata);
|
|
||||||
HandleCanPlayOrRecordChange(data->data());
|
|
||||||
delete data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kMessageTypePlayoutGlitchDetected:
|
|
||||||
HandlePlayoutGlitchDetected();
|
|
||||||
break;
|
|
||||||
case kMessageOutputVolumeChange:
|
|
||||||
HandleOutputVolumeChange();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioDeviceIOS::HandleInterruptionBegin() {
|
void AudioDeviceIOS::HandleInterruptionBegin() {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTCLog(@"Interruption begin. IsInterrupted changed from %d to 1.", is_interrupted_);
|
RTCLog(@"Interruption begin. IsInterrupted changed from %d to 1.", is_interrupted_);
|
||||||
if (audio_unit_ && audio_unit_->GetState() == VoiceProcessingAudioUnit::kStarted) {
|
if (audio_unit_ && audio_unit_->GetState() == VoiceProcessingAudioUnit::kStarted) {
|
||||||
RTCLog(@"Stopping the audio unit due to interruption begin.");
|
RTCLog(@"Stopping the audio unit due to interruption begin.");
|
||||||
@ -519,7 +481,7 @@ void AudioDeviceIOS::HandleInterruptionBegin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::HandleInterruptionEnd() {
|
void AudioDeviceIOS::HandleInterruptionEnd() {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTCLog(@"Interruption ended. IsInterrupted changed from %d to 0. "
|
RTCLog(@"Interruption ended. IsInterrupted changed from %d to 0. "
|
||||||
"Updating audio unit state.",
|
"Updating audio unit state.",
|
||||||
is_interrupted_);
|
is_interrupted_);
|
||||||
@ -542,7 +504,7 @@ void AudioDeviceIOS::HandleInterruptionEnd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::HandleValidRouteChange() {
|
void AudioDeviceIOS::HandleValidRouteChange() {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTC_OBJC_TYPE(RTCAudioSession)* session = [RTC_OBJC_TYPE(RTCAudioSession) sharedInstance];
|
RTC_OBJC_TYPE(RTCAudioSession)* session = [RTC_OBJC_TYPE(RTCAudioSession) sharedInstance];
|
||||||
RTCLog(@"%@", session);
|
RTCLog(@"%@", session);
|
||||||
HandleSampleRateChange();
|
HandleSampleRateChange();
|
||||||
@ -554,7 +516,7 @@ void AudioDeviceIOS::HandleCanPlayOrRecordChange(bool can_play_or_record) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::HandleSampleRateChange() {
|
void AudioDeviceIOS::HandleSampleRateChange() {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTCLog(@"Handling sample rate change.");
|
RTCLog(@"Handling sample rate change.");
|
||||||
|
|
||||||
// Don't do anything if we're interrupted.
|
// Don't do anything if we're interrupted.
|
||||||
@ -639,7 +601,7 @@ void AudioDeviceIOS::HandleSampleRateChange() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::HandlePlayoutGlitchDetected() {
|
void AudioDeviceIOS::HandlePlayoutGlitchDetected() {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
// Don't update metrics if we're interrupted since a "glitch" is expected
|
// Don't update metrics if we're interrupted since a "glitch" is expected
|
||||||
// in this state.
|
// in this state.
|
||||||
if (is_interrupted_) {
|
if (is_interrupted_) {
|
||||||
@ -664,7 +626,7 @@ void AudioDeviceIOS::HandlePlayoutGlitchDetected() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::HandleOutputVolumeChange() {
|
void AudioDeviceIOS::HandleOutputVolumeChange() {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTCLog(@"Output volume change detected.");
|
RTCLog(@"Output volume change detected.");
|
||||||
// Store time of this detection so it can be used to defer detection of
|
// Store time of this detection so it can be used to defer detection of
|
||||||
// glitches too close in time to this event.
|
// glitches too close in time to this event.
|
||||||
@ -752,7 +714,7 @@ bool AudioDeviceIOS::CreateAudioUnit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::UpdateAudioUnit(bool can_play_or_record) {
|
void AudioDeviceIOS::UpdateAudioUnit(bool can_play_or_record) {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTCLog(@"Updating audio unit state. CanPlayOrRecord=%d IsInterrupted=%d",
|
RTCLog(@"Updating audio unit state. CanPlayOrRecord=%d IsInterrupted=%d",
|
||||||
can_play_or_record,
|
can_play_or_record,
|
||||||
is_interrupted_);
|
is_interrupted_);
|
||||||
@ -839,7 +801,7 @@ void AudioDeviceIOS::UpdateAudioUnit(bool can_play_or_record) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AudioDeviceIOS::ConfigureAudioSession() {
|
bool AudioDeviceIOS::ConfigureAudioSession() {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTCLog(@"Configuring audio session.");
|
RTCLog(@"Configuring audio session.");
|
||||||
if (has_configured_session_) {
|
if (has_configured_session_) {
|
||||||
RTCLogWarning(@"Audio session already configured.");
|
RTCLogWarning(@"Audio session already configured.");
|
||||||
@ -859,7 +821,7 @@ bool AudioDeviceIOS::ConfigureAudioSession() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AudioDeviceIOS::ConfigureAudioSessionLocked() {
|
bool AudioDeviceIOS::ConfigureAudioSessionLocked() {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTCLog(@"Configuring audio session.");
|
RTCLog(@"Configuring audio session.");
|
||||||
if (has_configured_session_) {
|
if (has_configured_session_) {
|
||||||
RTCLogWarning(@"Audio session already configured.");
|
RTCLogWarning(@"Audio session already configured.");
|
||||||
@ -877,7 +839,7 @@ bool AudioDeviceIOS::ConfigureAudioSessionLocked() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceIOS::UnconfigureAudioSession() {
|
void AudioDeviceIOS::UnconfigureAudioSession() {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
RTCLog(@"Unconfiguring audio session.");
|
RTCLog(@"Unconfiguring audio session.");
|
||||||
if (!has_configured_session_) {
|
if (!has_configured_session_) {
|
||||||
RTCLogWarning(@"Audio session already unconfigured.");
|
RTCLogWarning(@"Audio session already unconfigured.");
|
||||||
@ -894,7 +856,7 @@ void AudioDeviceIOS::UnconfigureAudioSession() {
|
|||||||
|
|
||||||
bool AudioDeviceIOS::InitPlayOrRecord() {
|
bool AudioDeviceIOS::InitPlayOrRecord() {
|
||||||
LOGI() << "InitPlayOrRecord";
|
LOGI() << "InitPlayOrRecord";
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
|
|
||||||
// There should be no audio unit at this point.
|
// There should be no audio unit at this point.
|
||||||
if (!CreateAudioUnit()) {
|
if (!CreateAudioUnit()) {
|
||||||
@ -938,7 +900,7 @@ bool AudioDeviceIOS::InitPlayOrRecord() {
|
|||||||
|
|
||||||
void AudioDeviceIOS::ShutdownPlayOrRecord() {
|
void AudioDeviceIOS::ShutdownPlayOrRecord() {
|
||||||
LOGI() << "ShutdownPlayOrRecord";
|
LOGI() << "ShutdownPlayOrRecord";
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
|
|
||||||
// Stop the audio unit to prevent any additional audio callbacks.
|
// Stop the audio unit to prevent any additional audio callbacks.
|
||||||
audio_unit_->Stop();
|
audio_unit_->Stop();
|
||||||
|
|||||||
Reference in New Issue
Block a user