diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc index eeb912ad52..cb7c418407 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc +++ b/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc @@ -118,16 +118,16 @@ bool IsCng(int codec_id) { } // namespace AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config) - : id_(config.id), - neteq_(NetEq::Create(config.neteq_config)), + : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), + id_(config.id), last_audio_decoder_(-1), // Invalid value. - decode_lock_(RWLockWrapper::CreateRWLock()), - neteq_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), - vad_enabled_(true), previous_audio_activity_(AudioFrame::kVadPassive), current_sample_rate_hz_(config.neteq_config.sample_rate_hz), nack_(), nack_enabled_(false), + neteq_(NetEq::Create(config.neteq_config)), + decode_lock_(RWLockWrapper::CreateRWLock()), + vad_enabled_(true), clock_(config.clock), av_sync_(false), initial_delay_manager_(), @@ -150,7 +150,6 @@ AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config) AcmReceiver::~AcmReceiver() { delete neteq_; delete decode_lock_; - delete neteq_crit_sect_; } int AcmReceiver::SetMinimumDelay(int delay_ms) { @@ -164,7 +163,7 @@ int AcmReceiver::SetInitialDelay(int delay_ms) { if (delay_ms < 0 || delay_ms > 10000) { return -1; } - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); if (delay_ms == 0) { av_sync_ = false; @@ -208,7 +207,7 @@ int AcmReceiver::LeastRequiredDelayMs() const { } int AcmReceiver::current_sample_rate_hz() const { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); return current_sample_rate_hz_; } @@ -271,7 +270,7 @@ int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header, const RTPHeader* header = &rtp_header.header; // Just a shorthand. { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); int codec_id = RtpHeaderToCodecIndex(*header, incoming_payload); if (codec_id < 0) { @@ -330,7 +329,7 @@ int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header, rtp_header, receive_timestamp, packet_type, new_codec, sample_rate_hz, missing_packets_sync_stream_.get()); } - } + } // |crit_sect_| is released. { WriteLockScoped lock_codecs(*decode_lock_); // Lock to prevent an encoding. @@ -361,7 +360,7 @@ int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) { { // Accessing members, take the lock. - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); if (av_sync_) { assert(initial_delay_manager_.get()); @@ -406,7 +405,7 @@ int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) { } // Accessing members, take the lock. - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); // Update NACK. int decoded_sequence_num = 0; @@ -501,7 +500,7 @@ int32_t AcmReceiver::AddCodec(int acm_codec_id, neteq_decoder = kDecoderOpus_2ch; } - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); // The corresponding NetEq decoder ID. // If this coder has been registered before. @@ -547,13 +546,13 @@ int32_t AcmReceiver::AddCodec(int acm_codec_id, void AcmReceiver::EnableVad() { neteq_->EnableVad(); - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); vad_enabled_ = true; } void AcmReceiver::DisableVad() { neteq_->DisableVad(); - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); vad_enabled_ = false; } @@ -565,7 +564,7 @@ void AcmReceiver::FlushBuffers() { // many as it can. int AcmReceiver::RemoveAllCodecs() { int ret_val = 0; - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); for (int n = 0; n < ACMCodecDB::kMaxNumCodecs; ++n) { if (decoders_[n].registered) { if (neteq_->RemovePayloadType(decoders_[n].payload_type) == 0) { @@ -591,7 +590,7 @@ int AcmReceiver::RemoveCodec(uint8_t payload_type) { LOG_FERR1(LS_ERROR, "AcmReceiver::RemoveCodec", payload_type); return -1; } - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); decoders_[codec_index].registered = false; if (last_audio_decoder_ == codec_index) last_audio_decoder_ = -1; // Codec is removed, invalidate last decoder. @@ -599,7 +598,7 @@ int AcmReceiver::RemoveCodec(uint8_t payload_type) { } void AcmReceiver::set_id(int id) { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); id_ = id; } @@ -614,12 +613,12 @@ bool AcmReceiver::GetPlayoutTimestamp(uint32_t* timestamp) { } int AcmReceiver::last_audio_codec_id() const { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); return last_audio_decoder_; } int AcmReceiver::last_audio_payload_type() const { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); if (last_audio_decoder_ < 0) return -1; assert(decoders_[last_audio_decoder_].registered); @@ -627,7 +626,7 @@ int AcmReceiver::last_audio_payload_type() const { } int AcmReceiver::RedPayloadType() const { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); if (ACMCodecDB::kRED < 0 || !decoders_[ACMCodecDB::kRED].registered) { LOG_F(LS_WARNING) << "RED is not registered."; @@ -637,7 +636,7 @@ int AcmReceiver::RedPayloadType() const { } int AcmReceiver::LastAudioCodec(CodecInst* codec) const { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); if (last_audio_decoder_ < 0) { return -1; } @@ -692,7 +691,7 @@ void AcmReceiver::NetworkStatistics(ACMNetworkStatistics* acm_stat) { int AcmReceiver::DecoderByPayloadType(uint8_t payload_type, CodecInst* codec) const { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); int codec_index = PayloadType2CodecIndex(payload_type); if (codec_index < 0) { LOG_FERR1(LS_ERROR, "AcmReceiver::DecoderByPayloadType", payload_type); @@ -718,7 +717,7 @@ int AcmReceiver::EnableNack(size_t max_nack_list_size) { if (max_nack_list_size == 0 || max_nack_list_size > Nack::kNackListSizeLimit) return -1; - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); if (!nack_enabled_) { nack_.reset(Nack::Create(kNackThresholdPackets)); nack_enabled_ = true; @@ -734,14 +733,14 @@ int AcmReceiver::EnableNack(size_t max_nack_list_size) { } void AcmReceiver::DisableNack() { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); nack_.reset(); // Memory is released. nack_enabled_ = false; } std::vector AcmReceiver::GetNackList( int round_trip_time_ms) const { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); if (round_trip_time_ms < 0) { WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_, "GetNackList: round trip time cannot be negative." @@ -757,7 +756,7 @@ std::vector AcmReceiver::GetNackList( void AcmReceiver::ResetInitialDelay() { { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); av_sync_ = false; initial_delay_manager_.reset(NULL); missing_packets_sync_stream_.reset(NULL); @@ -860,7 +859,7 @@ void AcmReceiver::InsertStreamOfSyncPackets( void AcmReceiver::GetDecodingCallStatistics( AudioDecodingCallStats* stats) const { - CriticalSectionScoped lock(neteq_crit_sect_); + CriticalSectionScoped lock(crit_sect_.get()); *stats = call_stats_.GetDecodingStatistics(); } diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver.h b/webrtc/modules/audio_coding/main/acm2/acm_receiver.h index 11440d1211..b6898f73f9 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver.h +++ b/webrtc/modules/audio_coding/main/acm2/acm_receiver.h @@ -23,6 +23,7 @@ #include "webrtc/modules/audio_coding/neteq/interface/neteq.h" #include "webrtc/modules/interface/module_common_types.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/system_wrappers/interface/thread_annotations.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -327,7 +328,8 @@ class AcmReceiver { private: int PayloadType2CodecIndex(uint8_t payload_type) const; - bool GetSilence(int desired_sample_rate_hz, AudioFrame* frame); + bool GetSilence(int desired_sample_rate_hz, AudioFrame* frame) + EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); int GetNumSyncPacketToInsert(uint16_t received_squence_number); @@ -338,21 +340,23 @@ class AcmReceiver { void InsertStreamOfSyncPackets(InitialDelayManager::SyncStream* sync_stream); - int id_; + scoped_ptr crit_sect_; + int id_; // TODO(henrik.lundin) Make const. + int last_audio_decoder_ GUARDED_BY(crit_sect_); + AudioFrame::VADActivity previous_audio_activity_ GUARDED_BY(crit_sect_); + int current_sample_rate_hz_ GUARDED_BY(crit_sect_); + ACMResampler resampler_ GUARDED_BY(crit_sect_); + // Used in GetAudio, declared as member to avoid allocating every 10ms. + // TODO(henrik.lundin) Stack-allocate in GetAudio instead? + int16_t audio_buffer_[AudioFrame::kMaxDataSizeSamples] GUARDED_BY(crit_sect_); + scoped_ptr nack_ GUARDED_BY(crit_sect_); + bool nack_enabled_ GUARDED_BY(crit_sect_); + CallStatistics call_stats_ GUARDED_BY(crit_sect_); NetEq* neteq_; Decoder decoders_[ACMCodecDB::kMaxNumCodecs]; - int last_audio_decoder_; RWLockWrapper* decode_lock_; - CriticalSectionWrapper* neteq_crit_sect_; bool vad_enabled_; - AudioFrame::VADActivity previous_audio_activity_; - int current_sample_rate_hz_; - ACMResampler resampler_; - // Used in GetAudio, declared as member to avoid allocating every 10ms. - int16_t audio_buffer_[AudioFrame::kMaxDataSizeSamples]; - scoped_ptr nack_; - bool nack_enabled_; - Clock* clock_; + Clock* clock_; // TODO(henrik.lundin) Make const if possible. // Indicates if a non-zero initial delay is set, and the receiver is in // AV-sync mode. @@ -366,8 +370,6 @@ class AcmReceiver { // initial delay is set. scoped_ptr missing_packets_sync_stream_; scoped_ptr late_packets_sync_stream_; - - CallStatistics call_stats_; }; } // namespace acm2