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
This commit is contained in:
@ -18,10 +18,9 @@ namespace webrtc {
|
|||||||
|
|
||||||
int AudioDecoder::DecodeRedundant(const uint8_t* encoded,
|
int AudioDecoder::DecodeRedundant(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) {
|
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; }
|
bool AudioDecoder::HasDecodePlc() const { return false; }
|
||||||
|
@ -37,22 +37,14 @@ class AudioDecoder {
|
|||||||
// Decodes |encode_len| bytes from |encoded| and writes the result in
|
// Decodes |encode_len| bytes from |encoded| and writes the result in
|
||||||
// |decoded|. The number of samples from all channels produced is in
|
// |decoded|. The number of samples from all channels produced is in
|
||||||
// the return value. If the decoder produced comfort noise, |speech_type|
|
// the return value. If the decoder produced comfort noise, |speech_type|
|
||||||
// is set to kComfortNoise, otherwise it is kSpeech. The desired output
|
// is set to kComfortNoise, otherwise it is kSpeech.
|
||||||
// sample rate is provided in |sample_rate_hz|, which must be valid for the
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
// codec at hand.
|
int16_t* decoded, SpeechType* speech_type) = 0;
|
||||||
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.
|
// Same as Decode(), but interfaces to the decoders redundant decode function.
|
||||||
// The default implementation simply calls the regular Decode() method.
|
// The default implementation simply calls the regular Decode() method.
|
||||||
virtual int DecodeRedundant(const uint8_t* encoded,
|
virtual int DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type);
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type);
|
|
||||||
|
|
||||||
// Indicates if the decoder implements the DecodePlc method.
|
// Indicates if the decoder implements the DecodePlc method.
|
||||||
virtual bool HasDecodePlc() const;
|
virtual bool HasDecodePlc() const;
|
||||||
|
@ -66,6 +66,8 @@ class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder {
|
|||||||
explicit AudioEncoderDecoderIsacT(const ConfigAdaptive& config);
|
explicit AudioEncoderDecoderIsacT(const ConfigAdaptive& config);
|
||||||
virtual ~AudioEncoderDecoderIsacT() OVERRIDE;
|
virtual ~AudioEncoderDecoderIsacT() OVERRIDE;
|
||||||
|
|
||||||
|
void UpdateDecoderSampleRate(int sample_rate_hz);
|
||||||
|
|
||||||
// AudioEncoder public methods.
|
// AudioEncoder public methods.
|
||||||
virtual int SampleRateHz() const OVERRIDE;
|
virtual int SampleRateHz() const OVERRIDE;
|
||||||
virtual int NumChannels() const OVERRIDE;
|
virtual int NumChannels() const OVERRIDE;
|
||||||
@ -75,12 +77,10 @@ class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder {
|
|||||||
// AudioDecoder methods.
|
// AudioDecoder methods.
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) OVERRIDE;
|
SpeechType* speech_type) OVERRIDE;
|
||||||
virtual int DecodeRedundant(const uint8_t* encoded,
|
virtual int DecodeRedundant(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) OVERRIDE;
|
SpeechType* speech_type) OVERRIDE;
|
||||||
virtual bool HasDecodePlc() const OVERRIDE;
|
virtual bool HasDecodePlc() const OVERRIDE;
|
||||||
@ -116,8 +116,6 @@ class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder {
|
|||||||
typename T::instance_type* isac_state_
|
typename T::instance_type* isac_state_
|
||||||
GUARDED_BY(state_lock_) /* PT_GUARDED_BY(lock_)*/;
|
GUARDED_BY(state_lock_) /* PT_GUARDED_BY(lock_)*/;
|
||||||
|
|
||||||
int decoder_sample_rate_hz_ GUARDED_BY(state_lock_);
|
|
||||||
|
|
||||||
// Must be acquired before state_lock_.
|
// Must be acquired before state_lock_.
|
||||||
const scoped_ptr<CriticalSectionWrapper> lock_;
|
const scoped_ptr<CriticalSectionWrapper> lock_;
|
||||||
|
|
||||||
|
@ -109,7 +109,6 @@ AudioEncoderDecoderIsacT<T>::AudioEncoderDecoderIsacT(const Config& config)
|
|||||||
: payload_type_(config.payload_type),
|
: payload_type_(config.payload_type),
|
||||||
red_payload_type_(config.red_payload_type),
|
red_payload_type_(config.red_payload_type),
|
||||||
state_lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
state_lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
decoder_sample_rate_hz_(0),
|
|
||||||
lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
packet_in_progress_(false),
|
packet_in_progress_(false),
|
||||||
redundant_length_bytes_(0) {
|
redundant_length_bytes_(0) {
|
||||||
@ -137,7 +136,6 @@ AudioEncoderDecoderIsacT<T>::AudioEncoderDecoderIsacT(
|
|||||||
: payload_type_(config.payload_type),
|
: payload_type_(config.payload_type),
|
||||||
red_payload_type_(config.red_payload_type),
|
red_payload_type_(config.red_payload_type),
|
||||||
state_lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
state_lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
decoder_sample_rate_hz_(0),
|
|
||||||
lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
packet_in_progress_(false),
|
packet_in_progress_(false),
|
||||||
redundant_length_bytes_(0) {
|
redundant_length_bytes_(0) {
|
||||||
@ -161,6 +159,12 @@ AudioEncoderDecoderIsacT<T>::~AudioEncoderDecoderIsacT() {
|
|||||||
CHECK_EQ(0, T::Free(isac_state_));
|
CHECK_EQ(0, T::Free(isac_state_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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>
|
template <typename T>
|
||||||
int AudioEncoderDecoderIsacT<T>::SampleRateHz() const {
|
int AudioEncoderDecoderIsacT<T>::SampleRateHz() const {
|
||||||
CriticalSectionScoped cs(state_lock_.get());
|
CriticalSectionScoped cs(state_lock_.get());
|
||||||
@ -266,16 +270,9 @@ bool AudioEncoderDecoderIsacT<T>::EncodeInternal(uint32_t rtp_timestamp,
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
int AudioEncoderDecoderIsacT<T>::Decode(const uint8_t* encoded,
|
int AudioEncoderDecoderIsacT<T>::Decode(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) {
|
SpeechType* speech_type) {
|
||||||
CriticalSectionScoped cs(state_lock_.get());
|
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 temp_type = 1; // Default is speech.
|
||||||
int16_t ret =
|
int16_t ret =
|
||||||
T::Decode(isac_state_, encoded, static_cast<int16_t>(encoded_len),
|
T::Decode(isac_state_, encoded, static_cast<int16_t>(encoded_len),
|
||||||
@ -287,7 +284,6 @@ int AudioEncoderDecoderIsacT<T>::Decode(const uint8_t* encoded,
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
int AudioEncoderDecoderIsacT<T>::DecodeRedundant(const uint8_t* encoded,
|
int AudioEncoderDecoderIsacT<T>::DecodeRedundant(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int /*sample_rate_hz*/,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) {
|
SpeechType* speech_type) {
|
||||||
CriticalSectionScoped cs(state_lock_.get());
|
CriticalSectionScoped cs(state_lock_.get());
|
||||||
|
@ -158,22 +158,18 @@ bool AudioDecoderProxy::IsSet() const {
|
|||||||
|
|
||||||
int AudioDecoderProxy::Decode(const uint8_t* encoded,
|
int AudioDecoderProxy::Decode(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) {
|
SpeechType* speech_type) {
|
||||||
CriticalSectionScoped decoder_lock(decoder_lock_.get());
|
CriticalSectionScoped decoder_lock(decoder_lock_.get());
|
||||||
return decoder_->Decode(encoded, encoded_len, sample_rate_hz, decoded,
|
return decoder_->Decode(encoded, encoded_len, decoded, speech_type);
|
||||||
speech_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioDecoderProxy::DecodeRedundant(const uint8_t* encoded,
|
int AudioDecoderProxy::DecodeRedundant(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) {
|
SpeechType* speech_type) {
|
||||||
CriticalSectionScoped decoder_lock(decoder_lock_.get());
|
CriticalSectionScoped decoder_lock(decoder_lock_.get());
|
||||||
return decoder_->DecodeRedundant(encoded, encoded_len, sample_rate_hz,
|
return decoder_->DecodeRedundant(encoded, encoded_len, decoded, speech_type);
|
||||||
decoded, speech_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioDecoderProxy::HasDecodePlc() const {
|
bool AudioDecoderProxy::HasDecodePlc() const {
|
||||||
@ -553,6 +549,28 @@ void ACMGenericCodec::SetCngPt(int sample_rate_hz, int payload_type) {
|
|||||||
ResetAudioEncoder();
|
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(
|
int32_t ACMGenericCodec::SetISACMaxPayloadSize(
|
||||||
const uint16_t max_payload_len_bytes) {
|
const uint16_t max_payload_len_bytes) {
|
||||||
WriteLockScoped wl(codec_wrapper_lock_);
|
WriteLockScoped wl(codec_wrapper_lock_);
|
||||||
|
@ -48,12 +48,10 @@ class AudioDecoderProxy final : public AudioDecoder {
|
|||||||
bool IsSet() const;
|
bool IsSet() const;
|
||||||
int Decode(const uint8_t* encoded,
|
int Decode(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) override;
|
SpeechType* speech_type) override;
|
||||||
int DecodeRedundant(const uint8_t* encoded,
|
int DecodeRedundant(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) override;
|
SpeechType* speech_type) override;
|
||||||
bool HasDecodePlc() const override;
|
bool HasDecodePlc() const override;
|
||||||
@ -295,6 +293,33 @@ class ACMGenericCodec {
|
|||||||
// Registers comfort noise at |sample_rate_hz| to use |payload_type|.
|
// Registers comfort noise at |sample_rate_hz| to use |payload_type|.
|
||||||
void SetCngPt(int sample_rate_hz, int payload_type);
|
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()
|
// UpdateEncoderSampFreq()
|
||||||
// Call this function to update the encoder sampling frequency. This
|
// Call this function to update the encoder sampling frequency. This
|
||||||
|
@ -609,6 +609,14 @@ int AcmReceiver::last_audio_codec_id() const {
|
|||||||
return last_audio_decoder_;
|
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 {
|
int AcmReceiver::RedPayloadType() const {
|
||||||
CriticalSectionScoped lock(crit_sect_.get());
|
CriticalSectionScoped lock(crit_sect_.get());
|
||||||
if (ACMCodecDB::kRED < 0 ||
|
if (ACMCodecDB::kRED < 0 ||
|
||||||
|
@ -247,6 +247,12 @@ class AcmReceiver {
|
|||||||
//
|
//
|
||||||
int last_audio_codec_id() const; // TODO(turajs): can be inline.
|
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
|
// 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,
|
// payload. If no non-CNG/non-DTMF packet is received -1 is returned,
|
||||||
|
@ -321,6 +321,7 @@ TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(LastAudioCodec)) {
|
|||||||
// Has received, only, DTX. Last Audio codec is undefined.
|
// Has received, only, DTX. Last Audio codec is undefined.
|
||||||
EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
|
EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
|
||||||
EXPECT_EQ(-1, receiver_->last_audio_codec_id());
|
EXPECT_EQ(-1, receiver_->last_audio_codec_id());
|
||||||
|
EXPECT_EQ(-1, receiver_->last_audio_payload_type());
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
while (kCodecId[n] >= 0) { // Loop over codecs.
|
while (kCodecId[n] >= 0) { // Loop over codecs.
|
||||||
@ -346,6 +347,8 @@ TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(LastAudioCodec)) {
|
|||||||
ASSERT_TRUE(packet_sent_);
|
ASSERT_TRUE(packet_sent_);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id());
|
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_EQ(0, receiver_->LastAudioCodec(&codec));
|
||||||
EXPECT_TRUE(CodecsEqual(codecs_[kCodecId[n]], codec));
|
EXPECT_TRUE(CodecsEqual(codecs_[kCodecId[n]], codec));
|
||||||
++n;
|
++n;
|
||||||
|
@ -325,6 +325,7 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(LastAudioCodec)) {
|
|||||||
// Has received, only, DTX. Last Audio codec is undefined.
|
// Has received, only, DTX. Last Audio codec is undefined.
|
||||||
EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
|
EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
|
||||||
EXPECT_EQ(-1, receiver_->last_audio_codec_id());
|
EXPECT_EQ(-1, receiver_->last_audio_codec_id());
|
||||||
|
EXPECT_EQ(-1, receiver_->last_audio_payload_type());
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
while (kCodecId[n] >= 0) { // Loop over codecs.
|
while (kCodecId[n] >= 0) { // Loop over codecs.
|
||||||
@ -350,6 +351,8 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(LastAudioCodec)) {
|
|||||||
ASSERT_TRUE(packet_sent_);
|
ASSERT_TRUE(packet_sent_);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id());
|
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_EQ(0, receiver_->LastAudioCodec(&codec));
|
||||||
EXPECT_TRUE(CodecsEqual(codecs_[kCodecId[n]], codec));
|
EXPECT_TRUE(CodecsEqual(codecs_[kCodecId[n]], codec));
|
||||||
++n;
|
++n;
|
||||||
|
@ -1185,7 +1185,24 @@ int AudioCodingModuleImpl::ReceiveCodec(CodecInst* current_codec) const {
|
|||||||
int AudioCodingModuleImpl::IncomingPacket(const uint8_t* incoming_payload,
|
int AudioCodingModuleImpl::IncomingPacket(const uint8_t* incoming_payload,
|
||||||
const size_t payload_length,
|
const size_t payload_length,
|
||||||
const WebRtcRTPHeader& rtp_header) {
|
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).
|
// Minimum playout delay (Used for lip-sync).
|
||||||
|
@ -38,12 +38,8 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
// PCMu
|
// PCMu
|
||||||
int AudioDecoderPcmU::Decode(const uint8_t* encoded,
|
int AudioDecoderPcmU::Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) {
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) {
|
|
||||||
DCHECK_EQ(sample_rate_hz, 8000);
|
|
||||||
int16_t temp_type = 1; // Default is speech.
|
int16_t temp_type = 1; // Default is speech.
|
||||||
int16_t ret = WebRtcG711_DecodeU(encoded, static_cast<int16_t>(encoded_len),
|
int16_t ret = WebRtcG711_DecodeU(encoded, static_cast<int16_t>(encoded_len),
|
||||||
decoded, &temp_type);
|
decoded, &temp_type);
|
||||||
@ -58,12 +54,8 @@ int AudioDecoderPcmU::PacketDuration(const uint8_t* encoded,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PCMa
|
// PCMa
|
||||||
int AudioDecoderPcmA::Decode(const uint8_t* encoded,
|
int AudioDecoderPcmA::Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) {
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) {
|
|
||||||
DCHECK_EQ(sample_rate_hz, 8000);
|
|
||||||
int16_t temp_type = 1; // Default is speech.
|
int16_t temp_type = 1; // Default is speech.
|
||||||
int16_t ret = WebRtcG711_DecodeA(encoded, static_cast<int16_t>(encoded_len),
|
int16_t ret = WebRtcG711_DecodeA(encoded, static_cast<int16_t>(encoded_len),
|
||||||
decoded, &temp_type);
|
decoded, &temp_type);
|
||||||
@ -81,14 +73,8 @@ int AudioDecoderPcmA::PacketDuration(const uint8_t* encoded,
|
|||||||
#ifdef WEBRTC_CODEC_PCM16
|
#ifdef WEBRTC_CODEC_PCM16
|
||||||
AudioDecoderPcm16B::AudioDecoderPcm16B() {}
|
AudioDecoderPcm16B::AudioDecoderPcm16B() {}
|
||||||
|
|
||||||
int AudioDecoderPcm16B::Decode(const uint8_t* encoded,
|
int AudioDecoderPcm16B::Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) {
|
||||||
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;
|
|
||||||
int16_t ret =
|
int16_t ret =
|
||||||
WebRtcPcm16b_Decode(encoded, static_cast<int16_t>(encoded_len), decoded);
|
WebRtcPcm16b_Decode(encoded, static_cast<int16_t>(encoded_len), decoded);
|
||||||
*speech_type = ConvertSpeechType(1);
|
*speech_type = ConvertSpeechType(1);
|
||||||
@ -117,12 +103,8 @@ AudioDecoderIlbc::~AudioDecoderIlbc() {
|
|||||||
WebRtcIlbcfix_DecoderFree(dec_state_);
|
WebRtcIlbcfix_DecoderFree(dec_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioDecoderIlbc::Decode(const uint8_t* encoded,
|
int AudioDecoderIlbc::Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) {
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) {
|
|
||||||
DCHECK_EQ(sample_rate_hz, 8000);
|
|
||||||
int16_t temp_type = 1; // Default is speech.
|
int16_t temp_type = 1; // Default is speech.
|
||||||
int16_t ret = WebRtcIlbcfix_Decode(dec_state_, encoded,
|
int16_t ret = WebRtcIlbcfix_Decode(dec_state_, encoded,
|
||||||
static_cast<int16_t>(encoded_len), decoded,
|
static_cast<int16_t>(encoded_len), decoded,
|
||||||
@ -150,12 +132,8 @@ AudioDecoderG722::~AudioDecoderG722() {
|
|||||||
WebRtcG722_FreeDecoder(dec_state_);
|
WebRtcG722_FreeDecoder(dec_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioDecoderG722::Decode(const uint8_t* encoded,
|
int AudioDecoderG722::Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) {
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) {
|
|
||||||
DCHECK_EQ(sample_rate_hz, 16000);
|
|
||||||
int16_t temp_type = 1; // Default is speech.
|
int16_t temp_type = 1; // Default is speech.
|
||||||
int16_t ret =
|
int16_t ret =
|
||||||
WebRtcG722_Decode(dec_state_, encoded, static_cast<int16_t>(encoded_len),
|
WebRtcG722_Decode(dec_state_, encoded, static_cast<int16_t>(encoded_len),
|
||||||
@ -185,12 +163,8 @@ AudioDecoderG722Stereo::~AudioDecoderG722Stereo() {
|
|||||||
WebRtcG722_FreeDecoder(dec_state_right_);
|
WebRtcG722_FreeDecoder(dec_state_right_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioDecoderG722Stereo::Decode(const uint8_t* encoded,
|
int AudioDecoderG722Stereo::Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) {
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) {
|
|
||||||
DCHECK_EQ(sample_rate_hz, 16000);
|
|
||||||
int16_t temp_type = 1; // Default is speech.
|
int16_t temp_type = 1; // Default is speech.
|
||||||
// De-interleave the bit-stream into two separate payloads.
|
// De-interleave the bit-stream into two separate payloads.
|
||||||
uint8_t* encoded_deinterleaved = new uint8_t[encoded_len];
|
uint8_t* encoded_deinterleaved = new uint8_t[encoded_len];
|
||||||
@ -270,12 +244,8 @@ AudioDecoderOpus::~AudioDecoderOpus() {
|
|||||||
WebRtcOpus_DecoderFree(dec_state_);
|
WebRtcOpus_DecoderFree(dec_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioDecoderOpus::Decode(const uint8_t* encoded,
|
int AudioDecoderOpus::Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) {
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) {
|
|
||||||
DCHECK_EQ(sample_rate_hz, 48000);
|
|
||||||
int16_t temp_type = 1; // Default is speech.
|
int16_t temp_type = 1; // Default is speech.
|
||||||
int16_t ret = WebRtcOpus_Decode(dec_state_, encoded,
|
int16_t ret = WebRtcOpus_Decode(dec_state_, encoded,
|
||||||
static_cast<int16_t>(encoded_len), decoded,
|
static_cast<int16_t>(encoded_len), decoded,
|
||||||
@ -287,13 +257,11 @@ int AudioDecoderOpus::Decode(const uint8_t* encoded,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int AudioDecoderOpus::DecodeRedundant(const uint8_t* encoded,
|
int AudioDecoderOpus::DecodeRedundant(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len, int16_t* decoded,
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) {
|
SpeechType* speech_type) {
|
||||||
if (!PacketHasFec(encoded, encoded_len)) {
|
if (!PacketHasFec(encoded, encoded_len)) {
|
||||||
// This packet is a RED packet.
|
// 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.
|
int16_t temp_type = 1; // Default is speech.
|
||||||
|
@ -37,11 +37,8 @@ namespace webrtc {
|
|||||||
class AudioDecoderPcmU : public AudioDecoder {
|
class AudioDecoderPcmU : public AudioDecoder {
|
||||||
public:
|
public:
|
||||||
AudioDecoderPcmU() {}
|
AudioDecoderPcmU() {}
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type);
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type);
|
|
||||||
virtual int Init() { return 0; }
|
virtual int Init() { return 0; }
|
||||||
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
||||||
|
|
||||||
@ -52,11 +49,8 @@ class AudioDecoderPcmU : public AudioDecoder {
|
|||||||
class AudioDecoderPcmA : public AudioDecoder {
|
class AudioDecoderPcmA : public AudioDecoder {
|
||||||
public:
|
public:
|
||||||
AudioDecoderPcmA() {}
|
AudioDecoderPcmA() {}
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type);
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type);
|
|
||||||
virtual int Init() { return 0; }
|
virtual int Init() { return 0; }
|
||||||
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
||||||
|
|
||||||
@ -92,11 +86,8 @@ class AudioDecoderPcmAMultiCh : public AudioDecoderPcmA {
|
|||||||
class AudioDecoderPcm16B : public AudioDecoder {
|
class AudioDecoderPcm16B : public AudioDecoder {
|
||||||
public:
|
public:
|
||||||
AudioDecoderPcm16B();
|
AudioDecoderPcm16B();
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type);
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type);
|
|
||||||
virtual int Init() { return 0; }
|
virtual int Init() { return 0; }
|
||||||
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
||||||
|
|
||||||
@ -121,11 +112,8 @@ class AudioDecoderIlbc : public AudioDecoder {
|
|||||||
public:
|
public:
|
||||||
AudioDecoderIlbc();
|
AudioDecoderIlbc();
|
||||||
virtual ~AudioDecoderIlbc();
|
virtual ~AudioDecoderIlbc();
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type);
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type);
|
|
||||||
virtual bool HasDecodePlc() const { return true; }
|
virtual bool HasDecodePlc() const { return true; }
|
||||||
virtual int DecodePlc(int num_frames, int16_t* decoded);
|
virtual int DecodePlc(int num_frames, int16_t* decoded);
|
||||||
virtual int Init();
|
virtual int Init();
|
||||||
@ -141,11 +129,8 @@ class AudioDecoderG722 : public AudioDecoder {
|
|||||||
public:
|
public:
|
||||||
AudioDecoderG722();
|
AudioDecoderG722();
|
||||||
virtual ~AudioDecoderG722();
|
virtual ~AudioDecoderG722();
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type);
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type);
|
|
||||||
virtual bool HasDecodePlc() const { return false; }
|
virtual bool HasDecodePlc() const { return false; }
|
||||||
virtual int Init();
|
virtual int Init();
|
||||||
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
||||||
@ -159,11 +144,8 @@ class AudioDecoderG722Stereo : public AudioDecoder {
|
|||||||
public:
|
public:
|
||||||
AudioDecoderG722Stereo();
|
AudioDecoderG722Stereo();
|
||||||
virtual ~AudioDecoderG722Stereo();
|
virtual ~AudioDecoderG722Stereo();
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type);
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type);
|
|
||||||
virtual int Init();
|
virtual int Init();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -187,16 +169,10 @@ class AudioDecoderOpus : public AudioDecoder {
|
|||||||
public:
|
public:
|
||||||
explicit AudioDecoderOpus(int num_channels);
|
explicit AudioDecoderOpus(int num_channels);
|
||||||
virtual ~AudioDecoderOpus();
|
virtual ~AudioDecoderOpus();
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type);
|
||||||
int sample_rate_hz,
|
virtual int DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
|
||||||
int16_t* decoded,
|
int16_t* decoded, SpeechType* speech_type);
|
||||||
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 Init();
|
virtual int Init();
|
||||||
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
||||||
virtual int PacketDurationRedundant(const uint8_t* encoded,
|
virtual int PacketDurationRedundant(const uint8_t* encoded,
|
||||||
@ -219,13 +195,8 @@ class AudioDecoderCng : public AudioDecoder {
|
|||||||
public:
|
public:
|
||||||
explicit AudioDecoderCng();
|
explicit AudioDecoderCng();
|
||||||
virtual ~AudioDecoderCng();
|
virtual ~AudioDecoderCng();
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) { return -1; }
|
||||||
int /*sample_rate_hz*/,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
virtual int Init();
|
virtual int Init();
|
||||||
virtual int IncomingPacket(const uint8_t* payload,
|
virtual int IncomingPacket(const uint8_t* payload,
|
||||||
size_t payload_len,
|
size_t payload_len,
|
||||||
|
@ -186,9 +186,10 @@ class AudioDecoderTest : public ::testing::Test {
|
|||||||
// Make sure that frame_size_ * channels_ samples are allocated and free.
|
// Make sure that frame_size_ * channels_ samples are allocated and free.
|
||||||
decoded.resize((processed_samples + frame_size_) * channels_, 0);
|
decoded.resize((processed_samples + frame_size_) * channels_, 0);
|
||||||
AudioDecoder::SpeechType speech_type;
|
AudioDecoder::SpeechType speech_type;
|
||||||
size_t dec_len = decoder_->Decode(
|
size_t dec_len = decoder_->Decode(&encoded_[encoded_bytes_],
|
||||||
&encoded_[encoded_bytes_], enc_len, codec_input_rate_hz_,
|
enc_len,
|
||||||
&decoded[processed_samples * channels_], &speech_type);
|
&decoded[processed_samples * channels_],
|
||||||
|
&speech_type);
|
||||||
EXPECT_EQ(frame_size_ * channels_, dec_len);
|
EXPECT_EQ(frame_size_ * channels_, dec_len);
|
||||||
encoded_bytes_ += enc_len;
|
encoded_bytes_ += enc_len;
|
||||||
processed_samples += frame_size_;
|
processed_samples += frame_size_;
|
||||||
@ -221,15 +222,13 @@ class AudioDecoderTest : public ::testing::Test {
|
|||||||
AudioDecoder::SpeechType speech_type1, speech_type2;
|
AudioDecoder::SpeechType speech_type1, speech_type2;
|
||||||
EXPECT_EQ(0, decoder_->Init());
|
EXPECT_EQ(0, decoder_->Init());
|
||||||
scoped_ptr<int16_t[]> output1(new int16_t[frame_size_ * channels_]);
|
scoped_ptr<int16_t[]> output1(new int16_t[frame_size_ * channels_]);
|
||||||
dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
|
dec_len = decoder_->Decode(encoded_, enc_len, output1.get(), &speech_type1);
|
||||||
output1.get(), &speech_type1);
|
|
||||||
ASSERT_LE(dec_len, frame_size_ * channels_);
|
ASSERT_LE(dec_len, frame_size_ * channels_);
|
||||||
EXPECT_EQ(frame_size_ * channels_, dec_len);
|
EXPECT_EQ(frame_size_ * channels_, dec_len);
|
||||||
// Re-init decoder and decode again.
|
// Re-init decoder and decode again.
|
||||||
EXPECT_EQ(0, decoder_->Init());
|
EXPECT_EQ(0, decoder_->Init());
|
||||||
scoped_ptr<int16_t[]> output2(new int16_t[frame_size_ * channels_]);
|
scoped_ptr<int16_t[]> output2(new int16_t[frame_size_ * channels_]);
|
||||||
dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
|
dec_len = decoder_->Decode(encoded_, enc_len, output2.get(), &speech_type2);
|
||||||
output2.get(), &speech_type2);
|
|
||||||
ASSERT_LE(dec_len, frame_size_ * channels_);
|
ASSERT_LE(dec_len, frame_size_ * channels_);
|
||||||
EXPECT_EQ(frame_size_ * channels_, dec_len);
|
EXPECT_EQ(frame_size_ * channels_, dec_len);
|
||||||
for (unsigned int n = 0; n < frame_size_; ++n) {
|
for (unsigned int n = 0; n < frame_size_; ++n) {
|
||||||
@ -248,8 +247,8 @@ class AudioDecoderTest : public ::testing::Test {
|
|||||||
AudioDecoder::SpeechType speech_type;
|
AudioDecoder::SpeechType speech_type;
|
||||||
EXPECT_EQ(0, decoder_->Init());
|
EXPECT_EQ(0, decoder_->Init());
|
||||||
scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
|
scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
|
||||||
size_t dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
|
size_t dec_len =
|
||||||
output.get(), &speech_type);
|
decoder_->Decode(encoded_, enc_len, output.get(), &speech_type);
|
||||||
EXPECT_EQ(frame_size_ * channels_, dec_len);
|
EXPECT_EQ(frame_size_ * channels_, dec_len);
|
||||||
// Call DecodePlc and verify that we get one frame of data.
|
// Call DecodePlc and verify that we get one frame of data.
|
||||||
// (Overwrite the output from the above Decode call, but that does not
|
// (Overwrite the output from the above Decode call, but that does not
|
||||||
@ -339,8 +338,8 @@ class AudioDecoderIlbcTest : public AudioDecoderTest {
|
|||||||
AudioDecoder::SpeechType speech_type;
|
AudioDecoder::SpeechType speech_type;
|
||||||
EXPECT_EQ(0, decoder_->Init());
|
EXPECT_EQ(0, decoder_->Init());
|
||||||
scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
|
scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
|
||||||
size_t dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
|
size_t dec_len =
|
||||||
output.get(), &speech_type);
|
decoder_->Decode(encoded_, enc_len, output.get(), &speech_type);
|
||||||
EXPECT_EQ(frame_size_, dec_len);
|
EXPECT_EQ(frame_size_, dec_len);
|
||||||
// Simply call DecodePlc and verify that we get 0 as return value.
|
// Simply call DecodePlc and verify that we get 0 as return value.
|
||||||
EXPECT_EQ(0, decoder_->DecodePlc(1, output.get()));
|
EXPECT_EQ(0, decoder_->DecodePlc(1, output.get()));
|
||||||
|
@ -22,9 +22,8 @@ class MockAudioDecoder : public AudioDecoder {
|
|||||||
MockAudioDecoder() {}
|
MockAudioDecoder() {}
|
||||||
virtual ~MockAudioDecoder() { Die(); }
|
virtual ~MockAudioDecoder() { Die(); }
|
||||||
MOCK_METHOD0(Die, void());
|
MOCK_METHOD0(Die, void());
|
||||||
MOCK_METHOD5(
|
MOCK_METHOD4(Decode, int(const uint8_t*, size_t, int16_t*,
|
||||||
Decode,
|
AudioDecoder::SpeechType*));
|
||||||
int(const uint8_t*, size_t, int, int16_t*, AudioDecoder::SpeechType*));
|
|
||||||
MOCK_CONST_METHOD0(HasDecodePlc, bool());
|
MOCK_CONST_METHOD0(HasDecodePlc, bool());
|
||||||
MOCK_METHOD2(DecodePlc, int(int, int16_t*));
|
MOCK_METHOD2(DecodePlc, int(int, int16_t*));
|
||||||
MOCK_METHOD0(Init, int());
|
MOCK_METHOD0(Init, int());
|
||||||
|
@ -29,11 +29,8 @@ class ExternalPcm16B : public AudioDecoder {
|
|||||||
public:
|
public:
|
||||||
ExternalPcm16B() {}
|
ExternalPcm16B() {}
|
||||||
|
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) {
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) {
|
|
||||||
int16_t ret = WebRtcPcm16b_Decode(
|
int16_t ret = WebRtcPcm16b_Decode(
|
||||||
encoded, static_cast<int16_t>(encoded_len), decoded);
|
encoded, static_cast<int16_t>(encoded_len), decoded);
|
||||||
*speech_type = ConvertSpeechType(1);
|
*speech_type = ConvertSpeechType(1);
|
||||||
@ -52,7 +49,7 @@ class MockExternalPcm16B : public ExternalPcm16B {
|
|||||||
public:
|
public:
|
||||||
MockExternalPcm16B() {
|
MockExternalPcm16B() {
|
||||||
// By default, all calls are delegated to the real object.
|
// By default, all calls are delegated to the real object.
|
||||||
ON_CALL(*this, Decode(_, _, _, _, _))
|
ON_CALL(*this, Decode(_, _, _, _))
|
||||||
.WillByDefault(Invoke(&real_, &ExternalPcm16B::Decode));
|
.WillByDefault(Invoke(&real_, &ExternalPcm16B::Decode));
|
||||||
ON_CALL(*this, HasDecodePlc())
|
ON_CALL(*this, HasDecodePlc())
|
||||||
.WillByDefault(Invoke(&real_, &ExternalPcm16B::HasDecodePlc));
|
.WillByDefault(Invoke(&real_, &ExternalPcm16B::HasDecodePlc));
|
||||||
@ -68,11 +65,8 @@ class MockExternalPcm16B : public ExternalPcm16B {
|
|||||||
virtual ~MockExternalPcm16B() { Die(); }
|
virtual ~MockExternalPcm16B() { Die(); }
|
||||||
|
|
||||||
MOCK_METHOD0(Die, void());
|
MOCK_METHOD0(Die, void());
|
||||||
MOCK_METHOD5(Decode,
|
MOCK_METHOD4(Decode,
|
||||||
int(const uint8_t* encoded,
|
int(const uint8_t* encoded, size_t encoded_len, int16_t* decoded,
|
||||||
size_t encoded_len,
|
|
||||||
int sample_rate_hz,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type));
|
SpeechType* speech_type));
|
||||||
MOCK_CONST_METHOD0(HasDecodePlc,
|
MOCK_CONST_METHOD0(HasDecodePlc,
|
||||||
bool());
|
bool());
|
||||||
|
@ -100,8 +100,7 @@ class NetEqExternalDecoderUnitTest : public test::NetEqExternalDecoderTest {
|
|||||||
next_arrival_time = GetArrivalTime(next_send_time);
|
next_arrival_time = GetArrivalTime(next_send_time);
|
||||||
} while (Lost()); // If lost, immediately read the next packet.
|
} while (Lost()); // If lost, immediately read the next packet.
|
||||||
|
|
||||||
EXPECT_CALL(*external_decoder_,
|
EXPECT_CALL(*external_decoder_, Decode(_, payload_size_bytes_, _, _))
|
||||||
Decode(_, payload_size_bytes_, 1000 * samples_per_ms_, _, _))
|
|
||||||
.Times(NumExpectedDecodeCalls(num_loops));
|
.Times(NumExpectedDecodeCalls(num_loops));
|
||||||
|
|
||||||
uint32_t time_now = 0;
|
uint32_t time_now = 0;
|
||||||
|
@ -1266,7 +1266,7 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation,
|
|||||||
", ssrc=" << packet->header.ssrc <<
|
", ssrc=" << packet->header.ssrc <<
|
||||||
", len=" << packet->payload_length;
|
", len=" << packet->payload_length;
|
||||||
decode_length = decoder->DecodeRedundant(
|
decode_length = decoder->DecodeRedundant(
|
||||||
packet->payload, packet->payload_length, fs_hz_,
|
packet->payload, packet->payload_length,
|
||||||
&decoded_buffer_[*decoded_length], speech_type);
|
&decoded_buffer_[*decoded_length], speech_type);
|
||||||
} else {
|
} else {
|
||||||
LOG(LS_VERBOSE) << "Decoding packet: ts=" << packet->header.timestamp <<
|
LOG(LS_VERBOSE) << "Decoding packet: ts=" << packet->header.timestamp <<
|
||||||
@ -1274,9 +1274,10 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation,
|
|||||||
", pt=" << static_cast<int>(packet->header.payloadType) <<
|
", pt=" << static_cast<int>(packet->header.payloadType) <<
|
||||||
", ssrc=" << packet->header.ssrc <<
|
", ssrc=" << packet->header.ssrc <<
|
||||||
", len=" << packet->payload_length;
|
", len=" << packet->payload_length;
|
||||||
decode_length =
|
decode_length = decoder->Decode(packet->payload,
|
||||||
decoder->Decode(packet->payload, packet->payload_length, fs_hz_,
|
packet->payload_length,
|
||||||
&decoded_buffer_[*decoded_length], speech_type);
|
&decoded_buffer_[*decoded_length],
|
||||||
|
speech_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] packet->payload;
|
delete[] packet->payload;
|
||||||
@ -1606,8 +1607,7 @@ void NetEqImpl::DoCodecInternalCng() {
|
|||||||
if (decoder) {
|
if (decoder) {
|
||||||
const uint8_t* dummy_payload = NULL;
|
const uint8_t* dummy_payload = NULL;
|
||||||
AudioDecoder::SpeechType speech_type;
|
AudioDecoder::SpeechType speech_type;
|
||||||
length =
|
length = decoder->Decode(dummy_payload, 0, decoded_buffer, &speech_type);
|
||||||
decoder->Decode(dummy_payload, 0, fs_hz_, decoded_buffer, &speech_type);
|
|
||||||
}
|
}
|
||||||
assert(mute_factor_array_.get());
|
assert(mute_factor_array_.get());
|
||||||
normal_->Process(decoded_buffer, length, last_mode_, mute_factor_array_.get(),
|
normal_->Process(decoded_buffer, length, last_mode_, mute_factor_array_.get(),
|
||||||
|
@ -430,7 +430,6 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
|
|||||||
// Produce as many samples as input bytes (|encoded_len|).
|
// Produce as many samples as input bytes (|encoded_len|).
|
||||||
virtual int Decode(const uint8_t* encoded,
|
virtual int Decode(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int /*sample_rate_hz*/,
|
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
SpeechType* speech_type) {
|
SpeechType* speech_type) {
|
||||||
for (size_t i = 0; i < encoded_len; ++i) {
|
for (size_t i = 0; i < encoded_len; ++i) {
|
||||||
@ -522,11 +521,10 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
|
|||||||
int16_t dummy_output[kPayloadLengthSamples] = {0};
|
int16_t dummy_output[kPayloadLengthSamples] = {0};
|
||||||
// The below expectation will make the mock decoder write
|
// The below expectation will make the mock decoder write
|
||||||
// |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
|
// |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
|
||||||
EXPECT_CALL(mock_decoder,
|
EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes, _, _))
|
||||||
Decode(Pointee(0), kPayloadLengthBytes, kSampleRateHz, _, _))
|
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
|
||||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
|
||||||
dummy_output + kPayloadLengthSamples),
|
dummy_output + kPayloadLengthSamples),
|
||||||
SetArgPointee<4>(AudioDecoder::kSpeech),
|
SetArgPointee<3>(AudioDecoder::kSpeech),
|
||||||
Return(kPayloadLengthSamples)));
|
Return(kPayloadLengthSamples)));
|
||||||
EXPECT_EQ(NetEq::kOK,
|
EXPECT_EQ(NetEq::kOK,
|
||||||
neteq_->RegisterExternalDecoder(
|
neteq_->RegisterExternalDecoder(
|
||||||
@ -568,11 +566,10 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
|
|||||||
|
|
||||||
// Expect only the second packet to be decoded (the one with "2" as the first
|
// Expect only the second packet to be decoded (the one with "2" as the first
|
||||||
// payload byte).
|
// payload byte).
|
||||||
EXPECT_CALL(mock_decoder,
|
EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes, _, _))
|
||||||
Decode(Pointee(2), kPayloadLengthBytes, kSampleRateHz, _, _))
|
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
|
||||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
|
||||||
dummy_output + kPayloadLengthSamples),
|
dummy_output + kPayloadLengthSamples),
|
||||||
SetArgPointee<4>(AudioDecoder::kSpeech),
|
SetArgPointee<3>(AudioDecoder::kSpeech),
|
||||||
Return(kPayloadLengthSamples)));
|
Return(kPayloadLengthSamples)));
|
||||||
|
|
||||||
// Pull audio once.
|
// Pull audio once.
|
||||||
@ -685,31 +682,28 @@ TEST_F(NetEqImplTest, CodecInternalCng) {
|
|||||||
|
|
||||||
// Pointee(x) verifies that first byte of the payload equals x, this makes it
|
// 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().
|
// possible to verify that the correct payload is fed to Decode().
|
||||||
EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes,
|
EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes, _, _))
|
||||||
kSampleRateKhz * 1000, _, _))
|
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
|
||||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
|
||||||
dummy_output + kPayloadLengthSamples),
|
dummy_output + kPayloadLengthSamples),
|
||||||
SetArgPointee<4>(AudioDecoder::kSpeech),
|
SetArgPointee<3>(AudioDecoder::kSpeech),
|
||||||
Return(kPayloadLengthSamples)));
|
Return(kPayloadLengthSamples)));
|
||||||
|
|
||||||
EXPECT_CALL(mock_decoder, Decode(Pointee(1), kPayloadLengthBytes,
|
EXPECT_CALL(mock_decoder, Decode(Pointee(1), kPayloadLengthBytes, _, _))
|
||||||
kSampleRateKhz * 1000, _, _))
|
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
|
||||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
|
||||||
dummy_output + kPayloadLengthSamples),
|
dummy_output + kPayloadLengthSamples),
|
||||||
SetArgPointee<4>(AudioDecoder::kComfortNoise),
|
SetArgPointee<3>(AudioDecoder::kComfortNoise),
|
||||||
Return(kPayloadLengthSamples)));
|
Return(kPayloadLengthSamples)));
|
||||||
|
|
||||||
EXPECT_CALL(mock_decoder, Decode(IsNull(), 0, kSampleRateKhz * 1000, _, _))
|
EXPECT_CALL(mock_decoder, Decode(IsNull(), 0, _, _))
|
||||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
|
||||||
dummy_output + kPayloadLengthSamples),
|
dummy_output + kPayloadLengthSamples),
|
||||||
SetArgPointee<4>(AudioDecoder::kComfortNoise),
|
SetArgPointee<3>(AudioDecoder::kComfortNoise),
|
||||||
Return(kPayloadLengthSamples)));
|
Return(kPayloadLengthSamples)));
|
||||||
|
|
||||||
EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes,
|
EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes, _, _))
|
||||||
kSampleRateKhz * 1000, _, _))
|
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
|
||||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
|
||||||
dummy_output + kPayloadLengthSamples),
|
dummy_output + kPayloadLengthSamples),
|
||||||
SetArgPointee<4>(AudioDecoder::kSpeech),
|
SetArgPointee<3>(AudioDecoder::kSpeech),
|
||||||
Return(kPayloadLengthSamples)));
|
Return(kPayloadLengthSamples)));
|
||||||
|
|
||||||
EXPECT_EQ(NetEq::kOK,
|
EXPECT_EQ(NetEq::kOK,
|
||||||
|
@ -36,22 +36,16 @@ class MockAudioDecoderOpus : public AudioDecoderOpus {
|
|||||||
MOCK_METHOD0(Init, int());
|
MOCK_METHOD0(Init, int());
|
||||||
|
|
||||||
// Override the following methods such that no actual payload is needed.
|
// Override the following methods such that no actual payload is needed.
|
||||||
int Decode(const uint8_t* encoded,
|
int Decode(const uint8_t* encoded, size_t encoded_len, int16_t* decoded,
|
||||||
size_t encoded_len,
|
|
||||||
int /*sample_rate_hz*/,
|
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) override {
|
SpeechType* speech_type) override {
|
||||||
*speech_type = kSpeech;
|
*speech_type = kSpeech;
|
||||||
memset(decoded, 0, sizeof(int16_t) * kPacketDuration * channels_);
|
memset(decoded, 0, sizeof(int16_t) * kPacketDuration * channels_);
|
||||||
return kPacketDuration * channels_;
|
return kPacketDuration * channels_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DecodeRedundant(const uint8_t* encoded,
|
int DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
|
||||||
size_t encoded_len,
|
int16_t* decoded, SpeechType* speech_type) override {
|
||||||
int sample_rate_hz,
|
return Decode(encoded, encoded_len, decoded, speech_type);
|
||||||
int16_t* decoded,
|
|
||||||
SpeechType* speech_type) override {
|
|
||||||
return Decode(encoded, encoded_len, sample_rate_hz, decoded, speech_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PacketDuration(const uint8_t* encoded,
|
int PacketDuration(const uint8_t* encoded,
|
||||||
|
Reference in New Issue
Block a user