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:
parent
a134204aa3
commit
f693bfae5f
@ -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",
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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>());
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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() {
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
namespace webrtc {
|
||||
class AudioCodingModule;
|
||||
class AudioDecoder;
|
||||
struct CodecInst;
|
||||
|
||||
namespace test {
|
||||
class AudioSink;
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user