diff --git a/modules/audio_device/linux/audio_device_alsa_linux.cc b/modules/audio_device/linux/audio_device_alsa_linux.cc index 5fac1bcacd..84d05e0f6c 100644 --- a/modules/audio_device/linux/audio_device_alsa_linux.cc +++ b/modules/audio_device/linux/audio_device_alsa_linux.cc @@ -217,7 +217,10 @@ bool AudioDeviceLinuxALSA::Initialized() const { int32_t AudioDeviceLinuxALSA::InitSpeaker() { MutexLock lock(&mutex_); + return InitSpeakerLocked(); +} +int32_t AudioDeviceLinuxALSA::InitSpeakerLocked() { if (_playing) { return -1; } @@ -229,7 +232,10 @@ int32_t AudioDeviceLinuxALSA::InitSpeaker() { int32_t AudioDeviceLinuxALSA::InitMicrophone() { MutexLock lock(&mutex_); + return InitMicrophoneLocked(); +} +int32_t AudioDeviceLinuxALSA::InitMicrophoneLocked() { if (_recording) { return -1; } @@ -421,22 +427,22 @@ int32_t AudioDeviceLinuxALSA::StereoRecordingIsAvailable(bool& available) { // Stop/uninitialize recording if initialized (and possibly started) if (_recIsInitialized) { - StopRecording(); + StopRecordingLocked(); } // Try init in stereo; _recChannels = 2; - if (InitRecording() == 0) { + if (InitRecordingLocked() == 0) { available = true; } // Stop/uninitialize recording - StopRecording(); + StopRecordingLocked(); // Recover previous states _recChannels = recChannels; if (recIsInitialized) { - InitRecording(); + InitRecordingLocked(); } if (recording) { StartRecording(); @@ -481,22 +487,22 @@ int32_t AudioDeviceLinuxALSA::StereoPlayoutIsAvailable(bool& available) { // Stop/uninitialize recording if initialized (and possibly started) if (_playIsInitialized) { - StopPlayout(); + StopPlayoutLocked(); } // Try init in stereo; _playChannels = 2; - if (InitPlayout() == 0) { + if (InitPlayoutLocked() == 0) { available = true; } // Stop/uninitialize recording - StopPlayout(); + StopPlayoutLocked(); // Recover previous states _playChannels = playChannels; if (playIsInitialized) { - InitPlayout(); + InitPlayoutLocked(); } if (playing) { StartPlayout(); @@ -745,9 +751,13 @@ int32_t AudioDeviceLinuxALSA::RecordingIsAvailable(bool& available) { } int32_t AudioDeviceLinuxALSA::InitPlayout() { + MutexLock lock(&mutex_); + return InitPlayoutLocked(); +} + +int32_t AudioDeviceLinuxALSA::InitPlayoutLocked() { int errVal = 0; - MutexLock lock(&mutex_); if (_playing) { return -1; } @@ -760,7 +770,7 @@ int32_t AudioDeviceLinuxALSA::InitPlayout() { return 0; } // Initialize the speaker (devices might have been added or removed) - if (InitSpeaker() == -1) { + if (InitSpeakerLocked() == -1) { RTC_LOG(LS_WARNING) << "InitSpeaker() failed"; } @@ -864,9 +874,12 @@ int32_t AudioDeviceLinuxALSA::InitPlayout() { } int32_t AudioDeviceLinuxALSA::InitRecording() { - int errVal = 0; - MutexLock lock(&mutex_); + return InitRecordingLocked(); +} + +int32_t AudioDeviceLinuxALSA::InitRecordingLocked() { + int errVal = 0; if (_recording) { return -1; @@ -881,7 +894,7 @@ int32_t AudioDeviceLinuxALSA::InitRecording() { } // Initialize the microphone (devices might have been added or removed) - if (InitMicrophone() == -1) { + if (InitMicrophoneLocked() == -1) { RTC_LOG(LS_WARNING) << "InitMicrophone() failed"; } @@ -1058,28 +1071,28 @@ int32_t AudioDeviceLinuxALSA::StartRecording() { } int32_t AudioDeviceLinuxALSA::StopRecording() { - { MutexLock lock(&mutex_); + return StopRecordingLocked(); +} - if (!_recIsInitialized) { - return 0; - } - - if (_handleRecord == NULL) { - return -1; - } - - // Make sure we don't start recording (it's asynchronous). - _recIsInitialized = false; - _recording = false; +int32_t AudioDeviceLinuxALSA::StopRecordingLocked() { + if (!_recIsInitialized) { + return 0; } + if (_handleRecord == NULL) { + return -1; + } + + // Make sure we don't start recording (it's asynchronous). + _recIsInitialized = false; + _recording = false; + if (_ptrThreadRec) { _ptrThreadRec->Stop(); _ptrThreadRec.reset(); } - MutexLock lock(&mutex_); _recordingFramesLeft = 0; if (_recordingBuffer) { delete[] _recordingBuffer; @@ -1162,28 +1175,27 @@ int32_t AudioDeviceLinuxALSA::StartPlayout() { } int32_t AudioDeviceLinuxALSA::StopPlayout() { - { MutexLock lock(&mutex_); + return StopPlayoutLocked(); +} - if (!_playIsInitialized) { - return 0; - } - - if (_handlePlayout == NULL) { - return -1; - } - - _playing = false; +int32_t AudioDeviceLinuxALSA::StopPlayoutLocked() { + if (!_playIsInitialized) { + return 0; } + if (_handlePlayout == NULL) { + return -1; + } + + _playing = false; + // stop playout thread first if (_ptrThreadPlay) { _ptrThreadPlay->Stop(); _ptrThreadPlay.reset(); } - MutexLock lock(&mutex_); - _playoutFramesLeft = 0; delete[] _playoutBuffer; _playoutBuffer = NULL; diff --git a/modules/audio_device/linux/audio_device_alsa_linux.h b/modules/audio_device/linux/audio_device_alsa_linux.h index 0e0b7919ba..410afcf42c 100644 --- a/modules/audio_device/linux/audio_device_alsa_linux.h +++ b/modules/audio_device/linux/audio_device_alsa_linux.h @@ -40,8 +40,8 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric { AudioDeviceModule::AudioLayer& audioLayer) const override; // Main initializaton and termination - InitStatus Init() override; - int32_t Terminate() override; + InitStatus Init() RTC_LOCKS_EXCLUDED(mutex_) override; + int32_t Terminate() RTC_LOCKS_EXCLUDED(mutex_) override; bool Initialized() const override; // Device enumeration @@ -64,24 +64,24 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric { // Audio transport initialization int32_t PlayoutIsAvailable(bool& available) override; - int32_t InitPlayout() override; + int32_t InitPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; bool PlayoutIsInitialized() const override; int32_t RecordingIsAvailable(bool& available) override; - int32_t InitRecording() override; + int32_t InitRecording() RTC_LOCKS_EXCLUDED(mutex_) override; bool RecordingIsInitialized() const override; // Audio transport control int32_t StartPlayout() override; - int32_t StopPlayout() override; + int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; bool Playing() const override; int32_t StartRecording() override; - int32_t StopRecording() override; + int32_t StopRecording() RTC_LOCKS_EXCLUDED(mutex_) override; bool Recording() const override; // Audio mixer initialization - int32_t InitSpeaker() override; + int32_t InitSpeaker() RTC_LOCKS_EXCLUDED(mutex_) override; bool SpeakerIsInitialized() const override; - int32_t InitMicrophone() override; + int32_t InitMicrophone() RTC_LOCKS_EXCLUDED(mutex_) override; bool MicrophoneIsInitialized() const override; // Speaker volume controls @@ -109,19 +109,28 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric { int32_t MicrophoneMute(bool& enabled) const override; // Stereo support - int32_t StereoPlayoutIsAvailable(bool& available) override; + int32_t StereoPlayoutIsAvailable(bool& available) + RTC_LOCKS_EXCLUDED(mutex_) override; int32_t SetStereoPlayout(bool enable) override; int32_t StereoPlayout(bool& enabled) const override; - int32_t StereoRecordingIsAvailable(bool& available) override; + int32_t StereoRecordingIsAvailable(bool& available) + RTC_LOCKS_EXCLUDED(mutex_) override; int32_t SetStereoRecording(bool enable) override; int32_t StereoRecording(bool& enabled) const override; // Delay information and control int32_t PlayoutDelay(uint16_t& delayMS) const override; - void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override; + void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) + RTC_LOCKS_EXCLUDED(mutex_) override; private: + int32_t InitRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t StopRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t StopPlayoutLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t InitPlayoutLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t InitSpeakerLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t InitMicrophoneLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); int32_t GetDevicesInfo(const int32_t function, const bool playback, const int32_t enumDeviceNo = 0, diff --git a/modules/audio_device/linux/audio_device_pulse_linux.h b/modules/audio_device/linux/audio_device_pulse_linux.h index f05ba1ebf1..03aa16bb85 100644 --- a/modules/audio_device/linux/audio_device_pulse_linux.h +++ b/modules/audio_device/linux/audio_device_pulse_linux.h @@ -116,7 +116,7 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric { // Main initializaton and termination InitStatus Init() override; - int32_t Terminate() override; + int32_t Terminate() RTC_LOCKS_EXCLUDED(mutex_) override; bool Initialized() const override; // Device enumeration @@ -139,18 +139,18 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric { // Audio transport initialization int32_t PlayoutIsAvailable(bool& available) override; - int32_t InitPlayout() override; + int32_t InitPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; bool PlayoutIsInitialized() const override; int32_t RecordingIsAvailable(bool& available) override; int32_t InitRecording() override; bool RecordingIsInitialized() const override; // Audio transport control - int32_t StartPlayout() override; - int32_t StopPlayout() override; + int32_t StartPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; + int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; bool Playing() const override; - int32_t StartRecording() override; - int32_t StopRecording() override; + int32_t StartRecording() RTC_LOCKS_EXCLUDED(mutex_) override; + int32_t StopRecording() RTC_LOCKS_EXCLUDED(mutex_) override; bool Recording() const override; // Audio mixer initialization @@ -192,7 +192,8 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric { int32_t StereoRecording(bool& enabled) const override; // Delay information and control - int32_t PlayoutDelay(uint16_t& delayMS) const override; + int32_t PlayoutDelay(uint16_t& delayMS) const + RTC_LOCKS_EXCLUDED(mutex_) override; void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override; @@ -256,8 +257,8 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric { static void RecThreadFunc(void*); static void PlayThreadFunc(void*); - bool RecThreadProcess(); - bool PlayThreadProcess(); + bool RecThreadProcess() RTC_LOCKS_EXCLUDED(mutex_); + bool PlayThreadProcess() RTC_LOCKS_EXCLUDED(mutex_); AudioDeviceBuffer* _ptrAudioBuffer; diff --git a/modules/audio_device/linux/audio_mixer_manager_alsa_linux.cc b/modules/audio_device/linux/audio_mixer_manager_alsa_linux.cc index 028be5db6b..fb9d874ef3 100644 --- a/modules/audio_device/linux/audio_mixer_manager_alsa_linux.cc +++ b/modules/audio_device/linux/audio_mixer_manager_alsa_linux.cc @@ -47,16 +47,19 @@ int32_t AudioMixerManagerLinuxALSA::Close() { MutexLock lock(&mutex_); - CloseSpeaker(); - CloseMicrophone(); + CloseSpeakerLocked(); + CloseMicrophoneLocked(); return 0; } int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() { - RTC_LOG(LS_VERBOSE) << __FUNCTION__; - MutexLock lock(&mutex_); + return CloseSpeakerLocked(); +} + +int32_t AudioMixerManagerLinuxALSA::CloseSpeakerLocked() { + RTC_LOG(LS_VERBOSE) << __FUNCTION__; int errVal = 0; @@ -86,9 +89,12 @@ int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() { } int32_t AudioMixerManagerLinuxALSA::CloseMicrophone() { - RTC_LOG(LS_VERBOSE) << __FUNCTION__; - MutexLock lock(&mutex_); + return CloseMicrophoneLocked(); +} + +int32_t AudioMixerManagerLinuxALSA::CloseMicrophoneLocked() { + RTC_LOG(LS_VERBOSE) << __FUNCTION__; int errVal = 0; diff --git a/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h b/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h index 61490b4a78..d98287822d 100644 --- a/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h +++ b/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h @@ -21,27 +21,27 @@ namespace webrtc { class AudioMixerManagerLinuxALSA { public: - int32_t OpenSpeaker(char* deviceName); - int32_t OpenMicrophone(char* deviceName); - int32_t SetSpeakerVolume(uint32_t volume); + int32_t OpenSpeaker(char* deviceName) RTC_LOCKS_EXCLUDED(mutex_); + int32_t OpenMicrophone(char* deviceName) RTC_LOCKS_EXCLUDED(mutex_); + int32_t SetSpeakerVolume(uint32_t volume) RTC_LOCKS_EXCLUDED(mutex_); int32_t SpeakerVolume(uint32_t& volume) const; int32_t MaxSpeakerVolume(uint32_t& maxVolume) const; int32_t MinSpeakerVolume(uint32_t& minVolume) const; int32_t SpeakerVolumeIsAvailable(bool& available); int32_t SpeakerMuteIsAvailable(bool& available); - int32_t SetSpeakerMute(bool enable); + int32_t SetSpeakerMute(bool enable) RTC_LOCKS_EXCLUDED(mutex_); int32_t SpeakerMute(bool& enabled) const; int32_t MicrophoneMuteIsAvailable(bool& available); - int32_t SetMicrophoneMute(bool enable); + int32_t SetMicrophoneMute(bool enable) RTC_LOCKS_EXCLUDED(mutex_); int32_t MicrophoneMute(bool& enabled) const; int32_t MicrophoneVolumeIsAvailable(bool& available); - int32_t SetMicrophoneVolume(uint32_t volume); + int32_t SetMicrophoneVolume(uint32_t volume) RTC_LOCKS_EXCLUDED(mutex_); int32_t MicrophoneVolume(uint32_t& volume) const; int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const; int32_t MinMicrophoneVolume(uint32_t& minVolume) const; - int32_t Close(); - int32_t CloseSpeaker(); - int32_t CloseMicrophone(); + int32_t Close() RTC_LOCKS_EXCLUDED(mutex_); + int32_t CloseSpeaker() RTC_LOCKS_EXCLUDED(mutex_); + int32_t CloseMicrophone() RTC_LOCKS_EXCLUDED(mutex_); bool SpeakerIsInitialized() const; bool MicrophoneIsInitialized() const; @@ -50,6 +50,8 @@ class AudioMixerManagerLinuxALSA { ~AudioMixerManagerLinuxALSA(); private: + int32_t CloseSpeakerLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + int32_t CloseMicrophoneLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); int32_t LoadMicMixerElement() const; int32_t LoadSpeakerMixerElement() const; void GetControlName(char* controlName, char* deviceName) const;