Bug 1456115 - Stop locking when getting the sampling rate from the channel in acm_receiver.cc. r=dminor
☠☠ backed out by d1e4fdc34670 ☠ ☠
authorPaul Adenot <paul@paul.cx>
Mon, 09 Apr 2018 13:52:08 +0200
changeset 471497 bffecfd92808acbf5f3ab2d16482ac8f020c5892
parent 471496 bb4f5395f6dcb81d7073b71e07faa30a594ea064
child 471498 e48268ffa4d8c92fa5f740929625bde722c78b65
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdminor
bugs1456115
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
media/webrtc/trunk/webrtc/modules/audio_coding/acm2/acm_receiver.cc
media/webrtc/trunk/webrtc/modules/audio_coding/acm2/acm_receiver.h
media/webrtc/trunk/webrtc/modules/audio_coding/acm2/audio_coding_module.cc
media/webrtc/trunk/webrtc/modules/audio_coding/include/audio_coding_module.h
media/webrtc/trunk/webrtc/voice_engine/channel.cc
--- 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;
   }