Delete NetEq::RegisterExternalDecoder.
Bug: webrtc:10080 Change-Id: Ie36b10af6ab22f498636e38f36bef11f28fc7f7e Reviewed-on: https://webrtc-review.googlesource.com/c/112081 Reviewed-by: Ivo Creusen <ivoc@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26174}
This commit is contained in:
@ -1577,8 +1577,6 @@ if (rtc_include_tests) {
|
||||
rtc_source_set("neteq_test_support") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"neteq/tools/neteq_external_decoder_test.cc",
|
||||
"neteq/tools/neteq_external_decoder_test.h",
|
||||
"neteq/tools/neteq_performance_test.cc",
|
||||
"neteq/tools/neteq_performance_test.h",
|
||||
]
|
||||
@ -1992,13 +1990,11 @@ if (rtc_include_tests) {
|
||||
"neteq/mock/mock_dtmf_buffer.h",
|
||||
"neteq/mock/mock_dtmf_tone_generator.h",
|
||||
"neteq/mock/mock_expand.h",
|
||||
"neteq/mock/mock_external_decoder_pcm16b.h",
|
||||
"neteq/mock/mock_packet_buffer.h",
|
||||
"neteq/mock/mock_red_payload_splitter.h",
|
||||
"neteq/mock/mock_statistics_calculator.h",
|
||||
"neteq/nack_tracker_unittest.cc",
|
||||
"neteq/neteq_decoder_plc_unittest.cc",
|
||||
"neteq/neteq_external_decoder_unittest.cc",
|
||||
"neteq/neteq_impl_unittest.cc",
|
||||
"neteq/neteq_network_stats_unittest.cc",
|
||||
"neteq/neteq_stereo_unittest.cc",
|
||||
|
||||
@ -43,7 +43,6 @@ DecoderDatabase::DecoderInfo::DecoderInfo(
|
||||
audio_format_(audio_format),
|
||||
codec_pair_id_(codec_pair_id),
|
||||
factory_(factory),
|
||||
external_decoder_(nullptr),
|
||||
cng_decoder_(CngDecoder::Create(audio_format)),
|
||||
subtype_(SubtypeFromFormat(audio_format)) {}
|
||||
|
||||
@ -59,23 +58,11 @@ DecoderDatabase::DecoderInfo::DecoderInfo(
|
||||
AudioDecoderFactory* factory)
|
||||
: DecoderInfo(*NetEqDecoderToSdpAudioFormat(ct), codec_pair_id, factory) {}
|
||||
|
||||
DecoderDatabase::DecoderInfo::DecoderInfo(const SdpAudioFormat& audio_format,
|
||||
AudioDecoder* ext_dec,
|
||||
const std::string& codec_name)
|
||||
: name_(codec_name),
|
||||
audio_format_(audio_format),
|
||||
codec_pair_id_(absl::nullopt),
|
||||
factory_(nullptr),
|
||||
external_decoder_(ext_dec),
|
||||
subtype_(Subtype::kNormal) {
|
||||
RTC_CHECK(ext_dec);
|
||||
}
|
||||
|
||||
DecoderDatabase::DecoderInfo::DecoderInfo(DecoderInfo&&) = default;
|
||||
DecoderDatabase::DecoderInfo::~DecoderInfo() = default;
|
||||
|
||||
bool DecoderDatabase::DecoderInfo::CanGetDecoder() const {
|
||||
if (subtype_ == Subtype::kNormal && !external_decoder_ && !decoder_) {
|
||||
if (subtype_ == Subtype::kNormal && !decoder_) {
|
||||
// TODO(ossu): Keep a check here for now, since a number of tests create
|
||||
// DecoderInfos without factories.
|
||||
RTC_DCHECK(factory_);
|
||||
@ -90,11 +77,6 @@ AudioDecoder* DecoderDatabase::DecoderInfo::GetDecoder() const {
|
||||
// These are handled internally, so they have no AudioDecoder objects.
|
||||
return nullptr;
|
||||
}
|
||||
if (external_decoder_) {
|
||||
RTC_DCHECK(!decoder_);
|
||||
RTC_DCHECK(!cng_decoder_);
|
||||
return external_decoder_;
|
||||
}
|
||||
if (!decoder_) {
|
||||
// TODO(ossu): Keep a check here for now, since a number of tests create
|
||||
// DecoderInfos without factories.
|
||||
@ -227,31 +209,6 @@ int DecoderDatabase::RegisterPayload(int rtp_payload_type,
|
||||
return kOK;
|
||||
}
|
||||
|
||||
int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type,
|
||||
NetEqDecoder codec_type,
|
||||
const std::string& codec_name,
|
||||
AudioDecoder* decoder) {
|
||||
if (rtp_payload_type > 0x7F) {
|
||||
return kInvalidRtpPayloadType;
|
||||
}
|
||||
if (!decoder) {
|
||||
return kInvalidPointer;
|
||||
}
|
||||
|
||||
const auto opt_db_format = NetEqDecoderToSdpAudioFormat(codec_type);
|
||||
const SdpAudioFormat format =
|
||||
opt_db_format.value_or(SdpAudioFormat("arbitrary", 0, 0));
|
||||
|
||||
std::pair<DecoderMap::iterator, bool> ret;
|
||||
DecoderInfo info(format, decoder, codec_name);
|
||||
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|.
|
||||
return kDecoderExists;
|
||||
}
|
||||
return kOK;
|
||||
}
|
||||
|
||||
int DecoderDatabase::Remove(uint8_t rtp_payload_type) {
|
||||
if (decoders_.erase(rtp_payload_type) == 0) {
|
||||
// No decoder with that |rtp_payload_type|.
|
||||
|
||||
@ -50,9 +50,6 @@ class DecoderDatabase {
|
||||
explicit DecoderInfo(NetEqDecoder ct,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id,
|
||||
AudioDecoderFactory* factory = nullptr);
|
||||
DecoderInfo(const SdpAudioFormat& audio_format,
|
||||
AudioDecoder* ext_dec,
|
||||
const std::string& codec_name);
|
||||
DecoderInfo(DecoderInfo&&);
|
||||
~DecoderInfo();
|
||||
|
||||
@ -109,9 +106,6 @@ class DecoderDatabase {
|
||||
AudioDecoderFactory* const factory_;
|
||||
mutable std::unique_ptr<AudioDecoder> decoder_;
|
||||
|
||||
// Set iff this is an external decoder.
|
||||
AudioDecoder* const external_decoder_;
|
||||
|
||||
// Set iff this is a comfort noise decoder.
|
||||
struct CngDecoder {
|
||||
static absl::optional<CngDecoder> Create(const SdpAudioFormat& format);
|
||||
@ -165,13 +159,6 @@ class DecoderDatabase {
|
||||
virtual int RegisterPayload(int rtp_payload_type,
|
||||
const SdpAudioFormat& audio_format);
|
||||
|
||||
// Registers an externally created AudioDecoder object, and associates it
|
||||
// as a decoder of type |codec_type| with |rtp_payload_type|.
|
||||
virtual int InsertExternal(uint8_t rtp_payload_type,
|
||||
NetEqDecoder codec_type,
|
||||
const std::string& codec_name,
|
||||
AudioDecoder* decoder);
|
||||
|
||||
// Removes the entry for |rtp_payload_type| from the database.
|
||||
// Returns kDecoderNotFound or kOK depending on the outcome of the operation.
|
||||
virtual int Remove(uint8_t rtp_payload_type);
|
||||
|
||||
@ -165,35 +165,6 @@ TEST(DecoderDatabase, TypeTests) {
|
||||
EXPECT_TRUE(db.IsRed(kPayloadTypeRed));
|
||||
}
|
||||
|
||||
TEST(DecoderDatabase, ExternalDecoder) {
|
||||
DecoderDatabase db(new rtc::RefCountedObject<MockAudioDecoderFactory>,
|
||||
absl::nullopt);
|
||||
const uint8_t kPayloadType = 0;
|
||||
const std::string kCodecName = "Robert\'); DROP TABLE Students;";
|
||||
MockAudioDecoder decoder;
|
||||
// Load into database.
|
||||
EXPECT_EQ(DecoderDatabase::kOK,
|
||||
db.InsertExternal(kPayloadType, NetEqDecoder::kDecoderPCMu,
|
||||
kCodecName, &decoder));
|
||||
EXPECT_EQ(1, db.Size());
|
||||
// Get decoder and make sure we get the external one.
|
||||
EXPECT_EQ(&decoder, db.GetDecoder(kPayloadType));
|
||||
// Get the decoder info struct and check it too.
|
||||
const DecoderDatabase::DecoderInfo* info;
|
||||
info = db.GetDecoderInfo(kPayloadType);
|
||||
ASSERT_TRUE(info != NULL);
|
||||
EXPECT_TRUE(info->IsType("pcmu"));
|
||||
EXPECT_EQ(info->get_name(), kCodecName);
|
||||
EXPECT_EQ(kCodecName, info->get_name());
|
||||
// Expect not to delete the decoder when removing it from the database, since
|
||||
// it was declared externally.
|
||||
EXPECT_CALL(decoder, Die()).Times(0);
|
||||
EXPECT_EQ(DecoderDatabase::kOK, db.Remove(kPayloadType));
|
||||
EXPECT_TRUE(db.Empty());
|
||||
|
||||
EXPECT_CALL(decoder, Die()).Times(1); // Will be called when |db| is deleted.
|
||||
}
|
||||
|
||||
TEST(DecoderDatabase, CheckPayloadTypes) {
|
||||
constexpr int kNumPayloads = 10;
|
||||
rtc::scoped_refptr<MockAudioDecoderFactory> factory(
|
||||
|
||||
@ -174,17 +174,6 @@ class NetEq {
|
||||
const std::string& codec_name,
|
||||
uint8_t rtp_payload_type) = 0;
|
||||
|
||||
// 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|. 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) = 0;
|
||||
|
||||
// Associates |rtp_payload_type| with the given codec, which NetEq will
|
||||
// instantiate when it needs it. Returns true iff successful.
|
||||
virtual bool RegisterPayloadType(int rtp_payload_type,
|
||||
|
||||
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_EXTERNAL_DECODER_PCM16B_H_
|
||||
#define MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_EXTERNAL_DECODER_PCM16B_H_
|
||||
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Invoke;
|
||||
|
||||
// Implement an external version of the PCM16b decoder.
|
||||
class ExternalPcm16B : public AudioDecoder {
|
||||
public:
|
||||
explicit ExternalPcm16B(int sample_rate_hz)
|
||||
: sample_rate_hz_(sample_rate_hz) {}
|
||||
void Reset() override {}
|
||||
|
||||
int DecodeInternal(const uint8_t* encoded,
|
||||
size_t encoded_len,
|
||||
int sample_rate_hz,
|
||||
int16_t* decoded,
|
||||
SpeechType* speech_type) override {
|
||||
EXPECT_EQ(sample_rate_hz_, sample_rate_hz);
|
||||
size_t ret = WebRtcPcm16b_Decode(encoded, encoded_len, decoded);
|
||||
*speech_type = ConvertSpeechType(1);
|
||||
return static_cast<int>(ret);
|
||||
}
|
||||
int SampleRateHz() const override { return sample_rate_hz_; }
|
||||
size_t Channels() const override { return 1; }
|
||||
|
||||
private:
|
||||
const int sample_rate_hz_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(ExternalPcm16B);
|
||||
};
|
||||
|
||||
// Create a mock of ExternalPcm16B which delegates all calls to the real object.
|
||||
// The reason is that we can then track that the correct calls are being made.
|
||||
class MockExternalPcm16B : public AudioDecoder {
|
||||
public:
|
||||
explicit MockExternalPcm16B(int sample_rate_hz) : real_(sample_rate_hz) {
|
||||
// By default, all calls are delegated to the real object.
|
||||
ON_CALL(*this, DecodeInternal(_, _, _, _, _))
|
||||
.WillByDefault(Invoke(&real_, &ExternalPcm16B::DecodeInternal));
|
||||
ON_CALL(*this, HasDecodePlc())
|
||||
.WillByDefault(Invoke(&real_, &ExternalPcm16B::HasDecodePlc));
|
||||
ON_CALL(*this, DecodePlc(_, _))
|
||||
.WillByDefault(Invoke(&real_, &ExternalPcm16B::DecodePlc));
|
||||
ON_CALL(*this, Reset())
|
||||
.WillByDefault(Invoke(&real_, &ExternalPcm16B::Reset));
|
||||
ON_CALL(*this, IncomingPacket(_, _, _, _, _))
|
||||
.WillByDefault(Invoke(&real_, &ExternalPcm16B::IncomingPacket));
|
||||
ON_CALL(*this, ErrorCode())
|
||||
.WillByDefault(Invoke(&real_, &ExternalPcm16B::ErrorCode));
|
||||
}
|
||||
virtual ~MockExternalPcm16B() { Die(); }
|
||||
|
||||
MOCK_METHOD0(Die, void());
|
||||
MOCK_METHOD5(DecodeInternal,
|
||||
int(const uint8_t* encoded,
|
||||
size_t encoded_len,
|
||||
int sample_rate_hz,
|
||||
int16_t* decoded,
|
||||
SpeechType* speech_type));
|
||||
MOCK_CONST_METHOD0(HasDecodePlc, bool());
|
||||
MOCK_METHOD2(DecodePlc, size_t(size_t num_frames, int16_t* decoded));
|
||||
MOCK_METHOD0(Reset, void());
|
||||
MOCK_METHOD5(IncomingPacket,
|
||||
int(const uint8_t* payload,
|
||||
size_t payload_len,
|
||||
uint16_t rtp_sequence_number,
|
||||
uint32_t rtp_timestamp,
|
||||
uint32_t arrival_timestamp));
|
||||
MOCK_METHOD0(ErrorCode, int());
|
||||
|
||||
int SampleRateHz() const /* override */ { return real_.SampleRateHz(); }
|
||||
size_t Channels() const /* override */ { return real_.Channels(); }
|
||||
|
||||
private:
|
||||
ExternalPcm16B real_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_EXTERNAL_DECODER_PCM16B_H_
|
||||
@ -248,26 +248,6 @@ int NetEqImpl::RegisterPayloadType(NetEqDecoder codec,
|
||||
return kOK;
|
||||
}
|
||||
|
||||
int NetEqImpl::RegisterExternalDecoder(AudioDecoder* decoder,
|
||||
NetEqDecoder codec,
|
||||
const std::string& codec_name,
|
||||
uint8_t rtp_payload_type) {
|
||||
rtc::CritScope lock(&crit_sect_);
|
||||
RTC_LOG(LS_VERBOSE) << "RegisterExternalDecoder "
|
||||
<< static_cast<int>(rtp_payload_type) << " "
|
||||
<< static_cast<int>(codec);
|
||||
if (!decoder) {
|
||||
RTC_LOG(LS_ERROR) << "Cannot register external decoder with NULL pointer";
|
||||
assert(false);
|
||||
return kFail;
|
||||
}
|
||||
if (decoder_database_->InsertExternal(rtp_payload_type, codec, codec_name,
|
||||
decoder) != DecoderDatabase::kOK) {
|
||||
return kFail;
|
||||
}
|
||||
return kOK;
|
||||
}
|
||||
|
||||
bool NetEqImpl::RegisterPayloadType(int rtp_payload_type,
|
||||
const SdpAudioFormat& audio_format) {
|
||||
RTC_LOG(LS_VERBOSE) << "NetEqImpl::RegisterPayloadType: payload type "
|
||||
|
||||
@ -141,11 +141,6 @@ class NetEqImpl : public webrtc::NetEq {
|
||||
const std::string& codec_name,
|
||||
uint8_t rtp_payload_type) override;
|
||||
|
||||
int RegisterExternalDecoder(AudioDecoder* decoder,
|
||||
NetEqDecoder codec,
|
||||
const std::string& codec_name,
|
||||
uint8_t rtp_payload_type) override;
|
||||
|
||||
bool RegisterPayloadType(int rtp_payload_type,
|
||||
const SdpAudioFormat& audio_format) override;
|
||||
|
||||
|
||||
@ -10,9 +10,15 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "api/audio/audio_frame.h"
|
||||
#include "modules/audio_coding/neteq/tools/neteq_external_decoder_test.h"
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
|
||||
#include "modules/audio_coding/neteq/include/neteq.h"
|
||||
#include "modules/audio_coding/neteq/tools/rtp_generator.h"
|
||||
#include "rtc_base/refcountedobject.h"
|
||||
#include "test/audio_decoder_proxy_factory.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -117,10 +123,12 @@ class MockAudioDecoder final : public AudioDecoder {
|
||||
bool fec_enabled_;
|
||||
};
|
||||
|
||||
class NetEqNetworkStatsTest : public NetEqExternalDecoderTest {
|
||||
class NetEqNetworkStatsTest {
|
||||
public:
|
||||
static const int kPayloadSizeByte = 30;
|
||||
static const int kFrameSizeMs = 20;
|
||||
static const uint8_t kPayloadType = 95;
|
||||
static const int kOutputLengthMs = 10;
|
||||
|
||||
enum logic {
|
||||
kIgnore,
|
||||
@ -145,17 +153,19 @@ class NetEqNetworkStatsTest : public NetEqExternalDecoderTest {
|
||||
NetEqNetworkStatistics stats_ref;
|
||||
};
|
||||
|
||||
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),
|
||||
NetEqNetworkStatsTest(const SdpAudioFormat& format, MockAudioDecoder* decoder)
|
||||
: decoder_(decoder),
|
||||
decoder_factory_(
|
||||
new rtc::RefCountedObject<AudioDecoderProxyFactory>(decoder)),
|
||||
samples_per_ms_(format.clockrate_hz / 1000),
|
||||
frame_size_samples_(kFrameSizeMs * samples_per_ms_),
|
||||
rtp_generator_(new test::RtpGenerator(samples_per_ms_)),
|
||||
rtp_generator_(new RtpGenerator(samples_per_ms_)),
|
||||
last_lost_time_(0),
|
||||
packet_loss_interval_(0xffffffff) {
|
||||
Init();
|
||||
NetEq::Config config;
|
||||
config.sample_rate_hz = format.clockrate_hz;
|
||||
neteq_ = absl::WrapUnique(NetEq::Create(config, decoder_factory_));
|
||||
neteq_->RegisterPayloadType(kPayloadType, format);
|
||||
}
|
||||
|
||||
bool Lost(uint32_t send_time) {
|
||||
@ -179,7 +189,7 @@ class NetEqNetworkStatsTest : public NetEqExternalDecoderTest {
|
||||
// expects.x = 2, 'x' in current stats should > 'x' in |stats_ref|
|
||||
void CheckNetworkStatistics(NetEqNetworkStatsCheck expects) {
|
||||
NetEqNetworkStatistics stats;
|
||||
neteq()->NetworkStatistics(&stats);
|
||||
neteq_->NetworkStatistics(&stats);
|
||||
|
||||
#define CHECK_NETEQ_NETWORK_STATS(x) \
|
||||
switch (expects.x) { \
|
||||
@ -212,7 +222,7 @@ class NetEqNetworkStatsTest : public NetEqExternalDecoderTest {
|
||||
#undef CHECK_NETEQ_NETWORK_STATS
|
||||
|
||||
// Compare with CurrentDelay, which should be identical.
|
||||
EXPECT_EQ(stats.current_buffer_size_ms, neteq()->CurrentDelayMs());
|
||||
EXPECT_EQ(stats.current_buffer_size_ms, neteq_->CurrentDelayMs());
|
||||
}
|
||||
|
||||
void RunTest(int num_loops, NetEqNetworkStatsCheck expects) {
|
||||
@ -229,18 +239,26 @@ class NetEqNetworkStatsTest : public NetEqExternalDecoderTest {
|
||||
kPayloadType, frame_size_samples_, &rtp_header_);
|
||||
if (!Lost(next_send_time)) {
|
||||
static const uint8_t payload[kPayloadSizeByte] = {0};
|
||||
InsertPacket(rtp_header_, payload, next_send_time);
|
||||
ASSERT_EQ(NetEq::kOK,
|
||||
neteq_->InsertPacket(rtp_header_, payload, next_send_time));
|
||||
}
|
||||
}
|
||||
GetOutputAudio(&output_frame_);
|
||||
bool muted = true;
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_frame_, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
EXPECT_EQ(decoder_->Channels(), output_frame_.num_channels_);
|
||||
EXPECT_EQ(static_cast<size_t>(kOutputLengthMs * samples_per_ms_),
|
||||
output_frame_.samples_per_channel_);
|
||||
EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz());
|
||||
|
||||
time_now += kOutputLengthMs;
|
||||
}
|
||||
CheckNetworkStatistics(expects);
|
||||
neteq()->FlushBuffers();
|
||||
neteq_->FlushBuffers();
|
||||
}
|
||||
|
||||
void DecodeFecTest() {
|
||||
external_decoder_->set_fec_enabled(false);
|
||||
decoder_->set_fec_enabled(false);
|
||||
NetEqNetworkStatsCheck expects = {kIgnore, // current_buffer_size_ms
|
||||
kIgnore, // preferred_buffer_size_ms
|
||||
kIgnore, // jitter_peaks_found
|
||||
@ -263,7 +281,7 @@ class NetEqNetworkStatsTest : public NetEqExternalDecoderTest {
|
||||
RunTest(50, expects);
|
||||
|
||||
// Next we enable FEC.
|
||||
external_decoder_->set_fec_enabled(true);
|
||||
decoder_->set_fec_enabled(true);
|
||||
// If FEC fills in the lost packets, no packet loss will be counted.
|
||||
expects.stats_ref.packet_loss_rate = 0;
|
||||
expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 0;
|
||||
@ -295,10 +313,13 @@ class NetEqNetworkStatsTest : public NetEqExternalDecoderTest {
|
||||
}
|
||||
|
||||
private:
|
||||
MockAudioDecoder* external_decoder_;
|
||||
MockAudioDecoder* decoder_;
|
||||
rtc::scoped_refptr<AudioDecoderProxyFactory> decoder_factory_;
|
||||
std::unique_ptr<NetEq> neteq_;
|
||||
|
||||
const int samples_per_ms_;
|
||||
const size_t frame_size_samples_;
|
||||
std::unique_ptr<test::RtpGenerator> rtp_generator_;
|
||||
std::unique_ptr<RtpGenerator> rtp_generator_;
|
||||
RTPHeader rtp_header_;
|
||||
uint32_t last_lost_time_;
|
||||
uint32_t packet_loss_interval_;
|
||||
@ -307,21 +328,21 @@ class NetEqNetworkStatsTest : public NetEqExternalDecoderTest {
|
||||
|
||||
TEST(NetEqNetworkStatsTest, DecodeFec) {
|
||||
MockAudioDecoder decoder(48000, 1);
|
||||
NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, 48000, &decoder);
|
||||
NetEqNetworkStatsTest test(SdpAudioFormat("opus", 48000, 2), &decoder);
|
||||
test.DecodeFecTest();
|
||||
EXPECT_CALL(decoder, Die()).Times(1);
|
||||
}
|
||||
|
||||
TEST(NetEqNetworkStatsTest, StereoDecodeFec) {
|
||||
MockAudioDecoder decoder(48000, 2);
|
||||
NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, 48000, &decoder);
|
||||
NetEqNetworkStatsTest test(SdpAudioFormat("opus", 48000, 2), &decoder);
|
||||
test.DecodeFecTest();
|
||||
EXPECT_CALL(decoder, Die()).Times(1);
|
||||
}
|
||||
|
||||
TEST(NetEqNetworkStatsTest, NoiseExpansionTest) {
|
||||
MockAudioDecoder decoder(48000, 1);
|
||||
NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, 48000, &decoder);
|
||||
NetEqNetworkStatsTest test(SdpAudioFormat("opus", 48000, 2), &decoder);
|
||||
test.NoiseExpansionTest();
|
||||
EXPECT_CALL(decoder, Die()).Times(1);
|
||||
}
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_coding/neteq/tools/neteq_external_decoder_test.h"
|
||||
|
||||
#include "api/audio/audio_frame.h"
|
||||
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
|
||||
#include "rtc_base/format_macros.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
NetEqExternalDecoderTest::NetEqExternalDecoderTest(NetEqDecoder codec,
|
||||
int sample_rate_hz,
|
||||
AudioDecoder* decoder)
|
||||
: codec_(codec),
|
||||
decoder_(decoder),
|
||||
sample_rate_hz_(sample_rate_hz),
|
||||
channels_(decoder_->Channels()) {
|
||||
NetEq::Config config;
|
||||
config.sample_rate_hz = sample_rate_hz_;
|
||||
neteq_.reset(NetEq::Create(config, CreateBuiltinAudioDecoderFactory()));
|
||||
}
|
||||
|
||||
void NetEqExternalDecoderTest::Init() {
|
||||
ASSERT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(decoder_, codec_, name_,
|
||||
kPayloadType));
|
||||
}
|
||||
|
||||
void NetEqExternalDecoderTest::InsertPacket(
|
||||
RTPHeader rtp_header,
|
||||
rtc::ArrayView<const uint8_t> payload,
|
||||
uint32_t receive_timestamp) {
|
||||
ASSERT_EQ(NetEq::kOK,
|
||||
neteq_->InsertPacket(rtp_header, payload, receive_timestamp));
|
||||
}
|
||||
|
||||
void NetEqExternalDecoderTest::GetOutputAudio(AudioFrame* output) {
|
||||
// Get audio from regular instance.
|
||||
bool muted;
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(output, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
EXPECT_EQ(channels_, output->num_channels_);
|
||||
EXPECT_EQ(static_cast<size_t>(kOutputLengthMs * sample_rate_hz_ / 1000),
|
||||
output->samples_per_channel_);
|
||||
EXPECT_EQ(sample_rate_hz_, neteq_->last_output_sample_rate_hz());
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_EXTERNAL_DECODER_TEST_H_
|
||||
#define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_EXTERNAL_DECODER_TEST_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "modules/audio_coding/neteq/include/neteq.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
// This test class provides a way run NetEQ with an external decoder.
|
||||
class NetEqExternalDecoderTest {
|
||||
protected:
|
||||
static const uint8_t kPayloadType = 95;
|
||||
static const int kOutputLengthMs = 10;
|
||||
|
||||
// The external decoder |decoder| is suppose to be of type |codec|.
|
||||
NetEqExternalDecoderTest(NetEqDecoder codec,
|
||||
int sample_rate_hz,
|
||||
AudioDecoder* decoder);
|
||||
|
||||
virtual ~NetEqExternalDecoderTest() {}
|
||||
|
||||
// In Init(), we register the external decoder.
|
||||
void Init();
|
||||
|
||||
// Inserts a new packet with |rtp_header| and |payload| of
|
||||
// |payload_size_bytes| bytes. The |receive_timestamp| is an indication
|
||||
// of the time when the packet was received, and should be measured with
|
||||
// the same tick rate as the RTP timestamp of the current payload.
|
||||
virtual void InsertPacket(RTPHeader rtp_header,
|
||||
rtc::ArrayView<const uint8_t> payload,
|
||||
uint32_t receive_timestamp);
|
||||
|
||||
// Get 10 ms of audio data.
|
||||
void GetOutputAudio(AudioFrame* output);
|
||||
|
||||
NetEq* neteq() { return neteq_.get(); }
|
||||
|
||||
private:
|
||||
NetEqDecoder codec_;
|
||||
std::string name_ = "dummy name";
|
||||
AudioDecoder* decoder_;
|
||||
int sample_rate_hz_;
|
||||
size_t channels_;
|
||||
std::unique_ptr<NetEq> neteq_;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_EXTERNAL_DECODER_TEST_H_
|
||||
Reference in New Issue
Block a user