From 377a231c0d6f2843eea39d0997425af5fd346f79 Mon Sep 17 00:00:00 2001 From: Karl Wiberg Date: Mon, 24 Sep 2018 14:52:51 +0200 Subject: [PATCH] acm_receiver_unittest: Don't rely on the ACM to create encoders It will soon lose the ability to do so. Bug: webrtc:8396 Change-Id: Ifca101fce0c349dba8c402ab2b6ad614061a88f6 Reviewed-on: https://webrtc-review.googlesource.com/101281 Reviewed-by: Ivo Creusen Commit-Queue: Karl Wiberg Cr-Commit-Position: refs/heads/master@{#24836} --- modules/audio_coding/acm2/acm_receiver.cc | 6 + modules/audio_coding/acm2/acm_receiver.h | 1 + .../acm2/acm_receiver_unittest.cc | 307 ++++++++---------- 3 files changed, 146 insertions(+), 168 deletions(-) diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc index 892abe5706..f631746b88 100644 --- a/modules/audio_coding/acm2/acm_receiver.cc +++ b/modules/audio_coding/acm2/acm_receiver.cc @@ -361,6 +361,12 @@ int AcmReceiver::DecoderByPayloadType(uint8_t payload_type, } } +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; diff --git a/modules/audio_coding/acm2/acm_receiver.h b/modules/audio_coding/acm2/acm_receiver.h index 0731677c6e..a2ae723dee 100644 --- a/modules/audio_coding/acm2/acm_receiver.h +++ b/modules/audio_coding/acm2/acm_receiver.h @@ -224,6 +224,7 @@ class AcmReceiver { // int DecoderByPayloadType(uint8_t payload_type, CodecInst* codec) const; + absl::optional DecoderByPayloadType(int payload_type) const; // // Enable NACK and set the maximum size of the NACK list. If NACK is already diff --git a/modules/audio_coding/acm2/acm_receiver_unittest.cc b/modules/audio_coding/acm2/acm_receiver_unittest.cc index 457ea1d4d2..29f2a45669 100644 --- a/modules/audio_coding/acm2/acm_receiver_unittest.cc +++ b/modules/audio_coding/acm2/acm_receiver_unittest.cc @@ -14,7 +14,9 @@ #include #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" #include "modules/include/module_common_types.h" @@ -27,30 +29,6 @@ namespace webrtc { namespace acm2 { -namespace { - -bool CodecsEqual(const CodecInst& codec_a, const CodecInst& codec_b) { - if (strcmp(codec_a.plname, codec_b.plname) != 0 || - codec_a.plfreq != codec_b.plfreq || codec_a.pltype != codec_b.pltype || - codec_b.channels != codec_a.channels) - return false; - return true; -} - -struct CodecIdInst { - explicit CodecIdInst(RentACodec::CodecId codec_id) { - const auto codec_ix = RentACodec::CodecIndexFromId(codec_id); - EXPECT_TRUE(codec_ix); - id = *codec_ix; - const auto codec_inst = RentACodec::CodecInstById(codec_id); - EXPECT_TRUE(codec_inst); - inst = *codec_inst; - } - int id; - CodecInst inst; -}; - -} // namespace class AcmReceiverTestOldApi : public AudioPacketizationCallback, public ::testing::Test { @@ -60,7 +38,7 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback, packet_sent_(false), last_packet_send_timestamp_(timestamp_), last_frame_type_(kEmptyFrame) { - config_.decoder_factory = CreateBuiltinAudioDecoderFactory(); + config_.decoder_factory = decoder_factory_; } ~AcmReceiverTestOldApi() {} @@ -70,8 +48,6 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback, receiver_.reset(new AcmReceiver(config_)); ASSERT_TRUE(receiver_.get() != NULL); ASSERT_TRUE(acm_.get() != NULL); - codecs_ = RentACodec::Database(); - acm_->InitializeReceiver(); acm_->RegisterTransportCallback(this); @@ -86,40 +62,54 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback, void TearDown() override {} - void InsertOnePacketOfSilence(int codec_id) { - CodecInst codec = - *RentACodec::CodecInstById(*RentACodec::CodecIdFromIndex(codec_id)); - if (timestamp_ == 0) { // This is the first time inserting audio. - ASSERT_EQ(0, acm_->RegisterSendCodec(codec)); - } else { - auto current_codec = acm_->SendCodec(); - ASSERT_TRUE(current_codec); - if (!CodecsEqual(codec, *current_codec)) - ASSERT_EQ(0, acm_->RegisterSendCodec(codec)); + AudioCodecInfo SetEncoder(int payload_type, + const SdpAudioFormat& format, + const std::map cng_payload_types = {}) { + // Create the speech encoder. + AudioCodecInfo info = encoder_factory_->QueryAudioEncoder(format).value(); + std::unique_ptr enc = + encoder_factory_->MakeAudioEncoder(payload_type, format, absl::nullopt); + + // If we have a compatible CN specification, stack a CNG on top. + auto it = cng_payload_types.find(info.sample_rate_hz); + if (it != cng_payload_types.end()) { + AudioEncoderCng::Config config; + config.speech_encoder = std::move(enc); + config.num_channels = 1; + config.payload_type = it->second; + config.vad_mode = Vad::kVadNormal; + enc = absl::make_unique(std::move(config)); } - AudioFrame frame; + + // Actually start using the new encoder. + acm_->SetEncoder(std::move(enc)); + return info; + } + + int InsertOnePacketOfSilence(const AudioCodecInfo& info) { // Frame setup according to the codec. - frame.sample_rate_hz_ = codec.plfreq; - frame.samples_per_channel_ = codec.plfreq / 100; // 10 ms. - frame.num_channels_ = codec.channels; + AudioFrame frame; + frame.sample_rate_hz_ = info.sample_rate_hz; + frame.samples_per_channel_ = info.sample_rate_hz / 100; // 10 ms. + frame.num_channels_ = info.num_channels; frame.Mute(); packet_sent_ = false; last_packet_send_timestamp_ = timestamp_; + int num_10ms_frames = 0; while (!packet_sent_) { frame.timestamp_ = timestamp_; timestamp_ += rtc::checked_cast(frame.samples_per_channel_); - ASSERT_GE(acm_->Add10MsData(frame), 0); + EXPECT_GE(acm_->Add10MsData(frame), 0); + ++num_10ms_frames; } + return num_10ms_frames; } template - void AddSetOfCodecs(const RentACodec::CodecId (&ids)[N]) { - for (auto id : ids) { - const auto i = RentACodec::CodecIndexFromId(id); - ASSERT_TRUE(i); - ASSERT_EQ(0, receiver_->AddCodec(*i, codecs_[*i].pltype, - codecs_[*i].channels, codecs_[*i].plfreq, - nullptr, codecs_[*i].plname)); + void AddSetOfCodecs(rtc::ArrayView formats) { + static int payload_type = 0; + for (const auto& format : formats) { + EXPECT_TRUE(receiver_->AddCodec(payload_type++, format)); } } @@ -149,9 +139,12 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback, return 0; } + const rtc::scoped_refptr encoder_factory_ = + CreateBuiltinAudioEncoderFactory(); + const rtc::scoped_refptr decoder_factory_ = + CreateBuiltinAudioDecoderFactory(); AudioCodingModule::Config config_; std::unique_ptr receiver_; - rtc::ArrayView codecs_; std::unique_ptr acm_; WebRtcRTPHeader rtp_header_; uint32_t timestamp_; @@ -166,27 +159,26 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback, #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) { + for (size_t n = 0; n < codecs.size(); ++n) { if (n & 0x1) { // Just add codecs with odd index. - EXPECT_EQ( - 0, receiver_->AddCodec(rtc::checked_cast(n), codecs_[n].pltype, - codecs_[n].channels, codecs_[n].plfreq, NULL, - codecs_[n].plname)); + 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) { - CodecInst my_codec; + 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(0, - receiver_->DecoderByPayloadType(codecs_[n].pltype, &my_codec)); - EXPECT_TRUE(CodecsEqual(codecs_[n], my_codec)); + EXPECT_EQ(absl::make_optional(codecs[n].format), + receiver_->DecoderByPayloadType(payload_type)); } else { // Codecs with even index are not registered. - EXPECT_EQ(-1, - receiver_->DecoderByPayloadType(codecs_[n].pltype, &my_codec)); + EXPECT_EQ(absl::nullopt, receiver_->DecoderByPayloadType(payload_type)); } } } @@ -197,24 +189,15 @@ TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecGetCodec) { #define MAYBE_AddCodecChangePayloadType AddCodecChangePayloadType #endif TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecChangePayloadType) { - const CodecIdInst codec1(RentACodec::CodecId::kPCMA); - CodecInst codec2 = codec1.inst; - ++codec2.pltype; - CodecInst test_codec; + const SdpAudioFormat format("giraffe", 8000, 1); // Register the same codec with different payloads. - EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype, - codec1.inst.channels, codec1.inst.plfreq, - nullptr, codec1.inst.plname)); - EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec2.pltype, codec2.channels, - codec2.plfreq, NULL, codec2.plname)); + EXPECT_EQ(true, receiver_->AddCodec(17, format)); + EXPECT_EQ(true, receiver_->AddCodec(18, format)); // Both payload types should exist. - EXPECT_EQ(0, - receiver_->DecoderByPayloadType(codec1.inst.pltype, &test_codec)); - EXPECT_EQ(true, CodecsEqual(codec1.inst, test_codec)); - EXPECT_EQ(0, receiver_->DecoderByPayloadType(codec2.pltype, &test_codec)); - EXPECT_EQ(true, CodecsEqual(codec2, test_codec)); + EXPECT_EQ(absl::make_optional(format), receiver_->DecoderByPayloadType(17)); + EXPECT_EQ(absl::make_optional(format), receiver_->DecoderByPayloadType(18)); } #if defined(WEBRTC_ANDROID) @@ -223,23 +206,15 @@ TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecChangePayloadType) { #define MAYBE_AddCodecChangeCodecId AddCodecChangeCodecId #endif TEST_F(AcmReceiverTestOldApi, AddCodecChangeCodecId) { - const CodecIdInst codec1(RentACodec::CodecId::kPCMU); - CodecIdInst codec2(RentACodec::CodecId::kPCMA); - codec2.inst.pltype = codec1.inst.pltype; - CodecInst test_codec; + const SdpAudioFormat format1("giraffe", 8000, 1); + const SdpAudioFormat format2("gnu", 16000, 1); // Register the same payload type with different codec ID. - EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype, - codec1.inst.channels, codec1.inst.plfreq, - nullptr, codec1.inst.plname)); - EXPECT_EQ(0, receiver_->AddCodec(codec2.id, codec2.inst.pltype, - codec2.inst.channels, codec2.inst.plfreq, - nullptr, codec2.inst.plname)); + EXPECT_EQ(true, receiver_->AddCodec(17, format1)); + EXPECT_EQ(true, receiver_->AddCodec(17, format2)); // Make sure that the last codec is used. - EXPECT_EQ(0, - receiver_->DecoderByPayloadType(codec2.inst.pltype, &test_codec)); - EXPECT_EQ(true, CodecsEqual(codec2.inst, test_codec)); + EXPECT_EQ(absl::make_optional(format2), receiver_->DecoderByPayloadType(17)); } #if defined(WEBRTC_ANDROID) @@ -248,21 +223,16 @@ TEST_F(AcmReceiverTestOldApi, AddCodecChangeCodecId) { #define MAYBE_AddCodecRemoveCodec AddCodecRemoveCodec #endif TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecRemoveCodec) { - const CodecIdInst codec(RentACodec::CodecId::kPCMA); - const int payload_type = codec.inst.pltype; - EXPECT_EQ( - 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels, - codec.inst.plfreq, nullptr, codec.inst.plname)); + EXPECT_EQ(true, receiver_->AddCodec(17, SdpAudioFormat("giraffe", 8000, 1))); // Remove non-existing codec should not fail. ACM1 legacy. - EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1)); + EXPECT_EQ(0, receiver_->RemoveCodec(18)); // Remove an existing codec. - EXPECT_EQ(0, receiver_->RemoveCodec(payload_type)); + EXPECT_EQ(0, receiver_->RemoveCodec(17)); // Ask for the removed codec, must fail. - CodecInst ci; - EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &ci)); + EXPECT_EQ(absl::nullopt, receiver_->DecoderByPayloadType(17)); } #if defined(WEBRTC_ANDROID) @@ -271,21 +241,25 @@ TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecRemoveCodec) { #define MAYBE_SampleRate SampleRate #endif TEST_F(AcmReceiverTestOldApi, MAYBE_SampleRate) { - const RentACodec::CodecId kCodecId[] = {RentACodec::CodecId::kISAC, - RentACodec::CodecId::kISACSWB}; - AddSetOfCodecs(kCodecId); + 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])); + } - AudioFrame frame; - const int kOutSampleRateHz = 8000; // Different than codec sample rate. - for (const auto codec_id : kCodecId) { - const CodecIdInst codec(codec_id); - const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100); - InsertOnePacketOfSilence(codec.id); + 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])); for (int k = 0; k < num_10ms_frames; ++k) { + AudioFrame frame; bool muted; EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame, &muted)); } - EXPECT_EQ(codec.inst.plfreq, receiver_->last_output_sample_rate_hz()); + EXPECT_EQ(encoder_factory_->QueryAudioEncoder(codecs[i])->sample_rate_hz, + receiver_->last_output_sample_rate_hz()); } } @@ -295,7 +269,7 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { config_.neteq_config.for_test_no_time_stretching = true; } - void RunVerifyAudioFrame(RentACodec::CodecId codec_id) { + void RunVerifyAudioFrame(const SdpAudioFormat& codec) { // Make sure "fax mode" is enabled. This will avoid delay changes unless the // packet-loss concealment is made. We do this in order to make the // timestamp increments predictable; in normal mode, NetEq may decide to do @@ -303,16 +277,14 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { // the timestamp. EXPECT_TRUE(config_.neteq_config.for_test_no_time_stretching); - const RentACodec::CodecId kCodecId[] = {codec_id}; - AddSetOfCodecs(kCodecId); + constexpr int payload_type = 17; + EXPECT_TRUE(receiver_->AddCodec(payload_type, codec)); - const CodecIdInst codec(codec_id); - const int output_sample_rate_hz = codec.inst.plfreq; - const size_t output_channels = codec.inst.channels; + const AudioCodecInfo info = SetEncoder(payload_type, codec); + const int output_sample_rate_hz = info.sample_rate_hz; + const size_t output_channels = info.num_channels; const size_t samples_per_ms = rtc::checked_cast( rtc::CheckedDivExact(output_sample_rate_hz, 1000)); - const int num_10ms_frames = rtc::CheckedDivExact( - codec.inst.pacsize, rtc::checked_cast(10 * samples_per_ms)); const AudioFrame::VADActivity expected_vad_activity = output_sample_rate_hz > 16000 ? AudioFrame::kVadActive : AudioFrame::kVadPassive; @@ -330,7 +302,7 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { // Expect timestamp = 0 before first packet is inserted. EXPECT_EQ(0u, frame.timestamp_); for (int i = 0; i < 5; ++i) { - InsertOnePacketOfSilence(codec.id); + const int num_10ms_frames = InsertOnePacketOfSilence(info); for (int k = 0; k < num_10ms_frames; ++k) { EXPECT_EQ(0, receiver_->GetAudio(output_sample_rate_hz, &frame, &muted)); @@ -353,7 +325,7 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { #define MAYBE_VerifyAudioFramePCMU VerifyAudioFramePCMU #endif TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFramePCMU) { - RunVerifyAudioFrame(RentACodec::CodecId::kPCMU); + RunVerifyAudioFrame({"PCMU", 8000, 1}); } #if defined(WEBRTC_ANDROID) @@ -362,7 +334,7 @@ TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFramePCMU) { #define MAYBE_VerifyAudioFrameISAC VerifyAudioFrameISAC #endif TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameISAC) { - RunVerifyAudioFrame(RentACodec::CodecId::kISAC); + RunVerifyAudioFrame({"ISAC", 16000, 1}); } #if defined(WEBRTC_ANDROID) @@ -371,7 +343,7 @@ TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameISAC) { #define MAYBE_VerifyAudioFrameOpus VerifyAudioFrameOpus #endif TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameOpus) { - RunVerifyAudioFrame(RentACodec::CodecId::kOpus); + RunVerifyAudioFrame({"opus", 48000, 2}); } #if defined(WEBRTC_ANDROID) @@ -381,18 +353,17 @@ TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameOpus) { #endif TEST_F(AcmReceiverTestOldApi, MAYBE_PostdecodingVad) { EXPECT_TRUE(config_.neteq_config.enable_post_decode_vad); - const CodecIdInst codec(RentACodec::CodecId::kPCM16Bwb); - ASSERT_EQ( - 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels, - codec.inst.plfreq, nullptr, "")); - const int kNumPackets = 5; - const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100); + 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)); + constexpr int kNumPackets = 5; AudioFrame frame; for (int n = 0; n < kNumPackets; ++n) { - InsertOnePacketOfSilence(codec.id); + const int num_10ms_frames = InsertOnePacketOfSilence(info); for (int k = 0; k < num_10ms_frames; ++k) { bool muted; - ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame, &muted)); + ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted)); } } EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_); @@ -412,18 +383,18 @@ class AcmReceiverTestPostDecodeVadPassiveOldApi : public AcmReceiverTestOldApi { #endif TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) { EXPECT_FALSE(config_.neteq_config.enable_post_decode_vad); - const CodecIdInst codec(RentACodec::CodecId::kPCM16Bwb); - ASSERT_EQ( - 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels, - codec.inst.plfreq, nullptr, "")); + constexpr int payload_type = 34; + 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)); const int kNumPackets = 5; - const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100); AudioFrame frame; for (int n = 0; n < kNumPackets; ++n) { - InsertOnePacketOfSilence(codec.id); + const int num_10ms_frames = InsertOnePacketOfSilence(info); for (int k = 0; k < num_10ms_frames; ++k) { bool muted; - ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame, &muted)); + ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted)); } } EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_); @@ -436,64 +407,64 @@ TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) { #endif #if defined(WEBRTC_CODEC_ISAC) TEST_F(AcmReceiverTestOldApi, MAYBE_LastAudioCodec) { - const RentACodec::CodecId kCodecId[] = { - RentACodec::CodecId::kISAC, RentACodec::CodecId::kPCMA, - RentACodec::CodecId::kISACSWB, RentACodec::CodecId::kPCM16Bswb32kHz}; - AddSetOfCodecs(kCodecId); + 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 RentACodec::CodecId kCngId[] = { - // Not including full-band. - RentACodec::CodecId::kCNNB, RentACodec::CodecId::kCNWB, - RentACodec::CodecId::kCNSWB}; - AddSetOfCodecs(kCngId); + 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})); + } - // Register CNG at sender side. - for (auto id : kCngId) - ASSERT_EQ(0, acm_->RegisterSendCodec(CodecIdInst(id).inst)); - - CodecInst codec; // No audio payload is received. - EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec)); + EXPECT_EQ(absl::nullopt, receiver_->LastAudioFormat()); // Start with sending DTX. - ASSERT_EQ(0, acm_->SetVAD(true, true, VADVeryAggr)); packet_sent_ = false; - InsertOnePacketOfSilence(CodecIdInst(kCodecId[0]).id); // Enough to test - // with one codec. + InsertOnePacketOfSilence( + SetEncoder(0, codecs[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(-1, receiver_->LastAudioCodec(&codec)); + EXPECT_EQ(absl::nullopt, receiver_->LastAudioFormat()); EXPECT_FALSE(receiver_->last_packet_sample_rate_hz()); - for (auto id : kCodecId) { - const CodecIdInst c(id); - + for (size_t i = 0; i < codecs.size(); ++i) { // Set DTX off to send audio payload. - acm_->SetVAD(false, false, VADAggr); packet_sent_ = false; - InsertOnePacketOfSilence(c.id); + const int payload_type = rtc::checked_cast(i); + const AudioCodecInfo info_without_cng = SetEncoder(payload_type, codecs[i]); + InsertOnePacketOfSilence(info_without_cng); // Sanity check if Actually an audio payload received, and it should be // of type "speech." ASSERT_TRUE(packet_sent_); ASSERT_EQ(kAudioFrameSpeech, last_frame_type_); - EXPECT_EQ(c.inst.plfreq, receiver_->last_packet_sample_rate_hz()); + EXPECT_EQ(info_without_cng.sample_rate_hz, + receiver_->last_packet_sample_rate_hz()); // Set VAD on to send DTX. Then check if the "Last Audio codec" returns - // the expected codec. - acm_->SetVAD(true, true, VADAggr); - - // Do as many encoding until a DTX is sent. + // the expected codec. Encode repeatedly until a DTX is sent. + const AudioCodecInfo info_with_cng = + SetEncoder(payload_type, codecs[i], cng_payload_types); while (last_frame_type_ != kAudioFrameCN) { packet_sent_ = false; - InsertOnePacketOfSilence(c.id); + InsertOnePacketOfSilence(info_with_cng); ASSERT_TRUE(packet_sent_); } - EXPECT_EQ(c.inst.plfreq, receiver_->last_packet_sample_rate_hz()); - EXPECT_EQ(0, receiver_->LastAudioCodec(&codec)); - EXPECT_TRUE(CodecsEqual(c.inst, codec)); + EXPECT_EQ(info_with_cng.sample_rate_hz, + receiver_->last_packet_sample_rate_hz()); + EXPECT_EQ(codecs[i], receiver_->LastAudioFormat()); } } #endif