Bug 1456115 - Stop locking when getting the sampling rate from the channel in acm_receiver.cc. r?dminor
This accounts for half of our audio dropouts, there is very high contention on
this piece of data.
MozReview-Commit-ID: 2HSfqZHT2MK
--- a/media/webrtc/trunk/webrtc/modules/audio_coding/acm2/acm_receiver.cc
+++ b/media/webrtc/trunk/webrtc/modules/audio_coding/acm2/acm_receiver.cc
@@ -94,16 +94,17 @@ int AcmReceiver::InsertPacket(const WebR
if (last_audio_decoder_ && last_audio_decoder_->channels > 1) {
// This is a CNG and the audio codec is not mono, so skip pushing in
// packets into NetEq.
return 0;
}
} else {
last_audio_decoder_ = ci;
last_audio_format_ = neteq_->GetDecoderFormat(ci->pltype);
+ last_audio_format_clockrate_hz_ = last_audio_format_->clockrate_hz;
RTC_DCHECK(last_audio_format_);
last_packet_sample_rate_hz_ = rtc::Optional<int>(ci->plfreq);
}
} // |crit_sect_| is released.
if (neteq_->InsertPacket(rtp_header, incoming_payload, receive_timestamp) <
0) {
LOG(LERROR) << "AcmReceiver::InsertPacket "
@@ -300,16 +301,20 @@ int AcmReceiver::LastAudioCodec(CodecIns
return 0;
}
rtc::Optional<SdpAudioFormat> AcmReceiver::LastAudioFormat() const {
rtc::CritScope lock(&crit_sect_);
return last_audio_format_;
}
+int AcmReceiver::LastAudioSampleRate() const {
+ return last_audio_format_clockrate_hz_;
+}
+
void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) {
NetEqNetworkStatistics neteq_stat;
// NetEq function always returns zero, so we don't check the return value.
neteq_->NetworkStatistics(&neteq_stat);
acm_stat->currentBufferSize = neteq_stat.current_buffer_size_ms;
acm_stat->preferredBufferSize = neteq_stat.preferred_buffer_size_ms;
acm_stat->jitterPeaksFound = neteq_stat.jitter_peaks_found ? true : false;
--- a/media/webrtc/trunk/webrtc/modules/audio_coding/acm2/acm_receiver.h
+++ b/media/webrtc/trunk/webrtc/modules/audio_coding/acm2/acm_receiver.h
@@ -10,16 +10,17 @@
#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_
#define WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
+#include <atomic>
#include "webrtc/base/array_view.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/optional.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/common_audio/vad/include/webrtc_vad.h"
#include "webrtc/modules/audio_coding/acm2/acm_resampler.h"
#include "webrtc/modules/audio_coding/acm2/call_statistics.h"
@@ -204,16 +205,17 @@ class AcmReceiver {
//
// Get the audio codec associated with the last non-CNG/non-DTMF received
// payload. If no non-CNG/non-DTMF packet is received -1 is returned,
// otherwise return 0.
//
int LastAudioCodec(CodecInst* codec) const;
rtc::Optional<SdpAudioFormat> LastAudioFormat() const;
+ int LastAudioSampleRate() const;
//
// Get a decoder given its registered payload-type.
//
// Input:
// -payload_type : the payload-type of the codec to be retrieved.
//
// Output:
@@ -277,15 +279,16 @@ class AcmReceiver {
rtc::Optional<SdpAudioFormat> last_audio_format_ GUARDED_BY(crit_sect_);
ACMResampler resampler_ GUARDED_BY(crit_sect_);
std::unique_ptr<int16_t[]> last_audio_buffer_ GUARDED_BY(crit_sect_);
CallStatistics call_stats_ GUARDED_BY(crit_sect_);
NetEq* neteq_;
Clock* clock_; // TODO(henrik.lundin) Make const if possible.
bool resampled_last_output_frame_ GUARDED_BY(crit_sect_);
rtc::Optional<int> last_packet_sample_rate_hz_ GUARDED_BY(crit_sect_);
+ std::atomic<int> last_audio_format_clockrate_hz_;
};
} // namespace acm2
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_
--- a/media/webrtc/trunk/webrtc/modules/audio_coding/acm2/audio_coding_module.cc
+++ b/media/webrtc/trunk/webrtc/modules/audio_coding/acm2/audio_coding_module.cc
@@ -134,16 +134,17 @@ class AudioCodingModuleImpl final : publ
int sample_rate_hz,
int num_channels,
const std::string& name) override;
// Get current received codec.
int ReceiveCodec(CodecInst* current_codec) const override;
rtc::Optional<SdpAudioFormat> ReceiveFormat() const override;
+ int ReceiveSampleRate() const override;
// Incoming packet from network parsed and ready for decode.
int IncomingPacket(const uint8_t* incoming_payload,
const size_t payload_length,
const WebRtcRTPHeader& rtp_info) override;
// Incoming payloads, without rtp-info, the rtp-info will be created in ACM.
// One usage for this API is when pre-encoded files are pushed in ACM.
@@ -1084,16 +1085,20 @@ int AudioCodingModuleImpl::ReceiveCodec(
return receiver_.LastAudioCodec(current_codec);
}
rtc::Optional<SdpAudioFormat> AudioCodingModuleImpl::ReceiveFormat() const {
rtc::CritScope lock(&acm_crit_sect_);
return receiver_.LastAudioFormat();
}
+int AudioCodingModuleImpl::ReceiveSampleRate() const {
+ return receiver_.LastAudioSampleRate();
+}
+
// Incoming packet from network parsed and ready for decode.
int AudioCodingModuleImpl::IncomingPacket(const uint8_t* incoming_payload,
const size_t payload_length,
const WebRtcRTPHeader& rtp_header) {
return receiver_.InsertPacket(
rtp_header,
rtc::ArrayView<const uint8_t>(incoming_payload, payload_length));
}
--- a/media/webrtc/trunk/webrtc/modules/audio_coding/include/audio_coding_module.h
+++ b/media/webrtc/trunk/webrtc/modules/audio_coding/include/audio_coding_module.h
@@ -559,16 +559,27 @@ class AudioCodingModule {
// Return value:
// An SdpAudioFormat describing the format associated with the last
// received payload.
// An empty Optional if no payload has yet been received.
//
virtual rtc::Optional<SdpAudioFormat> ReceiveFormat() const = 0;
///////////////////////////////////////////////////////////////////////////
+ // int ReceiveSampleRate()
+ //
+ // Mozilla extension.
+ // Return the sample-rate of the inbound audio stream.
+ //
+ // Return value:
+ // 0 if no audio has been received, the sample-rate of the inbound audio
+ // otherwise.
+ virtual int ReceiveSampleRate() const = 0;
+
+ ///////////////////////////////////////////////////////////////////////////
// int32_t IncomingPacket()
// Call this function to insert a parsed RTP packet into ACM.
//
// Inputs:
// -incoming_payload : received payload.
// -payload_len_bytes : the length of payload in bytes.
// -rtp_info : the relevant information retrieved from RTP
// header.
--- a/media/webrtc/trunk/webrtc/voice_engine/channel.cc
+++ b/media/webrtc/trunk/webrtc/voice_engine/channel.cc
@@ -3490,23 +3490,22 @@ int Channel::SetSendRtpHeaderExtension(b
_rtpRtcpModule->DeregisterSendRtpHeaderExtension(type);
if (enable) {
error = _rtpRtcpModule->RegisterSendRtpHeaderExtension(type, id);
}
return error;
}
int Channel::GetRtpTimestampRateHz() const {
- const auto format = audio_coding_->ReceiveFormat();
+ int sampleRate = audio_coding_->ReceiveSampleRate();
// Default to the playout frequency if we've not gotten any packets yet.
// TODO(ossu): Zero clockrate can only happen if we've added an external
// decoder for a format we don't support internally. Remove once that way of
// adding decoders is gone!
- return (format && format->clockrate_hz != 0)
- ? format->clockrate_hz
+ return sampleRate != 0 ? sampleRate
: audio_coding_->PlayoutFrequency();
}
int64_t Channel::GetRTT(bool allow_associate_channel) const {
RtcpMode method = _rtpRtcpModule->RTCP();
if (method == RtcpMode::kOff) {
return 0;
}