Set decoder output frequency in AudioDecoder::Decode call
This CL changes the way the decoder sample rate is set and updated. In
practice, it only concerns the iSAC (float) codec.
One single iSAC decoder instance is used for both wideband and
super-wideband decoding, and the instance must be told to switch
output frequency if the payload type changes. This used to be done
through a call to UpdateDecoderSampleRate, but is now instead done in
the Decode call as an extra parameter.
R=kwiberg@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/34349004
Cr-Commit-Position: refs/heads/master@{#8476}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8476 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 bc6b9c5..0817873 100644
--- a/webrtc/modules/audio_coding/codecs/audio_decoder.cc
+++ b/webrtc/modules/audio_coding/codecs/audio_decoder.cc
@@ -18,9 +18,10 @@
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, decoded, speech_type);
+ return Decode(encoded, encoded_len, sample_rate_hz, 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 30fdc44..8c83e61 100644
--- a/webrtc/modules/audio_coding/codecs/audio_decoder.h
+++ b/webrtc/modules/audio_coding/codecs/audio_decoder.h
@@ -37,14 +37,22 @@
// 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.
- virtual int Decode(const uint8_t* encoded, size_t encoded_len,
- int16_t* decoded, SpeechType* speech_type) = 0;
+ // 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;
// 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,
- 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);
// 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 994d21b..668f491 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,8 +66,6 @@
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;
@@ -77,10 +75,12 @@
// 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,6 +116,8 @@
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 095bb7b..d9cec82 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,6 +109,7 @@
: 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) {
@@ -136,6 +137,7 @@
: 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) {
@@ -160,12 +162,6 @@
}
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_);
@@ -270,9 +266,16 @@
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),
@@ -284,6 +287,7 @@
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());