Revert r8476 "Set decoder output frequency in AudioDecoder::Decode call"

This change uncovered issue 4143, evading the Memcheck suppression
since the signature is changed in the Decode function.

A fix for this is in the making; see
https://review.webrtc.org/36309004. This CL will be re-landed once the
fix is in place.

BUG=4143
TBR=kwiberg@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/42089004

Cr-Commit-Position: refs/heads/master@{#8488}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8488 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/codecs/audio_decoder.cc b/webrtc/modules/audio_coding/codecs/audio_decoder.cc
index 0817873..bc6b9c5 100644
--- a/webrtc/modules/audio_coding/codecs/audio_decoder.cc
+++ b/webrtc/modules/audio_coding/codecs/audio_decoder.cc
@@ -18,10 +18,9 @@
 
 int AudioDecoder::DecodeRedundant(const uint8_t* encoded,
                                   size_t encoded_len,
-                                  int sample_rate_hz,
                                   int16_t* decoded,
                                   SpeechType* speech_type) {
-  return Decode(encoded, encoded_len, sample_rate_hz, decoded, speech_type);
+  return Decode(encoded, encoded_len, decoded, speech_type);
 }
 
 bool AudioDecoder::HasDecodePlc() const { return false; }
diff --git a/webrtc/modules/audio_coding/codecs/audio_decoder.h b/webrtc/modules/audio_coding/codecs/audio_decoder.h
index 8c83e61..30fdc44 100644
--- a/webrtc/modules/audio_coding/codecs/audio_decoder.h
+++ b/webrtc/modules/audio_coding/codecs/audio_decoder.h
@@ -37,22 +37,14 @@
   // Decodes |encode_len| bytes from |encoded| and writes the result in
   // |decoded|. The number of samples from all channels produced is in
   // the return value. If the decoder produced comfort noise, |speech_type|
-  // is set to kComfortNoise, otherwise it is kSpeech. The desired output
-  // sample rate is provided in |sample_rate_hz|, which must be valid for the
-  // codec at hand.
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int sample_rate_hz,
-                     int16_t* decoded,
-                     SpeechType* speech_type) = 0;
+  // is set to kComfortNoise, otherwise it is kSpeech.
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type) = 0;
 
   // Same as Decode(), but interfaces to the decoders redundant decode function.
   // The default implementation simply calls the regular Decode() method.
-  virtual int DecodeRedundant(const uint8_t* encoded,
-                              size_t encoded_len,
-                              int sample_rate_hz,
-                              int16_t* decoded,
-                              SpeechType* speech_type);
+  virtual int DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
+                              int16_t* decoded, SpeechType* speech_type);
 
   // Indicates if the decoder implements the DecodePlc method.
   virtual bool HasDecodePlc() const;
diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
index 668f491..994d21b 100644
--- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
+++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
@@ -66,6 +66,8 @@
   explicit AudioEncoderDecoderIsacT(const ConfigAdaptive& config);
   virtual ~AudioEncoderDecoderIsacT() OVERRIDE;
 
+  void UpdateDecoderSampleRate(int sample_rate_hz);
+
   // AudioEncoder public methods.
   virtual int SampleRateHz() const OVERRIDE;
   virtual int NumChannels() const OVERRIDE;
@@ -75,12 +77,10 @@
   // AudioDecoder methods.
   virtual int Decode(const uint8_t* encoded,
                      size_t encoded_len,
-                     int sample_rate_hz,
                      int16_t* decoded,
                      SpeechType* speech_type) OVERRIDE;
   virtual int DecodeRedundant(const uint8_t* encoded,
                               size_t encoded_len,
-                              int sample_rate_hz,
                               int16_t* decoded,
                               SpeechType* speech_type) OVERRIDE;
   virtual bool HasDecodePlc() const OVERRIDE;
@@ -116,8 +116,6 @@
   typename T::instance_type* isac_state_
       GUARDED_BY(state_lock_) /* PT_GUARDED_BY(lock_)*/;
 
-  int decoder_sample_rate_hz_ GUARDED_BY(state_lock_);
-
   // Must be acquired before state_lock_.
   const scoped_ptr<CriticalSectionWrapper> lock_;
 
diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
index d9cec82..095bb7b 100644
--- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
+++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
@@ -109,7 +109,6 @@
     : payload_type_(config.payload_type),
       red_payload_type_(config.red_payload_type),
       state_lock_(CriticalSectionWrapper::CreateCriticalSection()),
-      decoder_sample_rate_hz_(0),
       lock_(CriticalSectionWrapper::CreateCriticalSection()),
       packet_in_progress_(false),
       redundant_length_bytes_(0) {
@@ -137,7 +136,6 @@
     : payload_type_(config.payload_type),
       red_payload_type_(config.red_payload_type),
       state_lock_(CriticalSectionWrapper::CreateCriticalSection()),
-      decoder_sample_rate_hz_(0),
       lock_(CriticalSectionWrapper::CreateCriticalSection()),
       packet_in_progress_(false),
       redundant_length_bytes_(0) {
@@ -162,6 +160,12 @@
 }
 
 template <typename T>
+void AudioEncoderDecoderIsacT<T>::UpdateDecoderSampleRate(int sample_rate_hz) {
+  CriticalSectionScoped cs(state_lock_.get());
+  CHECK_EQ(0, T::SetDecSampRate(isac_state_, sample_rate_hz));
+}
+
+template <typename T>
 int AudioEncoderDecoderIsacT<T>::SampleRateHz() const {
   CriticalSectionScoped cs(state_lock_.get());
   return T::EncSampRate(isac_state_);
@@ -266,16 +270,9 @@
 template <typename T>
 int AudioEncoderDecoderIsacT<T>::Decode(const uint8_t* encoded,
                                         size_t encoded_len,
-                                        int sample_rate_hz,
                                         int16_t* decoded,
                                         SpeechType* speech_type) {
   CriticalSectionScoped cs(state_lock_.get());
-  CHECK(sample_rate_hz == 16000 || sample_rate_hz == 32000)
-      << "Unsupported sample rate " << sample_rate_hz;
-  if (sample_rate_hz != decoder_sample_rate_hz_) {
-    CHECK_EQ(0, T::SetDecSampRate(isac_state_, sample_rate_hz));
-    decoder_sample_rate_hz_ = sample_rate_hz;
-  }
   int16_t temp_type = 1;  // Default is speech.
   int16_t ret =
       T::Decode(isac_state_, encoded, static_cast<int16_t>(encoded_len),
@@ -287,7 +284,6 @@
 template <typename T>
 int AudioEncoderDecoderIsacT<T>::DecodeRedundant(const uint8_t* encoded,
                                                  size_t encoded_len,
-                                                 int /*sample_rate_hz*/,
                                                  int16_t* decoded,
                                                  SpeechType* speech_type) {
   CriticalSectionScoped cs(state_lock_.get());
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc
index 71df8a3..1a0e483 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc
+++ b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc
@@ -158,22 +158,18 @@
 
 int AudioDecoderProxy::Decode(const uint8_t* encoded,
                               size_t encoded_len,
-                              int sample_rate_hz,
                               int16_t* decoded,
                               SpeechType* speech_type) {
   CriticalSectionScoped decoder_lock(decoder_lock_.get());
-  return decoder_->Decode(encoded, encoded_len, sample_rate_hz, decoded,
-                          speech_type);
+  return decoder_->Decode(encoded, encoded_len, decoded, speech_type);
 }
 
 int AudioDecoderProxy::DecodeRedundant(const uint8_t* encoded,
                                        size_t encoded_len,
-                                       int sample_rate_hz,
                                        int16_t* decoded,
                                        SpeechType* speech_type) {
   CriticalSectionScoped decoder_lock(decoder_lock_.get());
-  return decoder_->DecodeRedundant(encoded, encoded_len, sample_rate_hz,
-                                   decoded, speech_type);
+  return decoder_->DecodeRedundant(encoded, encoded_len, decoded, speech_type);
 }
 
 bool AudioDecoderProxy::HasDecodePlc() const {
@@ -553,6 +549,28 @@
   ResetAudioEncoder();
 }
 
+int16_t ACMGenericCodec::UpdateDecoderSampFreq(int16_t codec_id) {
+#ifdef WEBRTC_CODEC_ISAC
+  WriteLockScoped wl(codec_wrapper_lock_);
+  if (is_isac_) {
+    switch (codec_id) {
+      case ACMCodecDB::kISAC:
+        static_cast<AudioEncoderDecoderIsac*>(audio_encoder_.get())
+            ->UpdateDecoderSampleRate(16000);
+        return 0;
+      case ACMCodecDB::kISACSWB:
+      case ACMCodecDB::kISACFB:
+        static_cast<AudioEncoderDecoderIsac*>(audio_encoder_.get())
+            ->UpdateDecoderSampleRate(32000);
+        return 0;
+      default:
+        FATAL() << "Unexpected codec id.";
+    }
+  }
+#endif
+  return 0;
+}
+
 int32_t ACMGenericCodec::SetISACMaxPayloadSize(
     const uint16_t max_payload_len_bytes) {
   WriteLockScoped wl(codec_wrapper_lock_);
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h
index fd3fbab..933306d 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h
+++ b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h
@@ -48,12 +48,10 @@
   bool IsSet() const;
   int Decode(const uint8_t* encoded,
              size_t encoded_len,
-             int sample_rate_hz,
              int16_t* decoded,
              SpeechType* speech_type) override;
   int DecodeRedundant(const uint8_t* encoded,
                       size_t encoded_len,
-                      int sample_rate_hz,
                       int16_t* decoded,
                       SpeechType* speech_type) override;
   bool HasDecodePlc() const override;
@@ -296,6 +294,33 @@
   void SetCngPt(int sample_rate_hz, int payload_type);
 
   ///////////////////////////////////////////////////////////////////////////
+  // UpdateDecoderSampFreq()
+  // For most of the codecs this function does nothing. It must be
+  // implemented for those codecs that one codec instance serves as the
+  // decoder for different flavors of the codec. One example is iSAC. there,
+  // iSAC 16 kHz and iSAC 32 kHz are treated as two different codecs with
+  // different payload types, however, there is only one iSAC instance to
+  // decode. The reason for that is we would like to decode and encode with
+  // the same codec instance for bandwidth estimator to work.
+  //
+  // Each time that we receive a new payload type, we call this function to
+  // prepare the decoder associated with the new payload. Normally, decoders
+  // doesn't have to do anything. For iSAC the decoder has to change it's
+  // sampling rate. The input parameter specifies the current flavor of the
+  // codec in codec database. For instance, if we just got a SWB payload then
+  // the input parameter is ACMCodecDB::isacswb.
+  //
+  // Input:
+  //   -codec_id           : the ID of the codec associated with the
+  //                         payload type that we just received.
+  //
+  // Return value:
+  //    0 if succeeded in updating the decoder.
+  //   -1 if failed to update.
+  //
+  int16_t UpdateDecoderSampFreq(int16_t /* codec_id */);
+
+  ///////////////////////////////////////////////////////////////////////////
   // UpdateEncoderSampFreq()
   // Call this function to update the encoder sampling frequency. This
   // is for codecs where one payload-name supports several encoder sampling
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc
index 5041eb7..7acb45a 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc
+++ b/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc
@@ -609,6 +609,14 @@
   return last_audio_decoder_;
 }
 
+int AcmReceiver::last_audio_payload_type() const {
+  CriticalSectionScoped lock(crit_sect_.get());
+  if (last_audio_decoder_ < 0)
+    return -1;
+  assert(decoders_[last_audio_decoder_].registered);
+  return decoders_[last_audio_decoder_].payload_type;
+}
+
 int AcmReceiver::RedPayloadType() const {
   CriticalSectionScoped lock(crit_sect_.get());
   if (ACMCodecDB::kRED < 0 ||
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver.h b/webrtc/modules/audio_coding/main/acm2/acm_receiver.h
index 43f304a..f3ef16f 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_receiver.h
+++ b/webrtc/modules/audio_coding/main/acm2/acm_receiver.h
@@ -248,6 +248,12 @@
   int last_audio_codec_id() const;  // TODO(turajs): can be inline.
 
   //
+  // Return the payload-type of the last non-CNG/non-DTMF RTP packet. If no
+  // non-CNG/non-DTMF packet is received -1 is returned.
+  //
+  int last_audio_payload_type() const;  // TODO(turajs): can be inline.
+
+  //
   // 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.
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc
index 6b15718..273bb5a 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc
+++ b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc
@@ -321,6 +321,7 @@
   // Has received, only, DTX. Last Audio codec is undefined.
   EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
   EXPECT_EQ(-1, receiver_->last_audio_codec_id());
+  EXPECT_EQ(-1, receiver_->last_audio_payload_type());
 
   n = 0;
   while (kCodecId[n] >= 0) {  // Loop over codecs.
@@ -346,6 +347,8 @@
       ASSERT_TRUE(packet_sent_);
     }
     EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id());
+    EXPECT_EQ(codecs_[kCodecId[n]].pltype,
+              receiver_->last_audio_payload_type());
     EXPECT_EQ(0, receiver_->LastAudioCodec(&codec));
     EXPECT_TRUE(CodecsEqual(codecs_[kCodecId[n]], codec));
     ++n;
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc
index d57d511..5b2c3cb 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc
+++ b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc
@@ -325,6 +325,7 @@
   // Has received, only, DTX. Last Audio codec is undefined.
   EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
   EXPECT_EQ(-1, receiver_->last_audio_codec_id());
+  EXPECT_EQ(-1, receiver_->last_audio_payload_type());
 
   n = 0;
   while (kCodecId[n] >= 0) {  // Loop over codecs.
@@ -350,6 +351,8 @@
       ASSERT_TRUE(packet_sent_);
     }
     EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id());
+    EXPECT_EQ(codecs_[kCodecId[n]].pltype,
+              receiver_->last_audio_payload_type());
     EXPECT_EQ(0, receiver_->LastAudioCodec(&codec));
     EXPECT_TRUE(CodecsEqual(codecs_[kCodecId[n]], codec));
     ++n;
diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
index bf9bb01..41e8d4d 100644
--- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
+++ b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
@@ -1185,7 +1185,24 @@
 int AudioCodingModuleImpl::IncomingPacket(const uint8_t* incoming_payload,
                                           const size_t payload_length,
                                           const WebRtcRTPHeader& rtp_header) {
-  return receiver_.InsertPacket(rtp_header, incoming_payload, payload_length);
+  int last_audio_pltype = receiver_.last_audio_payload_type();
+  if (receiver_.InsertPacket(rtp_header, incoming_payload, payload_length) <
+      0) {
+    return -1;
+  }
+  if (receiver_.last_audio_payload_type() != last_audio_pltype) {
+    int index = receiver_.last_audio_codec_id();
+    assert(index >= 0);
+    CriticalSectionScoped lock(acm_crit_sect_);
+
+    // |codec_[index]| might not be even created, simply because it is not
+    // yet registered as send codec. Even if it is registered, unless the
+    // codec shares same instance for encoder and decoder, this call is
+    // useless.
+    if (codecs_[index] != NULL)
+      codecs_[index]->UpdateDecoderSampFreq(index);
+  }
+  return 0;
 }
 
 // Minimum playout delay (Used for lip-sync).
diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc
index f77dead..43ba241 100644
--- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc
+++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc
@@ -38,12 +38,8 @@
 namespace webrtc {
 
 // PCMu
-int AudioDecoderPcmU::Decode(const uint8_t* encoded,
-                             size_t encoded_len,
-                             int sample_rate_hz,
-                             int16_t* decoded,
-                             SpeechType* speech_type) {
-  DCHECK_EQ(sample_rate_hz, 8000);
+int AudioDecoderPcmU::Decode(const uint8_t* encoded, size_t encoded_len,
+                              int16_t* decoded, SpeechType* speech_type) {
   int16_t temp_type = 1;  // Default is speech.
   int16_t ret = WebRtcG711_DecodeU(encoded, static_cast<int16_t>(encoded_len),
                                    decoded, &temp_type);
@@ -58,12 +54,8 @@
 }
 
 // PCMa
-int AudioDecoderPcmA::Decode(const uint8_t* encoded,
-                             size_t encoded_len,
-                             int sample_rate_hz,
-                             int16_t* decoded,
-                             SpeechType* speech_type) {
-  DCHECK_EQ(sample_rate_hz, 8000);
+int AudioDecoderPcmA::Decode(const uint8_t* encoded, size_t encoded_len,
+                              int16_t* decoded, SpeechType* speech_type) {
   int16_t temp_type = 1;  // Default is speech.
   int16_t ret = WebRtcG711_DecodeA(encoded, static_cast<int16_t>(encoded_len),
                                    decoded, &temp_type);
@@ -81,14 +73,8 @@
 #ifdef WEBRTC_CODEC_PCM16
 AudioDecoderPcm16B::AudioDecoderPcm16B() {}
 
-int AudioDecoderPcm16B::Decode(const uint8_t* encoded,
-                               size_t encoded_len,
-                               int sample_rate_hz,
-                               int16_t* decoded,
-                               SpeechType* speech_type) {
-  DCHECK(sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
-         sample_rate_hz == 32000 || sample_rate_hz == 48000)
-      << "Unsupported sample rate " << sample_rate_hz;
+int AudioDecoderPcm16B::Decode(const uint8_t* encoded, size_t encoded_len,
+                               int16_t* decoded, SpeechType* speech_type) {
   int16_t ret =
       WebRtcPcm16b_Decode(encoded, static_cast<int16_t>(encoded_len), decoded);
   *speech_type = ConvertSpeechType(1);
@@ -117,12 +103,8 @@
   WebRtcIlbcfix_DecoderFree(dec_state_);
 }
 
-int AudioDecoderIlbc::Decode(const uint8_t* encoded,
-                             size_t encoded_len,
-                             int sample_rate_hz,
-                             int16_t* decoded,
-                             SpeechType* speech_type) {
-  DCHECK_EQ(sample_rate_hz, 8000);
+int AudioDecoderIlbc::Decode(const uint8_t* encoded, size_t encoded_len,
+                             int16_t* decoded, SpeechType* speech_type) {
   int16_t temp_type = 1;  // Default is speech.
   int16_t ret = WebRtcIlbcfix_Decode(dec_state_, encoded,
                                      static_cast<int16_t>(encoded_len), decoded,
@@ -150,12 +132,8 @@
   WebRtcG722_FreeDecoder(dec_state_);
 }
 
-int AudioDecoderG722::Decode(const uint8_t* encoded,
-                             size_t encoded_len,
-                             int sample_rate_hz,
-                             int16_t* decoded,
-                             SpeechType* speech_type) {
-  DCHECK_EQ(sample_rate_hz, 16000);
+int AudioDecoderG722::Decode(const uint8_t* encoded, size_t encoded_len,
+                             int16_t* decoded, SpeechType* speech_type) {
   int16_t temp_type = 1;  // Default is speech.
   int16_t ret =
       WebRtcG722_Decode(dec_state_, encoded, static_cast<int16_t>(encoded_len),
@@ -185,12 +163,8 @@
   WebRtcG722_FreeDecoder(dec_state_right_);
 }
 
-int AudioDecoderG722Stereo::Decode(const uint8_t* encoded,
-                                   size_t encoded_len,
-                                   int sample_rate_hz,
-                                   int16_t* decoded,
-                                   SpeechType* speech_type) {
-  DCHECK_EQ(sample_rate_hz, 16000);
+int AudioDecoderG722Stereo::Decode(const uint8_t* encoded, size_t encoded_len,
+                                   int16_t* decoded, SpeechType* speech_type) {
   int16_t temp_type = 1;  // Default is speech.
   // De-interleave the bit-stream into two separate payloads.
   uint8_t* encoded_deinterleaved = new uint8_t[encoded_len];
@@ -270,12 +244,8 @@
   WebRtcOpus_DecoderFree(dec_state_);
 }
 
-int AudioDecoderOpus::Decode(const uint8_t* encoded,
-                             size_t encoded_len,
-                             int sample_rate_hz,
-                             int16_t* decoded,
-                             SpeechType* speech_type) {
-  DCHECK_EQ(sample_rate_hz, 48000);
+int AudioDecoderOpus::Decode(const uint8_t* encoded, size_t encoded_len,
+                             int16_t* decoded, SpeechType* speech_type) {
   int16_t temp_type = 1;  // Default is speech.
   int16_t ret = WebRtcOpus_Decode(dec_state_, encoded,
                                   static_cast<int16_t>(encoded_len), decoded,
@@ -287,13 +257,11 @@
 }
 
 int AudioDecoderOpus::DecodeRedundant(const uint8_t* encoded,
-                                      size_t encoded_len,
-                                      int sample_rate_hz,
-                                      int16_t* decoded,
+                                      size_t encoded_len, int16_t* decoded,
                                       SpeechType* speech_type) {
   if (!PacketHasFec(encoded, encoded_len)) {
     // This packet is a RED packet.
-    return Decode(encoded, encoded_len, sample_rate_hz, decoded, speech_type);
+    return Decode(encoded, encoded_len, decoded, speech_type);
   }
 
   int16_t temp_type = 1;  // Default is speech.
diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h
index 7d36a39..57bd522 100644
--- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h
+++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h
@@ -37,11 +37,8 @@
 class AudioDecoderPcmU : public AudioDecoder {
  public:
   AudioDecoderPcmU() {}
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int sample_rate_hz,
-                     int16_t* decoded,
-                     SpeechType* speech_type);
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type);
   virtual int Init() { return 0; }
   virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
 
@@ -52,11 +49,8 @@
 class AudioDecoderPcmA : public AudioDecoder {
  public:
   AudioDecoderPcmA() {}
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int sample_rate_hz,
-                     int16_t* decoded,
-                     SpeechType* speech_type);
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type);
   virtual int Init() { return 0; }
   virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
 
@@ -92,11 +86,8 @@
 class AudioDecoderPcm16B : public AudioDecoder {
  public:
   AudioDecoderPcm16B();
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int sample_rate_hz,
-                     int16_t* decoded,
-                     SpeechType* speech_type);
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type);
   virtual int Init() { return 0; }
   virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
 
@@ -121,11 +112,8 @@
  public:
   AudioDecoderIlbc();
   virtual ~AudioDecoderIlbc();
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int sample_rate_hz,
-                     int16_t* decoded,
-                     SpeechType* speech_type);
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type);
   virtual bool HasDecodePlc() const { return true; }
   virtual int DecodePlc(int num_frames, int16_t* decoded);
   virtual int Init();
@@ -141,11 +129,8 @@
  public:
   AudioDecoderG722();
   virtual ~AudioDecoderG722();
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int sample_rate_hz,
-                     int16_t* decoded,
-                     SpeechType* speech_type);
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type);
   virtual bool HasDecodePlc() const { return false; }
   virtual int Init();
   virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
@@ -159,11 +144,8 @@
  public:
   AudioDecoderG722Stereo();
   virtual ~AudioDecoderG722Stereo();
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int sample_rate_hz,
-                     int16_t* decoded,
-                     SpeechType* speech_type);
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type);
   virtual int Init();
 
  private:
@@ -187,16 +169,10 @@
  public:
   explicit AudioDecoderOpus(int num_channels);
   virtual ~AudioDecoderOpus();
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int sample_rate_hz,
-                     int16_t* decoded,
-                     SpeechType* speech_type);
-  virtual int DecodeRedundant(const uint8_t* encoded,
-                              size_t encoded_len,
-                              int sample_rate_hz,
-                              int16_t* decoded,
-                              SpeechType* speech_type);
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type);
+  virtual int DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
+                              int16_t* decoded, SpeechType* speech_type);
   virtual int Init();
   virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
   virtual int PacketDurationRedundant(const uint8_t* encoded,
@@ -219,13 +195,8 @@
  public:
   explicit AudioDecoderCng();
   virtual ~AudioDecoderCng();
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int /*sample_rate_hz*/,
-                     int16_t* decoded,
-                     SpeechType* speech_type) {
-    return -1;
-  }
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type) { return -1; }
   virtual int Init();
   virtual int IncomingPacket(const uint8_t* payload,
                              size_t payload_len,
diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc
index 1f0e881..95805d3 100644
--- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc
@@ -186,9 +186,10 @@
       // Make sure that frame_size_ * channels_ samples are allocated and free.
       decoded.resize((processed_samples + frame_size_) * channels_, 0);
       AudioDecoder::SpeechType speech_type;
-      size_t dec_len = decoder_->Decode(
-          &encoded_[encoded_bytes_], enc_len, codec_input_rate_hz_,
-          &decoded[processed_samples * channels_], &speech_type);
+      size_t dec_len = decoder_->Decode(&encoded_[encoded_bytes_],
+                                        enc_len,
+                                        &decoded[processed_samples * channels_],
+                                        &speech_type);
       EXPECT_EQ(frame_size_ * channels_, dec_len);
       encoded_bytes_ += enc_len;
       processed_samples += frame_size_;
@@ -221,15 +222,13 @@
     AudioDecoder::SpeechType speech_type1, speech_type2;
     EXPECT_EQ(0, decoder_->Init());
     scoped_ptr<int16_t[]> output1(new int16_t[frame_size_ * channels_]);
-    dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
-                               output1.get(), &speech_type1);
+    dec_len = decoder_->Decode(encoded_, enc_len, output1.get(), &speech_type1);
     ASSERT_LE(dec_len, frame_size_ * channels_);
     EXPECT_EQ(frame_size_ * channels_, dec_len);
     // Re-init decoder and decode again.
     EXPECT_EQ(0, decoder_->Init());
     scoped_ptr<int16_t[]> output2(new int16_t[frame_size_ * channels_]);
-    dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
-                               output2.get(), &speech_type2);
+    dec_len = decoder_->Decode(encoded_, enc_len, output2.get(), &speech_type2);
     ASSERT_LE(dec_len, frame_size_ * channels_);
     EXPECT_EQ(frame_size_ * channels_, dec_len);
     for (unsigned int n = 0; n < frame_size_; ++n) {
@@ -248,8 +247,8 @@
     AudioDecoder::SpeechType speech_type;
     EXPECT_EQ(0, decoder_->Init());
     scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
-    size_t dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
-                                      output.get(), &speech_type);
+    size_t dec_len =
+        decoder_->Decode(encoded_, enc_len, output.get(), &speech_type);
     EXPECT_EQ(frame_size_ * channels_, dec_len);
     // Call DecodePlc and verify that we get one frame of data.
     // (Overwrite the output from the above Decode call, but that does not
@@ -339,8 +338,8 @@
     AudioDecoder::SpeechType speech_type;
     EXPECT_EQ(0, decoder_->Init());
     scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
-    size_t dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
-                                      output.get(), &speech_type);
+    size_t dec_len =
+        decoder_->Decode(encoded_, enc_len, output.get(), &speech_type);
     EXPECT_EQ(frame_size_, dec_len);
     // Simply call DecodePlc and verify that we get 0 as return value.
     EXPECT_EQ(0, decoder_->DecodePlc(1, output.get()));
diff --git a/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h b/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h
index 7288f11..503e46f 100644
--- a/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h
+++ b/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h
@@ -22,9 +22,8 @@
   MockAudioDecoder() {}
   virtual ~MockAudioDecoder() { Die(); }
   MOCK_METHOD0(Die, void());
-  MOCK_METHOD5(
-      Decode,
-      int(const uint8_t*, size_t, int, int16_t*, AudioDecoder::SpeechType*));
+  MOCK_METHOD4(Decode, int(const uint8_t*, size_t, int16_t*,
+                           AudioDecoder::SpeechType*));
   MOCK_CONST_METHOD0(HasDecodePlc, bool());
   MOCK_METHOD2(DecodePlc, int(int, int16_t*));
   MOCK_METHOD0(Init, int());
diff --git a/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h b/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
index 22d2816..19f069a 100644
--- a/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
+++ b/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
@@ -29,11 +29,8 @@
  public:
   ExternalPcm16B() {}
 
-  virtual int Decode(const uint8_t* encoded,
-                     size_t encoded_len,
-                     int sample_rate_hz,
-                     int16_t* decoded,
-                     SpeechType* speech_type) {
+  virtual int Decode(const uint8_t* encoded, size_t encoded_len,
+                     int16_t* decoded, SpeechType* speech_type) {
     int16_t ret = WebRtcPcm16b_Decode(
         encoded, static_cast<int16_t>(encoded_len), decoded);
     *speech_type = ConvertSpeechType(1);
@@ -52,7 +49,7 @@
  public:
   MockExternalPcm16B() {
     // By default, all calls are delegated to the real object.
-    ON_CALL(*this, Decode(_, _, _, _, _))
+    ON_CALL(*this, Decode(_, _, _, _))
         .WillByDefault(Invoke(&real_, &ExternalPcm16B::Decode));
     ON_CALL(*this, HasDecodePlc())
         .WillByDefault(Invoke(&real_, &ExternalPcm16B::HasDecodePlc));
@@ -68,12 +65,9 @@
   virtual ~MockExternalPcm16B() { Die(); }
 
   MOCK_METHOD0(Die, void());
-  MOCK_METHOD5(Decode,
-               int(const uint8_t* encoded,
-                   size_t encoded_len,
-                   int sample_rate_hz,
-                   int16_t* decoded,
-                   SpeechType* speech_type));
+  MOCK_METHOD4(Decode,
+      int(const uint8_t* encoded, size_t encoded_len, int16_t* decoded,
+          SpeechType* speech_type));
   MOCK_CONST_METHOD0(HasDecodePlc,
       bool());
   MOCK_METHOD2(DecodePlc,
diff --git a/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc
index 0449044..a3dd271 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc
@@ -100,8 +100,7 @@
       next_arrival_time = GetArrivalTime(next_send_time);
     } while (Lost());  // If lost, immediately read the next packet.
 
-    EXPECT_CALL(*external_decoder_,
-                Decode(_, payload_size_bytes_, 1000 * samples_per_ms_, _, _))
+    EXPECT_CALL(*external_decoder_, Decode(_, payload_size_bytes_, _, _))
         .Times(NumExpectedDecodeCalls(num_loops));
 
     uint32_t time_now = 0;
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
index 7370825..f1a3a90 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
@@ -1266,7 +1266,7 @@
           ", ssrc=" << packet->header.ssrc <<
           ", len=" << packet->payload_length;
       decode_length = decoder->DecodeRedundant(
-          packet->payload, packet->payload_length, fs_hz_,
+          packet->payload, packet->payload_length,
           &decoded_buffer_[*decoded_length], speech_type);
     } else {
       LOG(LS_VERBOSE) << "Decoding packet: ts=" << packet->header.timestamp <<
@@ -1274,9 +1274,10 @@
           ", pt=" << static_cast<int>(packet->header.payloadType) <<
           ", ssrc=" << packet->header.ssrc <<
           ", len=" << packet->payload_length;
-      decode_length =
-          decoder->Decode(packet->payload, packet->payload_length, fs_hz_,
-                          &decoded_buffer_[*decoded_length], speech_type);
+      decode_length = decoder->Decode(packet->payload,
+                                      packet->payload_length,
+                                      &decoded_buffer_[*decoded_length],
+                                      speech_type);
     }
 
     delete[] packet->payload;
@@ -1606,8 +1607,7 @@
   if (decoder) {
     const uint8_t* dummy_payload = NULL;
     AudioDecoder::SpeechType speech_type;
-    length =
-        decoder->Decode(dummy_payload, 0, fs_hz_, decoded_buffer, &speech_type);
+    length = decoder->Decode(dummy_payload, 0, decoded_buffer, &speech_type);
   }
   assert(mute_factor_array_.get());
   normal_->Process(decoded_buffer, length, last_mode_, mute_factor_array_.get(),
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
index 54b393b..36ed35a 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
@@ -430,7 +430,6 @@
     // Produce as many samples as input bytes (|encoded_len|).
     virtual int Decode(const uint8_t* encoded,
                        size_t encoded_len,
-                       int /*sample_rate_hz*/,
                        int16_t* decoded,
                        SpeechType* speech_type) {
       for (size_t i = 0; i < encoded_len; ++i) {
@@ -522,11 +521,10 @@
   int16_t dummy_output[kPayloadLengthSamples] = {0};
   // The below expectation will make the mock decoder write
   // |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
-  EXPECT_CALL(mock_decoder,
-              Decode(Pointee(0), kPayloadLengthBytes, kSampleRateHz, _, _))
-      .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
+  EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes, _, _))
+      .WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
                                           dummy_output + kPayloadLengthSamples),
-                      SetArgPointee<4>(AudioDecoder::kSpeech),
+                      SetArgPointee<3>(AudioDecoder::kSpeech),
                       Return(kPayloadLengthSamples)));
   EXPECT_EQ(NetEq::kOK,
             neteq_->RegisterExternalDecoder(
@@ -568,11 +566,10 @@
 
   // Expect only the second packet to be decoded (the one with "2" as the first
   // payload byte).
-  EXPECT_CALL(mock_decoder,
-              Decode(Pointee(2), kPayloadLengthBytes, kSampleRateHz, _, _))
-      .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
+  EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes, _, _))
+      .WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
                                           dummy_output + kPayloadLengthSamples),
-                      SetArgPointee<4>(AudioDecoder::kSpeech),
+                      SetArgPointee<3>(AudioDecoder::kSpeech),
                       Return(kPayloadLengthSamples)));
 
   // Pull audio once.
@@ -685,31 +682,28 @@
 
   // Pointee(x) verifies that first byte of the payload equals x, this makes it
   // possible to verify that the correct payload is fed to Decode().
-  EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes,
-                                   kSampleRateKhz * 1000, _, _))
-      .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
+  EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes, _, _))
+      .WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
                                           dummy_output + kPayloadLengthSamples),
-                      SetArgPointee<4>(AudioDecoder::kSpeech),
+                      SetArgPointee<3>(AudioDecoder::kSpeech),
                       Return(kPayloadLengthSamples)));
 
-  EXPECT_CALL(mock_decoder, Decode(Pointee(1), kPayloadLengthBytes,
-                                   kSampleRateKhz * 1000, _, _))
-      .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
+  EXPECT_CALL(mock_decoder, Decode(Pointee(1), kPayloadLengthBytes, _, _))
+      .WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
                                           dummy_output + kPayloadLengthSamples),
-                      SetArgPointee<4>(AudioDecoder::kComfortNoise),
+                      SetArgPointee<3>(AudioDecoder::kComfortNoise),
                       Return(kPayloadLengthSamples)));
 
-  EXPECT_CALL(mock_decoder, Decode(IsNull(), 0, kSampleRateKhz * 1000, _, _))
-      .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
+  EXPECT_CALL(mock_decoder, Decode(IsNull(), 0, _, _))
+      .WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
                                           dummy_output + kPayloadLengthSamples),
-                      SetArgPointee<4>(AudioDecoder::kComfortNoise),
+                      SetArgPointee<3>(AudioDecoder::kComfortNoise),
                       Return(kPayloadLengthSamples)));
 
-  EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes,
-                                   kSampleRateKhz * 1000, _, _))
-      .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
+  EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes, _, _))
+      .WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
                                           dummy_output + kPayloadLengthSamples),
-                      SetArgPointee<4>(AudioDecoder::kSpeech),
+                      SetArgPointee<3>(AudioDecoder::kSpeech),
                       Return(kPayloadLengthSamples)));
 
   EXPECT_EQ(NetEq::kOK,
diff --git a/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
index cdcf0b3..b61bf83 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
@@ -36,22 +36,16 @@
   MOCK_METHOD0(Init, int());
 
   // Override the following methods such that no actual payload is needed.
-  int Decode(const uint8_t* encoded,
-             size_t encoded_len,
-             int /*sample_rate_hz*/,
-             int16_t* decoded,
+  int Decode(const uint8_t* encoded, size_t encoded_len, int16_t* decoded,
              SpeechType* speech_type) override {
     *speech_type = kSpeech;
     memset(decoded, 0, sizeof(int16_t) * kPacketDuration * channels_);
     return kPacketDuration * channels_;
   }
 
-  int DecodeRedundant(const uint8_t* encoded,
-                      size_t encoded_len,
-                      int sample_rate_hz,
-                      int16_t* decoded,
-                      SpeechType* speech_type) override {
-    return Decode(encoded, encoded_len, sample_rate_hz, decoded, speech_type);
+  int DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
+                      int16_t* decoded, SpeechType* speech_type) override {
+    return Decode(encoded, encoded_len, decoded, speech_type);
   }
 
   int PacketDuration(const uint8_t* encoded,