RentACodec: New class that takes over part of ACMCodecDB's job
Following CLs will finish the takeover completely. After that, RentACodec will also start creating and owning codecs, at which point its name will start making sense. BUG=webrtc:5028 Review URL: https://codereview.webrtc.org/1412683006 Cr-Commit-Position: refs/heads/master@{#10432}
This commit is contained in:
@ -9,6 +9,39 @@
|
|||||||
import("//build/config/arm.gni")
|
import("//build/config/arm.gni")
|
||||||
import("../../build/webrtc.gni")
|
import("../../build/webrtc.gni")
|
||||||
|
|
||||||
|
source_set("rent_a_codec") {
|
||||||
|
sources = [
|
||||||
|
"main/acm2/acm_codec_database.cc",
|
||||||
|
"main/acm2/acm_codec_database.h",
|
||||||
|
"main/acm2/rent_a_codec.cc",
|
||||||
|
"main/acm2/rent_a_codec.h",
|
||||||
|
]
|
||||||
|
configs += [ "../..:common_config" ]
|
||||||
|
public_configs = [ "../..:common_inherited_config" ]
|
||||||
|
deps = [
|
||||||
|
"../..:webrtc_common",
|
||||||
|
]
|
||||||
|
|
||||||
|
defines = []
|
||||||
|
if (rtc_include_opus) {
|
||||||
|
defines += [ "WEBRTC_CODEC_OPUS" ]
|
||||||
|
}
|
||||||
|
if (!build_with_mozilla) {
|
||||||
|
if (current_cpu == "arm") {
|
||||||
|
defines += [ "WEBRTC_CODEC_ISACFX" ]
|
||||||
|
} else {
|
||||||
|
defines += [ "WEBRTC_CODEC_ISAC" ]
|
||||||
|
}
|
||||||
|
defines += [ "WEBRTC_CODEC_G722" ]
|
||||||
|
}
|
||||||
|
if (!build_with_mozilla && !build_with_chromium) {
|
||||||
|
defines += [
|
||||||
|
"WEBRTC_CODEC_ILBC",
|
||||||
|
"WEBRTC_CODEC_RED",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config("audio_coding_config") {
|
config("audio_coding_config") {
|
||||||
include_dirs = [
|
include_dirs = [
|
||||||
"main/interface",
|
"main/interface",
|
||||||
@ -18,8 +51,6 @@ config("audio_coding_config") {
|
|||||||
|
|
||||||
source_set("audio_coding") {
|
source_set("audio_coding") {
|
||||||
sources = [
|
sources = [
|
||||||
"main/acm2/acm_codec_database.cc",
|
|
||||||
"main/acm2/acm_codec_database.h",
|
|
||||||
"main/acm2/acm_common_defs.h",
|
"main/acm2/acm_common_defs.h",
|
||||||
"main/acm2/acm_receiver.cc",
|
"main/acm2/acm_receiver.cc",
|
||||||
"main/acm2/acm_receiver.h",
|
"main/acm2/acm_receiver.h",
|
||||||
@ -69,6 +100,7 @@ source_set("audio_coding") {
|
|||||||
":g711",
|
":g711",
|
||||||
":neteq",
|
":neteq",
|
||||||
":pcm16b",
|
":pcm16b",
|
||||||
|
":rent_a_codec",
|
||||||
"../..:rtc_event_log",
|
"../..:rtc_event_log",
|
||||||
"../..:webrtc_common",
|
"../..:webrtc_common",
|
||||||
"../../common_audio",
|
"../../common_audio",
|
||||||
|
|||||||
@ -223,7 +223,7 @@ const NetEqDecoder ACMCodecDB::neteq_decoders_[] = {
|
|||||||
// TODO(tlegrand): replace memcpy with a pointer to the data base memory.
|
// TODO(tlegrand): replace memcpy with a pointer to the data base memory.
|
||||||
int ACMCodecDB::Codec(int codec_id, CodecInst* codec_inst) {
|
int ACMCodecDB::Codec(int codec_id, CodecInst* codec_inst) {
|
||||||
// Error check to see that codec_id is not out of bounds.
|
// Error check to see that codec_id is not out of bounds.
|
||||||
if ((codec_id < 0) || (codec_id >= kNumCodecs)) {
|
if (static_cast<size_t>(codec_id) >= RentACodec::NumberOfCodecs()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +318,7 @@ int ACMCodecDB::CodecId(const CodecInst& codec_inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ACMCodecDB::CodecId(const char* payload_name, int frequency, int channels) {
|
int ACMCodecDB::CodecId(const char* payload_name, int frequency, int channels) {
|
||||||
for (int id = 0; id < kNumCodecs; id++) {
|
for (const CodecInst& ci : RentACodec::Database()) {
|
||||||
bool name_match = false;
|
bool name_match = false;
|
||||||
bool frequency_match = false;
|
bool frequency_match = false;
|
||||||
bool channels_match = false;
|
bool channels_match = false;
|
||||||
@ -326,11 +326,11 @@ int ACMCodecDB::CodecId(const char* payload_name, int frequency, int channels) {
|
|||||||
// Payload name, sampling frequency and number of channels need to match.
|
// Payload name, sampling frequency and number of channels need to match.
|
||||||
// NOTE! If |frequency| is -1, the frequency is not applicable, and is
|
// NOTE! If |frequency| is -1, the frequency is not applicable, and is
|
||||||
// always treated as true, like for RED.
|
// always treated as true, like for RED.
|
||||||
name_match = (STR_CASE_CMP(database_[id].plname, payload_name) == 0);
|
name_match = (STR_CASE_CMP(ci.plname, payload_name) == 0);
|
||||||
frequency_match = (frequency == database_[id].plfreq) || (frequency == -1);
|
frequency_match = (frequency == ci.plfreq) || (frequency == -1);
|
||||||
// The number of channels must match for all codecs but Opus.
|
// The number of channels must match for all codecs but Opus.
|
||||||
if (STR_CASE_CMP(payload_name, "opus") != 0) {
|
if (STR_CASE_CMP(payload_name, "opus") != 0) {
|
||||||
channels_match = (channels == database_[id].channels);
|
channels_match = (channels == ci.channels);
|
||||||
} else {
|
} else {
|
||||||
// For opus we just check that number of channels is valid.
|
// For opus we just check that number of channels is valid.
|
||||||
channels_match = (channels == 1 || channels == 2);
|
channels_match = (channels == 1 || channels == 2);
|
||||||
@ -338,7 +338,7 @@ int ACMCodecDB::CodecId(const char* payload_name, int frequency, int channels) {
|
|||||||
|
|
||||||
if (name_match && frequency_match && channels_match) {
|
if (name_match && frequency_match && channels_match) {
|
||||||
// We have found a matching codec in the list.
|
// We have found a matching codec in the list.
|
||||||
return id;
|
return &ci - RentACodec::Database().data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,12 +354,9 @@ int ACMCodecDB::ReceiverCodecNumber(const CodecInst& codec_inst) {
|
|||||||
// Returns the codec sampling frequency for codec with id = "codec_id" in
|
// Returns the codec sampling frequency for codec with id = "codec_id" in
|
||||||
// database.
|
// database.
|
||||||
int ACMCodecDB::CodecFreq(int codec_id) {
|
int ACMCodecDB::CodecFreq(int codec_id) {
|
||||||
// Error check to see that codec_id is not out of bounds.
|
const size_t i = static_cast<size_t>(codec_id);
|
||||||
if (codec_id < 0 || codec_id >= kNumCodecs) {
|
const auto db = RentACodec::Database();
|
||||||
return -1;
|
return i < db.size() ? db[i].plfreq : -1;
|
||||||
}
|
|
||||||
|
|
||||||
return database_[codec_id].plfreq;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if the payload type is in the valid range.
|
// Checks if the payload type is in the valid range.
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "webrtc/common_types.h"
|
#include "webrtc/common_types.h"
|
||||||
#include "webrtc/engine_configurations.h"
|
#include "webrtc/engine_configurations.h"
|
||||||
|
#include "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h"
|
||||||
#include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
|
#include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -27,85 +28,6 @@ namespace acm2 {
|
|||||||
// TODO(tlegrand): replace class ACMCodecDB with a namespace.
|
// TODO(tlegrand): replace class ACMCodecDB with a namespace.
|
||||||
class ACMCodecDB {
|
class ACMCodecDB {
|
||||||
public:
|
public:
|
||||||
// Enum with array indexes for the supported codecs. NOTE! The order MUST
|
|
||||||
// be the same as when creating the database in acm_codec_database.cc.
|
|
||||||
enum {
|
|
||||||
kNone = -1
|
|
||||||
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
|
|
||||||
, kISAC
|
|
||||||
# if (defined(WEBRTC_CODEC_ISAC))
|
|
||||||
, kISACSWB
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
// Mono
|
|
||||||
, kPCM16B
|
|
||||||
, kPCM16Bwb
|
|
||||||
, kPCM16Bswb32kHz
|
|
||||||
// Stereo
|
|
||||||
, kPCM16B_2ch
|
|
||||||
, kPCM16Bwb_2ch
|
|
||||||
, kPCM16Bswb32kHz_2ch
|
|
||||||
// Mono
|
|
||||||
, kPCMU
|
|
||||||
, kPCMA
|
|
||||||
// Stereo
|
|
||||||
, kPCMU_2ch
|
|
||||||
, kPCMA_2ch
|
|
||||||
#ifdef WEBRTC_CODEC_ILBC
|
|
||||||
, kILBC
|
|
||||||
#endif
|
|
||||||
#ifdef WEBRTC_CODEC_G722
|
|
||||||
// Mono
|
|
||||||
, kG722
|
|
||||||
// Stereo
|
|
||||||
, kG722_2ch
|
|
||||||
#endif
|
|
||||||
#ifdef WEBRTC_CODEC_OPUS
|
|
||||||
// Mono and stereo
|
|
||||||
, kOpus
|
|
||||||
#endif
|
|
||||||
, kCNNB
|
|
||||||
, kCNWB
|
|
||||||
, kCNSWB
|
|
||||||
#ifdef ENABLE_48000_HZ
|
|
||||||
, kCNFB
|
|
||||||
#endif
|
|
||||||
, kAVT
|
|
||||||
#ifdef WEBRTC_CODEC_RED
|
|
||||||
, kRED
|
|
||||||
#endif
|
|
||||||
, kNumCodecs
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set unsupported codecs to -1
|
|
||||||
#ifndef WEBRTC_CODEC_ISAC
|
|
||||||
enum {kISACSWB = -1};
|
|
||||||
# ifndef WEBRTC_CODEC_ISACFX
|
|
||||||
enum {kISAC = -1};
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
// 48 kHz not supported, always set to -1.
|
|
||||||
enum {kPCM16Bswb48kHz = -1};
|
|
||||||
#ifndef WEBRTC_CODEC_ILBC
|
|
||||||
enum {kILBC = -1};
|
|
||||||
#endif
|
|
||||||
#ifndef WEBRTC_CODEC_G722
|
|
||||||
// Mono
|
|
||||||
enum {kG722 = -1};
|
|
||||||
// Stereo
|
|
||||||
enum {kG722_2ch = -1};
|
|
||||||
#endif
|
|
||||||
#ifndef WEBRTC_CODEC_OPUS
|
|
||||||
// Mono and stereo
|
|
||||||
enum {kOpus = -1};
|
|
||||||
#endif
|
|
||||||
#ifndef WEBRTC_CODEC_RED
|
|
||||||
enum {kRED = -1};
|
|
||||||
#endif
|
|
||||||
#ifndef ENABLE_48000_HZ
|
|
||||||
enum { kCNFB = -1 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// kMaxNumCodecs - Maximum number of codecs that can be activated in one
|
// kMaxNumCodecs - Maximum number of codecs that can be activated in one
|
||||||
// build.
|
// build.
|
||||||
// kMaxNumPacketSize - Maximum number of allowed packet sizes for one codec.
|
// kMaxNumPacketSize - Maximum number of allowed packet sizes for one codec.
|
||||||
|
|||||||
@ -111,9 +111,13 @@ void SetAudioFrameActivityAndType(bool vad_enabled,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Is the given codec a CNG codec?
|
// Is the given codec a CNG codec?
|
||||||
|
// TODO(kwiberg): Move to RentACodec.
|
||||||
bool IsCng(int codec_id) {
|
bool IsCng(int codec_id) {
|
||||||
return (codec_id == ACMCodecDB::kCNNB || codec_id == ACMCodecDB::kCNWB ||
|
auto i = RentACodec::CodecIdFromIndex(codec_id);
|
||||||
codec_id == ACMCodecDB::kCNSWB || codec_id == ACMCodecDB::kCNFB);
|
return (i && (*i == RentACodec::CodecId::kCNNB ||
|
||||||
|
*i == RentACodec::CodecId::kCNWB ||
|
||||||
|
*i == RentACodec::CodecId::kCNSWB ||
|
||||||
|
*i == RentACodec::CodecId::kCNFB));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -241,7 +245,8 @@ int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header,
|
|||||||
if (last_audio_decoder_ && last_audio_decoder_->channels > 1)
|
if (last_audio_decoder_ && last_audio_decoder_->channels > 1)
|
||||||
return 0;
|
return 0;
|
||||||
packet_type = InitialDelayManager::kCngPacket;
|
packet_type = InitialDelayManager::kCngPacket;
|
||||||
} else if (decoder->acm_codec_id == ACMCodecDB::kAVT) {
|
} else if (decoder->acm_codec_id ==
|
||||||
|
*RentACodec::CodecIndexFromId(RentACodec::CodecId::kAVT)) {
|
||||||
packet_type = InitialDelayManager::kAvtPacket;
|
packet_type = InitialDelayManager::kAvtPacket;
|
||||||
} else {
|
} else {
|
||||||
if (decoder != last_audio_decoder_) {
|
if (decoder != last_audio_decoder_) {
|
||||||
@ -566,11 +571,13 @@ int AcmReceiver::last_audio_codec_id() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int AcmReceiver::RedPayloadType() const {
|
int AcmReceiver::RedPayloadType() const {
|
||||||
if (ACMCodecDB::kRED >= 0) { // This ensures that RED is defined in WebRTC.
|
const auto red_index =
|
||||||
|
RentACodec::CodecIndexFromId(RentACodec::CodecId::kRED);
|
||||||
|
if (red_index) {
|
||||||
CriticalSectionScoped lock(crit_sect_.get());
|
CriticalSectionScoped lock(crit_sect_.get());
|
||||||
for (const auto& decoder_pair : decoders_) {
|
for (const auto& decoder_pair : decoders_) {
|
||||||
const Decoder& decoder = decoder_pair.second;
|
const Decoder& decoder = decoder_pair.second;
|
||||||
if (decoder.acm_codec_id == ACMCodecDB::kRED)
|
if (decoder.acm_codec_id == *red_index)
|
||||||
return decoder.payload_type;
|
return decoder.payload_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -737,8 +744,10 @@ const AcmReceiver::Decoder* AcmReceiver::RtpHeaderToDecoder(
|
|||||||
const RTPHeader& rtp_header,
|
const RTPHeader& rtp_header,
|
||||||
const uint8_t* payload) const {
|
const uint8_t* payload) const {
|
||||||
auto it = decoders_.find(rtp_header.payloadType);
|
auto it = decoders_.find(rtp_header.payloadType);
|
||||||
if (ACMCodecDB::kRED >= 0 && // This ensures that RED is defined in WebRTC.
|
const auto red_index =
|
||||||
it != decoders_.end() && ACMCodecDB::kRED == it->second.acm_codec_id) {
|
RentACodec::CodecIndexFromId(RentACodec::CodecId::kRED);
|
||||||
|
if (red_index && // This ensures that RED is defined in WebRTC.
|
||||||
|
it != decoders_.end() && it->second.acm_codec_id == *red_index) {
|
||||||
// This is a RED packet, get the payload of the audio codec.
|
// This is a RED packet, get the payload of the audio codec.
|
||||||
it = decoders_.find(payload[0] & 0x7F);
|
it = decoders_.find(payload[0] & 0x7F);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,19 @@ bool CodecsEqual(const CodecInst& codec_a, const CodecInst& codec_b) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CodecIdInst {
|
||||||
|
explicit CodecIdInst(RentACodec::CodecId codec_id) {
|
||||||
|
const auto codec_ix = RentACodec::CodecIndexFromId(codec_id);
|
||||||
|
EXPECT_TRUE(codec_ix);
|
||||||
|
id = *codec_ix;
|
||||||
|
const auto codec_inst = RentACodec::CodecInstById(codec_id);
|
||||||
|
EXPECT_TRUE(codec_inst);
|
||||||
|
inst = *codec_inst;
|
||||||
|
}
|
||||||
|
int id;
|
||||||
|
CodecInst inst;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class AcmReceiverTestOldApi : public AudioPacketizationCallback,
|
class AcmReceiverTestOldApi : public AudioPacketizationCallback,
|
||||||
@ -57,9 +70,7 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback,
|
|||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
ASSERT_TRUE(receiver_.get() != NULL);
|
ASSERT_TRUE(receiver_.get() != NULL);
|
||||||
ASSERT_TRUE(acm_.get() != NULL);
|
ASSERT_TRUE(acm_.get() != NULL);
|
||||||
for (int n = 0; n < ACMCodecDB::kNumCodecs; n++) {
|
codecs_ = RentACodec::Database();
|
||||||
ASSERT_EQ(0, ACMCodecDB::Codec(n, &codecs_[n]));
|
|
||||||
}
|
|
||||||
|
|
||||||
acm_->InitializeReceiver();
|
acm_->InitializeReceiver();
|
||||||
acm_->RegisterTransportCallback(this);
|
acm_->RegisterTransportCallback(this);
|
||||||
@ -103,14 +114,14 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last element of id should be negative.
|
template <size_t N>
|
||||||
void AddSetOfCodecs(const int* id) {
|
void AddSetOfCodecs(const RentACodec::CodecId(&ids)[N]) {
|
||||||
int n = 0;
|
for (auto id : ids) {
|
||||||
while (id[n] >= 0) {
|
const auto i = RentACodec::CodecIndexFromId(id);
|
||||||
ASSERT_EQ(0, receiver_->AddCodec(id[n], codecs_[id[n]].pltype,
|
ASSERT_TRUE(i);
|
||||||
codecs_[id[n]].channels,
|
ASSERT_EQ(
|
||||||
codecs_[id[n]].plfreq, NULL));
|
0, receiver_->AddCodec(*i, codecs_[*i].pltype, codecs_[*i].channels,
|
||||||
++n;
|
codecs_[*i].plfreq, nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +155,7 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_ptr<AcmReceiver> receiver_;
|
rtc::scoped_ptr<AcmReceiver> receiver_;
|
||||||
CodecInst codecs_[ACMCodecDB::kMaxNumCodecs];
|
rtc::ArrayView<const CodecInst> codecs_;
|
||||||
rtc::scoped_ptr<AudioCodingModule> acm_;
|
rtc::scoped_ptr<AudioCodingModule> acm_;
|
||||||
WebRtcRTPHeader rtp_header_;
|
WebRtcRTPHeader rtp_header_;
|
||||||
uint32_t timestamp_;
|
uint32_t timestamp_;
|
||||||
@ -155,14 +166,14 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback,
|
|||||||
|
|
||||||
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecGetCodec)) {
|
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecGetCodec)) {
|
||||||
// Add codec.
|
// Add codec.
|
||||||
for (int n = 0; n < ACMCodecDB::kNumCodecs; ++n) {
|
for (size_t n = 0; n < codecs_.size(); ++n) {
|
||||||
if (n & 0x1) // Just add codecs with odd index.
|
if (n & 0x1) // Just add codecs with odd index.
|
||||||
EXPECT_EQ(0,
|
EXPECT_EQ(0,
|
||||||
receiver_->AddCodec(n, codecs_[n].pltype, codecs_[n].channels,
|
receiver_->AddCodec(n, codecs_[n].pltype, codecs_[n].channels,
|
||||||
codecs_[n].plfreq, NULL));
|
codecs_[n].plfreq, NULL));
|
||||||
}
|
}
|
||||||
// Get codec and compare.
|
// Get codec and compare.
|
||||||
for (int n = 0; n < ACMCodecDB::kNumCodecs; ++n) {
|
for (size_t n = 0; n < codecs_.size(); ++n) {
|
||||||
CodecInst my_codec;
|
CodecInst my_codec;
|
||||||
if (n & 0x1) {
|
if (n & 0x1) {
|
||||||
// Codecs with odd index should match the reference.
|
// Codecs with odd index should match the reference.
|
||||||
@ -178,58 +189,52 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecGetCodec)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) {
|
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) {
|
||||||
const int codec_id = ACMCodecDB::kPCMA;
|
const CodecIdInst codec1(RentACodec::CodecId::kPCMA);
|
||||||
CodecInst ref_codec1;
|
CodecInst codec2 = codec1.inst;
|
||||||
EXPECT_EQ(0, ACMCodecDB::Codec(codec_id, &ref_codec1));
|
++codec2.pltype;
|
||||||
CodecInst ref_codec2 = ref_codec1;
|
|
||||||
++ref_codec2.pltype;
|
|
||||||
CodecInst test_codec;
|
CodecInst test_codec;
|
||||||
|
|
||||||
// Register the same codec with different payloads.
|
// Register the same codec with different payloads.
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype,
|
||||||
0, receiver_->AddCodec(codec_id, ref_codec1.pltype, ref_codec1.channels,
|
codec1.inst.channels, codec1.inst.plfreq,
|
||||||
ref_codec1.plfreq, NULL));
|
nullptr));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec2.pltype, codec2.channels,
|
||||||
0, receiver_->AddCodec(codec_id, ref_codec2.pltype, ref_codec2.channels,
|
codec2.plfreq, NULL));
|
||||||
ref_codec2.plfreq, NULL));
|
|
||||||
|
|
||||||
// Both payload types should exist.
|
// Both payload types should exist.
|
||||||
EXPECT_EQ(0, receiver_->DecoderByPayloadType(ref_codec1.pltype, &test_codec));
|
EXPECT_EQ(0,
|
||||||
EXPECT_EQ(true, CodecsEqual(ref_codec1, test_codec));
|
receiver_->DecoderByPayloadType(codec1.inst.pltype, &test_codec));
|
||||||
EXPECT_EQ(0, receiver_->DecoderByPayloadType(ref_codec2.pltype, &test_codec));
|
EXPECT_EQ(true, CodecsEqual(codec1.inst, test_codec));
|
||||||
EXPECT_EQ(true, CodecsEqual(ref_codec2, test_codec));
|
EXPECT_EQ(0, receiver_->DecoderByPayloadType(codec2.pltype, &test_codec));
|
||||||
|
EXPECT_EQ(true, CodecsEqual(codec2, test_codec));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangeCodecId)) {
|
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangeCodecId)) {
|
||||||
const int codec_id1 = ACMCodecDB::kPCMU;
|
const CodecIdInst codec1(RentACodec::CodecId::kPCMU);
|
||||||
CodecInst ref_codec1;
|
CodecIdInst codec2(RentACodec::CodecId::kPCMA);
|
||||||
EXPECT_EQ(0, ACMCodecDB::Codec(codec_id1, &ref_codec1));
|
codec2.inst.pltype = codec1.inst.pltype;
|
||||||
const int codec_id2 = ACMCodecDB::kPCMA;
|
|
||||||
CodecInst ref_codec2;
|
|
||||||
EXPECT_EQ(0, ACMCodecDB::Codec(codec_id2, &ref_codec2));
|
|
||||||
ref_codec2.pltype = ref_codec1.pltype;
|
|
||||||
CodecInst test_codec;
|
CodecInst test_codec;
|
||||||
|
|
||||||
// Register the same payload type with different codec ID.
|
// Register the same payload type with different codec ID.
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype,
|
||||||
0, receiver_->AddCodec(codec_id1, ref_codec1.pltype, ref_codec1.channels,
|
codec1.inst.channels, codec1.inst.plfreq,
|
||||||
ref_codec1.plfreq, NULL));
|
nullptr));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(0, receiver_->AddCodec(codec2.id, codec2.inst.pltype,
|
||||||
0, receiver_->AddCodec(codec_id2, ref_codec2.pltype, ref_codec2.channels,
|
codec2.inst.channels, codec2.inst.plfreq,
|
||||||
ref_codec2.plfreq, NULL));
|
nullptr));
|
||||||
|
|
||||||
// Make sure that the last codec is used.
|
// Make sure that the last codec is used.
|
||||||
EXPECT_EQ(0, receiver_->DecoderByPayloadType(ref_codec2.pltype, &test_codec));
|
EXPECT_EQ(0,
|
||||||
EXPECT_EQ(true, CodecsEqual(ref_codec2, test_codec));
|
receiver_->DecoderByPayloadType(codec2.inst.pltype, &test_codec));
|
||||||
|
EXPECT_EQ(true, CodecsEqual(codec2.inst, test_codec));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecRemoveCodec)) {
|
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecRemoveCodec)) {
|
||||||
CodecInst codec;
|
const CodecIdInst codec(RentACodec::CodecId::kPCMA);
|
||||||
const int codec_id = ACMCodecDB::kPCMA;
|
const int payload_type = codec.inst.pltype;
|
||||||
EXPECT_EQ(0, ACMCodecDB::Codec(codec_id, &codec));
|
EXPECT_EQ(
|
||||||
const int payload_type = codec.pltype;
|
0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
|
||||||
EXPECT_EQ(0, receiver_->AddCodec(codec_id, codec.pltype, codec.channels,
|
codec.inst.plfreq, nullptr));
|
||||||
codec.plfreq, NULL));
|
|
||||||
|
|
||||||
// Remove non-existing codec should not fail. ACM1 legacy.
|
// Remove non-existing codec should not fail. ACM1 legacy.
|
||||||
EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1));
|
EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1));
|
||||||
@ -238,46 +243,43 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecRemoveCodec)) {
|
|||||||
EXPECT_EQ(0, receiver_->RemoveCodec(payload_type));
|
EXPECT_EQ(0, receiver_->RemoveCodec(payload_type));
|
||||||
|
|
||||||
// Ask for the removed codec, must fail.
|
// Ask for the removed codec, must fail.
|
||||||
EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &codec));
|
CodecInst ci;
|
||||||
|
EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &ci));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(SampleRate)) {
|
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(SampleRate)) {
|
||||||
const int kCodecId[] = {
|
const RentACodec::CodecId kCodecId[] = {RentACodec::CodecId::kISAC,
|
||||||
ACMCodecDB::kISAC, ACMCodecDB::kISACSWB,
|
RentACodec::CodecId::kISACSWB};
|
||||||
-1 // Terminator.
|
|
||||||
};
|
|
||||||
AddSetOfCodecs(kCodecId);
|
AddSetOfCodecs(kCodecId);
|
||||||
|
|
||||||
AudioFrame frame;
|
AudioFrame frame;
|
||||||
const int kOutSampleRateHz = 8000; // Different than codec sample rate.
|
const int kOutSampleRateHz = 8000; // Different than codec sample rate.
|
||||||
int n = 0;
|
for (const auto codec_id : kCodecId) {
|
||||||
while (kCodecId[n] >= 0) {
|
const CodecIdInst codec(codec_id);
|
||||||
const int num_10ms_frames = codecs_[kCodecId[n]].pacsize /
|
const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
|
||||||
(codecs_[kCodecId[n]].plfreq / 100);
|
InsertOnePacketOfSilence(codec.id);
|
||||||
InsertOnePacketOfSilence(kCodecId[n]);
|
|
||||||
for (int k = 0; k < num_10ms_frames; ++k) {
|
for (int k = 0; k < num_10ms_frames; ++k) {
|
||||||
EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame));
|
EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame));
|
||||||
}
|
}
|
||||||
EXPECT_EQ(std::min(32000, codecs_[kCodecId[n]].plfreq),
|
EXPECT_EQ(std::min(32000, codec.inst.plfreq),
|
||||||
receiver_->current_sample_rate_hz());
|
receiver_->current_sample_rate_hz());
|
||||||
++n;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(PostdecodingVad)) {
|
TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(PostdecodingVad)) {
|
||||||
receiver_->EnableVad();
|
receiver_->EnableVad();
|
||||||
EXPECT_TRUE(receiver_->vad_enabled());
|
EXPECT_TRUE(receiver_->vad_enabled());
|
||||||
|
const CodecIdInst codec(RentACodec::CodecId::kPCM16Bwb);
|
||||||
const int id = ACMCodecDB::kPCM16Bwb;
|
ASSERT_EQ(
|
||||||
ASSERT_EQ(0, receiver_->AddCodec(id, codecs_[id].pltype, codecs_[id].channels,
|
0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
|
||||||
codecs_[id].plfreq, NULL));
|
codec.inst.plfreq, nullptr));
|
||||||
const int kNumPackets = 5;
|
const int kNumPackets = 5;
|
||||||
const int num_10ms_frames = codecs_[id].pacsize / (codecs_[id].plfreq / 100);
|
const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
|
||||||
AudioFrame frame;
|
AudioFrame frame;
|
||||||
for (int n = 0; n < kNumPackets; ++n) {
|
for (int n = 0; n < kNumPackets; ++n) {
|
||||||
InsertOnePacketOfSilence(id);
|
InsertOnePacketOfSilence(codec.id);
|
||||||
for (int k = 0; k < num_10ms_frames; ++k)
|
for (int k = 0; k < num_10ms_frames; ++k)
|
||||||
ASSERT_EQ(0, receiver_->GetAudio(codecs_[id].plfreq, &frame));
|
ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame));
|
||||||
}
|
}
|
||||||
EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_);
|
EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_);
|
||||||
|
|
||||||
@ -285,9 +287,9 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(PostdecodingVad)) {
|
|||||||
EXPECT_FALSE(receiver_->vad_enabled());
|
EXPECT_FALSE(receiver_->vad_enabled());
|
||||||
|
|
||||||
for (int n = 0; n < kNumPackets; ++n) {
|
for (int n = 0; n < kNumPackets; ++n) {
|
||||||
InsertOnePacketOfSilence(id);
|
InsertOnePacketOfSilence(codec.id);
|
||||||
for (int k = 0; k < num_10ms_frames; ++k)
|
for (int k = 0; k < num_10ms_frames; ++k)
|
||||||
ASSERT_EQ(0, receiver_->GetAudio(codecs_[id].plfreq, &frame));
|
ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame));
|
||||||
}
|
}
|
||||||
EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_);
|
EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_);
|
||||||
}
|
}
|
||||||
@ -300,25 +302,20 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(PostdecodingVad)) {
|
|||||||
|
|
||||||
TEST_F(AcmReceiverTestOldApi,
|
TEST_F(AcmReceiverTestOldApi,
|
||||||
DISABLED_ON_ANDROID(IF_ISAC_FLOAT(LastAudioCodec))) {
|
DISABLED_ON_ANDROID(IF_ISAC_FLOAT(LastAudioCodec))) {
|
||||||
const int kCodecId[] = {
|
const RentACodec::CodecId kCodecId[] = {
|
||||||
ACMCodecDB::kISAC, ACMCodecDB::kPCMA, ACMCodecDB::kISACSWB,
|
RentACodec::CodecId::kISAC, RentACodec::CodecId::kPCMA,
|
||||||
ACMCodecDB::kPCM16Bswb32kHz,
|
RentACodec::CodecId::kISACSWB, RentACodec::CodecId::kPCM16Bswb32kHz};
|
||||||
-1 // Terminator.
|
|
||||||
};
|
|
||||||
AddSetOfCodecs(kCodecId);
|
AddSetOfCodecs(kCodecId);
|
||||||
|
|
||||||
const int kCngId[] = { // Not including full-band.
|
const RentACodec::CodecId kCngId[] = {
|
||||||
ACMCodecDB::kCNNB, ACMCodecDB::kCNWB, ACMCodecDB::kCNSWB,
|
// Not including full-band.
|
||||||
-1 // Terminator.
|
RentACodec::CodecId::kCNNB, RentACodec::CodecId::kCNWB,
|
||||||
};
|
RentACodec::CodecId::kCNSWB};
|
||||||
AddSetOfCodecs(kCngId);
|
AddSetOfCodecs(kCngId);
|
||||||
|
|
||||||
// Register CNG at sender side.
|
// Register CNG at sender side.
|
||||||
int n = 0;
|
for (auto id : kCngId)
|
||||||
while (kCngId[n] > 0) {
|
ASSERT_EQ(0, acm_->RegisterSendCodec(CodecIdInst(id).inst));
|
||||||
ASSERT_EQ(0, acm_->RegisterSendCodec(codecs_[kCngId[n]]));
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodecInst codec;
|
CodecInst codec;
|
||||||
// No audio payload is received.
|
// No audio payload is received.
|
||||||
@ -327,7 +324,8 @@ TEST_F(AcmReceiverTestOldApi,
|
|||||||
// Start with sending DTX.
|
// Start with sending DTX.
|
||||||
ASSERT_EQ(0, acm_->SetVAD(true, true, VADVeryAggr));
|
ASSERT_EQ(0, acm_->SetVAD(true, true, VADVeryAggr));
|
||||||
packet_sent_ = false;
|
packet_sent_ = false;
|
||||||
InsertOnePacketOfSilence(kCodecId[0]); // Enough to test with one codec.
|
InsertOnePacketOfSilence(CodecIdInst(kCodecId[0]).id); // Enough to test
|
||||||
|
// with one codec.
|
||||||
ASSERT_TRUE(packet_sent_);
|
ASSERT_TRUE(packet_sent_);
|
||||||
EXPECT_EQ(kAudioFrameCN, last_frame_type_);
|
EXPECT_EQ(kAudioFrameCN, last_frame_type_);
|
||||||
|
|
||||||
@ -335,18 +333,19 @@ TEST_F(AcmReceiverTestOldApi,
|
|||||||
EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
|
EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
|
||||||
EXPECT_EQ(-1, receiver_->last_audio_codec_id());
|
EXPECT_EQ(-1, receiver_->last_audio_codec_id());
|
||||||
|
|
||||||
n = 0;
|
for (auto id : kCodecId) {
|
||||||
while (kCodecId[n] >= 0) { // Loop over codecs.
|
const CodecIdInst c(id);
|
||||||
|
|
||||||
// Set DTX off to send audio payload.
|
// Set DTX off to send audio payload.
|
||||||
acm_->SetVAD(false, false, VADAggr);
|
acm_->SetVAD(false, false, VADAggr);
|
||||||
packet_sent_ = false;
|
packet_sent_ = false;
|
||||||
InsertOnePacketOfSilence(kCodecId[n]);
|
InsertOnePacketOfSilence(c.id);
|
||||||
|
|
||||||
// Sanity check if Actually an audio payload received, and it should be
|
// Sanity check if Actually an audio payload received, and it should be
|
||||||
// of type "speech."
|
// of type "speech."
|
||||||
ASSERT_TRUE(packet_sent_);
|
ASSERT_TRUE(packet_sent_);
|
||||||
ASSERT_EQ(kAudioFrameSpeech, last_frame_type_);
|
ASSERT_EQ(kAudioFrameSpeech, last_frame_type_);
|
||||||
EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id());
|
EXPECT_EQ(c.id, receiver_->last_audio_codec_id());
|
||||||
|
|
||||||
// Set VAD on to send DTX. Then check if the "Last Audio codec" returns
|
// Set VAD on to send DTX. Then check if the "Last Audio codec" returns
|
||||||
// the expected codec.
|
// the expected codec.
|
||||||
@ -355,13 +354,12 @@ TEST_F(AcmReceiverTestOldApi,
|
|||||||
// Do as many encoding until a DTX is sent.
|
// Do as many encoding until a DTX is sent.
|
||||||
while (last_frame_type_ != kAudioFrameCN) {
|
while (last_frame_type_ != kAudioFrameCN) {
|
||||||
packet_sent_ = false;
|
packet_sent_ = false;
|
||||||
InsertOnePacketOfSilence(kCodecId[n]);
|
InsertOnePacketOfSilence(c.id);
|
||||||
ASSERT_TRUE(packet_sent_);
|
ASSERT_TRUE(packet_sent_);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id());
|
EXPECT_EQ(c.id, receiver_->last_audio_codec_id());
|
||||||
EXPECT_EQ(0, receiver_->LastAudioCodec(&codec));
|
EXPECT_EQ(0, receiver_->LastAudioCodec(&codec));
|
||||||
EXPECT_TRUE(CodecsEqual(codecs_[kCodecId[n]], codec));
|
EXPECT_TRUE(CodecsEqual(c.inst, codec));
|
||||||
++n;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/common_types.h"
|
#include "webrtc/common_types.h"
|
||||||
#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
|
|
||||||
#include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h"
|
#include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h"
|
||||||
|
#include "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h"
|
||||||
#include "webrtc/system_wrappers/interface/clock.h"
|
#include "webrtc/system_wrappers/interface/clock.h"
|
||||||
#include "webrtc/system_wrappers/interface/trace.h"
|
#include "webrtc/system_wrappers/interface/trace.h"
|
||||||
|
|
||||||
@ -38,29 +38,32 @@ AudioCodingModule* AudioCodingModule::Create(const Config& config) {
|
|||||||
return new acm2::AudioCodingModuleImpl(config);
|
return new acm2::AudioCodingModuleImpl(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get number of supported codecs
|
|
||||||
int AudioCodingModule::NumberOfCodecs() {
|
int AudioCodingModule::NumberOfCodecs() {
|
||||||
return acm2::ACMCodecDB::kNumCodecs;
|
return static_cast<int>(acm2::RentACodec::NumberOfCodecs());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get supported codec parameters with id
|
|
||||||
int AudioCodingModule::Codec(int list_id, CodecInst* codec) {
|
int AudioCodingModule::Codec(int list_id, CodecInst* codec) {
|
||||||
// Get the codec settings for the codec with the given list ID
|
auto codec_id = acm2::RentACodec::CodecIdFromIndex(list_id);
|
||||||
return acm2::ACMCodecDB::Codec(list_id, codec);
|
if (!codec_id)
|
||||||
|
return -1;
|
||||||
|
auto ci = acm2::RentACodec::CodecInstById(*codec_id);
|
||||||
|
if (!ci)
|
||||||
|
return -1;
|
||||||
|
*codec = *ci;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get supported codec parameters with name, frequency and number of channels.
|
|
||||||
int AudioCodingModule::Codec(const char* payload_name,
|
int AudioCodingModule::Codec(const char* payload_name,
|
||||||
CodecInst* codec,
|
CodecInst* codec,
|
||||||
int sampling_freq_hz,
|
int sampling_freq_hz,
|
||||||
int channels) {
|
int channels) {
|
||||||
int codec_id;
|
rtc::Maybe<CodecInst> ci = acm2::RentACodec::CodecInstByParams(
|
||||||
|
|
||||||
// Get the id of the codec from the database.
|
|
||||||
codec_id = acm2::ACMCodecDB::CodecId(
|
|
||||||
payload_name, sampling_freq_hz, channels);
|
payload_name, sampling_freq_hz, channels);
|
||||||
if (codec_id < 0) {
|
if (ci) {
|
||||||
// We couldn't find a matching codec, set the parameters to unacceptable
|
*codec = *ci;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
// We couldn't find a matching codec, so set the parameters to unacceptable
|
||||||
// values and return.
|
// values and return.
|
||||||
codec->plname[0] = '\0';
|
codec->plname[0] = '\0';
|
||||||
codec->pltype = -1;
|
codec->pltype = -1;
|
||||||
@ -69,35 +72,26 @@ int AudioCodingModule::Codec(const char* payload_name,
|
|||||||
codec->plfreq = 0;
|
codec->plfreq = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get default codec settings.
|
|
||||||
acm2::ACMCodecDB::Codec(codec_id, codec);
|
|
||||||
|
|
||||||
// Keep the number of channels from the function call. For most codecs it
|
|
||||||
// will be the same value as in default codec settings, but not for all.
|
|
||||||
codec->channels = channels;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get supported codec Index with name, frequency and number of channels.
|
|
||||||
int AudioCodingModule::Codec(const char* payload_name,
|
int AudioCodingModule::Codec(const char* payload_name,
|
||||||
int sampling_freq_hz,
|
int sampling_freq_hz,
|
||||||
int channels) {
|
int channels) {
|
||||||
return acm2::ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels);
|
rtc::Maybe<acm2::RentACodec::CodecId> ci = acm2::RentACodec::CodecIdByParams(
|
||||||
|
payload_name, sampling_freq_hz, channels);
|
||||||
|
if (!ci)
|
||||||
|
return -1;
|
||||||
|
rtc::Maybe<int> i = acm2::RentACodec::CodecIndexFromId(*ci);
|
||||||
|
return i ? *i : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks the validity of the parameters of the given codec
|
// Checks the validity of the parameters of the given codec
|
||||||
bool AudioCodingModule::IsCodecValid(const CodecInst& codec) {
|
bool AudioCodingModule::IsCodecValid(const CodecInst& codec) {
|
||||||
int codec_number = acm2::ACMCodecDB::CodecNumber(codec);
|
bool valid = acm2::RentACodec::IsCodecValid(codec);
|
||||||
|
if (!valid)
|
||||||
if (codec_number < 0) {
|
|
||||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, -1,
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, -1,
|
||||||
"Invalid codec setting");
|
"Invalid codec setting");
|
||||||
return false;
|
return valid;
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -36,20 +36,12 @@ namespace {
|
|||||||
|
|
||||||
// TODO(turajs): the same functionality is used in NetEq. If both classes
|
// TODO(turajs): the same functionality is used in NetEq. If both classes
|
||||||
// need them, make it a static function in ACMCodecDB.
|
// need them, make it a static function in ACMCodecDB.
|
||||||
bool IsCodecRED(const CodecInst* codec) {
|
bool IsCodecRED(const CodecInst& codec) {
|
||||||
return (STR_CASE_CMP(codec->plname, "RED") == 0);
|
return (STR_CASE_CMP(codec.plname, "RED") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsCodecRED(int index) {
|
bool IsCodecCN(const CodecInst& codec) {
|
||||||
return (IsCodecRED(&ACMCodecDB::database_[index]));
|
return (STR_CASE_CMP(codec.plname, "CN") == 0);
|
||||||
}
|
|
||||||
|
|
||||||
bool IsCodecCN(const CodecInst* codec) {
|
|
||||||
return (STR_CASE_CMP(codec->plname, "CN") == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsCodecCN(int index) {
|
|
||||||
return (IsCodecCN(&ACMCodecDB::database_[index]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stereo-to-mono can be used as in-place.
|
// Stereo-to-mono can be used as in-place.
|
||||||
@ -513,11 +505,12 @@ int AudioCodingModuleImpl::InitializeReceiverSafe() {
|
|||||||
receiver_.FlushBuffers();
|
receiver_.FlushBuffers();
|
||||||
|
|
||||||
// Register RED and CN.
|
// Register RED and CN.
|
||||||
for (int i = 0; i < ACMCodecDB::kNumCodecs; i++) {
|
auto db = RentACodec::Database();
|
||||||
if (IsCodecRED(i) || IsCodecCN(i)) {
|
for (size_t i = 0; i < db.size(); i++) {
|
||||||
uint8_t pl_type = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
|
if (IsCodecRED(db[i]) || IsCodecCN(db[i])) {
|
||||||
int fs = ACMCodecDB::database_[i].plfreq;
|
if (receiver_.AddCodec(static_cast<int>(i),
|
||||||
if (receiver_.AddCodec(i, pl_type, 1, fs, NULL) < 0) {
|
static_cast<uint8_t>(db[i].pltype), 1,
|
||||||
|
db[i].plfreq, nullptr) < 0) {
|
||||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
|
||||||
"Cannot register master codec.");
|
"Cannot register master codec.");
|
||||||
return -1;
|
return -1;
|
||||||
@ -561,11 +554,14 @@ int AudioCodingModuleImpl::RegisterReceiveCodec(const CodecInst& codec) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int codec_id = ACMCodecDB::ReceiverCodecNumber(codec);
|
auto codec_id =
|
||||||
if (codec_id < 0 || codec_id >= ACMCodecDB::kNumCodecs) {
|
RentACodec::CodecIdByParams(codec.plname, codec.plfreq, codec.channels);
|
||||||
|
if (!codec_id) {
|
||||||
LOG_F(LS_ERROR) << "Wrong codec params to be registered as receive codec";
|
LOG_F(LS_ERROR) << "Wrong codec params to be registered as receive codec";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto codec_index = RentACodec::CodecIndexFromId(*codec_id);
|
||||||
|
RTC_CHECK(codec_index) << "Invalid codec ID: " << static_cast<int>(*codec_id);
|
||||||
|
|
||||||
// Check if the payload-type is valid.
|
// Check if the payload-type is valid.
|
||||||
if (!ACMCodecDB::ValidPayloadType(codec.pltype)) {
|
if (!ACMCodecDB::ValidPayloadType(codec.pltype)) {
|
||||||
@ -576,7 +572,7 @@ int AudioCodingModuleImpl::RegisterReceiveCodec(const CodecInst& codec) {
|
|||||||
|
|
||||||
// Get |decoder| associated with |codec|. |decoder| is NULL if |codec| does
|
// Get |decoder| associated with |codec|. |decoder| is NULL if |codec| does
|
||||||
// not own its decoder.
|
// not own its decoder.
|
||||||
return receiver_.AddCodec(codec_id, codec.pltype, codec.channels,
|
return receiver_.AddCodec(*codec_index, codec.pltype, codec.channels,
|
||||||
codec.plfreq,
|
codec.plfreq,
|
||||||
codec_manager_.GetAudioDecoder(codec));
|
codec_manager_.GetAudioDecoder(codec));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,18 +23,10 @@ bool IsCodecRED(const CodecInst& codec) {
|
|||||||
return (STR_CASE_CMP(codec.plname, "RED") == 0);
|
return (STR_CASE_CMP(codec.plname, "RED") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsCodecRED(int index) {
|
|
||||||
return (IsCodecRED(ACMCodecDB::database_[index]));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsCodecCN(const CodecInst& codec) {
|
bool IsCodecCN(const CodecInst& codec) {
|
||||||
return (STR_CASE_CMP(codec.plname, "CN") == 0);
|
return (STR_CASE_CMP(codec.plname, "CN") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsCodecCN(int index) {
|
|
||||||
return (IsCodecCN(ACMCodecDB::database_[index]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the given codec is a valid to be registered as send codec.
|
// Check if the given codec is a valid to be registered as send codec.
|
||||||
int IsValidSendCodec(const CodecInst& send_codec, bool is_primary_encoder) {
|
int IsValidSendCodec(const CodecInst& send_codec, bool is_primary_encoder) {
|
||||||
int dummy_id = 0;
|
int dummy_id = 0;
|
||||||
@ -164,18 +156,18 @@ CodecManager::CodecManager()
|
|||||||
encoder_is_opus_(false) {
|
encoder_is_opus_(false) {
|
||||||
// Register the default payload type for RED and for CNG at sampling rates of
|
// Register the default payload type for RED and for CNG at sampling rates of
|
||||||
// 8, 16, 32 and 48 kHz.
|
// 8, 16, 32 and 48 kHz.
|
||||||
for (int i = (ACMCodecDB::kNumCodecs - 1); i >= 0; i--) {
|
for (const CodecInst& ci : RentACodec::Database()) {
|
||||||
if (IsCodecRED(i) && ACMCodecDB::database_[i].plfreq == 8000) {
|
if (IsCodecRED(ci) && ci.plfreq == 8000) {
|
||||||
red_nb_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
|
red_nb_pltype_ = static_cast<uint8_t>(ci.pltype);
|
||||||
} else if (IsCodecCN(i)) {
|
} else if (IsCodecCN(ci)) {
|
||||||
if (ACMCodecDB::database_[i].plfreq == 8000) {
|
if (ci.plfreq == 8000) {
|
||||||
cng_nb_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
|
cng_nb_pltype_ = static_cast<uint8_t>(ci.pltype);
|
||||||
} else if (ACMCodecDB::database_[i].plfreq == 16000) {
|
} else if (ci.plfreq == 16000) {
|
||||||
cng_wb_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
|
cng_wb_pltype_ = static_cast<uint8_t>(ci.pltype);
|
||||||
} else if (ACMCodecDB::database_[i].plfreq == 32000) {
|
} else if (ci.plfreq == 32000) {
|
||||||
cng_swb_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
|
cng_swb_pltype_ = static_cast<uint8_t>(ci.pltype);
|
||||||
} else if (ACMCodecDB::database_[i].plfreq == 48000) {
|
} else if (ci.plfreq == 48000) {
|
||||||
cng_fb_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
|
cng_fb_pltype_ = static_cast<uint8_t>(ci.pltype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
59
webrtc/modules/audio_coding/main/acm2/rent_a_codec.cc
Normal file
59
webrtc/modules/audio_coding/main/acm2/rent_a_codec.cc
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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 "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h"
|
||||||
|
|
||||||
|
#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
|
||||||
|
#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
namespace acm2 {
|
||||||
|
|
||||||
|
rtc::Maybe<RentACodec::CodecId> RentACodec::CodecIdByParams(
|
||||||
|
const char* payload_name,
|
||||||
|
int sampling_freq_hz,
|
||||||
|
int channels) {
|
||||||
|
return CodecIdFromIndex(
|
||||||
|
ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels));
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc::Maybe<CodecInst> RentACodec::CodecInstById(CodecId codec_id) {
|
||||||
|
rtc::Maybe<int> mi = CodecIndexFromId(codec_id);
|
||||||
|
return mi ? rtc::Maybe<CodecInst>(Database()[*mi]) : rtc::Maybe<CodecInst>();
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc::Maybe<CodecInst> RentACodec::CodecInstByParams(const char* payload_name,
|
||||||
|
int sampling_freq_hz,
|
||||||
|
int channels) {
|
||||||
|
rtc::Maybe<CodecId> codec_id =
|
||||||
|
CodecIdByParams(payload_name, sampling_freq_hz, channels);
|
||||||
|
if (!codec_id)
|
||||||
|
return rtc::Maybe<CodecInst>();
|
||||||
|
rtc::Maybe<CodecInst> ci = CodecInstById(*codec_id);
|
||||||
|
RTC_DCHECK(ci);
|
||||||
|
|
||||||
|
// Keep the number of channels from the function call. For most codecs it
|
||||||
|
// will be the same value as in default codec settings, but not for all.
|
||||||
|
ci->channels = channels;
|
||||||
|
|
||||||
|
return ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RentACodec::IsCodecValid(const CodecInst& codec_inst) {
|
||||||
|
return ACMCodecDB::CodecNumber(codec_inst) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc::ArrayView<const CodecInst> RentACodec::Database() {
|
||||||
|
return rtc::ArrayView<const CodecInst>(ACMCodecDB::database_,
|
||||||
|
NumberOfCodecs());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace acm2
|
||||||
|
} // namespace webrtc
|
||||||
129
webrtc/modules/audio_coding/main/acm2/rent_a_codec.h
Normal file
129
webrtc/modules/audio_coding/main/acm2/rent_a_codec.h
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* 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 WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_RENT_A_CODEC_H_
|
||||||
|
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_RENT_A_CODEC_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "webrtc/base/array_view.h"
|
||||||
|
#include "webrtc/base/maybe.h"
|
||||||
|
#include "webrtc/typedefs.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
struct CodecInst;
|
||||||
|
|
||||||
|
namespace acm2 {
|
||||||
|
|
||||||
|
class RentACodec {
|
||||||
|
public:
|
||||||
|
enum class CodecId {
|
||||||
|
#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
|
||||||
|
kISAC,
|
||||||
|
#endif
|
||||||
|
#ifdef WEBRTC_CODEC_ISAC
|
||||||
|
kISACSWB,
|
||||||
|
#endif
|
||||||
|
// Mono
|
||||||
|
kPCM16B,
|
||||||
|
kPCM16Bwb,
|
||||||
|
kPCM16Bswb32kHz,
|
||||||
|
// Stereo
|
||||||
|
kPCM16B_2ch,
|
||||||
|
kPCM16Bwb_2ch,
|
||||||
|
kPCM16Bswb32kHz_2ch,
|
||||||
|
// Mono
|
||||||
|
kPCMU,
|
||||||
|
kPCMA,
|
||||||
|
// Stereo
|
||||||
|
kPCMU_2ch,
|
||||||
|
kPCMA_2ch,
|
||||||
|
#ifdef WEBRTC_CODEC_ILBC
|
||||||
|
kILBC,
|
||||||
|
#endif
|
||||||
|
#ifdef WEBRTC_CODEC_G722
|
||||||
|
kG722, // Mono
|
||||||
|
kG722_2ch, // Stereo
|
||||||
|
#endif
|
||||||
|
#ifdef WEBRTC_CODEC_OPUS
|
||||||
|
kOpus, // Mono and stereo
|
||||||
|
#endif
|
||||||
|
kCNNB,
|
||||||
|
kCNWB,
|
||||||
|
kCNSWB,
|
||||||
|
#ifdef ENABLE_48000_HZ
|
||||||
|
kCNFB,
|
||||||
|
#endif
|
||||||
|
kAVT,
|
||||||
|
#ifdef WEBRTC_CODEC_RED
|
||||||
|
kRED,
|
||||||
|
#endif
|
||||||
|
kNumCodecs, // Implementation detail. Don't use.
|
||||||
|
|
||||||
|
// Set unsupported codecs to -1.
|
||||||
|
#if !defined(WEBRTC_CODEC_ISAC) && !defined(WEBRTC_CODEC_ISACFX)
|
||||||
|
kISAC = -1,
|
||||||
|
#endif
|
||||||
|
#ifndef WEBRTC_CODEC_ISAC
|
||||||
|
kISACSWB = -1,
|
||||||
|
#endif
|
||||||
|
// 48 kHz not supported, always set to -1.
|
||||||
|
kPCM16Bswb48kHz = -1,
|
||||||
|
#ifndef WEBRTC_CODEC_ILBC
|
||||||
|
kILBC = -1,
|
||||||
|
#endif
|
||||||
|
#ifndef WEBRTC_CODEC_G722
|
||||||
|
kG722 = -1, // Mono
|
||||||
|
kG722_2ch = -1, // Stereo
|
||||||
|
#endif
|
||||||
|
#ifndef WEBRTC_CODEC_OPUS
|
||||||
|
kOpus = -1, // Mono and stereo
|
||||||
|
#endif
|
||||||
|
#ifndef WEBRTC_CODEC_RED
|
||||||
|
kRED = -1,
|
||||||
|
#endif
|
||||||
|
#ifndef ENABLE_48000_HZ
|
||||||
|
kCNFB = -1,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
kNone = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline size_t NumberOfCodecs() {
|
||||||
|
return static_cast<size_t>(CodecId::kNumCodecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rtc::Maybe<int> CodecIndexFromId(CodecId codec_id) {
|
||||||
|
const int i = static_cast<int>(codec_id);
|
||||||
|
return i < static_cast<int>(NumberOfCodecs()) ? i : rtc::Maybe<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rtc::Maybe<CodecId> CodecIdFromIndex(int codec_index) {
|
||||||
|
return static_cast<size_t>(codec_index) < NumberOfCodecs()
|
||||||
|
? static_cast<RentACodec::CodecId>(codec_index)
|
||||||
|
: rtc::Maybe<RentACodec::CodecId>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static rtc::Maybe<CodecId> CodecIdByParams(const char* payload_name,
|
||||||
|
int sampling_freq_hz,
|
||||||
|
int channels);
|
||||||
|
static rtc::Maybe<CodecInst> CodecInstById(CodecId codec_id);
|
||||||
|
static rtc::Maybe<CodecInst> CodecInstByParams(const char* payload_name,
|
||||||
|
int sampling_freq_hz,
|
||||||
|
int channels);
|
||||||
|
static bool IsCodecValid(const CodecInst& codec_inst);
|
||||||
|
static rtc::ArrayView<const CodecInst> Database();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace acm2
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_RENT_A_CODEC_H_
|
||||||
@ -42,6 +42,30 @@
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
'targets': [
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'rent_a_codec',
|
||||||
|
'type': 'static_library',
|
||||||
|
'defines': [
|
||||||
|
'<@(audio_coding_defines)',
|
||||||
|
],
|
||||||
|
'dependencies': [
|
||||||
|
'<(webrtc_root)/common.gyp:webrtc_common',
|
||||||
|
],
|
||||||
|
'include_dirs': [
|
||||||
|
'<(webrtc_root)',
|
||||||
|
],
|
||||||
|
'direct_dependent_settings': {
|
||||||
|
'include_dirs': [
|
||||||
|
'<(webrtc_root)',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'sources': [
|
||||||
|
'acm2/acm_codec_database.cc',
|
||||||
|
'acm2/acm_codec_database.h',
|
||||||
|
'acm2/rent_a_codec.cc',
|
||||||
|
'acm2/rent_a_codec.h',
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'target_name': 'audio_coding_module',
|
'target_name': 'audio_coding_module',
|
||||||
'type': 'static_library',
|
'type': 'static_library',
|
||||||
@ -53,6 +77,7 @@
|
|||||||
'<(webrtc_root)/common.gyp:webrtc_common',
|
'<(webrtc_root)/common.gyp:webrtc_common',
|
||||||
'<(webrtc_root)/webrtc.gyp:rtc_event_log',
|
'<(webrtc_root)/webrtc.gyp:rtc_event_log',
|
||||||
'neteq',
|
'neteq',
|
||||||
|
'rent_a_codec',
|
||||||
],
|
],
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'interface',
|
'interface',
|
||||||
@ -67,8 +92,6 @@
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
'sources': [
|
'sources': [
|
||||||
'acm2/acm_codec_database.cc',
|
|
||||||
'acm2/acm_codec_database.h',
|
|
||||||
'acm2/acm_common_defs.h',
|
'acm2/acm_common_defs.h',
|
||||||
'acm2/acm_receiver.cc',
|
'acm2/acm_receiver.cc',
|
||||||
'acm2/acm_receiver.h',
|
'acm2/acm_receiver.h',
|
||||||
|
|||||||
Reference in New Issue
Block a user