NetEq: Ask AudioDecoder for sample rate instead of passing it as an argument

BUG=webrtc:5801
NOTRY=true

Review-Url: https://codereview.webrtc.org/2027993002
Cr-Commit-Position: refs/heads/master@{#13162}
This commit is contained in:
kwiberg
2016-06-16 03:18:00 -07:00
committed by Commit bot
parent 347d35129e
commit 342f74005f
11 changed files with 48 additions and 50 deletions

View File

@ -242,7 +242,7 @@ int32_t AcmReceiver::AddCodec(int acm_codec_id,
ret_val = neteq_->RegisterPayloadType(neteq_decoder, name, payload_type);
} else {
ret_val = neteq_->RegisterExternalDecoder(
audio_decoder, neteq_decoder, name, payload_type, sample_rate_hz);
audio_decoder, neteq_decoder, name, payload_type);
}
if (ret_val != NetEq::kOK) {
LOG(LERROR) << "AcmReceiver::AddCodec " << acm_codec_id

View File

@ -1019,6 +1019,9 @@ TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutputExternalDecoder) {
EXPECT_CALL(mock_decoder, IncomingPacket(_, _, _, _, _))
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::IncomingPacket));
EXPECT_CALL(mock_decoder, SampleRateHz())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::SampleRateHz));
EXPECT_CALL(mock_decoder, Channels())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::Channels));

View File

@ -32,16 +32,16 @@ DecoderDatabase::DecoderInfo::DecoderInfo(NetEqDecoder ct,
: codec_type(ct),
name(nm),
audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)),
external_decoder_(nullptr),
cng_decoder_(CngDecoder::Create(ct)) {}
DecoderDatabase::DecoderInfo::DecoderInfo(NetEqDecoder ct,
const std::string& nm,
int sample_rate_hz,
AudioDecoder* ext_dec)
: codec_type(ct),
name(nm),
audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)),
external_decoder({sample_rate_hz, ext_dec}) {
external_decoder_(ext_dec) {
RTC_CHECK(ext_dec);
}
@ -50,10 +50,10 @@ DecoderDatabase::DecoderInfo::~DecoderInfo() = default;
AudioDecoder* DecoderDatabase::DecoderInfo::GetDecoder(
AudioDecoderFactory* factory) {
if (external_decoder) {
if (external_decoder_) {
RTC_DCHECK(!decoder_);
RTC_DCHECK(external_decoder->decoder);
return external_decoder->decoder;
RTC_DCHECK(!cng_decoder_);
return external_decoder_;
}
RTC_DCHECK(audio_format_);
if (!decoder_) {
@ -115,7 +115,6 @@ int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type,
int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type,
NetEqDecoder codec_type,
const std::string& codec_name,
int fs_hz,
AudioDecoder* decoder) {
if (rtp_payload_type > 0x7F) {
return kInvalidRtpPayloadType;
@ -123,14 +122,11 @@ int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type,
if (!CodecSupported(codec_type)) {
return kCodecNotSupported;
}
if (fs_hz != 8000 && fs_hz != 16000 && fs_hz != 32000 && fs_hz != 48000) {
return kInvalidSampleRate;
}
if (!decoder) {
return kInvalidPointer;
}
std::pair<DecoderMap::iterator, bool> ret;
DecoderInfo info(codec_type, codec_name, fs_hz, decoder);
DecoderInfo info(codec_type, codec_name, decoder);
ret = decoders_.insert(std::make_pair(rtp_payload_type, std::move(info)));
if (ret.second == false) {
// Database already contains a decoder with type |rtp_payload_type|.

View File

@ -44,7 +44,6 @@ class DecoderDatabase {
DecoderInfo(NetEqDecoder ct, const std::string& nm);
DecoderInfo(NetEqDecoder ct,
const std::string& nm,
int sample_rate_hz,
AudioDecoder* ext_dec);
DecoderInfo(DecoderInfo&&);
~DecoderInfo();
@ -57,10 +56,10 @@ class DecoderDatabase {
void DropDecoder() { decoder_.reset(); }
int SampleRateHz() const {
RTC_DCHECK_EQ(1, !!decoder_ + !!external_decoder + !!cng_decoder_);
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;
: external_decoder_ ? external_decoder_->SampleRateHz()
: cng_decoder_->sample_rate_hz;
}
const NetEqDecoder codec_type;
@ -71,13 +70,7 @@ class DecoderDatabase {
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;
AudioDecoder* const external_decoder_;
// Set iff this is a comfort noise decoder.
struct CngDecoder {
@ -120,7 +113,6 @@ class DecoderDatabase {
virtual int InsertExternal(uint8_t rtp_payload_type,
NetEqDecoder codec_type,
const std::string& codec_name,
int fs_hz,
AudioDecoder* decoder);
// Removes the entry for |rtp_payload_type| from the database.

View File

@ -141,7 +141,7 @@ TEST(DecoderDatabase, ExternalDecoder) {
// Load into database.
EXPECT_EQ(DecoderDatabase::kOK,
db.InsertExternal(kPayloadType, NetEqDecoder::kDecoderPCMu,
kCodecName, 8000, &decoder));
kCodecName, &decoder));
EXPECT_EQ(1, db.Size());
// Get decoder and make sure we get the external one.
EXPECT_EQ(&decoder, db.GetDecoder(kPayloadType));

View File

@ -183,16 +183,14 @@ class NetEq {
// Provides an externally created decoder object |decoder| to insert in the
// decoder database. The decoder implements a decoder of type |codec| and
// associates it with |rtp_payload_type| and |codec_name|. The decoder will
// produce samples at the rate |sample_rate_hz|. Returns kOK on success, kFail
// on failure.
// The name is only used to provide information back to the caller about the
// decoders. Hence, the name is arbitrary, and may be empty.
// associates it with |rtp_payload_type| and |codec_name|. Returns kOK on
// success, kFail on failure. The name is only used to provide information
// back to the caller about the decoders. Hence, the name is arbitrary, and
// may be empty.
virtual int RegisterExternalDecoder(AudioDecoder* decoder,
NetEqDecoder codec,
const std::string& codec_name,
uint8_t rtp_payload_type,
int sample_rate_hz) = 0;
uint8_t rtp_payload_type) = 0;
// Removes |rtp_payload_type| from the codec database. Returns 0 on success,
// -1 on failure.

View File

@ -33,10 +33,11 @@ class MockDecoderDatabase : public DecoderDatabase {
MOCK_METHOD3(RegisterPayload,
int(uint8_t rtp_payload_type, NetEqDecoder codec_type,
const std::string& name));
MOCK_METHOD5(InsertExternal,
int(uint8_t rtp_payload_type, NetEqDecoder codec_type,
const std::string& codec_name, int fs_hz,
AudioDecoder* decoder));
MOCK_METHOD4(InsertExternal,
int(uint8_t rtp_payload_type,
NetEqDecoder codec_type,
const std::string& codec_name,
AudioDecoder* decoder));
MOCK_METHOD1(Remove,
int(uint8_t rtp_payload_type));
MOCK_CONST_METHOD1(GetDecoderInfo,

View File

@ -260,8 +260,7 @@ int NetEqImpl::RegisterPayloadType(NetEqDecoder codec,
int NetEqImpl::RegisterExternalDecoder(AudioDecoder* decoder,
NetEqDecoder codec,
const std::string& codec_name,
uint8_t rtp_payload_type,
int sample_rate_hz) {
uint8_t rtp_payload_type) {
rtc::CritScope lock(&crit_sect_);
LOG(LS_VERBOSE) << "RegisterExternalDecoder "
<< static_cast<int>(rtp_payload_type) << " "
@ -271,8 +270,8 @@ int NetEqImpl::RegisterExternalDecoder(AudioDecoder* decoder,
assert(false);
return kFail;
}
int ret = decoder_database_->InsertExternal(
rtp_payload_type, codec, codec_name, sample_rate_hz, decoder);
int ret = decoder_database_->InsertExternal(rtp_payload_type, codec,
codec_name, decoder);
if (ret != DecoderDatabase::kOK) {
switch (ret) {
case DecoderDatabase::kInvalidRtpPayloadType:

View File

@ -128,8 +128,7 @@ class NetEqImpl : public webrtc::NetEq {
int RegisterExternalDecoder(AudioDecoder* decoder,
NetEqDecoder codec,
const std::string& codec_name,
uint8_t rtp_payload_type,
int sample_rate_hz) override;
uint8_t rtp_payload_type) override;
// Removes |rtp_payload_type| from the codec database. Returns 0 on success,
// -1 on failure.

View File

@ -446,7 +446,7 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
&decoder_, NetEqDecoder::kDecoderPCM16B,
"dummy name", kPayloadType, kSampleRateHz));
"dummy name", kPayloadType));
// Insert one packet.
EXPECT_EQ(NetEq::kOK,
@ -509,6 +509,8 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
// Create a mock decoder object.
MockAudioDecoder mock_decoder;
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
EXPECT_CALL(mock_decoder, SampleRateHz())
.WillRepeatedly(Return(kSampleRateHz));
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
.WillRepeatedly(Return(0));
@ -525,7 +527,7 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
Return(kPayloadLengthSamples)));
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
"dummy name", kPayloadType, kSampleRateHz));
"dummy name", kPayloadType));
// Insert one packet.
EXPECT_EQ(NetEq::kOK,
@ -658,6 +660,8 @@ TEST_F(NetEqImplTest, CodecInternalCng) {
// Create a mock decoder object.
MockAudioDecoder mock_decoder;
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
EXPECT_CALL(mock_decoder, SampleRateHz())
.WillRepeatedly(Return(kSampleRateKhz * 1000));
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
.WillRepeatedly(Return(0));
@ -700,7 +704,7 @@ TEST_F(NetEqImplTest, CodecInternalCng) {
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
&mock_decoder, NetEqDecoder::kDecoderOpus,
"dummy name", kPayloadType, kSampleRateKhz * 1000));
"dummy name", kPayloadType));
// Insert one packet (decoder will return speech).
EXPECT_EQ(NetEq::kOK,
@ -844,7 +848,7 @@ TEST_F(NetEqImplTest, UnsupportedDecoder) {
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
&decoder_, NetEqDecoder::kDecoderPCM16B,
"dummy name", kPayloadType, kSampleRateHz));
"dummy name", kPayloadType));
// Insert one packet.
payload[0] = kFirstPayloadValue; // This will make Decode() fail.
@ -938,6 +942,8 @@ TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
// Create a mock decoder object.
MockAudioDecoder mock_decoder;
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
EXPECT_CALL(mock_decoder, SampleRateHz())
.WillRepeatedly(Return(kSampleRateHz));
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
.WillRepeatedly(Return(0));
@ -956,7 +962,7 @@ TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
Return(kPayloadLengthSamples - 5)));
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
"dummy name", kPayloadType, kSampleRateHz));
"dummy name", kPayloadType));
// Insert one packet.
EXPECT_EQ(NetEq::kOK,
@ -1003,6 +1009,8 @@ TEST_F(NetEqImplTest, DecodingError) {
// Create a mock decoder object.
MockAudioDecoder mock_decoder;
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
EXPECT_CALL(mock_decoder, SampleRateHz())
.WillRepeatedly(Return(kSampleRateHz));
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
.WillRepeatedly(Return(0));
@ -1047,7 +1055,7 @@ TEST_F(NetEqImplTest, DecodingError) {
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
"dummy name", kPayloadType, kSampleRateHz));
"dummy name", kPayloadType));
// Insert packets.
for (int i = 0; i < 6; ++i) {
@ -1117,6 +1125,8 @@ TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
// Create a mock decoder object.
MockAudioDecoder mock_decoder;
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
EXPECT_CALL(mock_decoder, SampleRateHz())
.WillRepeatedly(Return(kSampleRateHz));
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
.WillRepeatedly(Return(0));
@ -1157,7 +1167,7 @@ TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
"dummy name", kPayloadType, kSampleRateHz));
"dummy name", kPayloadType));
// Insert 2 packets. This will make netEq into codec internal CNG mode.
for (int i = 0; i < 2; ++i) {
@ -1293,7 +1303,7 @@ class NetEqImplTest120ms : public NetEqImplTest {
ASSERT_EQ(2u, decoder_->Channels());
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
decoder_.get(), NetEqDecoder::kDecoderOpus_2ch,
"120ms codec", kPayloadType, kSamplingFreq_));
"120ms codec", kPayloadType));
}
std::unique_ptr<Decoder120ms> decoder_;

View File

@ -34,7 +34,7 @@ NetEqExternalDecoderTest::NetEqExternalDecoderTest(NetEqDecoder codec,
void NetEqExternalDecoderTest::Init() {
ASSERT_EQ(NetEq::kOK,
neteq_->RegisterExternalDecoder(decoder_, codec_, name_,
kPayloadType, sample_rate_hz_));
kPayloadType));
}
void NetEqExternalDecoderTest::InsertPacket(