blob: d5392dc78c36001677eea7ccd954a2fcbdf689d3 [file] [log] [blame]
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_coding/acm2/acm_receiver.h"
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000012
13#include <algorithm> // std::min
kwiberg16c5a962016-02-15 02:27:22 -080014#include <memory>
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000015
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Karl Wiberg377a2312018-09-24 14:52:51 +020017#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Karl Wiberg377a2312018-09-24 14:52:51 +020018#include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/audio_coding/include/audio_coding_module.h"
20#include "modules/audio_coding/neteq/tools/rtp_generator.h"
Fredrik Solenbergbbf21a32018-04-12 22:44:09 +020021#include "modules/include/module_common_types.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/checks.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010023#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "system_wrappers/include/clock.h"
25#include "test/gtest.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "test/testsupport/file_utils.h"
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000027
28namespace webrtc {
29
30namespace acm2 {
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000031
32class AcmReceiverTestOldApi : public AudioPacketizationCallback,
33 public ::testing::Test {
34 protected:
35 AcmReceiverTestOldApi()
36 : timestamp_(0),
37 packet_sent_(false),
38 last_packet_send_timestamp_(timestamp_),
pbos22993e12015-10-19 02:39:06 -070039 last_frame_type_(kEmptyFrame) {
Karl Wiberg377a2312018-09-24 14:52:51 +020040 config_.decoder_factory = decoder_factory_;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000041 }
42
43 ~AcmReceiverTestOldApi() {}
44
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000045 void SetUp() override {
kwibergc13ded52016-06-17 06:00:45 -070046 acm_.reset(AudioCodingModule::Create(config_));
henrik.lundin500c04b2016-03-08 02:36:04 -080047 receiver_.reset(new AcmReceiver(config_));
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000048 ASSERT_TRUE(receiver_.get() != NULL);
49 ASSERT_TRUE(acm_.get() != NULL);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000050 acm_->InitializeReceiver();
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000051 acm_->RegisterTransportCallback(this);
52
53 rtp_header_.header.sequenceNumber = 0;
54 rtp_header_.header.timestamp = 0;
55 rtp_header_.header.markerBit = false;
56 rtp_header_.header.ssrc = 0x12345678; // Arbitrary.
57 rtp_header_.header.numCSRCs = 0;
58 rtp_header_.header.payloadType = 0;
59 rtp_header_.frameType = kAudioFrameSpeech;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000060 }
61
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000062 void TearDown() override {}
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000063
Karl Wiberg377a2312018-09-24 14:52:51 +020064 AudioCodecInfo SetEncoder(int payload_type,
65 const SdpAudioFormat& format,
66 const std::map<int, int> cng_payload_types = {}) {
67 // Create the speech encoder.
68 AudioCodecInfo info = encoder_factory_->QueryAudioEncoder(format).value();
69 std::unique_ptr<AudioEncoder> enc =
70 encoder_factory_->MakeAudioEncoder(payload_type, format, absl::nullopt);
71
72 // If we have a compatible CN specification, stack a CNG on top.
73 auto it = cng_payload_types.find(info.sample_rate_hz);
74 if (it != cng_payload_types.end()) {
Karl Wiberg23659362018-11-01 11:13:44 +010075 AudioEncoderCngConfig config;
Karl Wiberg377a2312018-09-24 14:52:51 +020076 config.speech_encoder = std::move(enc);
77 config.num_channels = 1;
78 config.payload_type = it->second;
79 config.vad_mode = Vad::kVadNormal;
Karl Wiberg23659362018-11-01 11:13:44 +010080 enc = CreateComfortNoiseEncoder(std::move(config));
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000081 }
Karl Wiberg377a2312018-09-24 14:52:51 +020082
83 // Actually start using the new encoder.
84 acm_->SetEncoder(std::move(enc));
85 return info;
86 }
87
88 int InsertOnePacketOfSilence(const AudioCodecInfo& info) {
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000089 // Frame setup according to the codec.
Karl Wiberg377a2312018-09-24 14:52:51 +020090 AudioFrame frame;
91 frame.sample_rate_hz_ = info.sample_rate_hz;
92 frame.samples_per_channel_ = info.sample_rate_hz / 100; // 10 ms.
93 frame.num_channels_ = info.num_channels;
yujo36b1a5f2017-06-12 12:45:32 -070094 frame.Mute();
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000095 packet_sent_ = false;
96 last_packet_send_timestamp_ = timestamp_;
Karl Wiberg377a2312018-09-24 14:52:51 +020097 int num_10ms_frames = 0;
henrik.lundin@webrtc.orgf56c1622015-03-02 12:29:30 +000098 while (!packet_sent_) {
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000099 frame.timestamp_ = timestamp_;
Mirko Bonadei737e0732017-10-19 09:00:17 +0200100 timestamp_ += rtc::checked_cast<uint32_t>(frame.samples_per_channel_);
Karl Wiberg377a2312018-09-24 14:52:51 +0200101 EXPECT_GE(acm_->Add10MsData(frame), 0);
102 ++num_10ms_frames;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000103 }
Karl Wiberg377a2312018-09-24 14:52:51 +0200104 return num_10ms_frames;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000105 }
106
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000107 int SendData(FrameType frame_type,
108 uint8_t payload_type,
109 uint32_t timestamp,
110 const uint8_t* payload_data,
111 size_t payload_len_bytes,
112 const RTPFragmentationHeader* fragmentation) override {
pbos22993e12015-10-19 02:39:06 -0700113 if (frame_type == kEmptyFrame)
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000114 return 0;
115
116 rtp_header_.header.payloadType = payload_type;
117 rtp_header_.frameType = frame_type;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000118 rtp_header_.header.timestamp = timestamp;
119
kwibergee2bac22015-11-11 10:34:00 -0800120 int ret_val = receiver_->InsertPacket(
121 rtp_header_,
122 rtc::ArrayView<const uint8_t>(payload_data, payload_len_bytes));
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000123 if (ret_val < 0) {
124 assert(false);
125 return -1;
126 }
127 rtp_header_.header.sequenceNumber++;
128 packet_sent_ = true;
129 last_frame_type_ = frame_type;
130 return 0;
131 }
132
Karl Wiberg377a2312018-09-24 14:52:51 +0200133 const rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_ =
134 CreateBuiltinAudioEncoderFactory();
135 const rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_ =
136 CreateBuiltinAudioDecoderFactory();
henrik.lundin500c04b2016-03-08 02:36:04 -0800137 AudioCodingModule::Config config_;
kwiberg16c5a962016-02-15 02:27:22 -0800138 std::unique_ptr<AcmReceiver> receiver_;
kwiberg16c5a962016-02-15 02:27:22 -0800139 std::unique_ptr<AudioCodingModule> acm_;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000140 WebRtcRTPHeader rtp_header_;
141 uint32_t timestamp_;
142 bool packet_sent_; // Set when SendData is called reset when inserting audio.
143 uint32_t last_packet_send_timestamp_;
144 FrameType last_frame_type_;
145};
146
Peter Boströme2976c82016-01-04 22:44:05 +0100147#if defined(WEBRTC_ANDROID)
Peter Boströme2976c82016-01-04 22:44:05 +0100148#define MAYBE_SampleRate DISABLED_SampleRate
149#else
150#define MAYBE_SampleRate SampleRate
151#endif
152TEST_F(AcmReceiverTestOldApi, MAYBE_SampleRate) {
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100153 const std::map<int, SdpAudioFormat> codecs = {{0, {"ISAC", 16000, 1}},
154 {1, {"ISAC", 32000, 1}}};
155 receiver_->SetCodecs(codecs);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000156
Karl Wiberg377a2312018-09-24 14:52:51 +0200157 constexpr int kOutSampleRateHz = 8000; // Different than codec sample rate.
158 for (size_t i = 0; i < codecs.size(); ++i) {
159 const int payload_type = rtc::checked_cast<int>(i);
160 const int num_10ms_frames =
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100161 InsertOnePacketOfSilence(SetEncoder(payload_type, codecs.at(i)));
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000162 for (int k = 0; k < num_10ms_frames; ++k) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200163 AudioFrame frame;
henrik.lundin834a6ea2016-05-13 03:45:24 -0700164 bool muted;
165 EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame, &muted));
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000166 }
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100167 EXPECT_EQ(encoder_factory_->QueryAudioEncoder(codecs.at(i))->sample_rate_hz,
Karl Wiberg377a2312018-09-24 14:52:51 +0200168 receiver_->last_output_sample_rate_hz());
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000169 }
170}
171
henrik.lundin7dc68892016-04-06 01:03:02 -0700172class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi {
173 protected:
174 AcmReceiverTestFaxModeOldApi() {
Henrik Lundin7687ad52018-07-02 10:14:46 +0200175 config_.neteq_config.for_test_no_time_stretching = true;
henrik.lundin7dc68892016-04-06 01:03:02 -0700176 }
177
Karl Wiberg377a2312018-09-24 14:52:51 +0200178 void RunVerifyAudioFrame(const SdpAudioFormat& codec) {
henrik.lundin7dc68892016-04-06 01:03:02 -0700179 // Make sure "fax mode" is enabled. This will avoid delay changes unless the
180 // packet-loss concealment is made. We do this in order to make the
181 // timestamp increments predictable; in normal mode, NetEq may decide to do
182 // accelerate or pre-emptive expand operations after some time, offsetting
183 // the timestamp.
Henrik Lundin7687ad52018-07-02 10:14:46 +0200184 EXPECT_TRUE(config_.neteq_config.for_test_no_time_stretching);
henrik.lundin7dc68892016-04-06 01:03:02 -0700185
Karl Wiberg377a2312018-09-24 14:52:51 +0200186 constexpr int payload_type = 17;
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100187 receiver_->SetCodecs({{payload_type, codec}});
henrik.lundin7dc68892016-04-06 01:03:02 -0700188
Karl Wiberg377a2312018-09-24 14:52:51 +0200189 const AudioCodecInfo info = SetEncoder(payload_type, codec);
190 const int output_sample_rate_hz = info.sample_rate_hz;
191 const size_t output_channels = info.num_channels;
henrik.lundin7dc68892016-04-06 01:03:02 -0700192 const size_t samples_per_ms = rtc::checked_cast<size_t>(
193 rtc::CheckedDivExact(output_sample_rate_hz, 1000));
henrik.lundin7dc68892016-04-06 01:03:02 -0700194 const AudioFrame::VADActivity expected_vad_activity =
195 output_sample_rate_hz > 16000 ? AudioFrame::kVadActive
196 : AudioFrame::kVadPassive;
197
198 // Expect the first output timestamp to be 5*fs/8000 samples before the
199 // first inserted timestamp (because of NetEq's look-ahead). (This value is
200 // defined in Expand::overlap_length_.)
Yves Gerey665174f2018-06-19 15:03:05 +0200201 uint32_t expected_output_ts =
202 last_packet_send_timestamp_ -
henrik.lundin7dc68892016-04-06 01:03:02 -0700203 rtc::CheckedDivExact(5 * output_sample_rate_hz, 8000);
204
205 AudioFrame frame;
henrik.lundin834a6ea2016-05-13 03:45:24 -0700206 bool muted;
207 EXPECT_EQ(0, receiver_->GetAudio(output_sample_rate_hz, &frame, &muted));
henrik.lundin15c51e32016-04-06 08:38:56 -0700208 // Expect timestamp = 0 before first packet is inserted.
209 EXPECT_EQ(0u, frame.timestamp_);
henrik.lundin7dc68892016-04-06 01:03:02 -0700210 for (int i = 0; i < 5; ++i) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200211 const int num_10ms_frames = InsertOnePacketOfSilence(info);
henrik.lundin7dc68892016-04-06 01:03:02 -0700212 for (int k = 0; k < num_10ms_frames; ++k) {
henrik.lundin834a6ea2016-05-13 03:45:24 -0700213 EXPECT_EQ(0,
214 receiver_->GetAudio(output_sample_rate_hz, &frame, &muted));
henrik.lundin7dc68892016-04-06 01:03:02 -0700215 EXPECT_EQ(expected_output_ts, frame.timestamp_);
Mirko Bonadei737e0732017-10-19 09:00:17 +0200216 expected_output_ts += rtc::checked_cast<uint32_t>(10 * samples_per_ms);
henrik.lundin7dc68892016-04-06 01:03:02 -0700217 EXPECT_EQ(10 * samples_per_ms, frame.samples_per_channel_);
218 EXPECT_EQ(output_sample_rate_hz, frame.sample_rate_hz_);
219 EXPECT_EQ(output_channels, frame.num_channels_);
220 EXPECT_EQ(AudioFrame::kNormalSpeech, frame.speech_type_);
221 EXPECT_EQ(expected_vad_activity, frame.vad_activity_);
henrik.lundin834a6ea2016-05-13 03:45:24 -0700222 EXPECT_FALSE(muted);
henrik.lundin7dc68892016-04-06 01:03:02 -0700223 }
224 }
225 }
226};
227
228#if defined(WEBRTC_ANDROID)
229#define MAYBE_VerifyAudioFramePCMU DISABLED_VerifyAudioFramePCMU
230#else
231#define MAYBE_VerifyAudioFramePCMU VerifyAudioFramePCMU
232#endif
233TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFramePCMU) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200234 RunVerifyAudioFrame({"PCMU", 8000, 1});
henrik.lundin7dc68892016-04-06 01:03:02 -0700235}
236
237#if defined(WEBRTC_ANDROID)
238#define MAYBE_VerifyAudioFrameISAC DISABLED_VerifyAudioFrameISAC
239#else
240#define MAYBE_VerifyAudioFrameISAC VerifyAudioFrameISAC
241#endif
242TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameISAC) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200243 RunVerifyAudioFrame({"ISAC", 16000, 1});
henrik.lundin7dc68892016-04-06 01:03:02 -0700244}
245
246#if defined(WEBRTC_ANDROID)
247#define MAYBE_VerifyAudioFrameOpus DISABLED_VerifyAudioFrameOpus
248#else
249#define MAYBE_VerifyAudioFrameOpus VerifyAudioFrameOpus
250#endif
251TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameOpus) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200252 RunVerifyAudioFrame({"opus", 48000, 2});
henrik.lundin7dc68892016-04-06 01:03:02 -0700253}
254
Peter Boströme2976c82016-01-04 22:44:05 +0100255#if defined(WEBRTC_ANDROID)
256#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad
257#else
258#define MAYBE_PostdecodingVad PostdecodingVad
259#endif
260TEST_F(AcmReceiverTestOldApi, MAYBE_PostdecodingVad) {
henrik.lundin500c04b2016-03-08 02:36:04 -0800261 EXPECT_TRUE(config_.neteq_config.enable_post_decode_vad);
Karl Wiberg377a2312018-09-24 14:52:51 +0200262 constexpr int payload_type = 34;
263 const SdpAudioFormat codec = {"L16", 16000, 1};
264 const AudioCodecInfo info = SetEncoder(payload_type, codec);
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100265 receiver_->SetCodecs({{payload_type, codec}});
Karl Wiberg377a2312018-09-24 14:52:51 +0200266 constexpr int kNumPackets = 5;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000267 AudioFrame frame;
268 for (int n = 0; n < kNumPackets; ++n) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200269 const int num_10ms_frames = InsertOnePacketOfSilence(info);
henrik.lundin834a6ea2016-05-13 03:45:24 -0700270 for (int k = 0; k < num_10ms_frames; ++k) {
271 bool muted;
Karl Wiberg377a2312018-09-24 14:52:51 +0200272 ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted));
henrik.lundin834a6ea2016-05-13 03:45:24 -0700273 }
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000274 }
275 EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_);
henrik.lundin500c04b2016-03-08 02:36:04 -0800276}
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000277
henrik.lundin500c04b2016-03-08 02:36:04 -0800278class AcmReceiverTestPostDecodeVadPassiveOldApi : public AcmReceiverTestOldApi {
279 protected:
280 AcmReceiverTestPostDecodeVadPassiveOldApi() {
281 config_.neteq_config.enable_post_decode_vad = false;
282 }
283};
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000284
henrik.lundin500c04b2016-03-08 02:36:04 -0800285#if defined(WEBRTC_ANDROID)
286#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad
287#else
288#define MAYBE_PostdecodingVad PostdecodingVad
289#endif
290TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) {
291 EXPECT_FALSE(config_.neteq_config.enable_post_decode_vad);
Karl Wiberg377a2312018-09-24 14:52:51 +0200292 constexpr int payload_type = 34;
293 const SdpAudioFormat codec = {"L16", 16000, 1};
294 const AudioCodecInfo info = SetEncoder(payload_type, codec);
295 encoder_factory_->QueryAudioEncoder(codec).value();
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100296 receiver_->SetCodecs({{payload_type, codec}});
henrik.lundin500c04b2016-03-08 02:36:04 -0800297 const int kNumPackets = 5;
henrik.lundin500c04b2016-03-08 02:36:04 -0800298 AudioFrame frame;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000299 for (int n = 0; n < kNumPackets; ++n) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200300 const int num_10ms_frames = InsertOnePacketOfSilence(info);
henrik.lundin834a6ea2016-05-13 03:45:24 -0700301 for (int k = 0; k < num_10ms_frames; ++k) {
302 bool muted;
Karl Wiberg377a2312018-09-24 14:52:51 +0200303 ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted));
henrik.lundin834a6ea2016-05-13 03:45:24 -0700304 }
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000305 }
306 EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_);
307}
308
Peter Boströme2976c82016-01-04 22:44:05 +0100309#if defined(WEBRTC_ANDROID)
310#define MAYBE_LastAudioCodec DISABLED_LastAudioCodec
kwiberg98ab3a42015-09-30 21:54:21 -0700311#else
Peter Boströme2976c82016-01-04 22:44:05 +0100312#define MAYBE_LastAudioCodec LastAudioCodec
kwiberg98ab3a42015-09-30 21:54:21 -0700313#endif
Peter Boströme2976c82016-01-04 22:44:05 +0100314#if defined(WEBRTC_CODEC_ISAC)
315TEST_F(AcmReceiverTestOldApi, MAYBE_LastAudioCodec) {
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100316 const std::map<int, SdpAudioFormat> codecs = {{0, {"ISAC", 16000, 1}},
317 {1, {"PCMA", 8000, 1}},
318 {2, {"ISAC", 32000, 1}},
319 {3, {"L16", 32000, 1}}};
320 const std::map<int, int> cng_payload_types = {{8000, 100},
321 {16000, 101},
322 {32000, 102}};
323 {
324 std::map<int, SdpAudioFormat> receive_codecs = codecs;
325 for (const auto& cng_type : cng_payload_types) {
326 receive_codecs.emplace(
327 std::make_pair(cng_type.second, SdpAudioFormat("CN", cng_type.first, 1)));
328 }
329 receiver_->SetCodecs(receive_codecs);
Karl Wiberg377a2312018-09-24 14:52:51 +0200330 }
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000331
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000332 // No audio payload is received.
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100333 EXPECT_EQ(absl::nullopt, receiver_->LastDecoder());
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000334
335 // Start with sending DTX.
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000336 packet_sent_ = false;
Karl Wiberg377a2312018-09-24 14:52:51 +0200337 InsertOnePacketOfSilence(
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100338 SetEncoder(0, codecs.at(0), cng_payload_types)); // Enough to test
Karl Wiberg377a2312018-09-24 14:52:51 +0200339 // with one codec.
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000340 ASSERT_TRUE(packet_sent_);
341 EXPECT_EQ(kAudioFrameCN, last_frame_type_);
342
343 // Has received, only, DTX. Last Audio codec is undefined.
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100344 EXPECT_EQ(absl::nullopt, receiver_->LastDecoder());
345 EXPECT_EQ(absl::nullopt, receiver_->last_packet_sample_rate_hz());
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000346
Karl Wiberg377a2312018-09-24 14:52:51 +0200347 for (size_t i = 0; i < codecs.size(); ++i) {
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000348 // Set DTX off to send audio payload.
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000349 packet_sent_ = false;
Karl Wiberg377a2312018-09-24 14:52:51 +0200350 const int payload_type = rtc::checked_cast<int>(i);
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100351 const AudioCodecInfo info_without_cng =
352 SetEncoder(payload_type, codecs.at(i));
Karl Wiberg377a2312018-09-24 14:52:51 +0200353 InsertOnePacketOfSilence(info_without_cng);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000354
355 // Sanity check if Actually an audio payload received, and it should be
356 // of type "speech."
357 ASSERT_TRUE(packet_sent_);
358 ASSERT_EQ(kAudioFrameSpeech, last_frame_type_);
Karl Wiberg377a2312018-09-24 14:52:51 +0200359 EXPECT_EQ(info_without_cng.sample_rate_hz,
360 receiver_->last_packet_sample_rate_hz());
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000361
362 // Set VAD on to send DTX. Then check if the "Last Audio codec" returns
Karl Wiberg377a2312018-09-24 14:52:51 +0200363 // the expected codec. Encode repeatedly until a DTX is sent.
364 const AudioCodecInfo info_with_cng =
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100365 SetEncoder(payload_type, codecs.at(i), cng_payload_types);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000366 while (last_frame_type_ != kAudioFrameCN) {
367 packet_sent_ = false;
Karl Wiberg377a2312018-09-24 14:52:51 +0200368 InsertOnePacketOfSilence(info_with_cng);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000369 ASSERT_TRUE(packet_sent_);
370 }
Karl Wiberg377a2312018-09-24 14:52:51 +0200371 EXPECT_EQ(info_with_cng.sample_rate_hz,
372 receiver_->last_packet_sample_rate_hz());
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100373 EXPECT_EQ(codecs.at(i), receiver_->LastDecoder()->second);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000374 }
375}
Peter Boströme2976c82016-01-04 22:44:05 +0100376#endif
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000377
378} // namespace acm2
379
380} // namespace webrtc