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}
This commit is contained in:
parent
799467d753
commit
c0f2dcf9ed
@ -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
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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>
|
||||
DecoderDatabase::DecoderInfo::CngDecoder::Create(NetEqDecoder ct) {
|
||||
const auto cng = [](int sample_rate_hz) {
|
||||
return rtc::Optional<DecoderDatabase::DecoderInfo::CngDecoder>(
|
||||
{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<DecoderDatabase::DecoderInfo::CngDecoder>();
|
||||
}
|
||||
}
|
||||
|
||||
bool DecoderDatabase::Empty() const { return decoders_.empty(); }
|
||||
|
||||
int DecoderDatabase::Size() const { return static_cast<int>(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;
|
||||
|
||||
@ -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<SdpAudioFormat> audio_format_;
|
||||
std::unique_ptr<AudioDecoder> 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<ExternalDecoder> external_decoder;
|
||||
|
||||
// Set iff this is a comfort noise decoder.
|
||||
struct CngDecoder {
|
||||
static rtc::Optional<CngDecoder> Create(NetEqDecoder ct);
|
||||
int sample_rate_hz;
|
||||
};
|
||||
const rtc::Optional<CngDecoder> cng_decoder_;
|
||||
};
|
||||
|
||||
// Maximum value for 8 bits, and an invalid RTP payload type (since it is
|
||||
|
||||
@ -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<MockAudioDecoderFactory>);
|
||||
rtc::scoped_refptr<MockAudioDecoderFactory> factory(
|
||||
new rtc::RefCountedObject<MockAudioDecoderFactory>);
|
||||
auto* decoder = new MockAudioDecoder;
|
||||
EXPECT_CALL(*factory, MakeAudioDecoderMock(_, _))
|
||||
.WillOnce(Invoke([decoder](const SdpAudioFormat& format,
|
||||
std::unique_ptr<AudioDecoder>* 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);
|
||||
|
||||
@ -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));
|
||||
};
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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<MockAudioDecoderFactory> mock_decoder_factory(
|
||||
new rtc::RefCountedObject<MockAudioDecoderFactory>);
|
||||
EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _))
|
||||
.WillOnce(Invoke([kPayloadLength, kFirstSequenceNumber, kFirstTimestamp,
|
||||
kFirstReceiveTime](const SdpAudioFormat& format,
|
||||
std::unique_ptr<AudioDecoder>* dec) {
|
||||
EXPECT_EQ("pcmu", format.name);
|
||||
|
||||
std::unique_ptr<MockAudioDecoder> 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));
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -375,33 +375,27 @@ TEST(AudioPayloadSplitter, NonSplittable) {
|
||||
// codec types.
|
||||
// Use scoped pointers to avoid having to delete them later.
|
||||
std::unique_ptr<DecoderDatabase::DecoderInfo> 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<DecoderDatabase::DecoderInfo> 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<DecoderDatabase::DecoderInfo> 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<DecoderDatabase::DecoderInfo> 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<DecoderDatabase::DecoderInfo> 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<DecoderDatabase::DecoderInfo> 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<DecoderDatabase::DecoderInfo> 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<DecoderDatabase::DecoderInfo> 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<DecoderDatabase::DecoderInfo> 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<DecoderDatabase::DecoderInfo> info(
|
||||
new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, "", 8000,
|
||||
nullptr));
|
||||
new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, ""));
|
||||
EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
|
||||
.WillRepeatedly(Return(info.get()));
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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() { }
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user