Consolidate anonymous namespace content and file-static methods to all be in the

anonymous namespace, in preparation for refactoring a few of the functions a
little.

No code change.

BUG=none
TEST=none
R=henrik.lundin@webrtc.org, tina.legrand@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/36949004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@8155 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pkasting@chromium.org 2015-01-26 19:59:32 +00:00
parent d7e34e1086
commit 4dba2e98a2

View File

@ -40,6 +40,7 @@ using webrtc::NetEq;
using webrtc::WebRtcRTPHeader;
namespace {
// Parses the input string for a valid SSRC (at the start of the string). If a
// valid SSRC is found, it is written to the output variable |ssrc|, and true is
// returned. Otherwise, false is returned.
@ -63,72 +64,70 @@ bool ParseSsrc(const std::string& str, uint32_t* ssrc) {
return true;
}
} // namespace
// Flag validators.
static bool ValidatePayloadType(const char* flagname, int32_t value) {
bool ValidatePayloadType(const char* flagname, int32_t value) {
if (value >= 0 && value <= 127) // Value is ok.
return true;
printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value));
return false;
}
static bool ValidateSsrcValue(const char* flagname, const std::string& str) {
bool ValidateSsrcValue(const char* flagname, const std::string& str) {
uint32_t dummy_ssrc;
return ParseSsrc(str, &dummy_ssrc);
}
// Define command line flags.
DEFINE_int32(pcmu, 0, "RTP payload type for PCM-u");
static const bool pcmu_dummy =
const bool pcmu_dummy =
google::RegisterFlagValidator(&FLAGS_pcmu, &ValidatePayloadType);
DEFINE_int32(pcma, 8, "RTP payload type for PCM-a");
static const bool pcma_dummy =
const bool pcma_dummy =
google::RegisterFlagValidator(&FLAGS_pcma, &ValidatePayloadType);
DEFINE_int32(ilbc, 102, "RTP payload type for iLBC");
static const bool ilbc_dummy =
const bool ilbc_dummy =
google::RegisterFlagValidator(&FLAGS_ilbc, &ValidatePayloadType);
DEFINE_int32(isac, 103, "RTP payload type for iSAC");
static const bool isac_dummy =
const bool isac_dummy =
google::RegisterFlagValidator(&FLAGS_isac, &ValidatePayloadType);
DEFINE_int32(isac_swb, 104, "RTP payload type for iSAC-swb (32 kHz)");
static const bool isac_swb_dummy =
const bool isac_swb_dummy =
google::RegisterFlagValidator(&FLAGS_isac_swb, &ValidatePayloadType);
DEFINE_int32(opus, 111, "RTP payload type for Opus");
static const bool opus_dummy =
const bool opus_dummy =
google::RegisterFlagValidator(&FLAGS_opus, &ValidatePayloadType);
DEFINE_int32(pcm16b, 93, "RTP payload type for PCM16b-nb (8 kHz)");
static const bool pcm16b_dummy =
const bool pcm16b_dummy =
google::RegisterFlagValidator(&FLAGS_pcm16b, &ValidatePayloadType);
DEFINE_int32(pcm16b_wb, 94, "RTP payload type for PCM16b-wb (16 kHz)");
static const bool pcm16b_wb_dummy =
const bool pcm16b_wb_dummy =
google::RegisterFlagValidator(&FLAGS_pcm16b_wb, &ValidatePayloadType);
DEFINE_int32(pcm16b_swb32, 95, "RTP payload type for PCM16b-swb32 (32 kHz)");
static const bool pcm16b_swb32_dummy =
const bool pcm16b_swb32_dummy =
google::RegisterFlagValidator(&FLAGS_pcm16b_swb32, &ValidatePayloadType);
DEFINE_int32(pcm16b_swb48, 96, "RTP payload type for PCM16b-swb48 (48 kHz)");
static const bool pcm16b_swb48_dummy =
const bool pcm16b_swb48_dummy =
google::RegisterFlagValidator(&FLAGS_pcm16b_swb48, &ValidatePayloadType);
DEFINE_int32(g722, 9, "RTP payload type for G.722");
static const bool g722_dummy =
const bool g722_dummy =
google::RegisterFlagValidator(&FLAGS_g722, &ValidatePayloadType);
DEFINE_int32(avt, 106, "RTP payload type for AVT/DTMF");
static const bool avt_dummy =
const bool avt_dummy =
google::RegisterFlagValidator(&FLAGS_avt, &ValidatePayloadType);
DEFINE_int32(red, 117, "RTP payload type for redundant audio (RED)");
static const bool red_dummy =
const bool red_dummy =
google::RegisterFlagValidator(&FLAGS_red, &ValidatePayloadType);
DEFINE_int32(cn_nb, 13, "RTP payload type for comfort noise (8 kHz)");
static const bool cn_nb_dummy =
const bool cn_nb_dummy =
google::RegisterFlagValidator(&FLAGS_cn_nb, &ValidatePayloadType);
DEFINE_int32(cn_wb, 98, "RTP payload type for comfort noise (16 kHz)");
static const bool cn_wb_dummy =
const bool cn_wb_dummy =
google::RegisterFlagValidator(&FLAGS_cn_wb, &ValidatePayloadType);
DEFINE_int32(cn_swb32, 99, "RTP payload type for comfort noise (32 kHz)");
static const bool cn_swb32_dummy =
const bool cn_swb32_dummy =
google::RegisterFlagValidator(&FLAGS_cn_swb32, &ValidatePayloadType);
DEFINE_int32(cn_swb48, 100, "RTP payload type for comfort noise (48 kHz)");
static const bool cn_swb48_dummy =
const bool cn_swb48_dummy =
google::RegisterFlagValidator(&FLAGS_cn_swb48, &ValidatePayloadType);
DEFINE_bool(codec_map, false, "Prints the mapping between RTP payload type and "
"codec");
@ -138,23 +137,334 @@ DEFINE_string(ssrc,
"",
"Only use packets with this SSRC (decimal or hex, the latter "
"starting with 0x)");
static const bool hex_ssrc_dummy =
const bool hex_ssrc_dummy =
google::RegisterFlagValidator(&FLAGS_ssrc, &ValidateSsrcValue);
// Declaring helper functions (defined further down in this file).
std::string CodecName(webrtc::NetEqDecoder codec);
void RegisterPayloadTypes(NetEq* neteq);
void PrintCodecMapping();
// Maps a codec type to a printable name string.
std::string CodecName(webrtc::NetEqDecoder codec) {
switch (codec) {
case webrtc::kDecoderPCMu:
return "PCM-u";
case webrtc::kDecoderPCMa:
return "PCM-a";
case webrtc::kDecoderILBC:
return "iLBC";
case webrtc::kDecoderISAC:
return "iSAC";
case webrtc::kDecoderISACswb:
return "iSAC-swb (32 kHz)";
case webrtc::kDecoderOpus:
return "Opus";
case webrtc::kDecoderPCM16B:
return "PCM16b-nb (8 kHz)";
case webrtc::kDecoderPCM16Bwb:
return "PCM16b-wb (16 kHz)";
case webrtc::kDecoderPCM16Bswb32kHz:
return "PCM16b-swb32 (32 kHz)";
case webrtc::kDecoderPCM16Bswb48kHz:
return "PCM16b-swb48 (48 kHz)";
case webrtc::kDecoderG722:
return "G.722";
case webrtc::kDecoderRED:
return "redundant audio (RED)";
case webrtc::kDecoderAVT:
return "AVT/DTMF";
case webrtc::kDecoderCNGnb:
return "comfort noise (8 kHz)";
case webrtc::kDecoderCNGwb:
return "comfort noise (16 kHz)";
case webrtc::kDecoderCNGswb32kHz:
return "comfort noise (32 kHz)";
case webrtc::kDecoderCNGswb48kHz:
return "comfort noise (48 kHz)";
default:
assert(false);
return "undefined";
}
}
// Registers all decoders in |neteq|.
void RegisterPayloadTypes(NetEq* neteq) {
assert(neteq);
int error;
error = neteq->RegisterPayloadType(webrtc::kDecoderPCMu, FLAGS_pcmu);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcmu <<
" as " << CodecName(webrtc::kDecoderPCMu).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCMa, FLAGS_pcma);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcma <<
" as " << CodecName(webrtc::kDecoderPCMa).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderILBC, FLAGS_ilbc);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_ilbc <<
" as " << CodecName(webrtc::kDecoderILBC).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderISAC, FLAGS_isac);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_isac <<
" as " << CodecName(webrtc::kDecoderISAC).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderISACswb, FLAGS_isac_swb);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_isac_swb <<
" as " << CodecName(webrtc::kDecoderISACswb).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderOpus, FLAGS_opus);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_opus << " as "
<< CodecName(webrtc::kDecoderOpus).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16B, FLAGS_pcm16b);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcm16b <<
" as " << CodecName(webrtc::kDecoderPCM16B).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16Bwb,
FLAGS_pcm16b_wb);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcm16b_wb <<
" as " << CodecName(webrtc::kDecoderPCM16Bwb).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16Bswb32kHz,
FLAGS_pcm16b_swb32);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcm16b_swb32 <<
" as " << CodecName(webrtc::kDecoderPCM16Bswb32kHz).c_str() <<
std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16Bswb48kHz,
FLAGS_pcm16b_swb48);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcm16b_swb48 <<
" as " << CodecName(webrtc::kDecoderPCM16Bswb48kHz).c_str() <<
std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderG722, FLAGS_g722);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_g722 <<
" as " << CodecName(webrtc::kDecoderG722).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderAVT, FLAGS_avt);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_avt <<
" as " << CodecName(webrtc::kDecoderAVT).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderRED, FLAGS_red);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_red <<
" as " << CodecName(webrtc::kDecoderRED).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderCNGnb, FLAGS_cn_nb);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_cn_nb <<
" as " << CodecName(webrtc::kDecoderCNGnb).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderCNGwb, FLAGS_cn_wb);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_cn_wb <<
" as " << CodecName(webrtc::kDecoderCNGwb).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderCNGswb32kHz,
FLAGS_cn_swb32);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_cn_swb32 <<
" as " << CodecName(webrtc::kDecoderCNGswb32kHz).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderCNGswb48kHz,
FLAGS_cn_swb48);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_cn_swb48 <<
" as " << CodecName(webrtc::kDecoderCNGswb48kHz).c_str() << std::endl;
exit(1);
}
}
void PrintCodecMapping() {
std::cout << CodecName(webrtc::kDecoderPCMu).c_str() << ": " << FLAGS_pcmu <<
std::endl;
std::cout << CodecName(webrtc::kDecoderPCMa).c_str() << ": " << FLAGS_pcma <<
std::endl;
std::cout << CodecName(webrtc::kDecoderILBC).c_str() << ": " << FLAGS_ilbc <<
std::endl;
std::cout << CodecName(webrtc::kDecoderISAC).c_str() << ": " << FLAGS_isac <<
std::endl;
std::cout << CodecName(webrtc::kDecoderISACswb).c_str() << ": " <<
FLAGS_isac_swb << std::endl;
std::cout << CodecName(webrtc::kDecoderOpus).c_str() << ": " << FLAGS_opus
<< std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16B).c_str() << ": " <<
FLAGS_pcm16b << std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16Bwb).c_str() << ": " <<
FLAGS_pcm16b_wb << std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16Bswb32kHz).c_str() << ": " <<
FLAGS_pcm16b_swb32 << std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16Bswb48kHz).c_str() << ": " <<
FLAGS_pcm16b_swb48 << std::endl;
std::cout << CodecName(webrtc::kDecoderG722).c_str() << ": " << FLAGS_g722 <<
std::endl;
std::cout << CodecName(webrtc::kDecoderAVT).c_str() << ": " << FLAGS_avt <<
std::endl;
std::cout << CodecName(webrtc::kDecoderRED).c_str() << ": " << FLAGS_red <<
std::endl;
std::cout << CodecName(webrtc::kDecoderCNGnb).c_str() << ": " <<
FLAGS_cn_nb << std::endl;
std::cout << CodecName(webrtc::kDecoderCNGwb).c_str() << ": " <<
FLAGS_cn_wb << std::endl;
std::cout << CodecName(webrtc::kDecoderCNGswb32kHz).c_str() << ": " <<
FLAGS_cn_swb32 << std::endl;
std::cout << CodecName(webrtc::kDecoderCNGswb48kHz).c_str() << ": " <<
FLAGS_cn_swb48 << std::endl;
}
bool IsComfortNosie(uint8_t payload_type) {
if (payload_type == FLAGS_cn_nb ||
payload_type == FLAGS_cn_wb ||
payload_type == FLAGS_cn_swb32 ||
payload_type == FLAGS_cn_swb48) {
return true;
} else {
return false;
}
}
int CodecSampleRate(uint8_t payload_type) {
if (payload_type == FLAGS_pcmu ||
payload_type == FLAGS_pcma ||
payload_type == FLAGS_ilbc ||
payload_type == FLAGS_pcm16b ||
payload_type == FLAGS_cn_nb) {
return 8000;
} else if (payload_type == FLAGS_isac ||
payload_type == FLAGS_pcm16b_wb ||
payload_type == FLAGS_g722 ||
payload_type == FLAGS_cn_wb) {
return 16000;
} else if (payload_type == FLAGS_isac_swb ||
payload_type == FLAGS_pcm16b_swb32 ||
payload_type == FLAGS_cn_swb32) {
return 32000;
} else if (payload_type == FLAGS_opus || payload_type == FLAGS_pcm16b_swb48 ||
payload_type == FLAGS_cn_swb48) {
return 48000;
} else if (payload_type == FLAGS_avt ||
payload_type == FLAGS_red) {
return 0;
} else {
return -1;
}
}
int CodecTimestampRate(uint8_t payload_type) {
if (payload_type == FLAGS_g722) {
return 8000;
} else {
return CodecSampleRate(payload_type);
}
}
size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file,
webrtc::scoped_ptr<int16_t[]>* replacement_audio,
webrtc::scoped_ptr<uint8_t[]>* payload,
size_t* payload_mem_size_bytes,
size_t* frame_size_samples,
WebRtcRTPHeader* rtp_header,
const webrtc::test::Packet* next_packet);
int CodecSampleRate(uint8_t payload_type);
int CodecTimestampRate(uint8_t payload_type);
bool IsComfortNosie(uint8_t payload_type);
const webrtc::test::Packet* next_packet) {
size_t payload_len = 0;
// Check for CNG.
if (IsComfortNosie(rtp_header->header.payloadType)) {
// If CNG, simply insert a zero-energy one-byte payload.
if (*payload_mem_size_bytes < 1) {
(*payload).reset(new uint8_t[1]);
*payload_mem_size_bytes = 1;
}
(*payload)[0] = 127; // Max attenuation of CNG.
payload_len = 1;
} else {
assert(next_packet->virtual_payload_length_bytes() > 0);
// Check if payload length has changed.
if (next_packet->header().sequenceNumber ==
rtp_header->header.sequenceNumber + 1) {
if (*frame_size_samples !=
next_packet->header().timestamp - rtp_header->header.timestamp) {
*frame_size_samples =
next_packet->header().timestamp - rtp_header->header.timestamp;
(*replacement_audio).reset(
new int16_t[*frame_size_samples]);
*payload_mem_size_bytes = 2 * *frame_size_samples;
(*payload).reset(new uint8_t[*payload_mem_size_bytes]);
}
}
// Get new speech.
assert((*replacement_audio).get());
if (CodecTimestampRate(rtp_header->header.payloadType) !=
CodecSampleRate(rtp_header->header.payloadType) ||
rtp_header->header.payloadType == FLAGS_red ||
rtp_header->header.payloadType == FLAGS_avt) {
// Some codecs have different sample and timestamp rates. And neither
// RED nor DTMF is supported for replacement.
std::cerr << "Codec not supported for audio replacement." <<
std::endl;
webrtc::Trace::ReturnTrace();
exit(1);
}
assert(*frame_size_samples > 0);
if (!replacement_audio_file->Read(*frame_size_samples,
(*replacement_audio).get())) {
std::cerr << "Could not read replacement audio file." << std::endl;
webrtc::Trace::ReturnTrace();
exit(1);
}
// Encode it as PCM16.
assert((*payload).get());
payload_len = WebRtcPcm16b_Encode((*replacement_audio).get(),
static_cast<int16_t>(*frame_size_samples),
(*payload).get());
assert(payload_len == 2 * *frame_size_samples);
// Change payload type to PCM16.
switch (CodecSampleRate(rtp_header->header.payloadType)) {
case 8000:
rtp_header->header.payloadType = FLAGS_pcm16b;
break;
case 16000:
rtp_header->header.payloadType = FLAGS_pcm16b_wb;
break;
case 32000:
rtp_header->header.payloadType = FLAGS_pcm16b_swb32;
break;
case 48000:
rtp_header->header.payloadType = FLAGS_pcm16b_swb48;
break;
default:
std::cerr << "Payload type " <<
static_cast<int>(rtp_header->header.payloadType) <<
" not supported or unknown." << std::endl;
webrtc::Trace::ReturnTrace();
exit(1);
}
}
return payload_len;
}
} // namespace
int main(int argc, char* argv[]) {
static const int kMaxChannels = 5;
@ -388,330 +698,3 @@ int main(int argc, char* argv[]) {
webrtc::Trace::ReturnTrace();
return 0;
}
// Help functions.
// Maps a codec type to a printable name string.
std::string CodecName(webrtc::NetEqDecoder codec) {
switch (codec) {
case webrtc::kDecoderPCMu:
return "PCM-u";
case webrtc::kDecoderPCMa:
return "PCM-a";
case webrtc::kDecoderILBC:
return "iLBC";
case webrtc::kDecoderISAC:
return "iSAC";
case webrtc::kDecoderISACswb:
return "iSAC-swb (32 kHz)";
case webrtc::kDecoderOpus:
return "Opus";
case webrtc::kDecoderPCM16B:
return "PCM16b-nb (8 kHz)";
case webrtc::kDecoderPCM16Bwb:
return "PCM16b-wb (16 kHz)";
case webrtc::kDecoderPCM16Bswb32kHz:
return "PCM16b-swb32 (32 kHz)";
case webrtc::kDecoderPCM16Bswb48kHz:
return "PCM16b-swb48 (48 kHz)";
case webrtc::kDecoderG722:
return "G.722";
case webrtc::kDecoderRED:
return "redundant audio (RED)";
case webrtc::kDecoderAVT:
return "AVT/DTMF";
case webrtc::kDecoderCNGnb:
return "comfort noise (8 kHz)";
case webrtc::kDecoderCNGwb:
return "comfort noise (16 kHz)";
case webrtc::kDecoderCNGswb32kHz:
return "comfort noise (32 kHz)";
case webrtc::kDecoderCNGswb48kHz:
return "comfort noise (48 kHz)";
default:
assert(false);
return "undefined";
}
}
// Registers all decoders in |neteq|.
void RegisterPayloadTypes(NetEq* neteq) {
assert(neteq);
int error;
error = neteq->RegisterPayloadType(webrtc::kDecoderPCMu, FLAGS_pcmu);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcmu <<
" as " << CodecName(webrtc::kDecoderPCMu).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCMa, FLAGS_pcma);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcma <<
" as " << CodecName(webrtc::kDecoderPCMa).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderILBC, FLAGS_ilbc);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_ilbc <<
" as " << CodecName(webrtc::kDecoderILBC).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderISAC, FLAGS_isac);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_isac <<
" as " << CodecName(webrtc::kDecoderISAC).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderISACswb, FLAGS_isac_swb);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_isac_swb <<
" as " << CodecName(webrtc::kDecoderISACswb).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderOpus, FLAGS_opus);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_opus << " as "
<< CodecName(webrtc::kDecoderOpus).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16B, FLAGS_pcm16b);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcm16b <<
" as " << CodecName(webrtc::kDecoderPCM16B).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16Bwb,
FLAGS_pcm16b_wb);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcm16b_wb <<
" as " << CodecName(webrtc::kDecoderPCM16Bwb).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16Bswb32kHz,
FLAGS_pcm16b_swb32);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcm16b_swb32 <<
" as " << CodecName(webrtc::kDecoderPCM16Bswb32kHz).c_str() <<
std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16Bswb48kHz,
FLAGS_pcm16b_swb48);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcm16b_swb48 <<
" as " << CodecName(webrtc::kDecoderPCM16Bswb48kHz).c_str() <<
std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderG722, FLAGS_g722);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_g722 <<
" as " << CodecName(webrtc::kDecoderG722).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderAVT, FLAGS_avt);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_avt <<
" as " << CodecName(webrtc::kDecoderAVT).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderRED, FLAGS_red);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_red <<
" as " << CodecName(webrtc::kDecoderRED).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderCNGnb, FLAGS_cn_nb);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_cn_nb <<
" as " << CodecName(webrtc::kDecoderCNGnb).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderCNGwb, FLAGS_cn_wb);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_cn_wb <<
" as " << CodecName(webrtc::kDecoderCNGwb).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderCNGswb32kHz,
FLAGS_cn_swb32);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_cn_swb32 <<
" as " << CodecName(webrtc::kDecoderCNGswb32kHz).c_str() << std::endl;
exit(1);
}
error = neteq->RegisterPayloadType(webrtc::kDecoderCNGswb48kHz,
FLAGS_cn_swb48);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_cn_swb48 <<
" as " << CodecName(webrtc::kDecoderCNGswb48kHz).c_str() << std::endl;
exit(1);
}
}
void PrintCodecMapping() {
std::cout << CodecName(webrtc::kDecoderPCMu).c_str() << ": " << FLAGS_pcmu <<
std::endl;
std::cout << CodecName(webrtc::kDecoderPCMa).c_str() << ": " << FLAGS_pcma <<
std::endl;
std::cout << CodecName(webrtc::kDecoderILBC).c_str() << ": " << FLAGS_ilbc <<
std::endl;
std::cout << CodecName(webrtc::kDecoderISAC).c_str() << ": " << FLAGS_isac <<
std::endl;
std::cout << CodecName(webrtc::kDecoderISACswb).c_str() << ": " <<
FLAGS_isac_swb << std::endl;
std::cout << CodecName(webrtc::kDecoderOpus).c_str() << ": " << FLAGS_opus
<< std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16B).c_str() << ": " <<
FLAGS_pcm16b << std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16Bwb).c_str() << ": " <<
FLAGS_pcm16b_wb << std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16Bswb32kHz).c_str() << ": " <<
FLAGS_pcm16b_swb32 << std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16Bswb48kHz).c_str() << ": " <<
FLAGS_pcm16b_swb48 << std::endl;
std::cout << CodecName(webrtc::kDecoderG722).c_str() << ": " << FLAGS_g722 <<
std::endl;
std::cout << CodecName(webrtc::kDecoderAVT).c_str() << ": " << FLAGS_avt <<
std::endl;
std::cout << CodecName(webrtc::kDecoderRED).c_str() << ": " << FLAGS_red <<
std::endl;
std::cout << CodecName(webrtc::kDecoderCNGnb).c_str() << ": " <<
FLAGS_cn_nb << std::endl;
std::cout << CodecName(webrtc::kDecoderCNGwb).c_str() << ": " <<
FLAGS_cn_wb << std::endl;
std::cout << CodecName(webrtc::kDecoderCNGswb32kHz).c_str() << ": " <<
FLAGS_cn_swb32 << std::endl;
std::cout << CodecName(webrtc::kDecoderCNGswb48kHz).c_str() << ": " <<
FLAGS_cn_swb48 << std::endl;
}
size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file,
webrtc::scoped_ptr<int16_t[]>* replacement_audio,
webrtc::scoped_ptr<uint8_t[]>* payload,
size_t* payload_mem_size_bytes,
size_t* frame_size_samples,
WebRtcRTPHeader* rtp_header,
const webrtc::test::Packet* next_packet) {
size_t payload_len = 0;
// Check for CNG.
if (IsComfortNosie(rtp_header->header.payloadType)) {
// If CNG, simply insert a zero-energy one-byte payload.
if (*payload_mem_size_bytes < 1) {
(*payload).reset(new uint8_t[1]);
*payload_mem_size_bytes = 1;
}
(*payload)[0] = 127; // Max attenuation of CNG.
payload_len = 1;
} else {
assert(next_packet->virtual_payload_length_bytes() > 0);
// Check if payload length has changed.
if (next_packet->header().sequenceNumber ==
rtp_header->header.sequenceNumber + 1) {
if (*frame_size_samples !=
next_packet->header().timestamp - rtp_header->header.timestamp) {
*frame_size_samples =
next_packet->header().timestamp - rtp_header->header.timestamp;
(*replacement_audio).reset(
new int16_t[*frame_size_samples]);
*payload_mem_size_bytes = 2 * *frame_size_samples;
(*payload).reset(new uint8_t[*payload_mem_size_bytes]);
}
}
// Get new speech.
assert((*replacement_audio).get());
if (CodecTimestampRate(rtp_header->header.payloadType) !=
CodecSampleRate(rtp_header->header.payloadType) ||
rtp_header->header.payloadType == FLAGS_red ||
rtp_header->header.payloadType == FLAGS_avt) {
// Some codecs have different sample and timestamp rates. And neither
// RED nor DTMF is supported for replacement.
std::cerr << "Codec not supported for audio replacement." <<
std::endl;
webrtc::Trace::ReturnTrace();
exit(1);
}
assert(*frame_size_samples > 0);
if (!replacement_audio_file->Read(*frame_size_samples,
(*replacement_audio).get())) {
std::cerr << "Could not read replacement audio file." << std::endl;
webrtc::Trace::ReturnTrace();
exit(1);
}
// Encode it as PCM16.
assert((*payload).get());
payload_len = WebRtcPcm16b_Encode((*replacement_audio).get(),
static_cast<int16_t>(*frame_size_samples),
(*payload).get());
assert(payload_len == 2 * *frame_size_samples);
// Change payload type to PCM16.
switch (CodecSampleRate(rtp_header->header.payloadType)) {
case 8000:
rtp_header->header.payloadType = FLAGS_pcm16b;
break;
case 16000:
rtp_header->header.payloadType = FLAGS_pcm16b_wb;
break;
case 32000:
rtp_header->header.payloadType = FLAGS_pcm16b_swb32;
break;
case 48000:
rtp_header->header.payloadType = FLAGS_pcm16b_swb48;
break;
default:
std::cerr << "Payload type " <<
static_cast<int>(rtp_header->header.payloadType) <<
" not supported or unknown." << std::endl;
webrtc::Trace::ReturnTrace();
exit(1);
}
}
return payload_len;
}
int CodecSampleRate(uint8_t payload_type) {
if (payload_type == FLAGS_pcmu ||
payload_type == FLAGS_pcma ||
payload_type == FLAGS_ilbc ||
payload_type == FLAGS_pcm16b ||
payload_type == FLAGS_cn_nb) {
return 8000;
} else if (payload_type == FLAGS_isac ||
payload_type == FLAGS_pcm16b_wb ||
payload_type == FLAGS_g722 ||
payload_type == FLAGS_cn_wb) {
return 16000;
} else if (payload_type == FLAGS_isac_swb ||
payload_type == FLAGS_pcm16b_swb32 ||
payload_type == FLAGS_cn_swb32) {
return 32000;
} else if (payload_type == FLAGS_opus || payload_type == FLAGS_pcm16b_swb48 ||
payload_type == FLAGS_cn_swb48) {
return 48000;
} else if (payload_type == FLAGS_avt ||
payload_type == FLAGS_red) {
return 0;
} else {
return -1;
}
}
int CodecTimestampRate(uint8_t payload_type) {
if (payload_type == FLAGS_g722) {
return 8000;
} else {
return CodecSampleRate(payload_type);
}
}
bool IsComfortNosie(uint8_t payload_type) {
if (payload_type == FLAGS_cn_nb ||
payload_type == FLAGS_cn_wb ||
payload_type == FLAGS_cn_swb32 ||
payload_type == FLAGS_cn_swb48) {
return true;
} else {
return false;
}
}