diff --git a/audio/BUILD.gn b/audio/BUILD.gn index c045af6376..3d53c278b9 100644 --- a/audio/BUILD.gn +++ b/audio/BUILD.gn @@ -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", diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc index 8d4afe08e3..143c6f77f1 100644 --- a/audio/audio_receive_stream.cc +++ b/audio/audio_receive_stream.cc @@ -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(); diff --git a/audio/audio_receive_stream_unittest.cc b/audio/audio_receive_stream_unittest.cc index 7422810856..25ca5282f2 100644 --- a/audio/audio_receive_stream_unittest.cc +++ b/audio/audio_receive_stream_unittest.cc @@ -10,6 +10,7 @@ #include #include +#include #include #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 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); diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc index 75e6efb9e8..8d2362200a 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc @@ -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 diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc index e400ada0e5..82cc319921 100644 --- a/audio/audio_send_stream_unittest.cc +++ b/audio/audio_send_stream_unittest.cc @@ -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(kReportBlock.extended_highest_sequence_number), stats.ext_seqnum); EXPECT_EQ(static_cast(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); diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc index f2d7c9d662..7ae2e267b8 100644 --- a/audio/channel_receive.cc +++ b/audio/channel_receive.cc @@ -120,7 +120,8 @@ class ChannelReceive : public ChannelReceiveInterface, void StopPlayout() override; // Codecs - bool GetRecCodec(CodecInst* codec) const override; + absl::optional> + 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> + ChannelReceive::GetReceiveCodec() const { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return (audio_coding_->ReceiveCodec(codec) == 0); + return audio_coding_->ReceiveCodec(); } std::vector 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(); } diff --git a/audio/channel_receive.h b/audio/channel_receive.h index 90276234a1..6bbf990f1c 100644 --- a/audio/channel_receive.h +++ b/audio/channel_receive.h @@ -13,6 +13,7 @@ #include #include +#include #include #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> + GetReceiveCodec() const = 0; virtual bool ReceivedRTCPPacket(const uint8_t* data, size_t length) = 0; diff --git a/audio/channel_send.cc b/audio/channel_send.cc index c458fe465b..7c7db79a5e 100644 --- a/audio/channel_send.cc +++ b/audio/channel_send.cc @@ -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(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; } diff --git a/audio/mock_voe_channel_proxy.h b/audio/mock_voe_channel_proxy.h index eee25c5a2d..33b00f9fc2 100644 --- a/audio/mock_voe_channel_proxy.h +++ b/audio/mock_voe_channel_proxy.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #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()); MOCK_METHOD1(SetMinimumPlayoutDelay, void(int delay_ms)); - MOCK_CONST_METHOD1(GetRecCodec, bool(CodecInst* codec_inst)); + MOCK_CONST_METHOD0(GetReceiveCodec, + absl::optional>()); MOCK_METHOD1(SetReceiveCodecs, void(const std::map& codecs)); MOCK_CONST_METHOD0(GetSources, std::vector()); diff --git a/media/BUILD.gn b/media/BUILD.gn index ab61ca15a2..201e0fb0e5 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -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", diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn index 6657495303..e2a13f3cfb 100644 --- a/modules/audio_coding/BUILD.gn +++ b/modules/audio_coding/BUILD.gn @@ -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", diff --git a/modules/audio_coding/acm2/acm_codec_database.cc b/modules/audio_coding/acm2/acm_codec_database.cc deleted file mode 100644 index cada80c061..0000000000 --- a/modules/audio_coding/acm2/acm_codec_database.cc +++ /dev/null @@ -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 diff --git a/modules/audio_coding/acm2/acm_codec_database.h b/modules/audio_coding/acm2/acm_codec_database.h deleted file mode 100644 index ee6bb46faa..0000000000 --- a/modules/audio_coding/acm2/acm_codec_database.h +++ /dev/null @@ -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_ diff --git a/modules/audio_coding/acm2/acm_receive_test.cc b/modules/audio_coding/acm2/acm_receive_test.cc index c149ec1b0b..76b0506abc 100644 --- a/modules/audio_coding/acm2/acm_receive_test.cc +++ b/modules/audio_coding/acm2/acm_receive_test.cc @@ -14,9 +14,7 @@ #include -#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 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() { diff --git a/modules/audio_coding/acm2/acm_receive_test.h b/modules/audio_coding/acm2/acm_receive_test.h index 83ffcb3a90..04aefc780e 100644 --- a/modules/audio_coding/acm2/acm_receive_test.h +++ b/modules/audio_coding/acm2/acm_receive_test.h @@ -23,7 +23,6 @@ namespace webrtc { class AudioCodingModule; class AudioDecoder; -struct CodecInst; namespace test { class AudioSink; diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc index d3af7c0341..ea84036fb5 100644 --- a/modules/audio_coding/acm2/acm_receiver.cc +++ b/modules/audio_coding/acm2/acm_receiver.cc @@ -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 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 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 ci = - RtpHeaderToDecoder(*header, incoming_payload[0]); - if (!ci) { - RTC_LOG_F(LS_ERROR) << "Payload-type " - << static_cast(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(header->payloadType) + << static_cast(header.payloadType) << " Failed to insert packet"; return -1; } @@ -186,85 +187,6 @@ void AcmReceiver::SetCodecs(const std::map& 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 cid = - RentACodec::CodecIdFromIndex(acm_codec_id); - RTC_DCHECK(cid) << "Invalid codec index: " << acm_codec_id; - const absl::optional ned = - RentACodec::NetEqDecoderFromCodecId(*cid, channels); - RTC_DCHECK(ned) << "Invalid codec ID: " << static_cast(*cid); - return *ned; - }(); - const absl::optional 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(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(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(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 AcmReceiver::GetPlayoutTimestamp() { @@ -304,18 +209,14 @@ int AcmReceiver::TargetDelayMs() const { return neteq_->TargetDelayMs(); } -int AcmReceiver::LastAudioCodec(CodecInst* codec) const { +absl::optional> + 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 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 ci = neteq_->GetDecoder(payload_type); - if (ci) { - *codec = *ci; - return 0; - } else { - RTC_LOG(LERROR) << "AcmReceiver::DecoderByPayloadType " - << static_cast(payload_type); - return -1; - } -} - -absl::optional 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 AcmReceiver::RtpHeaderToDecoder( - const RTPHeader& rtp_header, - uint8_t first_payload_byte) const { - const absl::optional 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. diff --git a/modules/audio_coding/acm2/acm_receiver.h b/modules/audio_coding/acm2/acm_receiver.h index 8e7d83978c..0cbaa9adf1 100644 --- a/modules/audio_coding/acm2/acm_receiver.h +++ b/modules/audio_coding/acm2/acm_receiver.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #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& 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 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 DecoderByPayloadType(int payload_type) const; + absl::optional> 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 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 last_audio_decoder_ RTC_GUARDED_BY(crit_sect_); - absl::optional last_audio_format_ RTC_GUARDED_BY(crit_sect_); + absl::optional> last_decoder_ + RTC_GUARDED_BY(crit_sect_); ACMResampler resampler_ RTC_GUARDED_BY(crit_sect_); std::unique_ptr last_audio_buffer_ RTC_GUARDED_BY(crit_sect_); CallStatistics call_stats_ RTC_GUARDED_BY(crit_sect_); const std::unique_ptr neteq_; // NetEq is thread-safe; no lock needed. const Clock* const clock_; bool resampled_last_output_frame_ RTC_GUARDED_BY(crit_sect_); - absl::optional last_packet_sample_rate_hz_ RTC_GUARDED_BY(crit_sect_); }; } // namespace acm2 diff --git a/modules/audio_coding/acm2/acm_receiver_unittest.cc b/modules/audio_coding/acm2/acm_receiver_unittest.cc index 46384febb5..8b3d2e4dca 100644 --- a/modules/audio_coding/acm2/acm_receiver_unittest.cc +++ b/modules/audio_coding/acm2/acm_receiver_unittest.cc @@ -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 - void AddSetOfCodecs(rtc::ArrayView 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 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(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(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 codecs = {{"ISAC", 16000, 1}, - {"ISAC", 32000, 1}}; - for (size_t i = 0; i < codecs.size(); ++i) { - const int payload_type = rtc::checked_cast(i); - EXPECT_EQ(true, receiver_->AddCodec(payload_type, codecs[i])); - } + const std::map 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(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 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(i); - EXPECT_TRUE(receiver_->AddCodec(payload_type, codecs[i])); - } - - const std::map 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 codecs = {{0, {"ISAC", 16000, 1}}, + {1, {"PCMA", 8000, 1}}, + {2, {"ISAC", 32000, 1}}, + {3, {"L16", 32000, 1}}}; + const std::map cng_payload_types = {{8000, 100}, + {16000, 101}, + {32000, 102}}; + { + std::map 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(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 diff --git a/modules/audio_coding/acm2/acm_send_test.cc b/modules/audio_coding/acm2/acm_send_test.cc index c5e010c79b..cf9c8eb761 100644 --- a/modules/audio_coding/acm2/acm_send_test.cc +++ b/modules/audio_coding/acm2/acm_send_test.cc @@ -14,10 +14,10 @@ #include #include +#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_; diff --git a/modules/audio_coding/acm2/audio_coding_module.cc b/modules/audio_coding/acm2/audio_coding_module.cc index c0aab3a30f..60da67929c 100644 --- a/modules/audio_coding/acm2/audio_coding_module.cc +++ b/modules/audio_coding/acm2/audio_coding_module.cc @@ -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*)> modifier) override; - // Get current send codec. - absl::optional 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& 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 ReceiveFormat() const override; + absl::optional> 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 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 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(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> + 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 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(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 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 ci = - acm2::RentACodec::CodecIdByParams(payload_name, sampling_freq_hz, - channels); - if (!ci) - return -1; - absl::optional i = acm2::RentACodec::CodecIndexFromId(*ci); - return i ? *i : -1; -} - } // namespace webrtc diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc index 4e262f7b03..446ac643f4 100644 --- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc +++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc @@ -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 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* 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(); // 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, 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); } diff --git a/modules/audio_coding/acm2/rent_a_codec.cc b/modules/audio_coding/acm2/rent_a_codec.cc deleted file mode 100644 index bfddc42bc9..0000000000 --- a/modules/audio_coding/acm2/rent_a_codec.cc +++ /dev/null @@ -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 -#include - -#include "rtc_base/logging.h" -#include "modules/audio_coding/acm2/acm_codec_database.h" - -namespace webrtc { -namespace acm2 { - -absl::optional 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 RentACodec::CodecInstById(CodecId codec_id) { - absl::optional mi = CodecIndexFromId(codec_id); - return mi ? absl::optional(ACMCodecDB::database_[*mi]) - : absl::nullopt; -} - -absl::optional RentACodec::CodecIdByInst( - const CodecInst& codec_inst) { - return CodecIdFromIndex(ACMCodecDB::CodecNumber(codec_inst)); -} - -absl::optional RentACodec::CodecInstByParams( - const char* payload_name, - int sampling_freq_hz, - size_t channels) { - absl::optional codec_id = - CodecIdByParams(payload_name, sampling_freq_hz, channels); - if (!codec_id) - return absl::nullopt; - absl::optional 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 RentACodec::NetEqDecoderFromCodecId( - CodecId codec_id, - size_t num_channels) { - absl::optional 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 diff --git a/modules/audio_coding/acm2/rent_a_codec.h b/modules/audio_coding/acm2/rent_a_codec.h deleted file mode 100644 index 2cf1c6e18c..0000000000 --- a/modules/audio_coding/acm2/rent_a_codec.h +++ /dev/null @@ -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 -#include -#include - -#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(CodecId::kNumCodecs); - } - - static inline absl::optional CodecIndexFromId(CodecId codec_id) { - const int i = static_cast(codec_id); - return i >= 0 && i < static_cast(NumberOfCodecs()) - ? absl::optional(i) - : absl::nullopt; - } - - static inline absl::optional CodecIdFromIndex(int codec_index) { - return static_cast(codec_index) < NumberOfCodecs() - ? absl::optional( - static_cast(codec_index)) - : absl::nullopt; - } - - static absl::optional CodecIdByParams(const char* payload_name, - int sampling_freq_hz, - size_t channels); - static absl::optional CodecInstById(CodecId codec_id); - static absl::optional CodecIdByInst(const CodecInst& codec_inst); - static absl::optional 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 NetEqDecoderFromCodecId( - CodecId codec_id, - size_t num_channels); -}; - -} // namespace acm2 -} // namespace webrtc - -#endif // MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_ diff --git a/modules/audio_coding/codecs/legacy_encoded_audio_frame_unittest.cc b/modules/audio_coding/codecs/legacy_encoded_audio_frame_unittest.cc index 9079bcd1dd..14993f8920 100644 --- a/modules/audio_coding/codecs/legacy_encoded_audio_frame_unittest.cc +++ b/modules/audio_coding/codecs/legacy_encoded_audio_frame_unittest.cc @@ -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" diff --git a/modules/audio_coding/include/audio_coding_module.h b/modules/audio_coding/include/audio_coding_module.h index f9fdba5f51..89c3b01b78 100644 --- a/modules/audio_coding/include/audio_coding_module.h +++ b/modules/audio_coding/include/audio_coding_module.h @@ -13,12 +13,12 @@ #include #include +#include #include #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 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& 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> 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 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 ReceiveFormat() const = 0; + virtual absl::optional> + ReceiveCodec() const = 0; /////////////////////////////////////////////////////////////////////////// // int32_t IncomingPacket() diff --git a/modules/audio_coding/neteq/include/neteq.h b/modules/audio_coding/neteq/include/neteq.h index 242ff64705..cde10bc137 100644 --- a/modules/audio_coding/neteq/include/neteq.h +++ b/modules/audio_coding/neteq/include/neteq.h @@ -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 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 GetDecoderFormat( int payload_type) const = 0; diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc index 436e60a7b3..d27d5d2664 100644 --- a/modules/audio_coding/neteq/neteq_impl.cc +++ b/modules/audio_coding/neteq/neteq_impl.cc @@ -416,27 +416,6 @@ int NetEqImpl::last_output_sample_rate_hz() const { return last_output_sample_rate_hz_; } -absl::optional 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 NetEqImpl::GetDecoderFormat( int payload_type) const { rtc::CritScope lock(&crit_sect_); @@ -445,7 +424,13 @@ absl::optional 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() { diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h index d035b9e55d..87b5aa90ea 100644 --- a/modules/audio_coding/neteq/neteq_impl.h +++ b/modules/audio_coding/neteq/neteq_impl.h @@ -184,8 +184,6 @@ class NetEqImpl : public webrtc::NetEq { int last_output_sample_rate_hz() const override; - absl::optional GetDecoder(int payload_type) const override; - absl::optional GetDecoderFormat( int payload_type) const override; diff --git a/modules/audio_coding/test/iSACTest.cc b/modules/audio_coding/test/iSACTest.cc index 339d419955..0dceca7f03 100644 --- a/modules/audio_coding/test/iSACTest.cc +++ b/modules/audio_coding/test/iSACTest.cc @@ -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(); diff --git a/modules/rtp_rtcp/include/rtp_rtcp.h b/modules/rtp_rtcp/include/rtp_rtcp.h index f3656e6dde..cccca03c53 100644 --- a/modules/rtp_rtcp/include/rtp_rtcp.h +++ b/modules/rtp_rtcp/include/rtp_rtcp.h @@ -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, diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h index b18bb1d2e5..02f258e01a 100644 --- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h +++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h @@ -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, diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index fc1c91be1f..b854e16ab6 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -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, diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h index e044823d23..788508c376 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -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,