NetEq: Use a BuiltinAudioDecoderFactory to create decoders

Later steps in the refactoring will have the factory injected from the
outside rather than owned by NetEq.

BUG=webrtc:5801

Review-Url: https://codereview.webrtc.org/1928293002
Cr-Commit-Position: refs/heads/master@{#12604}
This commit is contained in:
kwiberg
2016-05-03 01:39:01 -07:00
committed by Commit bot
parent ddf165393f
commit 5178ee86ba
18 changed files with 217 additions and 128 deletions

View File

@ -855,9 +855,11 @@ source_set("neteq") {
deps = [
":audio_decoder_interface",
":builtin_audio_decoder_factory",
":cng",
":g711",
":pcm16b",
":rent_a_codec",
"../..:webrtc_common",
"../../common_audio",
"../../system_wrappers",

View File

@ -47,6 +47,59 @@
namespace webrtc {
namespace acm2 {
rtc::Optional<SdpAudioFormat> RentACodec::NetEqDecoderToSdpAudioFormat(
NetEqDecoder nd) {
switch (nd) {
case NetEqDecoder::kDecoderPCMu:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("pcmu", 8000, 1));
case NetEqDecoder::kDecoderPCMa:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("pcma", 8000, 1));
case NetEqDecoder::kDecoderPCMu_2ch:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("pcmu", 8000, 2));
case NetEqDecoder::kDecoderPCMa_2ch:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("pcma", 8000, 2));
case NetEqDecoder::kDecoderILBC:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("ilbc", 8000, 1));
case NetEqDecoder::kDecoderISAC:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("isac", 16000, 1));
case NetEqDecoder::kDecoderISACswb:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("isac", 32000, 1));
case NetEqDecoder::kDecoderPCM16B:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 8000, 1));
case NetEqDecoder::kDecoderPCM16Bwb:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 16000, 1));
case NetEqDecoder::kDecoderPCM16Bswb32kHz:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 32000, 1));
case NetEqDecoder::kDecoderPCM16Bswb48kHz:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 48000, 1));
case NetEqDecoder::kDecoderPCM16B_2ch:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 8000, 2));
case NetEqDecoder::kDecoderPCM16Bwb_2ch:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 16000, 2));
case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 32000, 2));
case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 48000, 2));
case NetEqDecoder::kDecoderPCM16B_5ch:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 8000, 5));
case NetEqDecoder::kDecoderG722:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("g722", 8000, 1));
case NetEqDecoder::kDecoderG722_2ch:
return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("g722", 8000, 2));
case NetEqDecoder::kDecoderOpus:
return rtc::Optional<SdpAudioFormat>(
SdpAudioFormat("opus", 48000, 2,
std::map<std::string, std::string>{{"stereo", "0"}}));
case NetEqDecoder::kDecoderOpus_2ch:
return rtc::Optional<SdpAudioFormat>(
SdpAudioFormat("opus", 48000, 2,
std::map<std::string, std::string>{{"stereo", "1"}}));
default:
return rtc::Optional<SdpAudioFormat>();
}
}
rtc::Optional<RentACodec::CodecId> RentACodec::CodecIdByParams(
const char* payload_name,
int sampling_freq_hz,

View File

@ -20,6 +20,7 @@
#include "webrtc/base/optional.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
#include "webrtc/modules/audio_coding/codecs/audio_format.h"
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
#include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h"
#include "webrtc/typedefs.h"
@ -135,6 +136,9 @@ class RentACodec {
kDecoderOpus_2ch,
};
static rtc::Optional<SdpAudioFormat> NetEqDecoderToSdpAudioFormat(
NetEqDecoder nd);
static inline size_t NumberOfCodecs() {
return static_cast<size_t>(CodecId::kNumCodecs);
}

View File

@ -106,14 +106,22 @@ TEST(AudioDecoderFactoryTest, CreateG722) {
TEST(AudioDecoderFactoryTest, CreateOpus) {
std::unique_ptr<AudioDecoderFactory> adf = CreateBuiltinAudioDecoderFactory();
ASSERT_TRUE(adf);
// Opus supports 48 kHz, 1-2 channels.
EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("opus", 48000, 0)));
EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("opus", 48000, 1)));
EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("opus", 48000, 2)));
EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("opus", 48000, 3)));
EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("opus", 8000, 1)));
EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("opus", 16000, 1)));
EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("opus", 32000, 1)));
// Opus supports 48 kHz, 2 channels, and wants a "stereo" parameter whose
// value is either "0" or "1".
for (int hz : {8000, 16000, 32000, 48000}) {
for (int channels : {0, 1, 2, 3}) {
for (std::string stereo : {"XX", "0", "1", "2"}) {
std::map<std::string, std::string> params;
if (stereo != "XX") {
params["stereo"] = stereo;
}
bool good =
(hz == 48000 && channels == 2 && (stereo == "0" || stereo == "1"));
EXPECT_EQ(good, static_cast<bool>(adf->MakeAudioDecoder(SdpAudioFormat(
"opus", hz, channels, std::move(params)))));
}
}
}
}
} // namespace webrtc

View File

@ -21,6 +21,15 @@ SdpAudioFormat::SdpAudioFormat(const char* name,
int num_channels)
: name(name), clockrate_hz(clockrate_hz), num_channels(num_channels) {}
SdpAudioFormat::SdpAudioFormat(const char* name,
int clockrate_hz,
int num_channels,
Parameters&& param)
: name(name),
clockrate_hz(clockrate_hz),
num_channels(num_channels),
parameters(std::move(param)) {}
SdpAudioFormat::~SdpAudioFormat() = default;
SdpAudioFormat& SdpAudioFormat::operator=(const SdpAudioFormat&) = default;
SdpAudioFormat& SdpAudioFormat::operator=(SdpAudioFormat&&) = default;

View File

@ -21,18 +21,23 @@ namespace webrtc {
// SDP specification for a single audio codec.
// NOTE: This class is still under development and may change without notice.
struct SdpAudioFormat {
using Parameters = std::map<std::string, std::string>;
// TODO(kwiberg): Get rid of the default constructor when rtc::Optional no
// longer requires it.
SdpAudioFormat();
SdpAudioFormat(const SdpAudioFormat&);
SdpAudioFormat(SdpAudioFormat&&);
SdpAudioFormat(const char* name, int clockrate_hz, int num_channels);
SdpAudioFormat(const char* name,
int clockrate_hz,
int num_channels,
Parameters&& param);
~SdpAudioFormat();
SdpAudioFormat& operator=(const SdpAudioFormat&);
SdpAudioFormat& operator=(SdpAudioFormat&&);
using Parameters = std::map<std::string, std::string>;
std::string name;
int clockrate_hz;
int num_channels;

View File

@ -13,6 +13,7 @@
#include <vector>
#include "webrtc/base/checks.h"
#include "webrtc/base/optional.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h"
#include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
@ -39,8 +40,7 @@ namespace {
struct NamedDecoderConstructor {
const char* name;
std::unique_ptr<AudioDecoder> (*constructor)(int clockrate_hz,
int num_channels);
std::unique_ptr<AudioDecoder> (*constructor)(const SdpAudioFormat&);
};
std::unique_ptr<AudioDecoder> Unique(AudioDecoder* d) {
@ -51,53 +51,54 @@ std::unique_ptr<AudioDecoder> Unique(AudioDecoder* d) {
// decoder.
NamedDecoderConstructor decoder_constructors[] = {
{"pcmu",
[](int clockrate_hz, int num_channels) {
return clockrate_hz == 8000 && num_channels >= 1
? Unique(new AudioDecoderPcmU(num_channels))
[](const SdpAudioFormat& format) {
return format.clockrate_hz == 8000 && format.num_channels >= 1
? Unique(new AudioDecoderPcmU(format.num_channels))
: nullptr;
}},
{"pcma",
[](int clockrate_hz, int num_channels) {
return clockrate_hz == 8000 && num_channels >= 1
? Unique(new AudioDecoderPcmA(num_channels))
[](const SdpAudioFormat& format) {
return format.clockrate_hz == 8000 && format.num_channels >= 1
? Unique(new AudioDecoderPcmA(format.num_channels))
: nullptr;
}},
#ifdef WEBRTC_CODEC_ILBC
{"ilbc",
[](int clockrate_hz, int num_channels) {
return clockrate_hz == 8000 && num_channels == 1
[](const SdpAudioFormat& format) {
return format.clockrate_hz == 8000 && format.num_channels == 1
? Unique(new AudioDecoderIlbc)
: nullptr;
}},
#endif
#if defined(WEBRTC_CODEC_ISACFX)
{"isac",
[](int clockrate_hz, int num_channels) {
return clockrate_hz == 16000 && num_channels == 1
[](const SdpAudioFormat& format) {
return format.clockrate_hz == 16000 && format.num_channels == 1
? Unique(new AudioDecoderIsacFix)
: nullptr;
}},
#elif defined(WEBRTC_CODEC_ISAC)
{"isac",
[](int clockrate_hz, int num_channels) {
return (clockrate_hz == 16000 || clockrate_hz == 32000) &&
num_channels == 1
[](const SdpAudioFormat& format) {
return (format.clockrate_hz == 16000 || format.clockrate_hz == 32000) &&
format.num_channels == 1
? Unique(new AudioDecoderIsac)
: nullptr;
}},
#endif
{"l16",
[](int clockrate_hz, int num_channels) {
return num_channels >= 1 ? Unique(new AudioDecoderPcm16B(num_channels))
[](const SdpAudioFormat& format) {
return format.num_channels >= 1
? Unique(new AudioDecoderPcm16B(format.num_channels))
: nullptr;
}},
#ifdef WEBRTC_CODEC_G722
{"g722",
[](int clockrate_hz, int num_channels) {
if (clockrate_hz == 8000) {
if (num_channels == 1)
[](const SdpAudioFormat& format) {
if (format.clockrate_hz == 8000) {
if (format.num_channels == 1)
return Unique(new AudioDecoderG722);
if (num_channels == 2)
if (format.num_channels == 2)
return Unique(new AudioDecoderG722Stereo);
}
return Unique(nullptr);
@ -105,9 +106,21 @@ NamedDecoderConstructor decoder_constructors[] = {
#endif
#ifdef WEBRTC_CODEC_OPUS
{"opus",
[](int clockrate_hz, int num_channels) {
return clockrate_hz == 48000 && (num_channels == 1 || num_channels == 2)
? Unique(new AudioDecoderOpus(num_channels))
[](const SdpAudioFormat& format) {
rtc::Optional<int> num_channels = [&] {
auto stereo = format.parameters.find("stereo");
if (stereo != format.parameters.end()) {
if (stereo->second == "0") {
return rtc::Optional<int>(1);
} else if (stereo->second == "1") {
return rtc::Optional<int>(2);
}
}
return rtc::Optional<int>();
}();
return format.clockrate_hz == 48000 && format.num_channels == 2 &&
num_channels
? Unique(new AudioDecoderOpus(*num_channels))
: nullptr;
}},
#endif
@ -123,8 +136,7 @@ class BuiltinAudioDecoderFactory : public AudioDecoderFactory {
const SdpAudioFormat& format) override {
for (const auto& dc : decoder_constructors) {
if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) {
return std::unique_ptr<AudioDecoder>(
dc.constructor(format.clockrate_hz, format.num_channels));
return std::unique_ptr<AudioDecoder>(dc.constructor(format));
}
}
return nullptr;

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2016 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 WEBRTC_MODULES_AUDIO_CODING_CODECS_MOCK_MOCK_AUDIO_DECODER_FACTORY_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_MOCK_MOCK_AUDIO_DECODER_FACTORY_H_
#include <vector>
#include "testing/gmock/include/gmock/gmock.h"
#include "webrtc/modules/audio_coding/codecs/audio_decoder_factory.h"
namespace webrtc {
class MockAudioDecoderFactory : public AudioDecoderFactory {
public:
MOCK_METHOD0(GetSupportedFormats, std::vector<SdpAudioFormat>());
std::unique_ptr<AudioDecoder> MakeAudioDecoder(
const SdpAudioFormat& format) {
std::unique_ptr<AudioDecoder> return_value;
MakeAudioDecoderMock(format, &return_value);
return return_value;
}
MOCK_METHOD2(MakeAudioDecoderMock,
void(const SdpAudioFormat& format,
std::unique_ptr<AudioDecoder>* return_value));
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_MOCK_MOCK_AUDIO_DECODER_FACTORY_H_

View File

@ -137,67 +137,4 @@ int CodecSampleRateHz(NetEqDecoder codec_type) {
}
}
AudioDecoder* CreateAudioDecoder(NetEqDecoder codec_type) {
if (!CodecSupported(codec_type)) {
return NULL;
}
switch (codec_type) {
case NetEqDecoder::kDecoderPCMu:
return new AudioDecoderPcmU(1);
case NetEqDecoder::kDecoderPCMa:
return new AudioDecoderPcmA(1);
case NetEqDecoder::kDecoderPCMu_2ch:
return new AudioDecoderPcmU(2);
case NetEqDecoder::kDecoderPCMa_2ch:
return new AudioDecoderPcmA(2);
#ifdef WEBRTC_CODEC_ILBC
case NetEqDecoder::kDecoderILBC:
return new AudioDecoderIlbc;
#endif
#if defined(WEBRTC_CODEC_ISACFX)
case NetEqDecoder::kDecoderISAC:
return new AudioDecoderIsacFix();
#elif defined(WEBRTC_CODEC_ISAC)
case NetEqDecoder::kDecoderISAC:
case NetEqDecoder::kDecoderISACswb:
return new AudioDecoderIsac();
#endif
case NetEqDecoder::kDecoderPCM16B:
case NetEqDecoder::kDecoderPCM16Bwb:
case NetEqDecoder::kDecoderPCM16Bswb32kHz:
case NetEqDecoder::kDecoderPCM16Bswb48kHz:
return new AudioDecoderPcm16B(1);
case NetEqDecoder::kDecoderPCM16B_2ch:
case NetEqDecoder::kDecoderPCM16Bwb_2ch:
case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch:
case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch:
return new AudioDecoderPcm16B(2);
case NetEqDecoder::kDecoderPCM16B_5ch:
return new AudioDecoderPcm16B(5);
#ifdef WEBRTC_CODEC_G722
case NetEqDecoder::kDecoderG722:
return new AudioDecoderG722;
case NetEqDecoder::kDecoderG722_2ch:
return new AudioDecoderG722Stereo;
#endif
#ifdef WEBRTC_CODEC_OPUS
case NetEqDecoder::kDecoderOpus:
return new AudioDecoderOpus(1);
case NetEqDecoder::kDecoderOpus_2ch:
return new AudioDecoderOpus(2);
#endif
case NetEqDecoder::kDecoderCNGnb:
case NetEqDecoder::kDecoderCNGwb:
case NetEqDecoder::kDecoderCNGswb32kHz:
case NetEqDecoder::kDecoderCNGswb48kHz:
RTC_CHECK(false) << "CNG should not be created like this anymore!";
case NetEqDecoder::kDecoderRED:
case NetEqDecoder::kDecoderAVT:
case NetEqDecoder::kDecoderArbitrary:
default: {
return NULL;
}
}
}
} // namespace webrtc

View File

@ -32,10 +32,5 @@ bool CodecSupported(NetEqDecoder codec_type);
// Returns the sample rate for |codec_type|.
int CodecSampleRateHz(NetEqDecoder codec_type);
// Creates an AudioDecoder object of type |codec_type|. Returns NULL for for
// unsupported codecs, and when creating an AudioDecoder is not applicable
// (e.g., for RED and DTMF/AVT types).
AudioDecoder* CreateAudioDecoder(NetEqDecoder codec_type);
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_NETEQ_AUDIO_DECODER_IMPL_H_

View File

@ -11,6 +11,7 @@
// Unit tests for DecisionLogic class and derived classes.
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
#include "webrtc/modules/audio_coding/neteq/buffer_level_filter.h"
#include "webrtc/modules/audio_coding/neteq/decoder_database.h"
#include "webrtc/modules/audio_coding/neteq/decision_logic.h"
@ -24,7 +25,8 @@ namespace webrtc {
TEST(DecisionLogic, CreateAndDestroy) {
int fs_hz = 8000;
int output_size_samples = fs_hz / 100; // Samples per 10 ms.
DecoderDatabase decoder_database;
DecoderDatabase decoder_database(
std::unique_ptr<MockAudioDecoderFactory>(new MockAudioDecoderFactory));
TickTimer tick_timer;
PacketBuffer packet_buffer(10, &tick_timer);
DelayPeakDetector delay_peak_detector(&tick_timer);

View File

@ -19,9 +19,11 @@
namespace webrtc {
DecoderDatabase::DecoderDatabase()
: active_decoder_type_(-1), active_cng_decoder_type_(-1) {
}
DecoderDatabase::DecoderDatabase(
std::unique_ptr<AudioDecoderFactory> decoder_factory)
: active_decoder_type_(-1),
active_cng_decoder_type_(-1),
decoder_factory_(std::move(decoder_factory)) {}
DecoderDatabase::~DecoderDatabase() = default;
@ -32,20 +34,23 @@ DecoderDatabase::DecoderInfo::DecoderInfo(NetEqDecoder ct,
: codec_type(ct),
name(nm),
fs_hz(fs),
external_decoder(ext_dec) {}
external_decoder(ext_dec),
audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)) {}
DecoderDatabase::DecoderInfo::DecoderInfo(DecoderInfo&&) = default;
DecoderDatabase::DecoderInfo::~DecoderInfo() = default;
AudioDecoder* DecoderDatabase::DecoderInfo::GetDecoder() {
AudioDecoder* DecoderDatabase::DecoderInfo::GetDecoder(
AudioDecoderFactory* factory) {
if (external_decoder) {
RTC_DCHECK(!decoder_);
return external_decoder;
}
RTC_DCHECK(audio_format_);
if (!decoder_) {
decoder_.reset(CreateAudioDecoder(codec_type));
decoder_ = factory->MakeAudioDecoder(*audio_format_);
}
RTC_DCHECK(decoder_);
RTC_DCHECK(decoder_) << "Failed to create: " << *audio_format_;
return decoder_.get();
}
@ -155,7 +160,7 @@ AudioDecoder* DecoderDatabase::GetDecoder(uint8_t rtp_payload_type) {
return NULL;
}
DecoderInfo* info = &(*it).second;
return info->GetDecoder();
return info->GetDecoder(decoder_factory_.get());
}
bool DecoderDatabase::IsType(uint8_t rtp_payload_type,

View File

@ -17,6 +17,8 @@
#include "webrtc/base/constructormagic.h"
#include "webrtc/common_types.h" // NULL
#include "webrtc/modules/audio_coding/codecs/audio_decoder_factory.h"
#include "webrtc/modules/audio_coding/codecs/audio_format.h"
#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h"
#include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
#include "webrtc/modules/audio_coding/neteq/packet.h"
@ -47,7 +49,7 @@ class DecoderDatabase {
~DecoderInfo();
// Get the AudioDecoder object, creating it first if necessary.
AudioDecoder* GetDecoder();
AudioDecoder* GetDecoder(AudioDecoderFactory* factory);
// Delete the AudioDecoder object, unless it's external. (This means we can
// always recreate it later if we need it.)
@ -59,6 +61,7 @@ class DecoderDatabase {
AudioDecoder* const external_decoder;
private:
const rtc::Optional<SdpAudioFormat> audio_format_;
std::unique_ptr<AudioDecoder> decoder_;
};
@ -66,7 +69,7 @@ class DecoderDatabase {
// only 7 bits).
static const uint8_t kRtpPayloadTypeError = 0xFF;
DecoderDatabase();
DecoderDatabase(std::unique_ptr<AudioDecoderFactory> decoder_factory);
virtual ~DecoderDatabase();
@ -157,6 +160,7 @@ class DecoderDatabase {
int active_decoder_type_;
int active_cng_decoder_type_;
std::unique_ptr<ComfortNoiseDecoder> active_cng_decoder_;
const std::unique_ptr<AudioDecoderFactory> decoder_factory_;
RTC_DISALLOW_COPY_AND_ASSIGN(DecoderDatabase);
};

View File

@ -19,17 +19,21 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h"
#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
namespace webrtc {
TEST(DecoderDatabase, CreateAndDestroy) {
DecoderDatabase db;
std::unique_ptr<MockAudioDecoderFactory> factory(new MockAudioDecoderFactory);
DecoderDatabase db(std::move(factory));
EXPECT_EQ(0, db.Size());
EXPECT_TRUE(db.Empty());
}
TEST(DecoderDatabase, InsertAndRemove) {
DecoderDatabase db;
std::unique_ptr<MockAudioDecoderFactory> factory(new MockAudioDecoderFactory);
DecoderDatabase db(std::move(factory));
const uint8_t kPayloadType = 0;
const std::string kCodecName = "Robert\'); DROP TABLE Students;";
EXPECT_EQ(
@ -43,7 +47,8 @@ TEST(DecoderDatabase, InsertAndRemove) {
}
TEST(DecoderDatabase, GetDecoderInfo) {
DecoderDatabase db;
std::unique_ptr<MockAudioDecoderFactory> factory(new MockAudioDecoderFactory);
DecoderDatabase db(std::move(factory));
const uint8_t kPayloadType = 0;
const std::string kCodecName = "Robert\'); DROP TABLE Students;";
EXPECT_EQ(
@ -61,7 +66,8 @@ TEST(DecoderDatabase, GetDecoderInfo) {
}
TEST(DecoderDatabase, GetRtpPayloadType) {
DecoderDatabase db;
std::unique_ptr<MockAudioDecoderFactory> factory(new MockAudioDecoderFactory);
DecoderDatabase db(std::move(factory));
const uint8_t kPayloadType = 0;
const std::string kCodecName = "Robert\'); DROP TABLE Students;";
EXPECT_EQ(
@ -75,7 +81,7 @@ TEST(DecoderDatabase, GetRtpPayloadType) {
}
TEST(DecoderDatabase, GetDecoder) {
DecoderDatabase db;
DecoderDatabase db(CreateBuiltinAudioDecoderFactory());
const uint8_t kPayloadType = 0;
const std::string kCodecName = "Robert\'); DROP TABLE Students;";
EXPECT_EQ(DecoderDatabase::kOK,
@ -86,7 +92,8 @@ TEST(DecoderDatabase, GetDecoder) {
}
TEST(DecoderDatabase, TypeTests) {
DecoderDatabase db;
std::unique_ptr<MockAudioDecoderFactory> factory(new MockAudioDecoderFactory);
DecoderDatabase db(std::move(factory));
const uint8_t kPayloadTypePcmU = 0;
const uint8_t kPayloadTypeCng = 13;
const uint8_t kPayloadTypeDtmf = 100;
@ -121,7 +128,8 @@ TEST(DecoderDatabase, TypeTests) {
}
TEST(DecoderDatabase, ExternalDecoder) {
DecoderDatabase db;
std::unique_ptr<MockAudioDecoderFactory> factory(new MockAudioDecoderFactory);
DecoderDatabase db(std::move(factory));
const uint8_t kPayloadType = 0;
const std::string kCodecName = "Robert\'); DROP TABLE Students;";
MockAudioDecoder decoder;
@ -150,7 +158,8 @@ TEST(DecoderDatabase, ExternalDecoder) {
}
TEST(DecoderDatabase, CheckPayloadTypes) {
DecoderDatabase db;
std::unique_ptr<MockAudioDecoderFactory> factory(new MockAudioDecoderFactory);
DecoderDatabase db(std::move(factory));
// Load a number of payloads into the database. Payload types are 0, 1, ...,
// while the decoder type is the same for all payload types (this does not
// matter for the test).
@ -194,7 +203,7 @@ TEST(DecoderDatabase, CheckPayloadTypes) {
// Test the methods for setting and getting active speech and CNG decoders.
TEST(DecoderDatabase, IF_ISAC(ActiveDecoders)) {
DecoderDatabase db;
DecoderDatabase db(CreateBuiltinAudioDecoderFactory());
// Load payload types.
ASSERT_EQ(DecoderDatabase::kOK,
db.RegisterPayload(0, NetEqDecoder::kDecoderPCMu, "pcmu"));

View File

@ -21,6 +21,7 @@ namespace webrtc {
class MockDecoderDatabase : public DecoderDatabase {
public:
MockDecoderDatabase() : DecoderDatabase(nullptr) {}
virtual ~MockDecoderDatabase() { Die(); }
MOCK_METHOD0(Die, void());
MOCK_CONST_METHOD0(Empty,

View File

@ -51,6 +51,8 @@
'dependencies': [
'<@(neteq_dependencies)',
'<(webrtc_root)/common.gyp:webrtc_common',
'builtin_audio_decoder_factory',
'rent_a_codec',
],
'defines': [
'<@(neteq_defines)',

View File

@ -22,6 +22,7 @@
#include "webrtc/base/trace_event.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h"
#include "webrtc/modules/audio_coding/neteq/accelerate.h"
#include "webrtc/modules/audio_coding/neteq/background_noise.h"
#include "webrtc/modules/audio_coding/neteq/buffer_level_filter.h"
@ -57,7 +58,7 @@ namespace webrtc {
NetEqImpl::Dependencies::Dependencies(const NetEq::Config& config)
: tick_timer(new TickTimer),
buffer_level_filter(new BufferLevelFilter),
decoder_database(new DecoderDatabase),
decoder_database(new DecoderDatabase(CreateBuiltinAudioDecoderFactory())),
delay_peak_detector(new DelayPeakDetector(tick_timer.get())),
delay_manager(new DelayManager(config.max_packets_in_buffer,
delay_peak_detector.get(),

View File

@ -18,6 +18,8 @@
#include <utility> // pair
#include "testing/gtest/include/gtest/gtest.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/mock/mock_decoder_database.h"
#include "webrtc/modules/audio_coding/neteq/packet.h"
@ -309,7 +311,8 @@ TEST(RedPayloadSplitter, CheckRedPayloads) {
// Use a real DecoderDatabase object here instead of a mock, since it is
// easier to just register the payload types and let the actual implementation
// do its job.
DecoderDatabase decoder_database;
std::unique_ptr<MockAudioDecoderFactory> factory(new MockAudioDecoderFactory);
DecoderDatabase decoder_database(std::move(factory));
decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderCNGnb, "cng-nb");
decoder_database.RegisterPayload(1, NetEqDecoder::kDecoderPCMu, "pcmu");
decoder_database.RegisterPayload(2, NetEqDecoder::kDecoderAVT, "avt");
@ -743,7 +746,7 @@ TEST(IlbcPayloadSplitter, UnevenPayload) {
TEST(FecPayloadSplitter, MixedPayload) {
PacketList packet_list;
DecoderDatabase decoder_database;
DecoderDatabase decoder_database(CreateBuiltinAudioDecoderFactory());
decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderOpus, "opus");
decoder_database.RegisterPayload(1, NetEqDecoder::kDecoderPCMu, "pcmu");
@ -798,7 +801,7 @@ TEST(FecPayloadSplitter, MixedPayload) {
TEST(FecPayloadSplitter, EmbedFecInRed) {
PacketList packet_list;
DecoderDatabase decoder_database;
DecoderDatabase decoder_database(CreateBuiltinAudioDecoderFactory());
const int kTimestampOffset = 20 * 48; // 20 ms * 48 kHz.
uint8_t payload_types[] = {0, 0};