diff --git a/webrtc/voice_engine/level_indicator.cc b/webrtc/voice_engine/level_indicator.cc index 1b5cba579e..a32527c2d8 100644 --- a/webrtc/voice_engine/level_indicator.cc +++ b/webrtc/voice_engine/level_indicator.cc @@ -8,6 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include "critical_section_wrapper.h" #include "level_indicator.h" #include "module_common_types.h" #include "signal_processing_library.h" @@ -16,7 +17,6 @@ namespace webrtc { namespace voe { - // Number of bars on the indicator. // Note that the number of elements is specified because we are indexing it // in the range of 0-32 @@ -25,28 +25,26 @@ const WebRtc_Word8 permutation[33] = AudioLevel::AudioLevel() : + _critSect(*CriticalSectionWrapper::CreateCriticalSection()), _absMax(0), _count(0), _currentLevel(0), - _currentLevelFullRange(0) -{ + _currentLevelFullRange(0) { } -AudioLevel::~AudioLevel() -{ +AudioLevel::~AudioLevel() { } -void -AudioLevel::Clear() +void AudioLevel::Clear() { + CriticalSectionScoped cs(&_critSect); _absMax = 0; _count = 0; _currentLevel = 0; _currentLevelFullRange = 0; } -void -AudioLevel::ComputeLevel(const AudioFrame& audioFrame) +void AudioLevel::ComputeLevel(const AudioFrame& audioFrame) { WebRtc_Word16 absValue(0); @@ -54,6 +52,11 @@ AudioLevel::ComputeLevel(const AudioFrame& audioFrame) absValue = WebRtcSpl_MaxAbsValueW16( audioFrame.data_, audioFrame.samples_per_channel_*audioFrame.num_channels_); + + // Protect member access using a lock since this method is called on a + // dedicated audio thread in the RecordedDataIsAvailable() callback. + CriticalSectionScoped cs(&_critSect); + if (absValue > _absMax) _absMax = absValue; @@ -82,15 +85,15 @@ AudioLevel::ComputeLevel(const AudioFrame& audioFrame) } } -WebRtc_Word8 -AudioLevel::Level() const +WebRtc_Word8 AudioLevel::Level() const { + CriticalSectionScoped cs(&_critSect); return _currentLevel; } -WebRtc_Word16 -AudioLevel::LevelFullRange() const +WebRtc_Word16 AudioLevel::LevelFullRange() const { + CriticalSectionScoped cs(&_critSect); return _currentLevelFullRange; } diff --git a/webrtc/voice_engine/level_indicator.h b/webrtc/voice_engine/level_indicator.h index 564b068ef7..2041b1bbb8 100644 --- a/webrtc/voice_engine/level_indicator.h +++ b/webrtc/voice_engine/level_indicator.h @@ -17,6 +17,7 @@ namespace webrtc { class AudioFrame; +class CriticalSectionWrapper; namespace voe { class AudioLevel @@ -25,17 +26,22 @@ public: AudioLevel(); virtual ~AudioLevel(); - void ComputeLevel(const AudioFrame& audioFrame); - + // Called on "API thread(s)" from APIs like VoEBase::CreateChannel(), + // VoEBase::StopSend(), VoEVolumeControl::GetSpeechOutputLevel(). WebRtc_Word8 Level() const; - WebRtc_Word16 LevelFullRange() const; - void Clear(); + // Called on a native capture audio thread (platform dependent) from the + // AudioTransport::RecordedDataIsAvailable() callback. + // In Chrome, this method is called on the AudioInputDevice thread. + void ComputeLevel(const AudioFrame& audioFrame); + private: enum { kUpdateFrequency = 10}; + CriticalSectionWrapper& _critSect; + WebRtc_Word16 _absMax; WebRtc_Word16 _count; WebRtc_Word8 _currentLevel;