From c0f2dcf9ed1ef3d528c29cb1e85ba29f7c3d56ef Mon Sep 17 00:00:00 2001 From: kwiberg Date: Tue, 31 May 2016 06:28:03 -0700 Subject: [PATCH] NetEq decoder database: Don't keep track of sample rate for builtin decoders This allows us to get rid of the function that computes it, which gets us one step closer to getting rid of the NetEqDecoder type. BUG=webrtc:5801 Review-Url: https://codereview.webrtc.org/2021063002 Cr-Commit-Position: refs/heads/master@{#12974} --- .../audio_coding/neteq/audio_decoder_impl.cc | 55 ------------------- .../audio_coding/neteq/audio_decoder_impl.h | 3 - .../neteq/audio_decoder_unittest.cc | 40 -------------- .../audio_coding/neteq/decoder_database.cc | 44 ++++++++++++--- .../audio_coding/neteq/decoder_database.h | 28 +++++++++- .../neteq/decoder_database_unittest.cc | 19 +++++-- .../neteq/mock/mock_audio_decoder.h | 1 + .../neteq/neteq_external_decoder_unittest.cc | 13 +++-- .../modules/audio_coding/neteq/neteq_impl.cc | 10 ++-- .../audio_coding/neteq/neteq_impl_unittest.cc | 49 ++++++++++------- .../neteq/neteq_network_stats_unittest.cc | 27 ++++----- .../neteq/payload_splitter_unittest.cc | 29 ++++------ .../neteq/timestamp_scaler_unittest.cc | 30 ++++------ .../tools/neteq_external_decoder_test.cc | 3 +- .../neteq/tools/neteq_external_decoder_test.h | 4 +- 15 files changed, 157 insertions(+), 198 deletions(-) diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc index 762c385983..b3f307fa15 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc @@ -82,59 +82,4 @@ bool CodecSupported(NetEqDecoder codec_type) { } } -int CodecSampleRateHz(NetEqDecoder codec_type) { - switch (codec_type) { - case NetEqDecoder::kDecoderPCMu: - case NetEqDecoder::kDecoderPCMa: - case NetEqDecoder::kDecoderPCMu_2ch: - case NetEqDecoder::kDecoderPCMa_2ch: -#ifdef WEBRTC_CODEC_ILBC - case NetEqDecoder::kDecoderILBC: -#endif - case NetEqDecoder::kDecoderPCM16B: - case NetEqDecoder::kDecoderPCM16B_2ch: - case NetEqDecoder::kDecoderPCM16B_5ch: - case NetEqDecoder::kDecoderCNGnb: { - return 8000; - } -#if defined(WEBRTC_CODEC_ISACFX) || defined(WEBRTC_CODEC_ISAC) - case NetEqDecoder::kDecoderISAC: -#endif - case NetEqDecoder::kDecoderPCM16Bwb: - case NetEqDecoder::kDecoderPCM16Bwb_2ch: -#ifdef WEBRTC_CODEC_G722 - case NetEqDecoder::kDecoderG722: - case NetEqDecoder::kDecoderG722_2ch: -#endif - case NetEqDecoder::kDecoderCNGwb: { - return 16000; - } -#ifdef WEBRTC_CODEC_ISAC - case NetEqDecoder::kDecoderISACswb: -#endif - case NetEqDecoder::kDecoderPCM16Bswb32kHz: - case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch: - case NetEqDecoder::kDecoderCNGswb32kHz: { - return 32000; - } - case NetEqDecoder::kDecoderPCM16Bswb48kHz: - case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch: { - return 48000; - } -#ifdef WEBRTC_CODEC_OPUS - case NetEqDecoder::kDecoderOpus: - case NetEqDecoder::kDecoderOpus_2ch: { - return 48000; - } -#endif - case NetEqDecoder::kDecoderCNGswb48kHz: { - // TODO(tlegrand): Remove limitation once ACM has full 48 kHz support. - return 32000; - } - default: { - return -1; // Undefined sample rate. - } - } -} - } // namespace webrtc diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h index 579ccb36f7..8636922509 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h @@ -29,8 +29,5 @@ using NetEqDecoder = acm2::RentACodec::NetEqDecoder; // Returns true if |codec_type| is supported. bool CodecSupported(NetEqDecoder codec_type); -// Returns the sample rate for |codec_type|. -int CodecSampleRateHz(NetEqDecoder codec_type); - } // namespace webrtc #endif // WEBRTC_MODULES_AUDIO_CODING_NETEQ_AUDIO_DECODER_IMPL_H_ diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc index f83afccdf5..cddc3eb294 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc @@ -674,46 +674,6 @@ const bool has_opus = false; #endif } // namespace -TEST(AudioDecoder, CodecSampleRateHz) { - EXPECT_EQ(8000, CodecSampleRateHz(NetEqDecoder::kDecoderPCMu)); - EXPECT_EQ(8000, CodecSampleRateHz(NetEqDecoder::kDecoderPCMa)); - EXPECT_EQ(8000, CodecSampleRateHz(NetEqDecoder::kDecoderPCMu_2ch)); - EXPECT_EQ(8000, CodecSampleRateHz(NetEqDecoder::kDecoderPCMa_2ch)); - EXPECT_EQ(has_ilbc ? 8000 : -1, - CodecSampleRateHz(NetEqDecoder::kDecoderILBC)); - EXPECT_EQ(has_isac ? 16000 : -1, - CodecSampleRateHz(NetEqDecoder::kDecoderISAC)); - EXPECT_EQ(has_isac_swb ? 32000 : -1, - CodecSampleRateHz(NetEqDecoder::kDecoderISACswb)); - EXPECT_EQ(8000, CodecSampleRateHz(NetEqDecoder::kDecoderPCM16B)); - EXPECT_EQ(16000, CodecSampleRateHz(NetEqDecoder::kDecoderPCM16Bwb)); - EXPECT_EQ(32000, CodecSampleRateHz(NetEqDecoder::kDecoderPCM16Bswb32kHz)); - EXPECT_EQ(48000, CodecSampleRateHz(NetEqDecoder::kDecoderPCM16Bswb48kHz)); - EXPECT_EQ(8000, CodecSampleRateHz(NetEqDecoder::kDecoderPCM16B_2ch)); - EXPECT_EQ(16000, CodecSampleRateHz(NetEqDecoder::kDecoderPCM16Bwb_2ch)); - EXPECT_EQ(32000, CodecSampleRateHz(NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch)); - EXPECT_EQ(48000, CodecSampleRateHz(NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch)); - EXPECT_EQ(8000, CodecSampleRateHz(NetEqDecoder::kDecoderPCM16B_5ch)); - EXPECT_EQ(has_g722 ? 16000 : -1, - CodecSampleRateHz(NetEqDecoder::kDecoderG722)); - EXPECT_EQ(has_g722 ? 16000 : -1, - CodecSampleRateHz(NetEqDecoder::kDecoderG722_2ch)); - EXPECT_EQ(-1, CodecSampleRateHz(NetEqDecoder::kDecoderRED)); - EXPECT_EQ(-1, CodecSampleRateHz(NetEqDecoder::kDecoderAVT)); - EXPECT_EQ(8000, CodecSampleRateHz(NetEqDecoder::kDecoderCNGnb)); - EXPECT_EQ(16000, CodecSampleRateHz(NetEqDecoder::kDecoderCNGwb)); - EXPECT_EQ(32000, CodecSampleRateHz(NetEqDecoder::kDecoderCNGswb32kHz)); - EXPECT_EQ(has_opus ? 48000 : -1, - CodecSampleRateHz(NetEqDecoder::kDecoderOpus)); - EXPECT_EQ(has_opus ? 48000 : -1, - CodecSampleRateHz(NetEqDecoder::kDecoderOpus_2ch)); - EXPECT_EQ(48000, CodecSampleRateHz(NetEqDecoder::kDecoderOpus)); - EXPECT_EQ(48000, CodecSampleRateHz(NetEqDecoder::kDecoderOpus_2ch)); - // TODO(tlegrand): Change 32000 to 48000 below once ACM has 48 kHz support. - EXPECT_EQ(32000, CodecSampleRateHz(NetEqDecoder::kDecoderCNGswb48kHz)); - EXPECT_EQ(-1, CodecSampleRateHz(NetEqDecoder::kDecoderArbitrary)); -} - TEST(AudioDecoder, CodecSupported) { EXPECT_TRUE(CodecSupported(NetEqDecoder::kDecoderPCMu)); EXPECT_TRUE(CodecSupported(NetEqDecoder::kDecoderPCMa)); diff --git a/webrtc/modules/audio_coding/neteq/decoder_database.cc b/webrtc/modules/audio_coding/neteq/decoder_database.cc index e5f4462384..ce402a76ac 100644 --- a/webrtc/modules/audio_coding/neteq/decoder_database.cc +++ b/webrtc/modules/audio_coding/neteq/decoder_database.cc @@ -27,15 +27,23 @@ DecoderDatabase::DecoderDatabase( DecoderDatabase::~DecoderDatabase() = default; +DecoderDatabase::DecoderInfo::DecoderInfo(NetEqDecoder ct, + const std::string& nm) + : codec_type(ct), + name(nm), + audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)), + cng_decoder_(CngDecoder::Create(ct)) {} + DecoderDatabase::DecoderInfo::DecoderInfo(NetEqDecoder ct, const std::string& nm, - int fs, + int sample_rate_hz, AudioDecoder* ext_dec) : codec_type(ct), name(nm), - fs_hz(fs), - external_decoder(ext_dec), - audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)) {} + audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)), + external_decoder({sample_rate_hz, ext_dec}) { + RTC_CHECK(ext_dec); +} DecoderDatabase::DecoderInfo::DecoderInfo(DecoderInfo&&) = default; DecoderDatabase::DecoderInfo::~DecoderInfo() = default; @@ -44,7 +52,8 @@ AudioDecoder* DecoderDatabase::DecoderInfo::GetDecoder( AudioDecoderFactory* factory) { if (external_decoder) { RTC_DCHECK(!decoder_); - return external_decoder; + RTC_DCHECK(external_decoder->decoder); + return external_decoder->decoder; } RTC_DCHECK(audio_format_); if (!decoder_) { @@ -54,6 +63,26 @@ AudioDecoder* DecoderDatabase::DecoderInfo::GetDecoder( return decoder_.get(); } +rtc::Optional +DecoderDatabase::DecoderInfo::CngDecoder::Create(NetEqDecoder ct) { + const auto cng = [](int sample_rate_hz) { + return rtc::Optional( + {sample_rate_hz}); + }; + switch (ct) { + case NetEqDecoder::kDecoderCNGnb: + return cng(8000); + case NetEqDecoder::kDecoderCNGwb: + return cng(16000); + case NetEqDecoder::kDecoderCNGswb32kHz: + return cng(32000); + case NetEqDecoder::kDecoderCNGswb48kHz: + return cng(48000); + default: + return rtc::Optional(); + } +} + bool DecoderDatabase::Empty() const { return decoders_.empty(); } int DecoderDatabase::Size() const { return static_cast(decoders_.size()); } @@ -73,8 +102,7 @@ int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type, if (!CodecSupported(codec_type)) { return kCodecNotSupported; } - const int fs_hz = CodecSampleRateHz(codec_type); - DecoderInfo info(codec_type, name, fs_hz, nullptr); + DecoderInfo info(codec_type, name); auto ret = decoders_.insert(std::make_pair(rtp_payload_type, std::move(info))); if (ret.second == false) { @@ -247,8 +275,6 @@ int DecoderDatabase::SetActiveCngDecoder(uint8_t rtp_payload_type) { assert(false); return kDecoderNotFound; } - // The CNG decoder should never be provided externally. - RTC_CHECK(!it->second.external_decoder); active_cng_decoder_.reset(); } active_cng_decoder_type_ = rtp_payload_type; diff --git a/webrtc/modules/audio_coding/neteq/decoder_database.h b/webrtc/modules/audio_coding/neteq/decoder_database.h index 72b43df5b3..4169dc2b1b 100644 --- a/webrtc/modules/audio_coding/neteq/decoder_database.h +++ b/webrtc/modules/audio_coding/neteq/decoder_database.h @@ -41,9 +41,10 @@ class DecoderDatabase { // Class that stores decoder info in the database. class DecoderInfo { public: + DecoderInfo(NetEqDecoder ct, const std::string& nm); DecoderInfo(NetEqDecoder ct, const std::string& nm, - int fs, + int sample_rate_hz, AudioDecoder* ext_dec); DecoderInfo(DecoderInfo&&); ~DecoderInfo(); @@ -55,14 +56,35 @@ class DecoderDatabase { // always recreate it later if we need it.) void DropDecoder() { decoder_.reset(); } + int SampleRateHz() const { + RTC_DCHECK_EQ(1, !!decoder_ + !!external_decoder + !!cng_decoder_); + return decoder_ ? decoder_->SampleRateHz() + : external_decoder ? external_decoder->sample_rate_hz + : cng_decoder_->sample_rate_hz; + } + const NetEqDecoder codec_type; const std::string name; - const int fs_hz; - AudioDecoder* const external_decoder; private: const rtc::Optional audio_format_; std::unique_ptr decoder_; + + // Set iff this is an external decoder. + struct ExternalDecoder { + // TODO(kwiberg): Remove sample_rate_hz once we can trust all decoders to + // implement SampleRateHz(). + int sample_rate_hz; + AudioDecoder* decoder; + }; + const rtc::Optional external_decoder; + + // Set iff this is a comfort noise decoder. + struct CngDecoder { + static rtc::Optional Create(NetEqDecoder ct); + int sample_rate_hz; + }; + const rtc::Optional cng_decoder_; }; // Maximum value for 8 bits, and an invalid RTP payload type (since it is diff --git a/webrtc/modules/audio_coding/neteq/decoder_database_unittest.cc b/webrtc/modules/audio_coding/neteq/decoder_database_unittest.cc index 9efc2fc7a0..1aade2c7c0 100644 --- a/webrtc/modules/audio_coding/neteq/decoder_database_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/decoder_database_unittest.cc @@ -22,6 +22,9 @@ #include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h" #include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h" +using testing::_; +using testing::Invoke; + namespace webrtc { TEST(DecoderDatabase, CreateAndDestroy) { @@ -45,7 +48,16 @@ TEST(DecoderDatabase, InsertAndRemove) { } TEST(DecoderDatabase, GetDecoderInfo) { - DecoderDatabase db(new rtc::RefCountedObject); + rtc::scoped_refptr factory( + new rtc::RefCountedObject); + auto* decoder = new MockAudioDecoder; + EXPECT_CALL(*factory, MakeAudioDecoderMock(_, _)) + .WillOnce(Invoke([decoder](const SdpAudioFormat& format, + std::unique_ptr* dec) { + EXPECT_EQ("pcmu", format.name); + dec->reset(decoder); + })); + DecoderDatabase db(factory); const uint8_t kPayloadType = 0; const std::string kCodecName = "Robert\'); DROP TABLE Students;"; EXPECT_EQ( @@ -55,9 +67,8 @@ TEST(DecoderDatabase, GetDecoderInfo) { info = db.GetDecoderInfo(kPayloadType); ASSERT_TRUE(info != NULL); EXPECT_EQ(NetEqDecoder::kDecoderPCMu, info->codec_type); - EXPECT_EQ(nullptr, info->external_decoder); - EXPECT_EQ(8000, info->fs_hz); EXPECT_EQ(kCodecName, info->name); + EXPECT_EQ(decoder, db.GetDecoder(kPayloadType)); info = db.GetDecoderInfo(kPayloadType + 1); // Other payload type. EXPECT_TRUE(info == NULL); // Should not be found. } @@ -140,8 +151,6 @@ TEST(DecoderDatabase, ExternalDecoder) { ASSERT_TRUE(info != NULL); EXPECT_EQ(NetEqDecoder::kDecoderPCMu, info->codec_type); EXPECT_EQ(kCodecName, info->name); - EXPECT_EQ(&decoder, info->external_decoder); - EXPECT_EQ(8000, info->fs_hz); // Expect not to delete the decoder when removing it from the database, since // it was declared externally. EXPECT_CALL(decoder, Die()).Times(0); 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 c1cc09cb5e..6152799b82 100644 --- a/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h +++ b/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h @@ -32,6 +32,7 @@ class MockAudioDecoder : public AudioDecoder { MOCK_METHOD0(ErrorCode, int()); MOCK_CONST_METHOD2(PacketDuration, int(const uint8_t*, size_t)); MOCK_CONST_METHOD0(Channels, size_t()); + MOCK_CONST_METHOD0(SampleRateHz, int()); MOCK_CONST_METHOD0(codec_type, NetEqDecoder()); MOCK_METHOD1(CodecSupported, bool(NetEqDecoder)); }; 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 f92e36c026..f4f65aed2d 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc @@ -31,10 +31,11 @@ class NetEqExternalDecoderUnitTest : public test::NetEqExternalDecoderTest { static const int kFrameSizeMs = 10; // Frame size of Pcm16B. NetEqExternalDecoderUnitTest(NetEqDecoder codec, + int sample_rate_hz, MockExternalPcm16B* decoder) - : NetEqExternalDecoderTest(codec, decoder), + : NetEqExternalDecoderTest(codec, sample_rate_hz, decoder), external_decoder_(decoder), - samples_per_ms_(CodecSampleRateHz(codec) / 1000), + samples_per_ms_(sample_rate_hz / 1000), frame_size_samples_(kFrameSizeMs * samples_per_ms_), rtp_generator_(new test::RtpGenerator(samples_per_ms_)), input_(new int16_t[frame_size_samples_]), @@ -173,12 +174,11 @@ class NetEqExternalVsInternalDecoderTest : public NetEqExternalDecoderUnitTest, NetEqExternalVsInternalDecoderTest() : NetEqExternalDecoderUnitTest(NetEqDecoder::kDecoderPCM16Bswb32kHz, + 32000, new MockExternalPcm16B), - sample_rate_hz_( - CodecSampleRateHz(NetEqDecoder::kDecoderPCM16Bswb32kHz)) { + sample_rate_hz_(32000) { NetEq::Config config; - config.sample_rate_hz = - CodecSampleRateHz(NetEqDecoder::kDecoderPCM16Bswb32kHz); + config.sample_rate_hz = sample_rate_hz_; neteq_internal_.reset( NetEq::Create(config, CreateBuiltinAudioDecoderFactory())); } @@ -247,6 +247,7 @@ class LargeTimestampJumpTest : public NetEqExternalDecoderUnitTest, LargeTimestampJumpTest() : NetEqExternalDecoderUnitTest(NetEqDecoder::kDecoderPCM16B, + 8000, new MockExternalPcm16B), test_state_(kInitialPhase) { EXPECT_CALL(*external_decoder(), HasDecodePlc()) diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/webrtc/modules/audio_coding/neteq/neteq_impl.cc index 87d12f51f1..b8e8c71d34 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_impl.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_impl.cc @@ -761,9 +761,10 @@ int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header, const DecoderDatabase::DecoderInfo* decoder_info = decoder_database_->GetDecoderInfo(payload_type); assert(decoder_info); - if (decoder_info->fs_hz != fs_hz_ || + if (decoder_info->SampleRateHz() != fs_hz_ || channels != algorithm_buffer_->Channels()) { - SetSampleRateAndChannels(decoder_info->fs_hz, channels); + SetSampleRateAndChannels(decoder_info->SampleRateHz(), + channels); } if (nack_enabled_) { RTC_DCHECK(nack_); @@ -1347,10 +1348,11 @@ int NetEqImpl::Decode(PacketList* packet_list, Operations* operation, } // If sampling rate or number of channels has changed, we need to make // a reset. - if (decoder_info->fs_hz != fs_hz_ || + if (decoder_info->SampleRateHz() != fs_hz_ || decoder->Channels() != algorithm_buffer_->Channels()) { // TODO(tlegrand): Add unittest to cover this event. - SetSampleRateAndChannels(decoder_info->fs_hz, decoder->Channels()); + SetSampleRateAndChannels(decoder_info->SampleRateHz(), + decoder->Channels()); } sync_buffer_->set_end_timestamp(timestamp_); playout_timestamp_ = timestamp_; diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc index 6e6226af53..34e36dc60c 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc @@ -17,6 +17,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/safe_conversions.h" #include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h" +#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h" #include "webrtc/modules/audio_coding/neteq/accelerate.h" #include "webrtc/modules/audio_coding/neteq/expand.h" #include "webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h" @@ -244,22 +245,31 @@ TEST_F(NetEqImplTest, InsertPacket) { rtp_header.header.timestamp = kFirstTimestamp; rtp_header.header.ssrc = kSsrc; - // Create a mock decoder object. - MockAudioDecoder mock_decoder; - EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1)); - // BWE update function called with first packet. - EXPECT_CALL(mock_decoder, IncomingPacket(_, - kPayloadLength, - kFirstSequenceNumber, - kFirstTimestamp, - kFirstReceiveTime)); - // BWE update function called with second packet. - EXPECT_CALL(mock_decoder, IncomingPacket(_, - kPayloadLength, - kFirstSequenceNumber + 1, - kFirstTimestamp + 160, - kFirstReceiveTime + 155)); - EXPECT_CALL(mock_decoder, Die()).Times(1); // Called when deleted. + rtc::scoped_refptr mock_decoder_factory( + new rtc::RefCountedObject); + EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _)) + .WillOnce(Invoke([kPayloadLength, kFirstSequenceNumber, kFirstTimestamp, + kFirstReceiveTime](const SdpAudioFormat& format, + std::unique_ptr* dec) { + EXPECT_EQ("pcmu", format.name); + + std::unique_ptr mock_decoder(new MockAudioDecoder); + EXPECT_CALL(*mock_decoder, Channels()).WillRepeatedly(Return(1)); + EXPECT_CALL(*mock_decoder, SampleRateHz()).WillRepeatedly(Return(8000)); + // BWE update function called with first packet. + EXPECT_CALL(*mock_decoder, + IncomingPacket(_, kPayloadLength, kFirstSequenceNumber, + kFirstTimestamp, kFirstReceiveTime)); + // BWE update function called with second packet. + EXPECT_CALL( + *mock_decoder, + IncomingPacket(_, kPayloadLength, kFirstSequenceNumber + 1, + kFirstTimestamp + 160, kFirstReceiveTime + 155)); + EXPECT_CALL(*mock_decoder, Die()).Times(1); // Called when deleted. + + *dec = std::move(mock_decoder); + })); + DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu, ""); // Expectations for decoder database. EXPECT_CALL(*mock_decoder_database_, IsRed(kPayloadType)) @@ -271,11 +281,12 @@ TEST_F(NetEqImplTest, InsertPacket) { .WillRepeatedly(Return(false)); // This is not DTMF. EXPECT_CALL(*mock_decoder_database_, GetDecoder(kPayloadType)) .Times(3) - .WillRepeatedly(Return(&mock_decoder)); + .WillRepeatedly( + Invoke([&info, mock_decoder_factory](uint8_t payload_type) { + return info.GetDecoder(mock_decoder_factory); + })); EXPECT_CALL(*mock_decoder_database_, IsComfortNoise(kPayloadType)) .WillRepeatedly(Return(false)); // This is not CNG. - DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu, "", 8000, - nullptr); EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType)) .WillRepeatedly(Return(&info)); 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 1a77abcd50..cf413a4ca8 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc @@ -113,16 +113,17 @@ struct NetEqNetworkStatsCheck { NetEqNetworkStatistics stats_ref; }; - NetEqNetworkStatsTest(NetEqDecoder codec, - MockAudioDecoder* decoder) - : NetEqExternalDecoderTest(codec, decoder), - external_decoder_(decoder), - samples_per_ms_(CodecSampleRateHz(codec) / 1000), - frame_size_samples_(kFrameSizeMs * samples_per_ms_), - rtp_generator_(new test::RtpGenerator(samples_per_ms_)), - last_lost_time_(0), - packet_loss_interval_(0xffffffff) { - Init(); +NetEqNetworkStatsTest(NetEqDecoder codec, + int sample_rate_hz, + MockAudioDecoder* decoder) + : NetEqExternalDecoderTest(codec, sample_rate_hz, decoder), + external_decoder_(decoder), + samples_per_ms_(sample_rate_hz / 1000), + frame_size_samples_(kFrameSizeMs * samples_per_ms_), + rtp_generator_(new test::RtpGenerator(samples_per_ms_)), + last_lost_time_(0), + packet_loss_interval_(0xffffffff) { + Init(); } bool Lost(uint32_t send_time) { @@ -278,21 +279,21 @@ struct NetEqNetworkStatsCheck { TEST(NetEqNetworkStatsTest, DecodeFec) { MockAudioDecoder decoder(1); - NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, &decoder); + NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, 48000, &decoder); test.DecodeFecTest(); EXPECT_CALL(decoder, Die()).Times(1); } TEST(NetEqNetworkStatsTest, StereoDecodeFec) { MockAudioDecoder decoder(2); - NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, &decoder); + NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, 48000, &decoder); test.DecodeFecTest(); EXPECT_CALL(decoder, Die()).Times(1); } TEST(NetEqNetworkStatsTest, NoiseExpansionTest) { MockAudioDecoder decoder(1); - NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, &decoder); + NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, 48000, &decoder); test.NoiseExpansionTest(); EXPECT_CALL(decoder, Die()).Times(1); } diff --git a/webrtc/modules/audio_coding/neteq/payload_splitter_unittest.cc b/webrtc/modules/audio_coding/neteq/payload_splitter_unittest.cc index 128bdccd1e..f0b16d06aa 100644 --- a/webrtc/modules/audio_coding/neteq/payload_splitter_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/payload_splitter_unittest.cc @@ -375,33 +375,27 @@ TEST(AudioPayloadSplitter, NonSplittable) { // codec types. // Use scoped pointers to avoid having to delete them later. std::unique_ptr info0( - new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderISAC, "", 16000, - nullptr)); + new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderISAC, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(0)) .WillRepeatedly(Return(info0.get())); std::unique_ptr info1( - new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderISACswb, "", 32000, - nullptr)); + new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderISACswb, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(1)) .WillRepeatedly(Return(info1.get())); std::unique_ptr info2( - new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderRED, "", 8000, - nullptr)); + new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderRED, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(2)) .WillRepeatedly(Return(info2.get())); std::unique_ptr info3( - new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderAVT, "", 8000, - nullptr)); + new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderAVT, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(3)) .WillRepeatedly(Return(info3.get())); std::unique_ptr info4( - new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderCNGnb, "", 8000, - nullptr)); + new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderCNGnb, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(4)) .WillRepeatedly(Return(info4.get())); std::unique_ptr info5( - new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderArbitrary, "", - 8000, nullptr)); + new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderArbitrary, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(5)) .WillRepeatedly(Return(info5.get())); @@ -539,7 +533,7 @@ TEST_P(SplitBySamplesTest, PayloadSizes) { // Use scoped pointers to avoid having to delete them later. // (Sample rate is set to 8000 Hz, but does not matter.) std::unique_ptr info( - new DecoderDatabase::DecoderInfo(decoder_type_, "", 8000, nullptr)); + new DecoderDatabase::DecoderInfo(decoder_type_, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType)) .WillRepeatedly(Return(info.get())); @@ -626,8 +620,7 @@ TEST_P(SplitIlbcTest, NumFrames) { // codec types. // Use scoped pointers to avoid having to delete them later. std::unique_ptr info( - new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, "", 8000, - nullptr)); + new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType)) .WillRepeatedly(Return(info.get())); @@ -690,8 +683,7 @@ TEST(IlbcPayloadSplitter, TooLargePayload) { MockDecoderDatabase decoder_database; std::unique_ptr info( - new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, "", 8000, - nullptr)); + new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType)) .WillRepeatedly(Return(info.get())); @@ -722,8 +714,7 @@ TEST(IlbcPayloadSplitter, UnevenPayload) { MockDecoderDatabase decoder_database; std::unique_ptr info( - new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, "", 8000, - nullptr)); + new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, "")); EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType)) .WillRepeatedly(Return(info.get())); diff --git a/webrtc/modules/audio_coding/neteq/timestamp_scaler_unittest.cc b/webrtc/modules/audio_coding/neteq/timestamp_scaler_unittest.cc index adaf16223b..91e1342c70 100644 --- a/webrtc/modules/audio_coding/neteq/timestamp_scaler_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/timestamp_scaler_unittest.cc @@ -24,8 +24,7 @@ namespace webrtc { TEST(TimestampScaler, TestNoScaling) { MockDecoderDatabase db; // Use PCMu, because it doesn't use scaled timestamps. - const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu, "", 8000, - nullptr); + const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu, ""); static const uint8_t kRtpPayloadType = 0; EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType)) .WillRepeatedly(Return(&info)); @@ -45,8 +44,7 @@ TEST(TimestampScaler, TestNoScaling) { TEST(TimestampScaler, TestNoScalingLargeStep) { MockDecoderDatabase db; // Use PCMu, because it doesn't use scaled timestamps. - const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu, "", 8000, - nullptr); + const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu, ""); static const uint8_t kRtpPayloadType = 0; EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType)) .WillRepeatedly(Return(&info)); @@ -71,8 +69,7 @@ TEST(TimestampScaler, TestNoScalingLargeStep) { TEST(TimestampScaler, TestG722) { MockDecoderDatabase db; // Use G722, which has a factor 2 scaling. - const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, "", 16000, - nullptr); + const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, ""); static const uint8_t kRtpPayloadType = 17; EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType)) .WillRepeatedly(Return(&info)); @@ -96,8 +93,7 @@ TEST(TimestampScaler, TestG722) { TEST(TimestampScaler, TestG722LargeStep) { MockDecoderDatabase db; // Use G722, which has a factor 2 scaling. - const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, "", 16000, - nullptr); + const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, ""); static const uint8_t kRtpPayloadType = 17; EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType)) .WillRepeatedly(Return(&info)); @@ -125,10 +121,8 @@ TEST(TimestampScaler, TestG722LargeStep) { TEST(TimestampScaler, TestG722WithCng) { MockDecoderDatabase db; // Use G722, which has a factor 2 scaling. - const DecoderDatabase::DecoderInfo info_g722(NetEqDecoder::kDecoderG722, "", - 16000, nullptr); - const DecoderDatabase::DecoderInfo info_cng(NetEqDecoder::kDecoderCNGwb, "", - 16000, nullptr); + const DecoderDatabase::DecoderInfo info_g722(NetEqDecoder::kDecoderG722, ""); + const DecoderDatabase::DecoderInfo info_cng(NetEqDecoder::kDecoderCNGwb, ""); static const uint8_t kRtpPayloadTypeG722 = 17; static const uint8_t kRtpPayloadTypeCng = 13; EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadTypeG722)) @@ -168,8 +162,7 @@ TEST(TimestampScaler, TestG722WithCng) { TEST(TimestampScaler, TestG722Packet) { MockDecoderDatabase db; // Use G722, which has a factor 2 scaling. - const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, "", 16000, - nullptr); + const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, ""); static const uint8_t kRtpPayloadType = 17; EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType)) .WillRepeatedly(Return(&info)); @@ -197,8 +190,7 @@ TEST(TimestampScaler, TestG722Packet) { TEST(TimestampScaler, TestG722PacketList) { MockDecoderDatabase db; // Use G722, which has a factor 2 scaling. - const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, "", 16000, - nullptr); + const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, ""); static const uint8_t kRtpPayloadType = 17; EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType)) .WillRepeatedly(Return(&info)); @@ -227,8 +219,7 @@ TEST(TimestampScaler, TestG722PacketList) { TEST(TimestampScaler, TestG722Reset) { MockDecoderDatabase db; // Use G722, which has a factor 2 scaling. - const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, "", 16000, - nullptr); + const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderG722, ""); static const uint8_t kRtpPayloadType = 17; EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType)) .WillRepeatedly(Return(&info)); @@ -267,8 +258,7 @@ TEST(TimestampScaler, TestG722Reset) { // timestamp scaler. TEST(TimestampScaler, TestOpusLargeStep) { MockDecoderDatabase db; - const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderOpus, "", 48000, - nullptr); + const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderOpus, ""); static const uint8_t kRtpPayloadType = 17; EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType)) .WillRepeatedly(Return(&info)); diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc index 206e0ab6b4..cbbfd27d5c 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc @@ -19,10 +19,11 @@ namespace webrtc { namespace test { NetEqExternalDecoderTest::NetEqExternalDecoderTest(NetEqDecoder codec, + int sample_rate_hz, AudioDecoder* decoder) : codec_(codec), decoder_(decoder), - sample_rate_hz_(CodecSampleRateHz(codec_)), + sample_rate_hz_(sample_rate_hz), channels_(decoder_->Channels()) { NetEq::Config config; config.sample_rate_hz = sample_rate_hz_; diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h index 8999d027ab..fb1c5b2f6f 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h @@ -27,7 +27,9 @@ class NetEqExternalDecoderTest { static const int kOutputLengthMs = 10; // The external decoder |decoder| is suppose to be of type |codec|. - NetEqExternalDecoderTest(NetEqDecoder codec, AudioDecoder* decoder); + NetEqExternalDecoderTest(NetEqDecoder codec, + int sample_rate_hz, + AudioDecoder* decoder); virtual ~NetEqExternalDecoderTest() { }