blob: a5095f0c0f8e97dbd7c5e1a909df8566ba9b2718 [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
Alessio Bazzica17887eb2022-11-11 16:52:46 +010016#include "absl/types/optional.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Karl Wiberg377a2312018-09-24 14:52:51 +020018#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Karl Wiberg377a2312018-09-24 14:52:51 +020019#include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "modules/audio_coding/include/audio_coding_module.h"
21#include "modules/audio_coding/neteq/tools/rtp_generator.h"
Fredrik Solenbergbbf21a32018-04-12 22:44:09 +020022#include "modules/include/module_common_types.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/checks.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010024#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "system_wrappers/include/clock.h"
26#include "test/gtest.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "test/testsupport/file_utils.h"
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000028
29namespace webrtc {
30
31namespace acm2 {
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000032
33class AcmReceiverTestOldApi : public AudioPacketizationCallback,
34 public ::testing::Test {
35 protected:
36 AcmReceiverTestOldApi()
37 : timestamp_(0),
38 packet_sent_(false),
39 last_packet_send_timestamp_(timestamp_),
Niels Möllerc936cb62019-03-19 14:10:16 +010040 last_frame_type_(AudioFrameType::kEmptyFrame) {
Karl Wiberg377a2312018-09-24 14:52:51 +020041 config_.decoder_factory = decoder_factory_;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000042 }
43
44 ~AcmReceiverTestOldApi() {}
45
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000046 void SetUp() override {
Henrik Lundin84f75692023-02-01 12:07:10 +000047 acm_ = AudioCodingModule::Create();
henrik.lundin500c04b2016-03-08 02:36:04 -080048 receiver_.reset(new AcmReceiver(config_));
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000049 ASSERT_TRUE(receiver_.get() != NULL);
50 ASSERT_TRUE(acm_.get() != NULL);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000051 acm_->RegisterTransportCallback(this);
52
Niels Möllerafb5dbb2019-02-15 15:21:47 +010053 rtp_header_.sequenceNumber = 0;
54 rtp_header_.timestamp = 0;
55 rtp_header_.markerBit = false;
56 rtp_header_.ssrc = 0x12345678; // Arbitrary.
57 rtp_header_.numCSRCs = 0;
58 rtp_header_.payloadType = 0;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000059 }
60
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000061 void TearDown() override {}
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000062
Karl Wiberg377a2312018-09-24 14:52:51 +020063 AudioCodecInfo SetEncoder(int payload_type,
64 const SdpAudioFormat& format,
65 const std::map<int, int> cng_payload_types = {}) {
66 // Create the speech encoder.
Alessio Bazzica17887eb2022-11-11 16:52:46 +010067 absl::optional<AudioCodecInfo> info =
68 encoder_factory_->QueryAudioEncoder(format);
69 RTC_CHECK(info.has_value());
Karl Wiberg377a2312018-09-24 14:52:51 +020070 std::unique_ptr<AudioEncoder> enc =
71 encoder_factory_->MakeAudioEncoder(payload_type, format, absl::nullopt);
72
73 // If we have a compatible CN specification, stack a CNG on top.
Alessio Bazzica17887eb2022-11-11 16:52:46 +010074 auto it = cng_payload_types.find(info->sample_rate_hz);
Karl Wiberg377a2312018-09-24 14:52:51 +020075 if (it != cng_payload_types.end()) {
Karl Wiberg23659362018-11-01 11:13:44 +010076 AudioEncoderCngConfig config;
Karl Wiberg377a2312018-09-24 14:52:51 +020077 config.speech_encoder = std::move(enc);
78 config.num_channels = 1;
79 config.payload_type = it->second;
80 config.vad_mode = Vad::kVadNormal;
Karl Wiberg23659362018-11-01 11:13:44 +010081 enc = CreateComfortNoiseEncoder(std::move(config));
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000082 }
Karl Wiberg377a2312018-09-24 14:52:51 +020083
84 // Actually start using the new encoder.
85 acm_->SetEncoder(std::move(enc));
Alessio Bazzica17887eb2022-11-11 16:52:46 +010086 return *info;
Karl Wiberg377a2312018-09-24 14:52:51 +020087 }
88
89 int InsertOnePacketOfSilence(const AudioCodecInfo& info) {
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000090 // Frame setup according to the codec.
Karl Wiberg377a2312018-09-24 14:52:51 +020091 AudioFrame frame;
92 frame.sample_rate_hz_ = info.sample_rate_hz;
93 frame.samples_per_channel_ = info.sample_rate_hz / 100; // 10 ms.
94 frame.num_channels_ = info.num_channels;
yujo36b1a5f2017-06-12 12:45:32 -070095 frame.Mute();
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +000096 packet_sent_ = false;
97 last_packet_send_timestamp_ = timestamp_;
Karl Wiberg377a2312018-09-24 14:52:51 +020098 int num_10ms_frames = 0;
henrik.lundin@webrtc.orgf56c1622015-03-02 12:29:30 +000099 while (!packet_sent_) {
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000100 frame.timestamp_ = timestamp_;
Mirko Bonadei737e0732017-10-19 09:00:17 +0200101 timestamp_ += rtc::checked_cast<uint32_t>(frame.samples_per_channel_);
Karl Wiberg377a2312018-09-24 14:52:51 +0200102 EXPECT_GE(acm_->Add10MsData(frame), 0);
103 ++num_10ms_frames;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000104 }
Karl Wiberg377a2312018-09-24 14:52:51 +0200105 return num_10ms_frames;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000106 }
107
Niels Möller87e2d782019-03-07 10:18:23 +0100108 int SendData(AudioFrameType frame_type,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000109 uint8_t payload_type,
110 uint32_t timestamp,
111 const uint8_t* payload_data,
Minyue Liff0e4db2020-01-23 13:45:50 +0100112 size_t payload_len_bytes,
113 int64_t absolute_capture_timestamp_ms) override {
Niels Möllerc936cb62019-03-19 14:10:16 +0100114 if (frame_type == AudioFrameType::kEmptyFrame)
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000115 return 0;
116
Niels Möllerafb5dbb2019-02-15 15:21:47 +0100117 rtp_header_.payloadType = payload_type;
118 rtp_header_.timestamp = timestamp;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000119
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) {
Artem Titovd3251962021-11-15 16:57:07 +0100124 RTC_DCHECK_NOTREACHED();
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000125 return -1;
126 }
Niels Möllerafb5dbb2019-02-15 15:21:47 +0100127 rtp_header_.sequenceNumber++;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000128 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 Lundin84f75692023-02-01 12:07:10 +0000137 acm2::AcmReceiver::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_;
Niels Möllerafb5dbb2019-02-15 15:21:47 +0100140 RTPHeader rtp_header_;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000141 uint32_t timestamp_;
142 bool packet_sent_; // Set when SendData is called reset when inserting audio.
143 uint32_t last_packet_send_timestamp_;
Niels Möller87e2d782019-03-07 10:18:23 +0100144 AudioFrameType last_frame_type_;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000145};
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) {
Alessio Bazzica17887eb2022-11-11 16:52:46 +0100153 const std::map<int, SdpAudioFormat> codecs = {{0, {"OPUS", 48000, 2}}};
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100154 receiver_->SetCodecs(codecs);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000155
Karl Wiberg377a2312018-09-24 14:52:51 +0200156 constexpr int kOutSampleRateHz = 8000; // Different than codec sample rate.
157 for (size_t i = 0; i < codecs.size(); ++i) {
158 const int payload_type = rtc::checked_cast<int>(i);
159 const int num_10ms_frames =
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100160 InsertOnePacketOfSilence(SetEncoder(payload_type, codecs.at(i)));
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000161 for (int k = 0; k < num_10ms_frames; ++k) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200162 AudioFrame frame;
henrik.lundin834a6ea2016-05-13 03:45:24 -0700163 bool muted;
164 EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame, &muted));
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000165 }
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100166 EXPECT_EQ(encoder_factory_->QueryAudioEncoder(codecs.at(i))->sample_rate_hz,
Karl Wiberg377a2312018-09-24 14:52:51 +0200167 receiver_->last_output_sample_rate_hz());
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000168 }
169}
170
henrik.lundin7dc68892016-04-06 01:03:02 -0700171class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi {
172 protected:
173 AcmReceiverTestFaxModeOldApi() {
Henrik Lundin7687ad52018-07-02 10:14:46 +0200174 config_.neteq_config.for_test_no_time_stretching = true;
henrik.lundin7dc68892016-04-06 01:03:02 -0700175 }
176
Karl Wiberg377a2312018-09-24 14:52:51 +0200177 void RunVerifyAudioFrame(const SdpAudioFormat& codec) {
henrik.lundin7dc68892016-04-06 01:03:02 -0700178 // Make sure "fax mode" is enabled. This will avoid delay changes unless the
179 // packet-loss concealment is made. We do this in order to make the
180 // timestamp increments predictable; in normal mode, NetEq may decide to do
181 // accelerate or pre-emptive expand operations after some time, offsetting
182 // the timestamp.
Henrik Lundin7687ad52018-07-02 10:14:46 +0200183 EXPECT_TRUE(config_.neteq_config.for_test_no_time_stretching);
henrik.lundin7dc68892016-04-06 01:03:02 -0700184
Karl Wiberg377a2312018-09-24 14:52:51 +0200185 constexpr int payload_type = 17;
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100186 receiver_->SetCodecs({{payload_type, codec}});
henrik.lundin7dc68892016-04-06 01:03:02 -0700187
Karl Wiberg377a2312018-09-24 14:52:51 +0200188 const AudioCodecInfo info = SetEncoder(payload_type, codec);
189 const int output_sample_rate_hz = info.sample_rate_hz;
190 const size_t output_channels = info.num_channels;
henrik.lundin7dc68892016-04-06 01:03:02 -0700191 const size_t samples_per_ms = rtc::checked_cast<size_t>(
192 rtc::CheckedDivExact(output_sample_rate_hz, 1000));
henrik.lundin7dc68892016-04-06 01:03:02 -0700193 const AudioFrame::VADActivity expected_vad_activity =
194 output_sample_rate_hz > 16000 ? AudioFrame::kVadActive
195 : AudioFrame::kVadPassive;
196
197 // Expect the first output timestamp to be 5*fs/8000 samples before the
198 // first inserted timestamp (because of NetEq's look-ahead). (This value is
199 // defined in Expand::overlap_length_.)
Yves Gerey665174f2018-06-19 15:03:05 +0200200 uint32_t expected_output_ts =
201 last_packet_send_timestamp_ -
henrik.lundin7dc68892016-04-06 01:03:02 -0700202 rtc::CheckedDivExact(5 * output_sample_rate_hz, 8000);
203
204 AudioFrame frame;
henrik.lundin834a6ea2016-05-13 03:45:24 -0700205 bool muted;
206 EXPECT_EQ(0, receiver_->GetAudio(output_sample_rate_hz, &frame, &muted));
henrik.lundin15c51e32016-04-06 08:38:56 -0700207 // Expect timestamp = 0 before first packet is inserted.
208 EXPECT_EQ(0u, frame.timestamp_);
henrik.lundin7dc68892016-04-06 01:03:02 -0700209 for (int i = 0; i < 5; ++i) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200210 const int num_10ms_frames = InsertOnePacketOfSilence(info);
henrik.lundin7dc68892016-04-06 01:03:02 -0700211 for (int k = 0; k < num_10ms_frames; ++k) {
henrik.lundin834a6ea2016-05-13 03:45:24 -0700212 EXPECT_EQ(0,
213 receiver_->GetAudio(output_sample_rate_hz, &frame, &muted));
henrik.lundin7dc68892016-04-06 01:03:02 -0700214 EXPECT_EQ(expected_output_ts, frame.timestamp_);
Mirko Bonadei737e0732017-10-19 09:00:17 +0200215 expected_output_ts += rtc::checked_cast<uint32_t>(10 * samples_per_ms);
henrik.lundin7dc68892016-04-06 01:03:02 -0700216 EXPECT_EQ(10 * samples_per_ms, frame.samples_per_channel_);
217 EXPECT_EQ(output_sample_rate_hz, frame.sample_rate_hz_);
218 EXPECT_EQ(output_channels, frame.num_channels_);
219 EXPECT_EQ(AudioFrame::kNormalSpeech, frame.speech_type_);
220 EXPECT_EQ(expected_vad_activity, frame.vad_activity_);
henrik.lundin834a6ea2016-05-13 03:45:24 -0700221 EXPECT_FALSE(muted);
henrik.lundin7dc68892016-04-06 01:03:02 -0700222 }
223 }
224 }
225};
226
227#if defined(WEBRTC_ANDROID)
228#define MAYBE_VerifyAudioFramePCMU DISABLED_VerifyAudioFramePCMU
229#else
230#define MAYBE_VerifyAudioFramePCMU VerifyAudioFramePCMU
231#endif
232TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFramePCMU) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200233 RunVerifyAudioFrame({"PCMU", 8000, 1});
henrik.lundin7dc68892016-04-06 01:03:02 -0700234}
235
236#if defined(WEBRTC_ANDROID)
henrik.lundin7dc68892016-04-06 01:03:02 -0700237#define MAYBE_VerifyAudioFrameOpus DISABLED_VerifyAudioFrameOpus
238#else
239#define MAYBE_VerifyAudioFrameOpus VerifyAudioFrameOpus
240#endif
241TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameOpus) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200242 RunVerifyAudioFrame({"opus", 48000, 2});
henrik.lundin7dc68892016-04-06 01:03:02 -0700243}
244
Peter Boströme2976c82016-01-04 22:44:05 +0100245#if defined(WEBRTC_ANDROID)
246#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad
247#else
248#define MAYBE_PostdecodingVad PostdecodingVad
249#endif
250TEST_F(AcmReceiverTestOldApi, MAYBE_PostdecodingVad) {
henrik.lundin500c04b2016-03-08 02:36:04 -0800251 EXPECT_TRUE(config_.neteq_config.enable_post_decode_vad);
Karl Wiberg377a2312018-09-24 14:52:51 +0200252 constexpr int payload_type = 34;
253 const SdpAudioFormat codec = {"L16", 16000, 1};
254 const AudioCodecInfo info = SetEncoder(payload_type, codec);
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100255 receiver_->SetCodecs({{payload_type, codec}});
Karl Wiberg377a2312018-09-24 14:52:51 +0200256 constexpr int kNumPackets = 5;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000257 AudioFrame frame;
258 for (int n = 0; n < kNumPackets; ++n) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200259 const int num_10ms_frames = InsertOnePacketOfSilence(info);
henrik.lundin834a6ea2016-05-13 03:45:24 -0700260 for (int k = 0; k < num_10ms_frames; ++k) {
261 bool muted;
Karl Wiberg377a2312018-09-24 14:52:51 +0200262 ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted));
henrik.lundin834a6ea2016-05-13 03:45:24 -0700263 }
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000264 }
265 EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_);
henrik.lundin500c04b2016-03-08 02:36:04 -0800266}
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000267
henrik.lundin500c04b2016-03-08 02:36:04 -0800268class AcmReceiverTestPostDecodeVadPassiveOldApi : public AcmReceiverTestOldApi {
269 protected:
270 AcmReceiverTestPostDecodeVadPassiveOldApi() {
271 config_.neteq_config.enable_post_decode_vad = false;
272 }
273};
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000274
henrik.lundin500c04b2016-03-08 02:36:04 -0800275#if defined(WEBRTC_ANDROID)
276#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad
277#else
278#define MAYBE_PostdecodingVad PostdecodingVad
279#endif
280TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) {
281 EXPECT_FALSE(config_.neteq_config.enable_post_decode_vad);
Karl Wiberg377a2312018-09-24 14:52:51 +0200282 constexpr int payload_type = 34;
283 const SdpAudioFormat codec = {"L16", 16000, 1};
284 const AudioCodecInfo info = SetEncoder(payload_type, codec);
Jerome Humbert3e3c5512020-01-13 11:58:26 +0000285 auto const value = encoder_factory_->QueryAudioEncoder(codec);
286 ASSERT_TRUE(value.has_value());
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100287 receiver_->SetCodecs({{payload_type, codec}});
henrik.lundin500c04b2016-03-08 02:36:04 -0800288 const int kNumPackets = 5;
henrik.lundin500c04b2016-03-08 02:36:04 -0800289 AudioFrame frame;
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000290 for (int n = 0; n < kNumPackets; ++n) {
Karl Wiberg377a2312018-09-24 14:52:51 +0200291 const int num_10ms_frames = InsertOnePacketOfSilence(info);
henrik.lundin834a6ea2016-05-13 03:45:24 -0700292 for (int k = 0; k < num_10ms_frames; ++k) {
293 bool muted;
Karl Wiberg377a2312018-09-24 14:52:51 +0200294 ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted));
henrik.lundin834a6ea2016-05-13 03:45:24 -0700295 }
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000296 }
297 EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_);
298}
299
Peter Boströme2976c82016-01-04 22:44:05 +0100300#if defined(WEBRTC_ANDROID)
301#define MAYBE_LastAudioCodec DISABLED_LastAudioCodec
kwiberg98ab3a42015-09-30 21:54:21 -0700302#else
Peter Boströme2976c82016-01-04 22:44:05 +0100303#define MAYBE_LastAudioCodec LastAudioCodec
kwiberg98ab3a42015-09-30 21:54:21 -0700304#endif
Alessio Bazzica17887eb2022-11-11 16:52:46 +0100305#if defined(WEBRTC_CODEC_OPUS)
Peter Boströme2976c82016-01-04 22:44:05 +0100306TEST_F(AcmReceiverTestOldApi, MAYBE_LastAudioCodec) {
Alessio Bazzica17887eb2022-11-11 16:52:46 +0100307 const std::map<int, SdpAudioFormat> codecs = {
308 {0, {"PCMU", 8000, 1}}, {1, {"PCMA", 8000, 1}}, {2, {"L16", 32000, 1}}};
Jonas Olssona4d87372019-07-05 19:08:33 +0200309 const std::map<int, int> cng_payload_types = {
310 {8000, 100}, {16000, 101}, {32000, 102}};
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100311 {
312 std::map<int, SdpAudioFormat> receive_codecs = codecs;
313 for (const auto& cng_type : cng_payload_types) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200314 receive_codecs.emplace(std::make_pair(
315 cng_type.second, SdpAudioFormat("CN", cng_type.first, 1)));
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100316 }
317 receiver_->SetCodecs(receive_codecs);
Karl Wiberg377a2312018-09-24 14:52:51 +0200318 }
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000319
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000320 // No audio payload is received.
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100321 EXPECT_EQ(absl::nullopt, receiver_->LastDecoder());
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000322
323 // Start with sending DTX.
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000324 packet_sent_ = false;
Karl Wiberg377a2312018-09-24 14:52:51 +0200325 InsertOnePacketOfSilence(
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100326 SetEncoder(0, codecs.at(0), cng_payload_types)); // Enough to test
Jonas Olssona4d87372019-07-05 19:08:33 +0200327 // with one codec.
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000328 ASSERT_TRUE(packet_sent_);
Niels Möllerc936cb62019-03-19 14:10:16 +0100329 EXPECT_EQ(AudioFrameType::kAudioFrameCN, last_frame_type_);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000330
331 // Has received, only, DTX. Last Audio codec is undefined.
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100332 EXPECT_EQ(absl::nullopt, receiver_->LastDecoder());
333 EXPECT_EQ(absl::nullopt, receiver_->last_packet_sample_rate_hz());
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000334
Karl Wiberg377a2312018-09-24 14:52:51 +0200335 for (size_t i = 0; i < codecs.size(); ++i) {
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000336 // Set DTX off to send audio payload.
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000337 packet_sent_ = false;
Karl Wiberg377a2312018-09-24 14:52:51 +0200338 const int payload_type = rtc::checked_cast<int>(i);
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100339 const AudioCodecInfo info_without_cng =
340 SetEncoder(payload_type, codecs.at(i));
Karl Wiberg377a2312018-09-24 14:52:51 +0200341 InsertOnePacketOfSilence(info_without_cng);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000342
343 // Sanity check if Actually an audio payload received, and it should be
344 // of type "speech."
345 ASSERT_TRUE(packet_sent_);
Niels Möllerc936cb62019-03-19 14:10:16 +0100346 ASSERT_EQ(AudioFrameType::kAudioFrameSpeech, last_frame_type_);
Karl Wiberg377a2312018-09-24 14:52:51 +0200347 EXPECT_EQ(info_without_cng.sample_rate_hz,
348 receiver_->last_packet_sample_rate_hz());
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000349
350 // Set VAD on to send DTX. Then check if the "Last Audio codec" returns
Karl Wiberg377a2312018-09-24 14:52:51 +0200351 // the expected codec. Encode repeatedly until a DTX is sent.
352 const AudioCodecInfo info_with_cng =
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100353 SetEncoder(payload_type, codecs.at(i), cng_payload_types);
Niels Möllerc936cb62019-03-19 14:10:16 +0100354 while (last_frame_type_ != AudioFrameType::kAudioFrameCN) {
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000355 packet_sent_ = false;
Karl Wiberg377a2312018-09-24 14:52:51 +0200356 InsertOnePacketOfSilence(info_with_cng);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000357 ASSERT_TRUE(packet_sent_);
358 }
Karl Wiberg377a2312018-09-24 14:52:51 +0200359 EXPECT_EQ(info_with_cng.sample_rate_hz,
360 receiver_->last_packet_sample_rate_hz());
Fredrik Solenbergf693bfa2018-12-11 12:22:10 +0100361 EXPECT_EQ(codecs.at(i), receiver_->LastDecoder()->second);
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000362 }
363}
Peter Boströme2976c82016-01-04 22:44:05 +0100364#endif
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000365
Niels Möller32472442019-09-04 10:14:51 +0200366// Check if the statistics are initialized correctly. Before any call to ACM
367// all fields have to be zero.
368#if defined(WEBRTC_ANDROID)
369#define MAYBE_InitializedToZero DISABLED_InitializedToZero
370#else
371#define MAYBE_InitializedToZero InitializedToZero
372#endif
373TEST_F(AcmReceiverTestOldApi, MAYBE_InitializedToZero) {
374 AudioDecodingCallStats stats;
375 receiver_->GetDecodingCallStatistics(&stats);
376 EXPECT_EQ(0, stats.calls_to_neteq);
377 EXPECT_EQ(0, stats.calls_to_silence_generator);
378 EXPECT_EQ(0, stats.decoded_normal);
379 EXPECT_EQ(0, stats.decoded_cng);
380 EXPECT_EQ(0, stats.decoded_neteq_plc);
381 EXPECT_EQ(0, stats.decoded_plc_cng);
382 EXPECT_EQ(0, stats.decoded_muted_output);
383}
384
Henrik Lundin84f75692023-02-01 12:07:10 +0000385#if defined(WEBRTC_ANDROID)
386#define MAYBE_VerifyOutputFrame DISABLED_VerifyOutputFrame
387#else
388#define MAYBE_VerifyOutputFrame VerifyOutputFrame
389#endif
390TEST_F(AcmReceiverTestOldApi, MAYBE_VerifyOutputFrame) {
391 AudioFrame audio_frame;
392 const int kSampleRateHz = 32000;
393 bool muted;
394 EXPECT_EQ(0, receiver_->GetAudio(kSampleRateHz, &audio_frame, &muted));
395 ASSERT_FALSE(muted);
396 EXPECT_EQ(0u, audio_frame.timestamp_);
397 EXPECT_GT(audio_frame.num_channels_, 0u);
398 EXPECT_EQ(static_cast<size_t>(kSampleRateHz / 100),
399 audio_frame.samples_per_channel_);
400 EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_);
401}
402
Niels Möller32472442019-09-04 10:14:51 +0200403// Insert some packets and pull audio. Check statistics are valid. Then,
404// simulate packet loss and check if PLC and PLC-to-CNG statistics are
405// correctly updated.
406#if defined(WEBRTC_ANDROID)
407#define MAYBE_NetEqCalls DISABLED_NetEqCalls
408#else
409#define MAYBE_NetEqCalls NetEqCalls
410#endif
411TEST_F(AcmReceiverTestOldApi, MAYBE_NetEqCalls) {
412 AudioDecodingCallStats stats;
413 const int kNumNormalCalls = 10;
414 const int kSampleRateHz = 16000;
415 const int kNumSamples10ms = kSampleRateHz / 100;
416 const int kFrameSizeMs = 10; // Multiple of 10.
417 const int kFrameSizeSamples = kFrameSizeMs / 10 * kNumSamples10ms;
418 const int kPayloadSizeBytes = kFrameSizeSamples * sizeof(int16_t);
419 const uint8_t kPayloadType = 111;
420 RTPHeader rtp_header;
421 AudioFrame audio_frame;
422 bool muted;
423
424 receiver_->SetCodecs(
425 {{kPayloadType, SdpAudioFormat("L16", kSampleRateHz, 1)}});
426 rtp_header.sequenceNumber = 0xABCD;
427 rtp_header.timestamp = 0xABCDEF01;
428 rtp_header.payloadType = kPayloadType;
429 rtp_header.markerBit = false;
430 rtp_header.ssrc = 0x1234;
431 rtp_header.numCSRCs = 0;
432 rtp_header.payload_type_frequency = kSampleRateHz;
433
434 for (int num_calls = 0; num_calls < kNumNormalCalls; ++num_calls) {
435 const uint8_t kPayload[kPayloadSizeBytes] = {0};
436 ASSERT_EQ(0, receiver_->InsertPacket(rtp_header, kPayload));
437 ++rtp_header.sequenceNumber;
438 rtp_header.timestamp += kFrameSizeSamples;
439 ASSERT_EQ(0, receiver_->GetAudio(-1, &audio_frame, &muted));
440 EXPECT_FALSE(muted);
441 }
442 receiver_->GetDecodingCallStatistics(&stats);
443 EXPECT_EQ(kNumNormalCalls, stats.calls_to_neteq);
444 EXPECT_EQ(0, stats.calls_to_silence_generator);
445 EXPECT_EQ(kNumNormalCalls, stats.decoded_normal);
446 EXPECT_EQ(0, stats.decoded_cng);
447 EXPECT_EQ(0, stats.decoded_neteq_plc);
448 EXPECT_EQ(0, stats.decoded_plc_cng);
449 EXPECT_EQ(0, stats.decoded_muted_output);
450
451 const int kNumPlc = 3;
452 const int kNumPlcCng = 5;
453
454 // Simulate packet-loss. NetEq first performs PLC then PLC fades to CNG.
455 for (int n = 0; n < kNumPlc + kNumPlcCng; ++n) {
456 ASSERT_EQ(0, receiver_->GetAudio(-1, &audio_frame, &muted));
457 EXPECT_FALSE(muted);
458 }
459 receiver_->GetDecodingCallStatistics(&stats);
460 EXPECT_EQ(kNumNormalCalls + kNumPlc + kNumPlcCng, stats.calls_to_neteq);
461 EXPECT_EQ(0, stats.calls_to_silence_generator);
462 EXPECT_EQ(kNumNormalCalls, stats.decoded_normal);
463 EXPECT_EQ(0, stats.decoded_cng);
464 EXPECT_EQ(kNumPlc, stats.decoded_neteq_plc);
465 EXPECT_EQ(kNumPlcCng, stats.decoded_plc_cng);
466 EXPECT_EQ(0, stats.decoded_muted_output);
467 // TODO(henrik.lundin) Add a test with muted state enabled.
468}
469
andresp@webrtc.org4f6f22f2014-09-23 11:37:57 +0000470} // namespace acm2
471
472} // namespace webrtc