Remove CodecInst pt.2

The following APIs on AudioCodingModule are deprecated with this CL:
  static int NumberOfCodecs();
  static int Codec(int, CodecInst*);
  static int Codec(const char*, CodecInst*, int, size_t);
  static int Codec(const char*, int, size_t);
  absl::optional<CodecInst> SendCodec() const;
  bool RegisterReceiveCodec(int, const SdpAudioFormat&);
  int RegisterExternalReceiveCodec(int, AudioDecoder*, int, int, const std::string&);
  int UnregisterReceiveCodec(uint8_t);
  int32_t ReceiveCodec(CodecInst*);
  absl::optional<SdpAudioFormat> ReceiveFormat();

As well as this method on RtpRtcp module:
  int32_t RegisterSendPayload(const CodecInst&);

Bug: webrtc:7626
Change-Id: I1230732136f1fe9048cf74afdeab767ca57ac9ce
Reviewed-on: https://webrtc-review.googlesource.com/c/113816
Commit-Queue: Fredrik Solenberg <solenberg@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26025}
This commit is contained in:
Fredrik Solenberg 2018-12-11 12:22:10 +01:00 committed by Commit Bot
parent a134204aa3
commit f693bfae5f
33 changed files with 220 additions and 1625 deletions

View File

@ -61,7 +61,6 @@ rtc_static_library("audio") {
"../logging:rtc_stream_config",
"../modules/audio_coding",
"../modules/audio_coding:audio_encoder_cng",
"../modules/audio_coding:audio_format_conversion",
"../modules/audio_coding:audio_network_adaptor_config",
"../modules/audio_device",
"../modules/audio_processing",

View File

@ -175,8 +175,8 @@ webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const {
channel_receive_->GetRTCPStatistics();
// TODO(solenberg): Don't return here if we can't get the codec - return the
// stats we *can* get.
webrtc::CodecInst codec_inst = {0};
if (!channel_receive_->GetRecCodec(&codec_inst)) {
auto receive_codec = channel_receive_->GetReceiveCodec();
if (!receive_codec) {
return stats;
}
@ -185,13 +185,12 @@ webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const {
stats.packets_lost = call_stats.cumulativeLost;
stats.fraction_lost = Q8ToFloat(call_stats.fractionLost);
stats.capture_start_ntp_time_ms = call_stats.capture_start_ntp_time_ms_;
if (codec_inst.pltype != -1) {
stats.codec_name = codec_inst.plname;
stats.codec_payload_type = codec_inst.pltype;
}
stats.codec_name = receive_codec->second.name;
stats.codec_payload_type = receive_codec->first;
stats.ext_seqnum = call_stats.extendedMax;
if (codec_inst.plfreq / 1000 > 0) {
stats.jitter_ms = call_stats.jitterSamples / (codec_inst.plfreq / 1000);
int clockrate_khz = receive_codec->second.clockrate_hz / 1000;
if (clockrate_khz > 0) {
stats.jitter_ms = call_stats.jitterSamples / clockrate_khz;
}
stats.delay_estimate_ms = channel_receive_->GetDelayEstimate();
stats.audio_level = channel_receive_->GetSpeechOutputLevelFullRange();

View File

@ -10,6 +10,7 @@
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "api/test/mock_audio_mixer.h"
@ -63,7 +64,8 @@ const double kTotalOutputDuration = 0.5;
const CallReceiveStatistics kCallStats = {345, 678, 901, 234,
-12, 567, 890, 123};
const CodecInst kCodecInst = {123, "codec_name_recv", 96000, -187, 0, -103};
const std::pair<int, SdpAudioFormat> kReceiveCodec =
{123, {"codec_name_recv", 96000, 0}};
const NetworkStatistics kNetworkStats = {
123, 456, false, 789012, 3456, 123, 456, 0, {}, 789, 12,
345, 678, 901, 0, -1, -1, -1, -1, -1, 0};
@ -140,8 +142,8 @@ struct ConfigHelper {
.WillOnce(Return(kNetworkStats));
EXPECT_CALL(*channel_receive_, GetDecodingCallStatistics())
.WillOnce(Return(kAudioDecodeStats));
EXPECT_CALL(*channel_receive_, GetRecCodec(_))
.WillOnce(DoAll(SetArgPointee<0>(kCodecInst), Return(true)));
EXPECT_CALL(*channel_receive_, GetReceiveCodec())
.WillOnce(Return(kReceiveCodec));
}
private:
@ -267,10 +269,11 @@ TEST(AudioReceiveStreamTest, GetStats) {
stats.packets_rcvd);
EXPECT_EQ(kCallStats.cumulativeLost, stats.packets_lost);
EXPECT_EQ(Q8ToFloat(kCallStats.fractionLost), stats.fraction_lost);
EXPECT_EQ(std::string(kCodecInst.plname), stats.codec_name);
EXPECT_EQ(kReceiveCodec.second.name, stats.codec_name);
EXPECT_EQ(kCallStats.extendedMax, stats.ext_seqnum);
EXPECT_EQ(kCallStats.jitterSamples / (kCodecInst.plfreq / 1000),
stats.jitter_ms);
EXPECT_EQ(
kCallStats.jitterSamples / (kReceiveCodec.second.clockrate_hz / 1000),
stats.jitter_ms);
EXPECT_EQ(kNetworkStats.currentBufferSize, stats.jitter_buffer_ms);
EXPECT_EQ(kNetworkStats.preferredBufferSize,
stats.jitter_buffer_preferred_ms);

View File

@ -765,14 +765,8 @@ void AudioSendStream::RemoveBitrateObserver() {
void AudioSendStream::RegisterCngPayloadType(int payload_type,
int clockrate_hz) {
const CodecInst codec = {payload_type, "CN", clockrate_hz, 0, 1, 0};
if (rtp_rtcp_module_->RegisterSendPayload(codec) != 0) {
rtp_rtcp_module_->DeRegisterSendPayload(codec.pltype);
if (rtp_rtcp_module_->RegisterSendPayload(codec) != 0) {
RTC_DLOG(LS_ERROR) << "RegisterCngPayloadType() failed to register CN to "
"RTP/RTCP module";
}
}
rtp_rtcp_module_->RegisterAudioSendPayload(payload_type, "CN", clockrate_hz,
1, 0);
}
} // namespace internal
} // namespace webrtc

View File

@ -61,7 +61,6 @@ const int kTelephoneEventPayloadType = 123;
const int kTelephoneEventPayloadFrequency = 65432;
const int kTelephoneEventCode = 45;
const int kTelephoneEventDuration = 6789;
const CodecInst kIsacCodec = {103, "isac", 16000, 320, 1, 32000};
constexpr int kIsacPayloadType = 103;
const SdpAudioFormat kIsacFormat = {"isac", 16000, 1};
const SdpAudioFormat kOpusFormat = {"opus", 48000, 2};
@ -375,11 +374,11 @@ TEST(AudioSendStreamTest, GetStats) {
EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent);
EXPECT_EQ(kReportBlock.cumulative_num_packets_lost, stats.packets_lost);
EXPECT_EQ(Q8ToFloat(kReportBlock.fraction_lost), stats.fraction_lost);
EXPECT_EQ(std::string(kIsacCodec.plname), stats.codec_name);
EXPECT_EQ(kIsacFormat.name, stats.codec_name);
EXPECT_EQ(static_cast<int32_t>(kReportBlock.extended_highest_sequence_number),
stats.ext_seqnum);
EXPECT_EQ(static_cast<int32_t>(kReportBlock.interarrival_jitter /
(kIsacCodec.plfreq / 1000)),
(kIsacFormat.clockrate_hz / 1000)),
stats.jitter_ms);
EXPECT_EQ(kCallStats.rttMs, stats.rtt_ms);
EXPECT_EQ(0, stats.audio_level);

View File

@ -120,7 +120,8 @@ class ChannelReceive : public ChannelReceiveInterface,
void StopPlayout() override;
// Codecs
bool GetRecCodec(CodecInst* codec) const override;
absl::optional<std::pair<int, SdpAudioFormat>>
GetReceiveCodec() const override;
bool ReceivedRTCPPacket(const uint8_t* data, size_t length) override;
@ -553,9 +554,10 @@ void ChannelReceive::StopPlayout() {
_outputAudioLevel.Clear();
}
bool ChannelReceive::GetRecCodec(CodecInst* codec) const {
absl::optional<std::pair<int, SdpAudioFormat>>
ChannelReceive::GetReceiveCodec() const {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
return (audio_coding_->ReceiveCodec(codec) == 0);
return audio_coding_->ReceiveCodec();
}
std::vector<webrtc::RtpSource> ChannelReceive::GetSources() const {
@ -924,13 +926,13 @@ void ChannelReceive::UpdatePlayoutTimestamp(bool rtcp) {
}
int ChannelReceive::GetRtpTimestampRateHz() const {
const auto format = audio_coding_->ReceiveFormat();
const auto decoder = audio_coding_->ReceiveCodec();
// Default to the playout frequency if we've not gotten any packets yet.
// TODO(ossu): Zero clockrate can only happen if we've added an external
// decoder for a format we don't support internally. Remove once that way of
// adding decoders is gone!
return (format && format->clockrate_hz != 0)
? format->clockrate_hz
return (decoder && decoder->second.clockrate_hz != 0)
? decoder->second.clockrate_hz
: audio_coding_->PlayoutFrequency();
}

View File

@ -13,6 +13,7 @@
#include <map>
#include <memory>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
@ -79,7 +80,9 @@ class ChannelReceiveInterface : public RtpPacketSinkInterface {
virtual void StartPlayout() = 0;
virtual void StopPlayout() = 0;
virtual bool GetRecCodec(CodecInst* codec) const = 0;
// Payload type and format of last received RTP packet, if any.
virtual absl::optional<std::pair<int, SdpAudioFormat>>
GetReceiveCodec() const = 0;
virtual bool ReceivedRTCPPacket(const uint8_t* data, size_t length) = 0;

View File

@ -854,33 +854,14 @@ bool ChannelSend::SetEncoder(int payload_type,
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
RTC_DCHECK_GE(payload_type, 0);
RTC_DCHECK_LE(payload_type, 127);
// TODO(ossu): Make CodecInsts up, for now: one for the RTP/RTCP module and
// one for for us to keep track of sample rate and number of channels, etc.
// The RTP/RTCP module needs to know the RTP timestamp rate (i.e. clockrate)
// as well as some other things, so we collect this info and send it along.
CodecInst rtp_codec;
rtp_codec.pltype = payload_type;
strncpy(rtp_codec.plname, "audio", sizeof(rtp_codec.plname));
rtp_codec.plname[sizeof(rtp_codec.plname) - 1] = 0;
// Seems unclear if it should be clock rate or sample rate. CodecInst
// supposedly carries the sample rate, but only clock rate seems sensible to
// send to the RTP/RTCP module.
rtp_codec.plfreq = encoder->RtpTimestampRateHz();
rtp_codec.pacsize = rtc::CheckedDivExact(
static_cast<int>(encoder->Max10MsFramesInAPacket() * rtp_codec.plfreq),
100);
rtp_codec.channels = encoder->NumChannels();
rtp_codec.rate = 0;
if (_rtpRtcpModule->RegisterSendPayload(rtp_codec) != 0) {
_rtpRtcpModule->DeRegisterSendPayload(payload_type);
if (_rtpRtcpModule->RegisterSendPayload(rtp_codec) != 0) {
RTC_DLOG(LS_ERROR)
<< "SetEncoder() failed to register codec to RTP/RTCP module";
return false;
}
}
_rtpRtcpModule->RegisterAudioSendPayload(payload_type,
"audio",
encoder->RtpTimestampRateHz(),
encoder->NumChannels(),
0);
if (media_transport_) {
rtc::CritScope cs(&media_transport_lock_);
@ -1017,19 +998,8 @@ bool ChannelSend::SetSendTelephoneEventPayloadType(int payload_type,
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
RTC_DCHECK_LE(0, payload_type);
RTC_DCHECK_GE(127, payload_type);
CodecInst codec = {0};
codec.pltype = payload_type;
codec.plfreq = payload_frequency;
memcpy(codec.plname, "telephone-event", 16);
if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
_rtpRtcpModule->DeRegisterSendPayload(codec.pltype);
if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
RTC_DLOG(LS_ERROR)
<< "SetSendTelephoneEventPayloadType() failed to register "
"send payload type";
return false;
}
}
_rtpRtcpModule->RegisterAudioSendPayload(payload_type, "telephone-event",
payload_frequency, 0, 0);
return true;
}

View File

@ -14,6 +14,7 @@
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "api/test/mock_frame_encryptor.h"
@ -52,7 +53,8 @@ class MockChannelReceive : public voe::ChannelReceiveInterface {
MOCK_CONST_METHOD0(GetPlayoutTimestamp, uint32_t());
MOCK_CONST_METHOD0(GetSyncInfo, absl::optional<Syncable::Info>());
MOCK_METHOD1(SetMinimumPlayoutDelay, void(int delay_ms));
MOCK_CONST_METHOD1(GetRecCodec, bool(CodecInst* codec_inst));
MOCK_CONST_METHOD0(GetReceiveCodec,
absl::optional<std::pair<int, SdpAudioFormat>>());
MOCK_METHOD1(SetReceiveCodecs,
void(const std::map<int, SdpAudioFormat>& codecs));
MOCK_CONST_METHOD0(GetSources, std::vector<RtpSource>());

View File

@ -40,6 +40,7 @@ rtc_source_set("rtc_h264_profile_id") {
deps = [
"..:webrtc_common",
"../rtc_base:checks",
"../rtc_base:rtc_base",
"../rtc_base:rtc_base_approved",
"../rtc_base/system:rtc_export",
@ -488,7 +489,6 @@ if (rtc_include_tests) {
"../api/video:video_frame_i420",
"../call:video_stream_api",
"../common_video:common_video",
"../modules/audio_coding:rent_a_codec",
"../modules/audio_processing:api",
"../modules/audio_processing:audio_processing",
"../modules/rtp_rtcp:rtp_rtcp_format",

View File

@ -32,35 +32,6 @@ rtc_static_library("audio_format_conversion") {
]
}
rtc_static_library("rent_a_codec") {
# Client code SHOULD NOT USE THIS TARGET, but for now it needs to be public
# because there exists client code that uses it.
# TODO(bugs.webrtc.org/9808): Move to private visibility as soon as that
# client code gets updated.
visibility += [ "*" ]
sources = [
"acm2/acm_codec_database.cc",
"acm2/acm_codec_database.h",
"acm2/rent_a_codec.cc",
"acm2/rent_a_codec.h",
]
deps = [
":audio_coding_module_typedefs",
":neteq_decoder_enum",
"../..:webrtc_common",
"../../api:array_view",
"../../api/audio_codecs:audio_codecs_api",
"../../rtc_base:checks",
"../../rtc_base:protobuf_utils",
"../../rtc_base:rtc_base_approved",
"../../system_wrappers",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
defines = audio_codec_defines
}
rtc_source_set("audio_coding_module_typedefs") {
sources = [
"include/audio_coding_module_typedefs.h",
@ -90,7 +61,6 @@ rtc_static_library("audio_coding") {
":audio_coding_module_typedefs",
":neteq",
":neteq_decoder_enum",
":rent_a_codec",
"..:module_api",
"..:module_api_public",
"../..:webrtc_common",
@ -2081,11 +2051,11 @@ if (rtc_include_tests) {
":legacy_encoded_audio_frame",
":mocks",
":neteq",
":neteq_decoder_enum",
":neteq_test_support",
":neteq_test_tools",
":pcm16b",
":red",
":rent_a_codec",
":webrtc_cng",
":webrtc_opus",
"..:module_api",

View File

@ -1,336 +0,0 @@
/*
* Copyright (c) 2012 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.
*/
/*
* This file generates databases with information about all supported audio
* codecs.
*/
// TODO(tlegrand): Change constant input pointers in all functions to constant
// references, where appropriate.
#include "modules/audio_coding/acm2/acm_codec_database.h"
#include "absl/strings/match.h"
#include "api/array_view.h"
#include "modules/audio_coding/acm2/rent_a_codec.h"
#if ((defined WEBRTC_CODEC_ISAC) && (defined WEBRTC_CODEC_ISACFX))
#error iSAC and iSACFX codecs cannot be enabled at the same time
#endif
namespace webrtc {
namespace acm2 {
namespace {
// Checks if the bitrate is valid for iSAC.
bool IsISACRateValid(int rate) {
return (rate == -1) || ((rate <= 56000) && (rate >= 10000));
}
// Checks if the bitrate is valid for iLBC.
bool IsILBCRateValid(int rate, int frame_size_samples) {
if (((frame_size_samples == 240) || (frame_size_samples == 480)) &&
(rate == 13300)) {
return true;
} else if (((frame_size_samples == 160) || (frame_size_samples == 320)) &&
(rate == 15200)) {
return true;
} else {
return false;
}
}
// Checks if the bitrate is valid for Opus.
bool IsOpusRateValid(int rate) {
return (rate >= 6000) && (rate <= 510000);
}
} // namespace
// Not yet used payload-types.
// 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68,
// 67, 66, 65
const CodecInst ACMCodecDB::database_[] = {
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
{103, "ISAC", 16000, 480, 1, 32000},
#if (defined(WEBRTC_CODEC_ISAC))
{104, "ISAC", 32000, 960, 1, 56000},
#endif
#endif
// Mono
{107, "L16", 8000, 80, 1, 128000},
{108, "L16", 16000, 160, 1, 256000},
{109, "L16", 32000, 320, 1, 512000},
// Stereo
{111, "L16", 8000, 80, 2, 128000},
{112, "L16", 16000, 160, 2, 256000},
{113, "L16", 32000, 320, 2, 512000},
// G.711, PCM mu-law and A-law.
// Mono
{0, "PCMU", 8000, 160, 1, 64000},
{8, "PCMA", 8000, 160, 1, 64000},
// Stereo
{110, "PCMU", 8000, 160, 2, 64000},
{118, "PCMA", 8000, 160, 2, 64000},
#ifdef WEBRTC_CODEC_ILBC
{102, "ILBC", 8000, 240, 1, 13300},
#endif
// Mono
{9, "G722", 16000, 320, 1, 64000},
// Stereo
{119, "G722", 16000, 320, 2, 64000},
#ifdef WEBRTC_CODEC_OPUS
// Opus internally supports 48, 24, 16, 12, 8 kHz.
// Mono and stereo.
{120, "opus", 48000, 960, 2, 64000},
#endif
// Comfort noise for four different sampling frequencies.
{13, "CN", 8000, 240, 1, 0},
{98, "CN", 16000, 480, 1, 0},
{99, "CN", 32000, 960, 1, 0},
#ifdef ENABLE_48000_HZ
{100, "CN", 48000, 1440, 1, 0},
#endif
{106, "telephone-event", 8000, 240, 1, 0},
{114, "telephone-event", 16000, 240, 1, 0},
{115, "telephone-event", 32000, 240, 1, 0},
{116, "telephone-event", 48000, 240, 1, 0},
#ifdef WEBRTC_CODEC_RED
{127, "red", 8000, 0, 1, 0},
#endif
// To prevent compile errors due to trailing commas.
{-1, "Null", -1, -1, 0, -1}};
// Create database with all codec settings at compile time.
// Each entry needs the following parameters in the given order:
// Number of allowed packet sizes, a vector with the allowed packet sizes,
// Basic block samples, max number of channels that are supported.
const ACMCodecDB::CodecSettings ACMCodecDB::codec_settings_[] = {
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
{2, {480, 960}, 0, 1},
#if (defined(WEBRTC_CODEC_ISAC))
{1, {960}, 0, 1},
#endif
#endif
// Mono
{4, {80, 160, 240, 320}, 0, 2},
{4, {160, 320, 480, 640}, 0, 2},
{2, {320, 640}, 0, 2},
// Stereo
{4, {80, 160, 240, 320}, 0, 2},
{4, {160, 320, 480, 640}, 0, 2},
{2, {320, 640}, 0, 2},
// G.711, PCM mu-law and A-law.
// Mono
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
// Stereo
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
#ifdef WEBRTC_CODEC_ILBC
{4, {160, 240, 320, 480}, 0, 1},
#endif
// Mono
{6, {160, 320, 480, 640, 800, 960}, 0, 2},
// Stereo
{6, {160, 320, 480, 640, 800, 960}, 0, 2},
#ifdef WEBRTC_CODEC_OPUS
// Opus supports frames shorter than 10ms,
// but it doesn't help us to use them.
// Mono and stereo.
#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
{5, {480, 960, 1920, 2880, 5760}, 0, 2},
#else
{4, {480, 960, 1920, 2880}, 0, 2},
#endif
#endif
// Comfort noise for three different sampling frequencies.
{1, {240}, 240, 1},
{1, {480}, 480, 1},
{1, {960}, 960, 1},
// TODO(solenberg): What is this flag? It is never set in the build files.
#ifdef ENABLE_48000_HZ
{1, {1440}, 1440, 1},
#endif
{1, {240}, 240, 1},
{1, {240}, 240, 1},
{1, {240}, 240, 1},
{1, {240}, 240, 1},
#ifdef WEBRTC_CODEC_RED
{1, {0}, 0, 1},
#endif
// To prevent compile errors due to trailing commas.
{-1, {-1}, -1, 0}};
// Create a database of all NetEQ decoders at compile time.
const NetEqDecoder ACMCodecDB::neteq_decoders_[] = {
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
NetEqDecoder::kDecoderISAC,
#if (defined(WEBRTC_CODEC_ISAC))
NetEqDecoder::kDecoderISACswb,
#endif
#endif
// Mono
NetEqDecoder::kDecoderPCM16B, NetEqDecoder::kDecoderPCM16Bwb,
NetEqDecoder::kDecoderPCM16Bswb32kHz,
// Stereo
NetEqDecoder::kDecoderPCM16B_2ch, NetEqDecoder::kDecoderPCM16Bwb_2ch,
NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch,
// G.711, PCM mu-las and A-law.
// Mono
NetEqDecoder::kDecoderPCMu, NetEqDecoder::kDecoderPCMa,
// Stereo
NetEqDecoder::kDecoderPCMu_2ch, NetEqDecoder::kDecoderPCMa_2ch,
#ifdef WEBRTC_CODEC_ILBC
NetEqDecoder::kDecoderILBC,
#endif
// Mono
NetEqDecoder::kDecoderG722,
// Stereo
NetEqDecoder::kDecoderG722_2ch,
#ifdef WEBRTC_CODEC_OPUS
// Mono and stereo.
NetEqDecoder::kDecoderOpus,
#endif
// Comfort noise for three different sampling frequencies.
NetEqDecoder::kDecoderCNGnb, NetEqDecoder::kDecoderCNGwb,
NetEqDecoder::kDecoderCNGswb32kHz,
#ifdef ENABLE_48000_HZ
NetEqDecoder::kDecoderCNGswb48kHz,
#endif
NetEqDecoder::kDecoderAVT, NetEqDecoder::kDecoderAVT16kHz,
NetEqDecoder::kDecoderAVT32kHz, NetEqDecoder::kDecoderAVT48kHz,
#ifdef WEBRTC_CODEC_RED
NetEqDecoder::kDecoderRED,
#endif
};
// Enumerator for error codes when asking for codec database id.
enum {
kInvalidCodec = -10,
kInvalidPayloadtype = -30,
kInvalidPacketSize = -40,
kInvalidRate = -50
};
// Gets the codec id number from the database. If there is some mismatch in
// the codec settings, the function will return an error code.
// NOTE! The first mismatch found will generate the return value.
int ACMCodecDB::CodecNumber(const CodecInst& codec_inst) {
// Look for a matching codec in the database.
int codec_id = CodecId(codec_inst);
// Checks if we found a matching codec.
if (codec_id == -1) {
return kInvalidCodec;
}
// Checks the validity of payload type
if (!RentACodec::IsPayloadTypeValid(codec_inst.pltype)) {
return kInvalidPayloadtype;
}
// Comfort Noise is special case, packet-size & rate is not checked.
if (absl::EqualsIgnoreCase(database_[codec_id].plname, "CN")) {
return codec_id;
}
// RED is special case, packet-size & rate is not checked.
if (absl::EqualsIgnoreCase(database_[codec_id].plname, "red")) {
return codec_id;
}
// Checks the validity of packet size.
if (codec_settings_[codec_id].num_packet_sizes > 0) {
bool packet_size_ok = false;
int i;
int packet_size_samples;
for (i = 0; i < codec_settings_[codec_id].num_packet_sizes; i++) {
packet_size_samples = codec_settings_[codec_id].packet_sizes_samples[i];
if (codec_inst.pacsize == packet_size_samples) {
packet_size_ok = true;
break;
}
}
if (!packet_size_ok) {
return kInvalidPacketSize;
}
}
if (codec_inst.pacsize < 1) {
return kInvalidPacketSize;
}
// Check the validity of rate. Codecs with multiple rates have their own
// function for this.
if (absl::EqualsIgnoreCase("isac", codec_inst.plname)) {
return IsISACRateValid(codec_inst.rate) ? codec_id : kInvalidRate;
} else if (absl::EqualsIgnoreCase("ilbc", codec_inst.plname)) {
return IsILBCRateValid(codec_inst.rate, codec_inst.pacsize) ? codec_id
: kInvalidRate;
} else if (absl::EqualsIgnoreCase("opus", codec_inst.plname)) {
return IsOpusRateValid(codec_inst.rate) ? codec_id : kInvalidRate;
}
return database_[codec_id].rate == codec_inst.rate ? codec_id : kInvalidRate;
}
// Looks for a matching payload name, frequency, and channels in the
// codec list. Need to check all three since some codecs have several codec
// entries with different frequencies and/or channels.
// Does not check other codec settings, such as payload type and packet size.
// Returns the id of the codec, or -1 if no match is found.
int ACMCodecDB::CodecId(const CodecInst& codec_inst) {
return (CodecId(codec_inst.plname, codec_inst.plfreq, codec_inst.channels));
}
int ACMCodecDB::CodecId(const char* payload_name,
int frequency,
size_t channels) {
for (const CodecInst& ci : database_) {
bool name_match = false;
bool frequency_match = false;
bool channels_match = false;
// Payload name, sampling frequency and number of channels need to match.
// NOTE! If |frequency| is -1, the frequency is not applicable, and is
// always treated as true, like for RED.
name_match = absl::EqualsIgnoreCase(ci.plname, payload_name);
frequency_match = (frequency == ci.plfreq) || (frequency == -1);
// The number of channels must match for all codecs but Opus.
if (!absl::EqualsIgnoreCase(payload_name, "opus")) {
channels_match = (channels == ci.channels);
} else {
// For opus we just check that number of channels is valid.
channels_match = (channels == 1 || channels == 2);
}
if (name_match && frequency_match && channels_match) {
// We have found a matching codec in the list.
return &ci - database_;
}
}
// We didn't find a matching codec.
return -1;
}
// Gets codec id number from database for the receiver.
int ACMCodecDB::ReceiverCodecNumber(const CodecInst& codec_inst) {
// Look for a matching codec in the database.
return CodecId(codec_inst);
}
} // namespace acm2
} // namespace webrtc

View File

@ -1,81 +0,0 @@
/*
* Copyright (c) 2012 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.
*/
/*
* This file generates databases with information about all supported audio
* codecs.
*/
#ifndef MODULES_AUDIO_CODING_ACM2_ACM_CODEC_DATABASE_H_
#define MODULES_AUDIO_CODING_ACM2_ACM_CODEC_DATABASE_H_
#include "common_types.h" // NOLINT(build/include)
#include "modules/audio_coding/acm2/rent_a_codec.h"
namespace webrtc {
namespace acm2 {
// TODO(tlegrand): replace class ACMCodecDB with a namespace.
class ACMCodecDB {
public:
// kMaxNumCodecs - Maximum number of codecs that can be activated in one
// build.
// kMaxNumPacketSize - Maximum number of allowed packet sizes for one codec.
// These might need to be increased if adding a new codec to the database
static const int kMaxNumCodecs = 50;
static const int kMaxNumPacketSize = 6;
// Codec specific settings
//
// num_packet_sizes - number of allowed packet sizes.
// packet_sizes_samples - list of the allowed packet sizes.
// basic_block_samples - assigned a value different from 0 if the codec
// requires to be fed with a specific number of samples
// that can be different from packet size.
// channel_support - number of channels supported to encode;
// 1 = mono, 2 = stereo, etc.
struct CodecSettings {
int num_packet_sizes;
int packet_sizes_samples[kMaxNumPacketSize];
int basic_block_samples;
size_t channel_support;
};
// Returns codec id from database, given the information received in the input
// [codec_inst].
// Input:
// [codec_inst] - Information about the codec for which we require the
// database id.
// Return:
// codec id if successful, otherwise < 0.
static int CodecNumber(const CodecInst& codec_inst);
static int CodecId(const CodecInst& codec_inst);
static int CodecId(const char* payload_name, int frequency, size_t channels);
static int ReceiverCodecNumber(const CodecInst& codec_inst);
// Databases with information about the supported codecs
// database_ - stored information about all codecs: payload type, name,
// sampling frequency, packet size in samples, default channel
// support, and default rate.
// codec_settings_ - stored codec settings: number of allowed packet sizes,
// a vector with the allowed packet sizes, basic block
// samples, and max number of channels that are supported.
// neteq_decoders_ - list of supported decoders in NetEQ.
static const CodecInst database_[kMaxNumCodecs];
static const CodecSettings codec_settings_[kMaxNumCodecs];
static const NetEqDecoder neteq_decoders_[kMaxNumCodecs];
};
} // namespace acm2
} // namespace webrtc
#endif // MODULES_AUDIO_CODING_ACM2_ACM_CODEC_DATABASE_H_

View File

@ -14,9 +14,7 @@
#include <memory>
#include "absl/strings/match.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "modules/audio_coding/codecs/audio_format_conversion.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/neteq/tools/audio_sink.h"
#include "modules/audio_coding/neteq/tools/packet.h"
@ -28,89 +26,6 @@ namespace webrtc {
namespace test {
namespace {
// Returns true if the codec should be registered, otherwise false. Changes
// the number of channels for the Opus codec to always be 1.
bool ModifyAndUseThisCodec(CodecInst* codec_param) {
if (absl::EqualsIgnoreCase(codec_param->plname, "CN") &&
codec_param->plfreq == 48000)
return false; // Skip 48 kHz comfort noise.
if (absl::EqualsIgnoreCase(codec_param->plname, "telephone-event"))
return false; // Skip DTFM.
return true;
}
// Remaps payload types from ACM's default to those used in the resource file
// neteq_universal_new.rtp. Returns true if the codec should be registered,
// otherwise false. The payload types are set as follows (all are mono codecs):
// PCMu = 0;
// PCMa = 8;
// Comfort noise 8 kHz = 13
// Comfort noise 16 kHz = 98
// Comfort noise 32 kHz = 99
// iLBC = 102
// iSAC wideband = 103
// iSAC super-wideband = 104
// AVT/DTMF = 106
// RED = 117
// PCM16b 8 kHz = 93
// PCM16b 16 kHz = 94
// PCM16b 32 kHz = 95
// G.722 = 94
bool RemapPltypeAndUseThisCodec(const char* plname,
int plfreq,
size_t channels,
int* pltype) {
if (channels != 1)
return false; // Don't use non-mono codecs.
// Re-map pltypes to those used in the NetEq test files.
if (absl::EqualsIgnoreCase(plname, "PCMU") && plfreq == 8000) {
*pltype = 0;
} else if (absl::EqualsIgnoreCase(plname, "PCMA") && plfreq == 8000) {
*pltype = 8;
} else if (absl::EqualsIgnoreCase(plname, "CN") && plfreq == 8000) {
*pltype = 13;
} else if (absl::EqualsIgnoreCase(plname, "CN") && plfreq == 16000) {
*pltype = 98;
} else if (absl::EqualsIgnoreCase(plname, "CN") && plfreq == 32000) {
*pltype = 99;
} else if (absl::EqualsIgnoreCase(plname, "ILBC")) {
*pltype = 102;
} else if (absl::EqualsIgnoreCase(plname, "ISAC") && plfreq == 16000) {
*pltype = 103;
} else if (absl::EqualsIgnoreCase(plname, "ISAC") && plfreq == 32000) {
*pltype = 104;
} else if (absl::EqualsIgnoreCase(plname, "telephone-event") &&
plfreq == 8000) {
*pltype = 106;
} else if (absl::EqualsIgnoreCase(plname, "telephone-event") &&
plfreq == 16000) {
*pltype = 114;
} else if (absl::EqualsIgnoreCase(plname, "telephone-event") &&
plfreq == 32000) {
*pltype = 115;
} else if (absl::EqualsIgnoreCase(plname, "telephone-event") &&
plfreq == 48000) {
*pltype = 116;
} else if (absl::EqualsIgnoreCase(plname, "red")) {
*pltype = 117;
} else if (absl::EqualsIgnoreCase(plname, "L16") && plfreq == 8000) {
*pltype = 93;
} else if (absl::EqualsIgnoreCase(plname, "L16") && plfreq == 16000) {
*pltype = 94;
} else if (absl::EqualsIgnoreCase(plname, "L16") && plfreq == 32000) {
*pltype = 95;
} else if (absl::EqualsIgnoreCase(plname, "G722")) {
*pltype = 9;
} else {
// Don't use any other codecs.
return false;
}
return true;
}
AudioCodingModule::Config MakeAcmConfig(
Clock* clock,
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) {
@ -119,7 +34,6 @@ AudioCodingModule::Config MakeAcmConfig(
config.decoder_factory = std::move(decoder_factory);
return config;
}
} // namespace
AcmReceiveTestOldApi::AcmReceiveTestOldApi(
@ -139,36 +53,43 @@ AcmReceiveTestOldApi::AcmReceiveTestOldApi(
AcmReceiveTestOldApi::~AcmReceiveTestOldApi() = default;
void AcmReceiveTestOldApi::RegisterDefaultCodecs() {
CodecInst my_codec_param;
for (int n = 0; n < acm_->NumberOfCodecs(); n++) {
ASSERT_EQ(0, acm_->Codec(n, &my_codec_param)) << "Failed to get codec.";
if (ModifyAndUseThisCodec(&my_codec_param)) {
ASSERT_EQ(true,
acm_->RegisterReceiveCodec(my_codec_param.pltype,
CodecInstToSdp(my_codec_param)))
<< "Couldn't register receive codec.\n";
}
}
acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
{104, {"ISAC", 32000, 1}},
{107, {"L16", 8000, 1}},
{108, {"L16", 16000, 1}},
{109, {"L16", 32000, 1}},
{111, {"L16", 8000, 2}},
{112, {"L16", 16000, 2}},
{113, {"L16", 32000, 2}},
{0, {"PCMU", 8000, 1}},
{110, {"PCMU", 8000, 2}},
{8, {"PCMA", 8000, 1}},
{118, {"PCMA", 8000, 2}},
{102, {"ILBC", 8000, 1}},
{9, {"G722", 8000, 1}},
{119, {"G722", 8000, 2}},
{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
{13, {"CN", 8000, 1}},
{98, {"CN", 16000, 1}},
{99, {"CN", 32000, 1}}});
}
// Remaps payload types from ACM's default to those used in the resource file
// neteq_universal_new.rtp.
void AcmReceiveTestOldApi::RegisterNetEqTestCodecs() {
CodecInst my_codec_param;
for (int n = 0; n < acm_->NumberOfCodecs(); n++) {
ASSERT_EQ(0, acm_->Codec(n, &my_codec_param)) << "Failed to get codec.";
if (!ModifyAndUseThisCodec(&my_codec_param)) {
// Skip this codec.
continue;
}
if (RemapPltypeAndUseThisCodec(my_codec_param.plname, my_codec_param.plfreq,
my_codec_param.channels,
&my_codec_param.pltype)) {
ASSERT_EQ(true,
acm_->RegisterReceiveCodec(my_codec_param.pltype,
CodecInstToSdp(my_codec_param)))
<< "Couldn't register receive codec.\n";
}
}
acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
{104, {"ISAC", 32000, 1}},
{93, {"L16", 8000, 1}},
{94, {"L16", 16000, 1}},
{95, {"L16", 32000, 1}},
{0, {"PCMU", 8000, 1}},
{8, {"PCMA", 8000, 1}},
{102, {"ILBC", 8000, 1}},
{9, {"G722", 8000, 1}},
{120, {"OPUS", 48000, 2}},
{13, {"CN", 8000, 1}},
{98, {"CN", 16000, 1}},
{99, {"CN", 32000, 1}}});
}
void AcmReceiveTestOldApi::Run() {

View File

@ -23,7 +23,6 @@
namespace webrtc {
class AudioCodingModule;
class AudioDecoder;
struct CodecInst;
namespace test {
class AudioSink;

View File

@ -20,7 +20,6 @@
#include "api/audio_codecs/audio_decoder.h"
#include "modules/audio_coding/acm2/acm_resampler.h"
#include "modules/audio_coding/acm2/call_statistics.h"
#include "modules/audio_coding/acm2/rent_a_codec.h"
#include "modules/audio_coding/neteq/include/neteq.h"
#include "modules/audio_coding/neteq/neteq_decoder_enum.h"
#include "modules/include/module_common_types.h"
@ -62,7 +61,10 @@ int AcmReceiver::SetMaximumDelay(int delay_ms) {
absl::optional<int> AcmReceiver::last_packet_sample_rate_hz() const {
rtc::CritScope lock(&crit_sect_);
return last_packet_sample_rate_hz_;
if (!last_decoder_) {
return absl::nullopt;
}
return last_decoder_->second.clockrate_hz;
}
int AcmReceiver::last_output_sample_rate_hz() const {
@ -71,45 +73,44 @@ int AcmReceiver::last_output_sample_rate_hz() const {
int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header,
rtc::ArrayView<const uint8_t> incoming_payload) {
uint32_t receive_timestamp = 0;
const RTPHeader* header = &rtp_header.header; // Just a shorthand.
if (incoming_payload.empty()) {
neteq_->InsertEmptyPacket(rtp_header.header);
return 0;
}
const RTPHeader& header = rtp_header.header; // Just a shorthand.
int payload_type = header.payloadType;
auto format = neteq_->GetDecoderFormat(payload_type);
if (format && absl::EqualsIgnoreCase(format->name, "red")) {
// This is a RED packet. Get the format of the audio codec.
payload_type = incoming_payload[0] & 0x7f;
format = neteq_->GetDecoderFormat(payload_type);
}
if (!format) {
RTC_LOG_F(LS_ERROR) << "Payload-type "
<< payload_type
<< " is not registered.";
return -1;
}
{
rtc::CritScope lock(&crit_sect_);
const absl::optional<CodecInst> ci =
RtpHeaderToDecoder(*header, incoming_payload[0]);
if (!ci) {
RTC_LOG_F(LS_ERROR) << "Payload-type "
<< static_cast<int>(header->payloadType)
<< " is not registered.";
return -1;
}
receive_timestamp = NowInTimestamp(ci->plfreq);
if (absl::EqualsIgnoreCase(ci->plname, "cn")) {
if (last_audio_decoder_ && last_audio_decoder_->channels > 1) {
if (absl::EqualsIgnoreCase(format->name, "cn")) {
if (last_decoder_ && last_decoder_->second.num_channels > 1) {
// This is a CNG and the audio codec is not mono, so skip pushing in
// packets into NetEq.
return 0;
}
} else {
last_audio_decoder_ = ci;
last_audio_format_ = neteq_->GetDecoderFormat(ci->pltype);
RTC_DCHECK(last_audio_format_);
last_packet_sample_rate_hz_ = ci->plfreq;
RTC_DCHECK(format);
last_decoder_ = std::make_pair(payload_type, *format);
}
} // |crit_sect_| is released.
if (neteq_->InsertPacket(rtp_header.header, incoming_payload,
receive_timestamp) < 0) {
uint32_t receive_timestamp = NowInTimestamp(format->clockrate_hz);
if (neteq_->InsertPacket(header, incoming_payload, receive_timestamp) < 0) {
RTC_LOG(LERROR) << "AcmReceiver::InsertPacket "
<< static_cast<int>(header->payloadType)
<< static_cast<int>(header.payloadType)
<< " Failed to insert packet";
return -1;
}
@ -186,85 +187,6 @@ void AcmReceiver::SetCodecs(const std::map<int, SdpAudioFormat>& codecs) {
neteq_->SetCodecs(codecs);
}
int32_t AcmReceiver::AddCodec(int acm_codec_id,
uint8_t payload_type,
size_t channels,
int /*sample_rate_hz*/,
AudioDecoder* audio_decoder,
const std::string& name) {
// TODO(kwiberg): This function has been ignoring the |sample_rate_hz|
// argument for a long time. Arguably, it should simply be removed.
const auto neteq_decoder = [acm_codec_id, channels]() -> NetEqDecoder {
if (acm_codec_id == -1)
return NetEqDecoder::kDecoderArbitrary; // External decoder.
const absl::optional<RentACodec::CodecId> cid =
RentACodec::CodecIdFromIndex(acm_codec_id);
RTC_DCHECK(cid) << "Invalid codec index: " << acm_codec_id;
const absl::optional<NetEqDecoder> ned =
RentACodec::NetEqDecoderFromCodecId(*cid, channels);
RTC_DCHECK(ned) << "Invalid codec ID: " << static_cast<int>(*cid);
return *ned;
}();
const absl::optional<SdpAudioFormat> new_format =
NetEqDecoderToSdpAudioFormat(neteq_decoder);
rtc::CritScope lock(&crit_sect_);
const auto old_format = neteq_->GetDecoderFormat(payload_type);
if (old_format && new_format && *old_format == *new_format) {
// Re-registering the same codec. Do nothing and return.
return 0;
}
if (neteq_->RemovePayloadType(payload_type) != NetEq::kOK) {
RTC_LOG(LERROR) << "Cannot remove payload "
<< static_cast<int>(payload_type);
return -1;
}
int ret_val;
if (!audio_decoder) {
ret_val = neteq_->RegisterPayloadType(neteq_decoder, name, payload_type);
} else {
ret_val = neteq_->RegisterExternalDecoder(audio_decoder, neteq_decoder,
name, payload_type);
}
if (ret_val != NetEq::kOK) {
RTC_LOG(LERROR) << "AcmReceiver::AddCodec " << acm_codec_id
<< static_cast<int>(payload_type)
<< " channels: " << channels;
return -1;
}
return 0;
}
bool AcmReceiver::AddCodec(int rtp_payload_type,
const SdpAudioFormat& audio_format) {
const auto old_format = neteq_->GetDecoderFormat(rtp_payload_type);
if (old_format && *old_format == audio_format) {
// Re-registering the same codec. Do nothing and return.
return true;
}
if (neteq_->RemovePayloadType(rtp_payload_type) != NetEq::kOK) {
RTC_LOG(LERROR)
<< "AcmReceiver::AddCodec: Could not remove existing decoder"
" for payload type "
<< rtp_payload_type;
return false;
}
const bool success =
neteq_->RegisterPayloadType(rtp_payload_type, audio_format);
if (!success) {
RTC_LOG(LERROR) << "AcmReceiver::AddCodec failed for payload type "
<< rtp_payload_type << ", decoder format "
<< rtc::ToString(audio_format);
}
return success;
}
void AcmReceiver::FlushBuffers() {
neteq_->FlushBuffers();
}
@ -272,24 +194,7 @@ void AcmReceiver::FlushBuffers() {
void AcmReceiver::RemoveAllCodecs() {
rtc::CritScope lock(&crit_sect_);
neteq_->RemoveAllPayloadTypes();
last_audio_decoder_ = absl::nullopt;
last_audio_format_ = absl::nullopt;
last_packet_sample_rate_hz_ = absl::nullopt;
}
int AcmReceiver::RemoveCodec(uint8_t payload_type) {
rtc::CritScope lock(&crit_sect_);
if (neteq_->RemovePayloadType(payload_type) != NetEq::kOK) {
RTC_LOG(LERROR) << "AcmReceiver::RemoveCodec "
<< static_cast<int>(payload_type);
return -1;
}
if (last_audio_decoder_ && payload_type == last_audio_decoder_->pltype) {
last_audio_decoder_ = absl::nullopt;
last_audio_format_ = absl::nullopt;
last_packet_sample_rate_hz_ = absl::nullopt;
}
return 0;
last_decoder_ = absl::nullopt;
}
absl::optional<uint32_t> AcmReceiver::GetPlayoutTimestamp() {
@ -304,18 +209,14 @@ int AcmReceiver::TargetDelayMs() const {
return neteq_->TargetDelayMs();
}
int AcmReceiver::LastAudioCodec(CodecInst* codec) const {
absl::optional<std::pair<int, SdpAudioFormat>>
AcmReceiver::LastDecoder() const {
rtc::CritScope lock(&crit_sect_);
if (!last_audio_decoder_) {
return -1;
if (!last_decoder_) {
return absl::nullopt;
}
*codec = *last_audio_decoder_;
return 0;
}
absl::optional<SdpAudioFormat> AcmReceiver::LastAudioFormat() const {
rtc::CritScope lock(&crit_sect_);
return last_audio_format_;
RTC_DCHECK_NE(-1, last_decoder_->first); // Payload type should be valid.
return last_decoder_;
}
void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) {
@ -354,26 +255,6 @@ void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) {
neteq_operations_and_state.packet_buffer_flushes;
}
int AcmReceiver::DecoderByPayloadType(uint8_t payload_type,
CodecInst* codec) const {
rtc::CritScope lock(&crit_sect_);
const absl::optional<CodecInst> ci = neteq_->GetDecoder(payload_type);
if (ci) {
*codec = *ci;
return 0;
} else {
RTC_LOG(LERROR) << "AcmReceiver::DecoderByPayloadType "
<< static_cast<int>(payload_type);
return -1;
}
}
absl::optional<SdpAudioFormat> AcmReceiver::DecoderByPayloadType(
int payload_type) const {
rtc::CritScope lock(&crit_sect_);
return neteq_->GetDecoderFormat(payload_type);
}
int AcmReceiver::EnableNack(size_t max_nack_list_size) {
neteq_->EnableNack(max_nack_list_size);
return 0;
@ -393,19 +274,6 @@ void AcmReceiver::ResetInitialDelay() {
// TODO(turajs): Should NetEq Buffer be flushed?
}
const absl::optional<CodecInst> AcmReceiver::RtpHeaderToDecoder(
const RTPHeader& rtp_header,
uint8_t first_payload_byte) const {
const absl::optional<CodecInst> ci =
neteq_->GetDecoder(rtp_header.payloadType);
if (ci && absl::EqualsIgnoreCase(ci->plname, "red")) {
// This is a RED packet. Get the payload of the audio codec.
return neteq_->GetDecoder(first_payload_byte & 0x7f);
} else {
return ci;
}
}
uint32_t AcmReceiver::NowInTimestamp(int decoder_sampling_rate) const {
// Down-cast the time to (32-6)-bit since we only care about
// the least significant bits. (32-6) bits cover 2^(32-6) = 67108864 ms.

View File

@ -15,6 +15,7 @@
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
@ -30,7 +31,6 @@
namespace webrtc {
class Clock;
struct CodecInst;
class NetEq;
struct RTPHeader;
struct WebRtcRTPHeader;
@ -84,43 +84,6 @@ class AcmReceiver {
// Replace the current set of decoders with the specified set.
void SetCodecs(const std::map<int, SdpAudioFormat>& codecs);
//
// Adds a new codec to the NetEq codec database.
//
// Input:
// - acm_codec_id : ACM codec ID; -1 means external decoder.
// - payload_type : payload type.
// - sample_rate_hz : sample rate.
// - audio_decoder : pointer to a decoder object. If it's null, then
// NetEq will internally create a decoder object
// based on the value of |acm_codec_id| (which
// mustn't be -1). Otherwise, NetEq will use the
// given decoder for the given payload type. NetEq
// won't take ownership of the decoder; it's up to
// the caller to delete it when it's no longer
// needed.
//
// Providing an existing decoder object here is
// necessary for external decoders, but may also be
// used for built-in decoders if NetEq doesn't have
// all the info it needs to construct them properly
// (e.g. iSAC, where the decoder needs to be paired
// with an encoder).
//
// Return value : 0 if OK.
// <0 if NetEq returned an error.
//
int AddCodec(int acm_codec_id,
uint8_t payload_type,
size_t channels,
int sample_rate_hz,
AudioDecoder* audio_decoder,
const std::string& name);
// Adds a new decoder to the NetEq codec database. Returns true iff
// successful.
bool AddCodec(int rtp_payload_type, const SdpAudioFormat& audio_format);
//
// Sets a minimum delay for packet buffer. The given delay is maintained,
// unless channel condition dictates a higher delay.
@ -172,17 +135,6 @@ class AcmReceiver {
//
void FlushBuffers();
//
// Removes a payload-type from the NetEq codec database.
//
// Input:
// - payload_type : the payload-type to be removed.
//
// Return value : 0 if OK.
// -1 if an error occurred.
//
int RemoveCodec(uint8_t payload_type);
//
// Remove all registered codecs.
//
@ -204,30 +156,10 @@ class AcmReceiver {
int TargetDelayMs() const;
//
// Get the audio codec associated with the last non-CNG/non-DTMF received
// payload. If no non-CNG/non-DTMF packet is received -1 is returned,
// otherwise return 0.
// Get payload type and format of the last non-CNG/non-DTMF received payload.
// If no non-CNG/non-DTMF packet is received absl::nullopt is returned.
//
int LastAudioCodec(CodecInst* codec) const;
absl::optional<SdpAudioFormat> LastAudioFormat() const;
//
// Get a decoder given its registered payload-type.
//
// Input:
// -payload_type : the payload-type of the codec to be retrieved.
//
// Output:
// -codec : codec associated with the given payload-type.
//
// Return value : 0 if succeeded.
// -1 if failed, e.g. given payload-type is not
// registered.
//
int DecoderByPayloadType(uint8_t payload_type,
CodecInst* codec) const;
absl::optional<SdpAudioFormat> DecoderByPayloadType(int payload_type) const;
absl::optional<std::pair<int, SdpAudioFormat>> LastDecoder() const;
//
// Enable NACK and set the maximum size of the NACK list. If NACK is already
@ -260,32 +192,17 @@ class AcmReceiver {
void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const;
private:
struct Decoder {
int acm_codec_id;
uint8_t payload_type;
// This field is meaningful for codecs where both mono and
// stereo versions are registered under the same ID.
size_t channels;
int sample_rate_hz;
};
const absl::optional<CodecInst> RtpHeaderToDecoder(
const RTPHeader& rtp_header,
uint8_t first_payload_byte) const
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
uint32_t NowInTimestamp(int decoder_sampling_rate) const;
rtc::CriticalSection crit_sect_;
absl::optional<CodecInst> last_audio_decoder_ RTC_GUARDED_BY(crit_sect_);
absl::optional<SdpAudioFormat> last_audio_format_ RTC_GUARDED_BY(crit_sect_);
absl::optional<std::pair<int, SdpAudioFormat>> last_decoder_
RTC_GUARDED_BY(crit_sect_);
ACMResampler resampler_ RTC_GUARDED_BY(crit_sect_);
std::unique_ptr<int16_t[]> last_audio_buffer_ RTC_GUARDED_BY(crit_sect_);
CallStatistics call_stats_ RTC_GUARDED_BY(crit_sect_);
const std::unique_ptr<NetEq> neteq_; // NetEq is thread-safe; no lock needed.
const Clock* const clock_;
bool resampled_last_output_frame_ RTC_GUARDED_BY(crit_sect_);
absl::optional<int> last_packet_sample_rate_hz_ RTC_GUARDED_BY(crit_sect_);
};
} // namespace acm2

View File

@ -15,7 +15,6 @@
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "modules/audio_coding/acm2/rent_a_codec.h"
#include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/neteq/tools/rtp_generator.h"
@ -105,14 +104,6 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback,
return num_10ms_frames;
}
template <size_t N>
void AddSetOfCodecs(rtc::ArrayView<SdpAudioFormat> formats) {
static int payload_type = 0;
for (const auto& format : formats) {
EXPECT_TRUE(receiver_->AddCodec(payload_type++, format));
}
}
int SendData(FrameType frame_type,
uint8_t payload_type,
uint32_t timestamp,
@ -153,112 +144,27 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback,
FrameType last_frame_type_;
};
#if defined(WEBRTC_ANDROID)
#define MAYBE_AddCodecGetCodec DISABLED_AddCodecGetCodec
#else
#define MAYBE_AddCodecGetCodec AddCodecGetCodec
#endif
TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecGetCodec) {
const std::vector<AudioCodecSpec> codecs =
decoder_factory_->GetSupportedDecoders();
// Add codec.
for (size_t n = 0; n < codecs.size(); ++n) {
if (n & 0x1) { // Just add codecs with odd index.
const int payload_type = rtc::checked_cast<int>(n);
EXPECT_TRUE(receiver_->AddCodec(payload_type, codecs[n].format));
}
}
// Get codec and compare.
for (size_t n = 0; n < codecs.size(); ++n) {
const int payload_type = rtc::checked_cast<int>(n);
if (n & 0x1) {
// Codecs with odd index should match the reference.
EXPECT_EQ(absl::make_optional(codecs[n].format),
receiver_->DecoderByPayloadType(payload_type));
} else {
// Codecs with even index are not registered.
EXPECT_EQ(absl::nullopt, receiver_->DecoderByPayloadType(payload_type));
}
}
}
#if defined(WEBRTC_ANDROID)
#define MAYBE_AddCodecChangePayloadType DISABLED_AddCodecChangePayloadType
#else
#define MAYBE_AddCodecChangePayloadType AddCodecChangePayloadType
#endif
TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecChangePayloadType) {
const SdpAudioFormat format("giraffe", 8000, 1);
// Register the same codec with different payloads.
EXPECT_EQ(true, receiver_->AddCodec(17, format));
EXPECT_EQ(true, receiver_->AddCodec(18, format));
// Both payload types should exist.
EXPECT_EQ(absl::make_optional(format), receiver_->DecoderByPayloadType(17));
EXPECT_EQ(absl::make_optional(format), receiver_->DecoderByPayloadType(18));
}
#if defined(WEBRTC_ANDROID)
#define MAYBE_AddCodecChangeCodecId DISABLED_AddCodecChangeCodecId
#else
#define MAYBE_AddCodecChangeCodecId AddCodecChangeCodecId
#endif
TEST_F(AcmReceiverTestOldApi, AddCodecChangeCodecId) {
const SdpAudioFormat format1("giraffe", 8000, 1);
const SdpAudioFormat format2("gnu", 16000, 1);
// Register the same payload type with different codec ID.
EXPECT_EQ(true, receiver_->AddCodec(17, format1));
EXPECT_EQ(true, receiver_->AddCodec(17, format2));
// Make sure that the last codec is used.
EXPECT_EQ(absl::make_optional(format2), receiver_->DecoderByPayloadType(17));
}
#if defined(WEBRTC_ANDROID)
#define MAYBE_AddCodecRemoveCodec DISABLED_AddCodecRemoveCodec
#else
#define MAYBE_AddCodecRemoveCodec AddCodecRemoveCodec
#endif
TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecRemoveCodec) {
EXPECT_EQ(true, receiver_->AddCodec(17, SdpAudioFormat("giraffe", 8000, 1)));
// Remove non-existing codec should not fail. ACM1 legacy.
EXPECT_EQ(0, receiver_->RemoveCodec(18));
// Remove an existing codec.
EXPECT_EQ(0, receiver_->RemoveCodec(17));
// Ask for the removed codec, must fail.
EXPECT_EQ(absl::nullopt, receiver_->DecoderByPayloadType(17));
}
#if defined(WEBRTC_ANDROID)
#define MAYBE_SampleRate DISABLED_SampleRate
#else
#define MAYBE_SampleRate SampleRate
#endif
TEST_F(AcmReceiverTestOldApi, MAYBE_SampleRate) {
const std::vector<SdpAudioFormat> codecs = {{"ISAC", 16000, 1},
{"ISAC", 32000, 1}};
for (size_t i = 0; i < codecs.size(); ++i) {
const int payload_type = rtc::checked_cast<int>(i);
EXPECT_EQ(true, receiver_->AddCodec(payload_type, codecs[i]));
}
const std::map<int, SdpAudioFormat> codecs = {{0, {"ISAC", 16000, 1}},
{1, {"ISAC", 32000, 1}}};
receiver_->SetCodecs(codecs);
constexpr int kOutSampleRateHz = 8000; // Different than codec sample rate.
for (size_t i = 0; i < codecs.size(); ++i) {
const int payload_type = rtc::checked_cast<int>(i);
const int num_10ms_frames =
InsertOnePacketOfSilence(SetEncoder(payload_type, codecs[i]));
InsertOnePacketOfSilence(SetEncoder(payload_type, codecs.at(i)));
for (int k = 0; k < num_10ms_frames; ++k) {
AudioFrame frame;
bool muted;
EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame, &muted));
}
EXPECT_EQ(encoder_factory_->QueryAudioEncoder(codecs[i])->sample_rate_hz,
EXPECT_EQ(encoder_factory_->QueryAudioEncoder(codecs.at(i))->sample_rate_hz,
receiver_->last_output_sample_rate_hz());
}
}
@ -278,7 +184,7 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi {
EXPECT_TRUE(config_.neteq_config.for_test_no_time_stretching);
constexpr int payload_type = 17;
EXPECT_TRUE(receiver_->AddCodec(payload_type, codec));
receiver_->SetCodecs({{payload_type, codec}});
const AudioCodecInfo info = SetEncoder(payload_type, codec);
const int output_sample_rate_hz = info.sample_rate_hz;
@ -356,7 +262,7 @@ TEST_F(AcmReceiverTestOldApi, MAYBE_PostdecodingVad) {
constexpr int payload_type = 34;
const SdpAudioFormat codec = {"L16", 16000, 1};
const AudioCodecInfo info = SetEncoder(payload_type, codec);
EXPECT_TRUE(receiver_->AddCodec(payload_type, codec));
receiver_->SetCodecs({{payload_type, codec}});
constexpr int kNumPackets = 5;
AudioFrame frame;
for (int n = 0; n < kNumPackets; ++n) {
@ -387,7 +293,7 @@ TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) {
const SdpAudioFormat codec = {"L16", 16000, 1};
const AudioCodecInfo info = SetEncoder(payload_type, codec);
encoder_factory_->QueryAudioEncoder(codec).value();
EXPECT_TRUE(receiver_->AddCodec(payload_type, codec));
receiver_->SetCodecs({{payload_type, codec}});
const int kNumPackets = 5;
AudioFrame frame;
for (int n = 0; n < kNumPackets; ++n) {
@ -407,43 +313,43 @@ TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) {
#endif
#if defined(WEBRTC_CODEC_ISAC)
TEST_F(AcmReceiverTestOldApi, MAYBE_LastAudioCodec) {
const std::vector<SdpAudioFormat> codecs = {{"ISAC", 16000, 1},
{"PCMA", 8000, 1},
{"ISAC", 32000, 1},
{"L16", 32000, 1}};
for (size_t i = 0; i < codecs.size(); ++i) {
const int payload_type = rtc::checked_cast<int>(i);
EXPECT_TRUE(receiver_->AddCodec(payload_type, codecs[i]));
}
const std::map<int, int> cng_payload_types = {
{8000, 100}, {16000, 101}, {32000, 102}};
for (const auto& x : cng_payload_types) {
const int sample_rate_hz = x.first;
const int payload_type = x.second;
EXPECT_TRUE(receiver_->AddCodec(payload_type, {"CN", sample_rate_hz, 1}));
const std::map<int, SdpAudioFormat> codecs = {{0, {"ISAC", 16000, 1}},
{1, {"PCMA", 8000, 1}},
{2, {"ISAC", 32000, 1}},
{3, {"L16", 32000, 1}}};
const std::map<int, int> cng_payload_types = {{8000, 100},
{16000, 101},
{32000, 102}};
{
std::map<int, SdpAudioFormat> receive_codecs = codecs;
for (const auto& cng_type : cng_payload_types) {
receive_codecs.emplace(
std::make_pair(cng_type.second, SdpAudioFormat("CN", cng_type.first, 1)));
}
receiver_->SetCodecs(receive_codecs);
}
// No audio payload is received.
EXPECT_EQ(absl::nullopt, receiver_->LastAudioFormat());
EXPECT_EQ(absl::nullopt, receiver_->LastDecoder());
// Start with sending DTX.
packet_sent_ = false;
InsertOnePacketOfSilence(
SetEncoder(0, codecs[0], cng_payload_types)); // Enough to test
SetEncoder(0, codecs.at(0), cng_payload_types)); // Enough to test
// with one codec.
ASSERT_TRUE(packet_sent_);
EXPECT_EQ(kAudioFrameCN, last_frame_type_);
// Has received, only, DTX. Last Audio codec is undefined.
EXPECT_EQ(absl::nullopt, receiver_->LastAudioFormat());
EXPECT_FALSE(receiver_->last_packet_sample_rate_hz());
EXPECT_EQ(absl::nullopt, receiver_->LastDecoder());
EXPECT_EQ(absl::nullopt, receiver_->last_packet_sample_rate_hz());
for (size_t i = 0; i < codecs.size(); ++i) {
// Set DTX off to send audio payload.
packet_sent_ = false;
const int payload_type = rtc::checked_cast<int>(i);
const AudioCodecInfo info_without_cng = SetEncoder(payload_type, codecs[i]);
const AudioCodecInfo info_without_cng =
SetEncoder(payload_type, codecs.at(i));
InsertOnePacketOfSilence(info_without_cng);
// Sanity check if Actually an audio payload received, and it should be
@ -456,7 +362,7 @@ TEST_F(AcmReceiverTestOldApi, MAYBE_LastAudioCodec) {
// Set VAD on to send DTX. Then check if the "Last Audio codec" returns
// the expected codec. Encode repeatedly until a DTX is sent.
const AudioCodecInfo info_with_cng =
SetEncoder(payload_type, codecs[i], cng_payload_types);
SetEncoder(payload_type, codecs.at(i), cng_payload_types);
while (last_frame_type_ != kAudioFrameCN) {
packet_sent_ = false;
InsertOnePacketOfSilence(info_with_cng);
@ -464,7 +370,7 @@ TEST_F(AcmReceiverTestOldApi, MAYBE_LastAudioCodec) {
}
EXPECT_EQ(info_with_cng.sample_rate_hz,
receiver_->last_packet_sample_rate_hz());
EXPECT_EQ(codecs[i], receiver_->LastAudioFormat());
EXPECT_EQ(codecs.at(i), receiver_->LastDecoder()->second);
}
}
#endif

View File

@ -14,10 +14,10 @@
#include <stdio.h>
#include <string.h>
#include "absl/strings/match.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "modules/audio_coding/codecs/audio_format_conversion.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/neteq/tools/input_audio_file.h"
#include "modules/audio_coding/neteq/tools/packet.h"
@ -59,23 +59,28 @@ AcmSendTestOldApi::AcmSendTestOldApi(InputAudioFile* audio_source,
AcmSendTestOldApi::~AcmSendTestOldApi() = default;
bool AcmSendTestOldApi::RegisterCodec(const char* payload_name,
int sampling_freq_hz,
int channels,
int clockrate_hz,
int num_channels,
int payload_type,
int frame_size_samples) {
CodecInst codec;
RTC_CHECK_EQ(0, AudioCodingModule::Codec(payload_name, &codec,
sampling_freq_hz, channels));
codec.pltype = payload_type;
codec.pacsize = frame_size_samples;
auto factory = CreateBuiltinAudioEncoderFactory();
SdpAudioFormat format = CodecInstToSdp(codec);
SdpAudioFormat format(payload_name, clockrate_hz, num_channels);
if (absl::EqualsIgnoreCase(payload_name, "g722")) {
RTC_CHECK_EQ(16000, clockrate_hz);
format.clockrate_hz = 8000;
} else if (absl::EqualsIgnoreCase(payload_name, "opus")) {
RTC_CHECK(num_channels == 1 || num_channels == 2);
if (num_channels == 2) {
format.parameters["stereo"] = "1";
}
format.num_channels = 2;
}
format.parameters["ptime"] = rtc::ToString(rtc::CheckedDivExact(
frame_size_samples, rtc::CheckedDivExact(sampling_freq_hz, 1000)));
frame_size_samples, rtc::CheckedDivExact(clockrate_hz, 1000)));
auto factory = CreateBuiltinAudioEncoderFactory();
acm_->SetEncoder(
factory->MakeAudioEncoder(payload_type, format, absl::nullopt));
codec_registered_ = true;
input_frame_.num_channels_ = channels;
input_frame_.num_channels_ = num_channels;
assert(input_block_size_samples_ * input_frame_.num_channels_ <=
AudioFrame::kMaxDataSizeSamples);
return codec_registered_;

View File

@ -18,7 +18,6 @@
#include "api/array_view.h"
#include "modules/audio_coding/acm2/acm_receiver.h"
#include "modules/audio_coding/acm2/acm_resampler.h"
#include "modules/audio_coding/acm2/rent_a_codec.h"
#include "modules/include/module_common_types.h"
#include "modules/include/module_common_types_public.h"
#include "rtc_base/buffer.h"
@ -45,9 +44,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
void ModifyEncoder(rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)>
modifier) override;
// Get current send codec.
absl::optional<CodecInst> SendCodec() const override;
// Sets the bitrate to the specified value in bits/sec. In case the codec does
// not support the requested value it will choose an appropriate value
// instead.
@ -90,19 +86,8 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs) override;
bool RegisterReceiveCodec(int rtp_payload_type,
const SdpAudioFormat& audio_format) override;
int RegisterExternalReceiveCodec(int rtp_payload_type,
AudioDecoder* external_decoder,
int sample_rate_hz,
int num_channels,
const std::string& name) override;
// Get current received codec.
int ReceiveCodec(CodecInst* current_codec) const override;
absl::optional<SdpAudioFormat> ReceiveFormat() const override;
absl::optional<std::pair<int, SdpAudioFormat>> ReceiveCodec() const override;
// Incoming packet from network parsed and ready for decode.
int IncomingPacket(const uint8_t* incoming_payload,
@ -141,8 +126,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
int DisableOpusDtx() override;
int UnregisterReceiveCodec(uint8_t payload_type) override;
int EnableNack(size_t max_nack_list_size) override;
void DisableNack() override;
@ -317,42 +300,6 @@ void ConvertEncodedInfoToFragmentationHeader(
}
}
// Wraps a raw AudioEncoder pointer. The idea is that you can put one of these
// in a unique_ptr, to protect the contained raw pointer from being deleted
// when the unique_ptr expires. (This is of course a bad idea in general, but
// backwards compatibility.)
class RawAudioEncoderWrapper final : public AudioEncoder {
public:
RawAudioEncoderWrapper(AudioEncoder* enc) : enc_(enc) {}
int SampleRateHz() const override { return enc_->SampleRateHz(); }
size_t NumChannels() const override { return enc_->NumChannels(); }
int RtpTimestampRateHz() const override { return enc_->RtpTimestampRateHz(); }
size_t Num10MsFramesInNextPacket() const override {
return enc_->Num10MsFramesInNextPacket();
}
size_t Max10MsFramesInAPacket() const override {
return enc_->Max10MsFramesInAPacket();
}
int GetTargetBitrate() const override { return enc_->GetTargetBitrate(); }
EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
rtc::ArrayView<const int16_t> audio,
rtc::Buffer* encoded) override {
return enc_->Encode(rtp_timestamp, audio, encoded);
}
void Reset() override { return enc_->Reset(); }
bool SetFec(bool enable) override { return enc_->SetFec(enable); }
bool SetDtx(bool enable) override { return enc_->SetDtx(enable); }
bool SetApplication(Application application) override {
return enc_->SetApplication(application);
}
void SetMaxPlaybackRate(int frequency_hz) override {
return enc_->SetMaxPlaybackRate(frequency_hz);
}
private:
AudioEncoder* enc_;
};
void AudioCodingModuleImpl::ChangeLogger::MaybeLog(int value) {
if (value != last_value_ || first_time_) {
first_time_ = false;
@ -480,26 +427,6 @@ void AudioCodingModuleImpl::ModifyEncoder(
modifier(&encoder_stack_);
}
// Get current send codec.
absl::optional<CodecInst> AudioCodingModuleImpl::SendCodec() const {
rtc::CritScope lock(&acm_crit_sect_);
if (encoder_stack_) {
CodecInst ci;
ci.channels = encoder_stack_->NumChannels();
ci.plfreq = encoder_stack_->SampleRateHz();
ci.pacsize = rtc::CheckedDivExact(
static_cast<int>(encoder_stack_->Max10MsFramesInAPacket() * ci.plfreq),
100);
ci.pltype = -1; // Not valid.
ci.rate = -1; // Not valid.
static const char kName[] = "external";
memcpy(ci.plname, kName, sizeof(kName));
return ci;
} else {
return absl::nullopt;
}
}
void AudioCodingModuleImpl::SetBitRate(int bitrate_bps) {
rtc::CritScope lock(&acm_crit_sect_);
if (encoder_stack_) {
@ -748,54 +675,10 @@ void AudioCodingModuleImpl::SetReceiveCodecs(
receiver_.SetCodecs(codecs);
}
bool AudioCodingModuleImpl::RegisterReceiveCodec(
int rtp_payload_type,
const SdpAudioFormat& audio_format) {
absl::optional<std::pair<int, SdpAudioFormat>>
AudioCodingModuleImpl::ReceiveCodec() const {
rtc::CritScope lock(&acm_crit_sect_);
RTC_DCHECK(receiver_initialized_);
if (!acm2::RentACodec::IsPayloadTypeValid(rtp_payload_type)) {
RTC_LOG_F(LS_ERROR) << "Invalid payload-type " << rtp_payload_type
<< " for decoder.";
return false;
}
return receiver_.AddCodec(rtp_payload_type, audio_format);
}
int AudioCodingModuleImpl::RegisterExternalReceiveCodec(
int rtp_payload_type,
AudioDecoder* external_decoder,
int sample_rate_hz,
int num_channels,
const std::string& name) {
rtc::CritScope lock(&acm_crit_sect_);
RTC_DCHECK(receiver_initialized_);
if (num_channels > 2 || num_channels < 0) {
RTC_LOG_F(LS_ERROR) << "Unsupported number of channels: " << num_channels;
return -1;
}
// Check if the payload-type is valid.
if (!acm2::RentACodec::IsPayloadTypeValid(rtp_payload_type)) {
RTC_LOG_F(LS_ERROR) << "Invalid payload-type " << rtp_payload_type
<< " for external decoder.";
return -1;
}
return receiver_.AddCodec(-1 /* external */, rtp_payload_type, num_channels,
sample_rate_hz, external_decoder, name);
}
// Get current received codec.
int AudioCodingModuleImpl::ReceiveCodec(CodecInst* current_codec) const {
rtc::CritScope lock(&acm_crit_sect_);
return receiver_.LastAudioCodec(current_codec);
}
absl::optional<SdpAudioFormat> AudioCodingModuleImpl::ReceiveFormat() const {
rtc::CritScope lock(&acm_crit_sect_);
return receiver_.LastAudioFormat();
return receiver_.LastDecoder();
}
// Incoming packet from network parsed and ready for decode.
@ -902,10 +785,6 @@ bool AudioCodingModuleImpl::HaveValidEncoder(const char* caller_name) const {
return true;
}
int AudioCodingModuleImpl::UnregisterReceiveCodec(uint8_t payload_type) {
return receiver_.RemoveCodec(payload_type);
}
int AudioCodingModuleImpl::EnableNack(size_t max_nack_list_size) {
return receiver_.EnableNack(max_nack_list_size);
}
@ -951,52 +830,4 @@ AudioCodingModule* AudioCodingModule::Create(const Config& config) {
return new AudioCodingModuleImpl(config);
}
int AudioCodingModule::NumberOfCodecs() {
return static_cast<int>(acm2::RentACodec::NumberOfCodecs());
}
int AudioCodingModule::Codec(int list_id, CodecInst* codec) {
auto codec_id = acm2::RentACodec::CodecIdFromIndex(list_id);
if (!codec_id)
return -1;
auto ci = acm2::RentACodec::CodecInstById(*codec_id);
if (!ci)
return -1;
*codec = *ci;
return 0;
}
int AudioCodingModule::Codec(const char* payload_name,
CodecInst* codec,
int sampling_freq_hz,
size_t channels) {
absl::optional<CodecInst> ci = acm2::RentACodec::CodecInstByParams(
payload_name, sampling_freq_hz, channels);
if (ci) {
*codec = *ci;
return 0;
} else {
// We couldn't find a matching codec, so set the parameters to unacceptable
// values and return.
codec->plname[0] = '\0';
codec->pltype = -1;
codec->pacsize = 0;
codec->rate = 0;
codec->plfreq = 0;
return -1;
}
}
int AudioCodingModule::Codec(const char* payload_name,
int sampling_freq_hz,
size_t channels) {
absl::optional<acm2::RentACodec::CodecId> ci =
acm2::RentACodec::CodecIdByParams(payload_name, sampling_freq_hz,
channels);
if (!ci)
return -1;
absl::optional<int> i = acm2::RentACodec::CodecIndexFromId(*ci);
return i ? *i : -1;
}
} // namespace webrtc

View File

@ -19,7 +19,6 @@
#include "api/audio_codecs/opus/audio_encoder_opus.h"
#include "modules/audio_coding/acm2/acm_receive_test.h"
#include "modules/audio_coding/acm2/acm_send_test.h"
#include "modules/audio_coding/codecs/audio_format_conversion.h"
#include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
#include "modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
#include "modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
@ -190,12 +189,11 @@ class AudioCodingModuleTestOldApi : public ::testing::Test {
// Set up L16 codec.
virtual void SetUpL16Codec() {
audio_format_ = SdpAudioFormat("L16", kSampleRateHz, 1);
ASSERT_EQ(0, AudioCodingModule::Codec("L16", &codec_, kSampleRateHz, 1));
codec_.pltype = kPayloadType;
pac_size_ = 160;
}
virtual void RegisterCodec() {
EXPECT_EQ(true, acm_->RegisterReceiveCodec(kPayloadType, *audio_format_));
acm_->SetReceiveCodecs({{kPayloadType, *audio_format_}});
acm_->SetEncoder(CreateBuiltinAudioEncoderFactory()->MakeAudioEncoder(
kPayloadType, *audio_format_, absl::nullopt));
}
@ -226,7 +224,7 @@ class AudioCodingModuleTestOldApi : public ::testing::Test {
virtual void VerifyEncoding() {
int last_length = packet_cb_.last_payload_len_bytes();
EXPECT_TRUE(last_length == 2 * codec_.pacsize || last_length == 0)
EXPECT_TRUE(last_length == 2 * pac_size_ || last_length == 0)
<< "Last encoded packet was " << last_length << " bytes.";
}
@ -241,10 +239,8 @@ class AudioCodingModuleTestOldApi : public ::testing::Test {
WebRtcRTPHeader rtp_header_;
AudioFrame input_frame_;
// These two have to be kept in sync for now. In the future, we'll be able to
// eliminate the CodecInst and keep only the SdpAudioFormat.
absl::optional<SdpAudioFormat> audio_format_;
CodecInst codec_;
int pac_size_ = -1;
Clock* clock_;
};
@ -343,7 +339,7 @@ TEST_F(AudioCodingModuleTestOldApi, FailOnZeroDesiredFrequency) {
// Also checks that the frame type is kAudioFrameSpeech.
TEST_F(AudioCodingModuleTestOldApi, TransportCallbackIsInvokedForEachPacket) {
const int k10MsBlocksPerPacket = 3;
codec_.pacsize = k10MsBlocksPerPacket * kSampleRateHz / 100;
pac_size_ = k10MsBlocksPerPacket * kSampleRateHz / 100;
audio_format_->parameters["ptime"] = "30";
RegisterCodec();
const int kLoops = 10;
@ -363,7 +359,7 @@ TEST_F(AudioCodingModuleTestOldApi, TransportCallbackIsInvokedForEachPacket) {
TEST_F(AudioCodingModuleTestOldApi, TimestampSeriesContinuesWhenCodecChanges) {
RegisterCodec(); // This registers the default codec.
uint32_t expected_ts = input_frame_.timestamp_;
int blocks_per_packet = codec_.pacsize / (kSampleRateHz / 100);
int blocks_per_packet = pac_size_ / (kSampleRateHz / 100);
// Encode 5 packets of the first codec type.
const int kNumPackets1 = 5;
for (int j = 0; j < kNumPackets1; ++j) {
@ -373,14 +369,14 @@ TEST_F(AudioCodingModuleTestOldApi, TimestampSeriesContinuesWhenCodecChanges) {
}
EXPECT_EQ(j + 1, packet_cb_.num_calls());
EXPECT_EQ(expected_ts, packet_cb_.last_timestamp());
expected_ts += codec_.pacsize;
expected_ts += pac_size_;
}
// Change codec.
ASSERT_EQ(0, AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1));
audio_format_ = SdpAudioFormat("ISAC", kSampleRateHz, 1);
pac_size_ = 480;
RegisterCodec();
blocks_per_packet = codec_.pacsize / (kSampleRateHz / 100);
blocks_per_packet = pac_size_ / (kSampleRateHz / 100);
// Encode another 5 packets.
const int kNumPackets2 = 5;
for (int j = 0; j < kNumPackets2; ++j) {
@ -390,7 +386,7 @@ TEST_F(AudioCodingModuleTestOldApi, TimestampSeriesContinuesWhenCodecChanges) {
}
EXPECT_EQ(kNumPackets1 + j + 1, packet_cb_.num_calls());
EXPECT_EQ(expected_ts, packet_cb_.last_timestamp());
expected_ts += codec_.pacsize;
expected_ts += pac_size_;
}
}
#endif
@ -404,9 +400,8 @@ class AudioCodingModuleTestWithComfortNoiseOldApi
: public AudioCodingModuleTestOldApi {
protected:
void RegisterCngCodec(int rtp_payload_type) {
EXPECT_EQ(true,
acm_->RegisterReceiveCodec(
rtp_payload_type, SdpAudioFormat("cn", kSampleRateHz, 1)));
acm_->SetReceiveCodecs({{kPayloadType, *audio_format_},
{rtp_payload_type, {"cn", kSampleRateHz, 1}}});
acm_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* enc) {
AudioEncoderCngConfig config;
config.speech_encoder = std::move(*enc);
@ -461,7 +456,7 @@ class AudioCodingModuleTestWithComfortNoiseOldApi
TEST_F(AudioCodingModuleTestWithComfortNoiseOldApi,
TransportCallbackTestForComfortNoiseRegisterCngLast) {
const int k10MsBlocksPerPacket = 3;
codec_.pacsize = k10MsBlocksPerPacket * kSampleRateHz / 100;
pac_size_ = k10MsBlocksPerPacket * kSampleRateHz / 100;
audio_format_->parameters["ptime"] = "30";
RegisterCodec();
const int kCngPayloadType = 105;
@ -650,12 +645,11 @@ class AcmIsacMtTestOldApi : public AudioCodingModuleMtTestOldApi {
void RegisterCodec() override {
static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz");
audio_format_ = SdpAudioFormat("isac", kSampleRateHz, 1);
AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1);
codec_.pltype = kPayloadType;
pac_size_ = 480;
// Register iSAC codec in ACM, effectively unregistering the PCM16B codec
// registered in AudioCodingModuleTestOldApi::SetUp();
EXPECT_EQ(true, acm_->RegisterReceiveCodec(kPayloadType, *audio_format_));
acm_->SetReceiveCodecs({{kPayloadType, *audio_format_}});
acm_->SetEncoder(CreateBuiltinAudioEncoderFactory()->MakeAudioEncoder(
kPayloadType, *audio_format_, absl::nullopt));
}
@ -755,15 +749,11 @@ class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi {
}
void RegisterCodec() override {
static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz");
AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1);
codec_.pltype = kPayloadType;
// Register iSAC codec in ACM, effectively unregistering the PCM16B codec
// registered in AudioCodingModuleTestOldApi::SetUp();
// Only register the decoder for now. The encoder is registered later.
ASSERT_EQ(true, acm_->RegisterReceiveCodec(codec_.pltype,
CodecInstToSdp(codec_)));
static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz");
acm_->SetReceiveCodecs({{kPayloadType, {"ISAC", kSampleRateHz, 1}}});
}
void StartThreads() {
@ -1085,7 +1075,17 @@ TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutputExternalDecoder) {
"bd44bf97e7899186532f91235cef444d",
"9d092dbc96e7ef6870b78c1056e87315"),
factory, [](AudioCodingModule* acm) {
acm->RegisterReceiveCodec(0, {"MockPCMu", 8000, 1});
acm->SetReceiveCodecs({{0, {"MockPCMu", 8000, 1}},
{103, {"ISAC", 16000, 1}},
{104, {"ISAC", 32000, 1}},
{93, {"L16", 8000, 1}},
{94, {"L16", 16000, 1}},
{95, {"L16", 32000, 1}},
{8, {"PCMA", 8000, 1}},
{102, {"ILBC", 8000, 1}},
{13, {"CN", 8000, 1}},
{98, {"CN", 16000, 1}},
{99, {"CN", 32000, 1}}});
});
}
#endif
@ -1746,11 +1746,11 @@ TEST_F(AcmChangeBitRateOldApi, Pcm16_8khz_10ms_32kbps) {
}
TEST_F(AcmSenderBitExactnessOldApi, External_Pcmu_20ms) {
CodecInst codec_inst;
codec_inst.channels = 1;
codec_inst.pacsize = 160;
codec_inst.pltype = 0;
AudioEncoderPcmU encoder(codec_inst);
AudioEncoderPcmU::Config config;
config.frame_size_ms = 20;
config.num_channels = 1;
config.payload_type = 0;
AudioEncoderPcmU encoder(config);
auto mock_encoder = absl::make_unique<MockAudioEncoder>();
// Set expectations on the mock encoder and also delegate the calls to the
// real encoder.
@ -1777,7 +1777,7 @@ TEST_F(AcmSenderBitExactnessOldApi, External_Pcmu_20ms) {
uint32_t, rtc::ArrayView<const int16_t>, rtc::Buffer*)>(
&AudioEncoderPcmU::Encode)));
ASSERT_NO_FATAL_FAILURE(
SetUpTestExternalEncoder(std::move(mock_encoder), codec_inst.pltype));
SetUpTestExternalEncoder(std::move(mock_encoder), config.payload_type));
Run("81a9d4c0bb72e9becc43aef124c981e9", "8f9b8750bd80fe26b6cbf6659b89f0f9",
50, test::AcmReceiveTestOldApi::kMonoOutput);
}

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_coding/acm2/rent_a_codec.h"
#include <memory>
#include <utility>
#include "rtc_base/logging.h"
#include "modules/audio_coding/acm2/acm_codec_database.h"
namespace webrtc {
namespace acm2 {
absl::optional<RentACodec::CodecId> RentACodec::CodecIdByParams(
const char* payload_name,
int sampling_freq_hz,
size_t channels) {
return CodecIdFromIndex(
ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels));
}
absl::optional<CodecInst> RentACodec::CodecInstById(CodecId codec_id) {
absl::optional<int> mi = CodecIndexFromId(codec_id);
return mi ? absl::optional<CodecInst>(ACMCodecDB::database_[*mi])
: absl::nullopt;
}
absl::optional<RentACodec::CodecId> RentACodec::CodecIdByInst(
const CodecInst& codec_inst) {
return CodecIdFromIndex(ACMCodecDB::CodecNumber(codec_inst));
}
absl::optional<CodecInst> RentACodec::CodecInstByParams(
const char* payload_name,
int sampling_freq_hz,
size_t channels) {
absl::optional<CodecId> codec_id =
CodecIdByParams(payload_name, sampling_freq_hz, channels);
if (!codec_id)
return absl::nullopt;
absl::optional<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;
}
absl::optional<NetEqDecoder> RentACodec::NetEqDecoderFromCodecId(
CodecId codec_id,
size_t num_channels) {
absl::optional<int> i = CodecIndexFromId(codec_id);
if (!i)
return absl::nullopt;
const NetEqDecoder ned = ACMCodecDB::neteq_decoders_[*i];
return (ned == NetEqDecoder::kDecoderOpus && num_channels == 2)
? NetEqDecoder::kDecoderOpus_2ch
: ned;
}
} // namespace acm2
} // namespace webrtc

View File

@ -1,143 +0,0 @@
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_
#define MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_
#include <stddef.h>
#include <map>
#include <memory>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_encoder.h"
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
#include "modules/audio_coding/neteq/neteq_decoder_enum.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/scoped_ref_ptr.h"
namespace webrtc {
struct CodecInst;
class LockedIsacBandwidthInfo;
namespace acm2 {
struct RentACodec {
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
kG722, // Mono
kG722_2ch, // Stereo
#ifdef WEBRTC_CODEC_OPUS
kOpus, // Mono and stereo
#endif
kCNNB,
kCNWB,
kCNSWB,
#ifdef ENABLE_48000_HZ
kCNFB,
#endif
kAVT,
kAVT16kHz,
kAVT32kHz,
kAVT48kHz,
#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_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 absl::optional<int> CodecIndexFromId(CodecId codec_id) {
const int i = static_cast<int>(codec_id);
return i >= 0 && i < static_cast<int>(NumberOfCodecs())
? absl::optional<int>(i)
: absl::nullopt;
}
static inline absl::optional<CodecId> CodecIdFromIndex(int codec_index) {
return static_cast<size_t>(codec_index) < NumberOfCodecs()
? absl::optional<RentACodec::CodecId>(
static_cast<RentACodec::CodecId>(codec_index))
: absl::nullopt;
}
static absl::optional<CodecId> CodecIdByParams(const char* payload_name,
int sampling_freq_hz,
size_t channels);
static absl::optional<CodecInst> CodecInstById(CodecId codec_id);
static absl::optional<CodecId> CodecIdByInst(const CodecInst& codec_inst);
static absl::optional<CodecInst> CodecInstByParams(const char* payload_name,
int sampling_freq_hz,
size_t channels);
static inline bool IsPayloadTypeValid(int payload_type) {
return payload_type >= 0 && payload_type <= 127;
}
static absl::optional<NetEqDecoder> NetEqDecoderFromCodecId(
CodecId codec_id,
size_t num_channels);
};
} // namespace acm2
} // namespace webrtc
#endif // MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_

View File

@ -10,7 +10,7 @@
#include "modules/audio_coding/codecs/legacy_encoded_audio_frame.h"
#include "modules/audio_coding/acm2/rent_a_codec.h"
#include "modules/audio_coding/neteq/neteq_decoder_enum.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "test/gtest.h"

View File

@ -13,12 +13,12 @@
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_decoder_factory.h"
#include "api/audio_codecs/audio_encoder.h"
#include "common_types.h" // NOLINT(build/include)
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
#include "modules/audio_coding/neteq/include/neteq.h"
#include "rtc_base/function_view.h"
@ -27,7 +27,6 @@
namespace webrtc {
// forward declarations
struct CodecInst;
struct WebRtcRTPHeader;
class AudioDecoder;
class AudioEncoder;
@ -76,80 +75,6 @@ class AudioCodingModule {
static AudioCodingModule* Create(const Config& config);
virtual ~AudioCodingModule() = default;
///////////////////////////////////////////////////////////////////////////
// Utility functions
//
///////////////////////////////////////////////////////////////////////////
// uint8_t NumberOfCodecs()
// Returns number of supported codecs.
//
// Return value:
// number of supported codecs.
///
static int NumberOfCodecs();
///////////////////////////////////////////////////////////////////////////
// int32_t Codec()
// Get supported codec with list number.
//
// Input:
// -list_id : list number.
//
// Output:
// -codec : a structure where the parameters of the codec,
// given by list number is written to.
//
// Return value:
// -1 if the list number (list_id) is invalid.
// 0 if succeeded.
//
static int Codec(int list_id, CodecInst* codec);
///////////////////////////////////////////////////////////////////////////
// int32_t Codec()
// Get supported codec with the given codec name, sampling frequency, and
// a given number of channels.
//
// Input:
// -payload_name : name of the codec.
// -sampling_freq_hz : sampling frequency of the codec. Note! for RED
// a sampling frequency of -1 is a valid input.
// -channels : number of channels ( 1 - mono, 2 - stereo).
//
// Output:
// -codec : a structure where the function returns the
// default parameters of the codec.
//
// Return value:
// -1 if no codec matches the given parameters.
// 0 if succeeded.
//
static int Codec(const char* payload_name,
CodecInst* codec,
int sampling_freq_hz,
size_t channels);
///////////////////////////////////////////////////////////////////////////
// int32_t Codec()
//
// Returns the list number of the given codec name, sampling frequency, and
// a given number of channels.
//
// Input:
// -payload_name : name of the codec.
// -sampling_freq_hz : sampling frequency of the codec. Note! for RED
// a sampling frequency of -1 is a valid input.
// -channels : number of channels ( 1 - mono, 2 - stereo).
//
// Return value:
// if the codec is found, the index of the codec in the list,
// -1 if the codec is not found.
//
static int Codec(const char* payload_name,
int sampling_freq_hz,
size_t channels);
///////////////////////////////////////////////////////////////////////////
// Sender
//
@ -169,15 +94,6 @@ class AudioCodingModule {
});
}
///////////////////////////////////////////////////////////////////////////
// int32_t SendCodec()
// Get parameters for the codec currently registered as send codec.
//
// Return value:
// The send codec, or nothing if we don't have one
//
virtual absl::optional<CodecInst> SendCodec() const = 0;
///////////////////////////////////////////////////////////////////////////
// Sets the bitrate to the specified value in bits/sec. If the value is not
// supported by the codec, it will choose another appropriate value.
@ -302,60 +218,17 @@ class AudioCodingModule {
virtual void SetReceiveCodecs(
const std::map<int, SdpAudioFormat>& codecs) = 0;
// Registers a decoder for the given payload type. Returns true iff
// successful.
virtual bool RegisterReceiveCodec(int rtp_payload_type,
const SdpAudioFormat& audio_format) = 0;
// Registers an external decoder. The name is only used to provide information
// back to the caller about the decoder. Hence, the name is arbitrary, and may
// be empty.
virtual int RegisterExternalReceiveCodec(int rtp_payload_type,
AudioDecoder* external_decoder,
int sample_rate_hz,
int num_channels,
const std::string& name) = 0;
///////////////////////////////////////////////////////////////////////////
// int32_t UnregisterReceiveCodec()
// Unregister the codec currently registered with a specific payload type
// from the list of possible receive codecs.
//
// Input:
// -payload_type : The number representing the payload type to
// unregister.
//
// Output:
// -1 if fails to unregister.
// 0 if the given codec is successfully unregistered.
//
virtual int UnregisterReceiveCodec(uint8_t payload_type) = 0;
///////////////////////////////////////////////////////////////////////////
// int32_t ReceiveCodec()
// Get the codec associated with last received payload.
//
// Output:
// -curr_receive_codec : parameters of the codec associated with the last
// received payload, c.f. common_types.h for
// the definition of CodecInst.
// absl::optional<std::pair<int, SdpAudioFormat>> ReceiveCodec()
// Get the codec info associated with last received payload.
//
// Return value:
// -1 if failed to retrieve the codec,
// 0 if the codec is successfully retrieved.
//
virtual int32_t ReceiveCodec(CodecInst* curr_receive_codec) const = 0;
///////////////////////////////////////////////////////////////////////////
// absl::optional<SdpAudioFormat> ReceiveFormat()
// Get the format associated with last received payload.
//
// Return value:
// An SdpAudioFormat describing the format associated with the last
// received payload.
// A payload type and SdpAudioFormat describing the format associated with
// the last received payload.
// An empty Optional if no payload has yet been received.
//
virtual absl::optional<SdpAudioFormat> ReceiveFormat() const = 0;
virtual absl::optional<std::pair<int, SdpAudioFormat>>
ReceiveCodec() const = 0;
///////////////////////////////////////////////////////////////////////////
// int32_t IncomingPacket()

View File

@ -20,7 +20,6 @@
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/rtp_headers.h"
#include "common_types.h" // NOLINT(build/include)
#include "modules/audio_coding/neteq/defines.h"
#include "modules/audio_coding/neteq/neteq_decoder_enum.h"
#include "rtc_base/constructormagic.h"
@ -251,11 +250,7 @@ class NetEq {
// (Config::sample_rate_hz) is returned.
virtual int last_output_sample_rate_hz() const = 0;
// Returns info about the decoder for the given payload type, or an empty
// value if we have no decoder for that payload type.
virtual absl::optional<CodecInst> GetDecoder(int payload_type) const = 0;
// Returns the decoder format for the given payload type. Returns empty if no
// Returns the decoder info for the given payload type. Returns empty if no
// such payload type was registered.
virtual absl::optional<SdpAudioFormat> GetDecoderFormat(
int payload_type) const = 0;

View File

@ -416,27 +416,6 @@ int NetEqImpl::last_output_sample_rate_hz() const {
return last_output_sample_rate_hz_;
}
absl::optional<CodecInst> NetEqImpl::GetDecoder(int payload_type) const {
rtc::CritScope lock(&crit_sect_);
const DecoderDatabase::DecoderInfo* di =
decoder_database_->GetDecoderInfo(payload_type);
if (!di) {
return absl::nullopt;
}
// Create a CodecInst with some fields set. The remaining fields are zeroed,
// but we tell MSan to consider them uninitialized.
CodecInst ci = {0};
rtc::MsanMarkUninitialized(rtc::MakeArrayView(&ci, 1));
ci.pltype = payload_type;
std::strncpy(ci.plname, di->get_name().c_str(), sizeof(ci.plname));
ci.plname[sizeof(ci.plname) - 1] = '\0';
ci.plfreq = di->IsRed() ? 8000 : di->SampleRateHz();
AudioDecoder* const decoder = di->GetDecoder();
ci.channels = decoder ? decoder->Channels() : 1;
return ci;
}
absl::optional<SdpAudioFormat> NetEqImpl::GetDecoderFormat(
int payload_type) const {
rtc::CritScope lock(&crit_sect_);
@ -445,7 +424,13 @@ absl::optional<SdpAudioFormat> NetEqImpl::GetDecoderFormat(
if (!di) {
return absl::nullopt; // Payload type not registered.
}
return di->GetFormat();
SdpAudioFormat format = di->GetFormat();
// TODO(solenberg): This is legacy but messed up - mixing RTP rate and SR.
format.clockrate_hz = di->IsRed() ? 8000 : di->SampleRateHz();
const AudioDecoder* const decoder = di->GetDecoder();
format.num_channels = decoder ? decoder->Channels() : 1;
return format;
}
void NetEqImpl::FlushBuffers() {

View File

@ -184,8 +184,6 @@ class NetEqImpl : public webrtc::NetEq {
int last_output_sample_rate_hz() const override;
absl::optional<CodecInst> GetDecoder(int payload_type) const override;
absl::optional<SdpAudioFormat> GetDecoderFormat(
int payload_type) const override;

View File

@ -188,8 +188,8 @@ void ISACTest::Setup() {
Run10ms();
}
EXPECT_TRUE(_acmA->ReceiveFormat());
EXPECT_TRUE(_acmB->ReceiveFormat());
EXPECT_TRUE(_acmA->ReceiveCodec());
EXPECT_TRUE(_acmB->ReceiveCodec());
_inFileA.Close();
_outFileA.Close();

View File

@ -136,9 +136,6 @@ class RtpRtcp : public Module, public RtcpFeedbackSenderInterface {
// FEC/ULP/RED overhead (when FEC is enabled).
virtual size_t MaxRtpPacketSize() const = 0;
// Sets codec name and payload type. Returns -1 on failure else 0.
virtual int32_t RegisterSendPayload(const CodecInst& voice_codec) = 0;
virtual void RegisterAudioSendPayload(int payload_type,
absl::string_view payload_name,
int frequency,

View File

@ -37,7 +37,6 @@ class MockRtpRtcp : public RtpRtcp {
MOCK_METHOD1(SetRemoteSSRC, void(uint32_t ssrc));
MOCK_METHOD1(SetMaxRtpPacketSize, void(size_t size));
MOCK_CONST_METHOD0(MaxRtpPacketSize, size_t());
MOCK_METHOD1(RegisterSendPayload, int32_t(const CodecInst& voice_codec));
MOCK_METHOD5(RegisterAudioSendPayload,
void(int payload_type,
absl::string_view payload_name,

View File

@ -264,13 +264,6 @@ void ModuleRtpRtcpImpl::IncomingRtcpPacket(const uint8_t* rtcp_packet,
rtcp_receiver_.IncomingPacket(rtcp_packet, length);
}
int32_t ModuleRtpRtcpImpl::RegisterSendPayload(const CodecInst& voice_codec) {
rtcp_sender_.SetRtpClockRate(voice_codec.pltype, voice_codec.plfreq);
return rtp_sender_->RegisterPayload(
voice_codec.plname, voice_codec.pltype, voice_codec.plfreq,
voice_codec.channels, (voice_codec.rate < 0) ? 0 : voice_codec.rate);
}
void ModuleRtpRtcpImpl::RegisterAudioSendPayload(int payload_type,
absl::string_view payload_name,
int frequency,

View File

@ -63,7 +63,6 @@ class ModuleRtpRtcpImpl : public RtpRtcp, public RTCPReceiver::ModuleRtpRtcp {
// Sender part.
int32_t RegisterSendPayload(const CodecInst& voice_codec) override;
void RegisterAudioSendPayload(int payload_type,
absl::string_view payload_name,
int frequency,