diff --git a/modules/audio_coding/neteq/tools/fake_decode_from_file.cc b/modules/audio_coding/neteq/tools/fake_decode_from_file.cc index bb8033bb5d..a38de32c1f 100644 --- a/modules/audio_coding/neteq/tools/fake_decode_from_file.cc +++ b/modules/audio_coding/neteq/tools/fake_decode_from_file.cc @@ -23,14 +23,18 @@ int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded, int16_t* decoded, SpeechType* speech_type) { RTC_DCHECK_EQ(sample_rate_hz, SampleRateHz()); + + const int samples_to_decode = PacketDuration(encoded, encoded_len); + const int total_samples_to_decode = samples_to_decode * (stereo_ ? 2 : 1); + if (encoded_len == 0) { // Decoder is asked to produce codec-internal comfort noise. RTC_DCHECK(!encoded); // NetEq always sends nullptr in this case. RTC_DCHECK(cng_mode_); RTC_DCHECK_GT(last_decoded_length_, 0); - std::fill_n(decoded, last_decoded_length_, 0); + std::fill_n(decoded, total_samples_to_decode, 0); *speech_type = kComfortNoise; - return rtc::dchecked_cast(last_decoded_length_); + return rtc::dchecked_cast(total_samples_to_decode); } RTC_CHECK_GE(encoded_len, 12); @@ -45,7 +49,6 @@ int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded, RTC_CHECK(input_->Seek(jump)); } - int samples_to_decode = PacketDuration(encoded, encoded_len); next_timestamp_from_input_ = timestamp_to_decode + samples_to_decode; uint32_t original_payload_size_bytes = @@ -53,10 +56,10 @@ int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded, if (original_payload_size_bytes == 1) { // This is a comfort noise payload. RTC_DCHECK_GT(last_decoded_length_, 0); - std::fill_n(decoded, last_decoded_length_, 0); + std::fill_n(decoded, total_samples_to_decode, 0); *speech_type = kComfortNoise; cng_mode_ = true; - return rtc::dchecked_cast(last_decoded_length_); + return rtc::dchecked_cast(total_samples_to_decode); } cng_mode_ = false; @@ -65,32 +68,36 @@ int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded, if (stereo_) { InputAudioFile::DuplicateInterleaved(decoded, samples_to_decode, 2, decoded); - samples_to_decode *= 2; } *speech_type = kSpeech; last_decoded_length_ = samples_to_decode; - return rtc::dchecked_cast(last_decoded_length_); + return rtc::dchecked_cast(total_samples_to_decode); } int FakeDecodeFromFile::PacketDuration(const uint8_t* encoded, size_t encoded_len) const { - uint32_t samples_to_decode = - encoded_len == 0 ? 0 - : ByteReader::ReadLittleEndian(&encoded[4]); - if (samples_to_decode == 0 || + const uint32_t original_payload_size_bytes = + encoded_len < 8 + sizeof(uint32_t) + ? 0 + : ByteReader::ReadLittleEndian(&encoded[8]); + const uint32_t samples_to_decode = + encoded_len < 4 + sizeof(uint32_t) + ? 0 + : ByteReader::ReadLittleEndian(&encoded[4]); + if ( // Decoder is asked to produce codec-internal comfort noise + encoded_len == 0 || + // Comfort noise payload + original_payload_size_bytes == 1 || samples_to_decode == 0 || + // Erroneous duration since it is not a multiple of 10ms samples_to_decode % rtc::CheckedDivExact(SampleRateHz(), 100) != 0) { - // Number of samples being zero or non-multiple of 10ms is considered - // erroneous. if (last_decoded_length_ > 0) { - // Use length of last decoded packet, but since this is the total for all - // channels, we have to divide by 2 in the stereo case. - samples_to_decode = rtc::dchecked_cast(rtc::CheckedDivExact( - last_decoded_length_, static_cast(stereo_ ? 2uL : 1uL))); + // Use length of last decoded packet. + return rtc::dchecked_cast(last_decoded_length_); } else { // This is the first packet to decode, and we do not know the length of // it. Set it to 10 ms. - samples_to_decode = rtc::CheckedDivExact(SampleRateHz(), 100); + return rtc::CheckedDivExact(SampleRateHz(), 100); } } return samples_to_decode;