blob: ce2be656ef48a8ff76d1c127edc302f5a84577f6 [file] [log] [blame]
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001/*
2 * Copyright (c) 2012 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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/audio_coding/neteq/neteq_impl.h"
12
kwiberg84be5112016-04-27 01:19:58 -070013#include <memory>
Alessio Bazzica8f319a32019-07-24 16:47:02 +000014#include <utility>
15#include <vector>
kwiberg84be5112016-04-27 01:19:58 -070016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Ivo Creusen3ce44a32019-10-31 14:38:11 +010018#include "api/neteq/default_neteq_controller_factory.h"
19#include "api/neteq/neteq.h"
20#include "api/neteq/neteq_controller.h"
Ivo Creusen500d6e72021-11-24 12:32:07 +000021#include "modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "modules/audio_coding/neteq/accelerate.h"
Ivo Creusen53a31f72019-10-24 15:20:39 +020023#include "modules/audio_coding/neteq/decision_logic.h"
Ivo Creusen39cf3c72019-11-28 14:07:14 +010024#include "modules/audio_coding/neteq/default_neteq_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "modules/audio_coding/neteq/expand.h"
Jakob Ivarsson1eb3d7e2019-02-21 15:42:31 +010026#include "modules/audio_coding/neteq/histogram.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "modules/audio_coding/neteq/mock/mock_dtmf_buffer.h"
29#include "modules/audio_coding/neteq/mock/mock_dtmf_tone_generator.h"
Ivo Creusen53a31f72019-10-24 15:20:39 +020030#include "modules/audio_coding/neteq/mock/mock_neteq_controller.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "modules/audio_coding/neteq/mock/mock_packet_buffer.h"
32#include "modules/audio_coding/neteq/mock/mock_red_payload_splitter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "modules/audio_coding/neteq/preemptive_expand.h"
Jakob Ivarsson44507082019-03-05 16:59:03 +010034#include "modules/audio_coding/neteq/statistics_calculator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020035#include "modules/audio_coding/neteq/sync_buffer.h"
36#include "modules/audio_coding/neteq/timestamp_scaler.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010037#include "rtc_base/numerics/safe_conversions.h"
Alessio Bazzica8f319a32019-07-24 16:47:02 +000038#include "system_wrappers/include/clock.h"
Niels Möllerb7180c02018-12-06 13:07:11 +010039#include "test/audio_decoder_proxy_factory.h"
Niels Möllera0f44302018-11-30 10:45:12 +010040#include "test/function_audio_decoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "test/gmock.h"
42#include "test/gtest.h"
43#include "test/mock_audio_decoder.h"
44#include "test/mock_audio_decoder_factory.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000045
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000046using ::testing::_;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010047using ::testing::AtLeast;
48using ::testing::DoAll;
Alessio Bazzica8f319a32019-07-24 16:47:02 +000049using ::testing::ElementsAre;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000050using ::testing::InSequence;
51using ::testing::Invoke;
Alessio Bazzica8f319a32019-07-24 16:47:02 +000052using ::testing::IsEmpty;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +000053using ::testing::IsNull;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010054using ::testing::Pointee;
55using ::testing::Return;
56using ::testing::ReturnNull;
57using ::testing::SetArgPointee;
58using ::testing::SetArrayArgument;
Alessio Bazzica8f319a32019-07-24 16:47:02 +000059using ::testing::SizeIs;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010060using ::testing::WithArg;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000061
62namespace webrtc {
63
64// This function is called when inserting a packet list into the mock packet
65// buffer. The purpose is to delete all inserted packets properly, to avoid
66// memory leaks in the test.
67int DeletePacketsAndReturnOk(PacketList* packet_list) {
ossua73f6c92016-10-24 08:25:28 -070068 packet_list->clear();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000069 return PacketBuffer::kOK;
70}
71
72class NetEqImplTest : public ::testing::Test {
73 protected:
Alessio Bazzica8f319a32019-07-24 16:47:02 +000074 NetEqImplTest() : clock_(0) { config_.sample_rate_hz = 8000; }
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000075
Niels Möllera0f44302018-11-30 10:45:12 +010076 void CreateInstance(
77 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) {
78 ASSERT_TRUE(decoder_factory);
Ivo Creusen500d6e72021-11-24 12:32:07 +000079 config_.enable_muted_state = enable_muted_state_;
Ivo Creusen3ce44a32019-10-31 14:38:11 +010080 NetEqImpl::Dependencies deps(config_, &clock_, decoder_factory,
81 DefaultNetEqControllerFactory());
henrik.lundin1d9061e2016-04-26 12:19:34 -070082
83 // Get a local pointer to NetEq's TickTimer object.
84 tick_timer_ = deps.tick_timer.get();
85
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000086 if (use_mock_decoder_database_) {
henrik.lundin1d9061e2016-04-26 12:19:34 -070087 std::unique_ptr<MockDecoderDatabase> mock(new MockDecoderDatabase);
88 mock_decoder_database_ = mock.get();
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000089 EXPECT_CALL(*mock_decoder_database_, GetActiveCngDecoder())
90 .WillOnce(ReturnNull());
henrik.lundin1d9061e2016-04-26 12:19:34 -070091 deps.decoder_database = std::move(mock);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000092 }
henrik.lundin1d9061e2016-04-26 12:19:34 -070093 decoder_database_ = deps.decoder_database.get();
henrik.lundin@webrtc.orgd9faa462014-01-14 10:18:45 +000094
henrik.lundin1d9061e2016-04-26 12:19:34 -070095 if (use_mock_dtmf_buffer_) {
96 std::unique_ptr<MockDtmfBuffer> mock(
97 new MockDtmfBuffer(config_.sample_rate_hz));
98 mock_dtmf_buffer_ = mock.get();
99 deps.dtmf_buffer = std::move(mock);
100 }
101 dtmf_buffer_ = deps.dtmf_buffer.get();
102
103 if (use_mock_dtmf_tone_generator_) {
104 std::unique_ptr<MockDtmfToneGenerator> mock(new MockDtmfToneGenerator);
105 mock_dtmf_tone_generator_ = mock.get();
106 deps.dtmf_tone_generator = std::move(mock);
107 }
108 dtmf_tone_generator_ = deps.dtmf_tone_generator.get();
109
110 if (use_mock_packet_buffer_) {
111 std::unique_ptr<MockPacketBuffer> mock(
112 new MockPacketBuffer(config_.max_packets_in_buffer, tick_timer_));
113 mock_packet_buffer_ = mock.get();
114 deps.packet_buffer = std::move(mock);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700115 }
116 packet_buffer_ = deps.packet_buffer.get();
117
Ivo Creusen53a31f72019-10-24 15:20:39 +0200118 if (use_mock_neteq_controller_) {
119 std::unique_ptr<MockNetEqController> mock(new MockNetEqController());
120 mock_neteq_controller_ = mock.get();
121 deps.neteq_controller = std::move(mock);
122 } else {
123 deps.stats = std::make_unique<StatisticsCalculator>();
124 NetEqController::Config controller_config;
125 controller_config.tick_timer = tick_timer_;
126 controller_config.base_min_delay_ms = config_.min_delay_ms;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200127 controller_config.allow_time_stretching = true;
128 controller_config.max_packets_in_buffer = config_.max_packets_in_buffer;
Ivo Creusen88636c62020-01-24 11:04:56 +0100129 controller_config.clock = &clock_;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200130 deps.neteq_controller =
131 std::make_unique<DecisionLogic>(std::move(controller_config));
132 }
133 neteq_controller_ = deps.neteq_controller.get();
134
henrik.lundin1d9061e2016-04-26 12:19:34 -0700135 if (use_mock_payload_splitter_) {
ossua70695a2016-09-22 02:06:28 -0700136 std::unique_ptr<MockRedPayloadSplitter> mock(new MockRedPayloadSplitter);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700137 mock_payload_splitter_ = mock.get();
ossua70695a2016-09-22 02:06:28 -0700138 deps.red_payload_splitter = std::move(mock);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700139 }
ossua70695a2016-09-22 02:06:28 -0700140 red_payload_splitter_ = deps.red_payload_splitter.get();
henrik.lundin1d9061e2016-04-26 12:19:34 -0700141
142 deps.timestamp_scaler = std::unique_ptr<TimestampScaler>(
143 new TimestampScaler(*deps.decoder_database.get()));
144
145 neteq_.reset(new NetEqImpl(config_, std::move(deps)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000146 ASSERT_TRUE(neteq_ != NULL);
147 }
148
Niels Möllera0f44302018-11-30 10:45:12 +0100149 void CreateInstance() { CreateInstance(CreateBuiltinAudioDecoderFactory()); }
150
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000151 void UseNoMocks() {
152 ASSERT_TRUE(neteq_ == NULL) << "Must call UseNoMocks before CreateInstance";
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000153 use_mock_decoder_database_ = false;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200154 use_mock_neteq_controller_ = false;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000155 use_mock_dtmf_buffer_ = false;
156 use_mock_dtmf_tone_generator_ = false;
157 use_mock_packet_buffer_ = false;
158 use_mock_payload_splitter_ = false;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000159 }
160
161 virtual ~NetEqImplTest() {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000162 if (use_mock_decoder_database_) {
163 EXPECT_CALL(*mock_decoder_database_, Die()).Times(1);
164 }
Ivo Creusen53a31f72019-10-24 15:20:39 +0200165 if (use_mock_neteq_controller_) {
166 EXPECT_CALL(*mock_neteq_controller_, Die()).Times(1);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000167 }
168 if (use_mock_dtmf_buffer_) {
169 EXPECT_CALL(*mock_dtmf_buffer_, Die()).Times(1);
170 }
171 if (use_mock_dtmf_tone_generator_) {
172 EXPECT_CALL(*mock_dtmf_tone_generator_, Die()).Times(1);
173 }
174 if (use_mock_packet_buffer_) {
175 EXPECT_CALL(*mock_packet_buffer_, Die()).Times(1);
176 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000177 }
178
Niels Möller05543682019-01-10 16:55:06 +0100179 void TestDtmfPacket(int sample_rate_hz) {
solenberg2779bab2016-11-17 04:45:19 -0800180 const size_t kPayloadLength = 4;
181 const uint8_t kPayloadType = 110;
solenberg2779bab2016-11-17 04:45:19 -0800182 const int kSampleRateHz = 16000;
183 config_.sample_rate_hz = kSampleRateHz;
184 UseNoMocks();
185 CreateInstance();
186 // Event: 2, E bit, Volume: 17, Length: 4336.
Jonas Olssona4d87372019-07-05 19:08:33 +0200187 uint8_t payload[kPayloadLength] = {0x02, 0x80 + 0x11, 0x10, 0xF0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700188 RTPHeader rtp_header;
189 rtp_header.payloadType = kPayloadType;
190 rtp_header.sequenceNumber = 0x1234;
191 rtp_header.timestamp = 0x12345678;
192 rtp_header.ssrc = 0x87654321;
solenberg2779bab2016-11-17 04:45:19 -0800193
Niels Möller05543682019-01-10 16:55:06 +0100194 EXPECT_TRUE(neteq_->RegisterPayloadType(
195 kPayloadType, SdpAudioFormat("telephone-event", sample_rate_hz, 1)));
solenberg2779bab2016-11-17 04:45:19 -0800196
197 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200198 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
solenberg2779bab2016-11-17 04:45:19 -0800199
200 // Pull audio once.
201 const size_t kMaxOutputSize =
202 static_cast<size_t>(10 * kSampleRateHz / 1000);
203 AudioFrame output;
204 bool muted;
205 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
206 ASSERT_FALSE(muted);
207 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
208 EXPECT_EQ(1u, output.num_channels_);
209 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
210
Artem Titovd00ce742021-07-28 20:00:17 +0200211 // DTMF packets are immediately consumed by `InsertPacket()` and won't be
212 // returned by `GetAudio()`.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000213 EXPECT_THAT(output.packet_infos_, IsEmpty());
214
solenberg2779bab2016-11-17 04:45:19 -0800215 // Verify first 64 samples of actual output.
Jonas Olssona4d87372019-07-05 19:08:33 +0200216 const std::vector<int16_t> kOutput(
217 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 -1578, -2816, -3460, -3403, -2709, -1594, -363, 671, 1269, 1328,
219 908, 202, -513, -964, -955, -431, 504, 1617, 2602, 3164,
220 3101, 2364, 1073, -511, -2047, -3198, -3721, -3525, -2688, -1440,
221 -99, 1015, 1663, 1744, 1319, 588, -171, -680, -747, -315,
222 515, 1512, 2378, 2828, 2674, 1877, 568, -986, -2446, -3482,
223 -3864, -3516, -2534, -1163});
solenberg2779bab2016-11-17 04:45:19 -0800224 ASSERT_GE(kMaxOutputSize, kOutput.size());
yujo36b1a5f2017-06-12 12:45:32 -0700225 EXPECT_TRUE(std::equal(kOutput.begin(), kOutput.end(), output.data()));
solenberg2779bab2016-11-17 04:45:19 -0800226 }
227
henrik.lundin1d9061e2016-04-26 12:19:34 -0700228 std::unique_ptr<NetEqImpl> neteq_;
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000229 NetEq::Config config_;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000230 SimulatedClock clock_;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700231 TickTimer* tick_timer_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700232 MockDecoderDatabase* mock_decoder_database_ = nullptr;
233 DecoderDatabase* decoder_database_ = nullptr;
234 bool use_mock_decoder_database_ = true;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200235 MockNetEqController* mock_neteq_controller_ = nullptr;
236 NetEqController* neteq_controller_ = nullptr;
237 bool use_mock_neteq_controller_ = true;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700238 MockDtmfBuffer* mock_dtmf_buffer_ = nullptr;
239 DtmfBuffer* dtmf_buffer_ = nullptr;
240 bool use_mock_dtmf_buffer_ = true;
241 MockDtmfToneGenerator* mock_dtmf_tone_generator_ = nullptr;
242 DtmfToneGenerator* dtmf_tone_generator_ = nullptr;
243 bool use_mock_dtmf_tone_generator_ = true;
244 MockPacketBuffer* mock_packet_buffer_ = nullptr;
245 PacketBuffer* packet_buffer_ = nullptr;
246 bool use_mock_packet_buffer_ = true;
ossua70695a2016-09-22 02:06:28 -0700247 MockRedPayloadSplitter* mock_payload_splitter_ = nullptr;
248 RedPayloadSplitter* red_payload_splitter_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700249 bool use_mock_payload_splitter_ = true;
Ivo Creusen500d6e72021-11-24 12:32:07 +0000250 bool enable_muted_state_ = false;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000251};
252
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000253// This tests the interface class NetEq.
254// TODO(hlundin): Move to separate file?
255TEST(NetEq, CreateAndDestroy) {
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000256 NetEq::Config config;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000257 SimulatedClock clock(0);
Ivo Creusen39cf3c72019-11-28 14:07:14 +0100258 auto decoder_factory = CreateBuiltinAudioDecoderFactory();
259 std::unique_ptr<NetEq> neteq =
260 DefaultNetEqFactory().CreateNetEq(config, decoder_factory, &clock);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000261}
262
kwiberg5adaf732016-10-04 09:33:27 -0700263TEST_F(NetEqImplTest, RegisterPayloadType) {
264 CreateInstance();
265 constexpr int rtp_payload_type = 0;
266 const SdpAudioFormat format("pcmu", 8000, 1);
267 EXPECT_CALL(*mock_decoder_database_,
268 RegisterPayload(rtp_payload_type, format));
269 neteq_->RegisterPayloadType(rtp_payload_type, format);
270}
271
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000272TEST_F(NetEqImplTest, RemovePayloadType) {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000273 CreateInstance();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000274 uint8_t rtp_payload_type = 0;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000275 EXPECT_CALL(*mock_decoder_database_, Remove(rtp_payload_type))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000276 .WillOnce(Return(DecoderDatabase::kDecoderNotFound));
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200277 // Check that kOK is returned when database returns kDecoderNotFound, because
278 // removing a payload type that was never registered is not an error.
279 EXPECT_EQ(NetEq::kOK, neteq_->RemovePayloadType(rtp_payload_type));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000280}
281
kwiberg6b19b562016-09-20 04:02:25 -0700282TEST_F(NetEqImplTest, RemoveAllPayloadTypes) {
283 CreateInstance();
284 EXPECT_CALL(*mock_decoder_database_, RemoveAll()).WillOnce(Return());
285 neteq_->RemoveAllPayloadTypes();
286}
287
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000288TEST_F(NetEqImplTest, InsertPacket) {
Ivo Creusena2b31c32020-10-14 17:54:22 +0200289 using ::testing::AllOf;
290 using ::testing::Field;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000291 CreateInstance();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000292 const size_t kPayloadLength = 100;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000293 const uint8_t kPayloadType = 0;
294 const uint16_t kFirstSequenceNumber = 0x1234;
295 const uint32_t kFirstTimestamp = 0x12345678;
296 const uint32_t kSsrc = 0x87654321;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000297 uint8_t payload[kPayloadLength] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700298 RTPHeader rtp_header;
299 rtp_header.payloadType = kPayloadType;
300 rtp_header.sequenceNumber = kFirstSequenceNumber;
301 rtp_header.timestamp = kFirstTimestamp;
302 rtp_header.ssrc = kSsrc;
ossu7a377612016-10-18 04:06:13 -0700303 Packet fake_packet;
304 fake_packet.payload_type = kPayloadType;
305 fake_packet.sequence_number = kFirstSequenceNumber;
306 fake_packet.timestamp = kFirstTimestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000307
Tommi87f70902021-04-27 14:43:08 +0200308 auto mock_decoder_factory = rtc::make_ref_counted<MockAudioDecoderFactory>();
Karl Wibergd6fbf2a2018-02-27 13:37:31 +0100309 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _, _))
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800310 .WillOnce(Invoke([&](const SdpAudioFormat& format,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200311 absl::optional<AudioCodecPairId> codec_pair_id,
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800312 std::unique_ptr<AudioDecoder>* dec) {
kwibergc0f2dcf2016-05-31 06:28:03 -0700313 EXPECT_EQ("pcmu", format.name);
314
315 std::unique_ptr<MockAudioDecoder> mock_decoder(new MockAudioDecoder);
316 EXPECT_CALL(*mock_decoder, Channels()).WillRepeatedly(Return(1));
317 EXPECT_CALL(*mock_decoder, SampleRateHz()).WillRepeatedly(Return(8000));
kwibergc0f2dcf2016-05-31 06:28:03 -0700318 EXPECT_CALL(*mock_decoder, Die()).Times(1); // Called when deleted.
319
320 *dec = std::move(mock_decoder);
321 }));
Niels Möller72899062019-01-11 09:36:13 +0100322 DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Niels Möllerc7b69022022-04-21 15:06:35 +0200323 absl::nullopt, mock_decoder_factory.get());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000324
325 // Expectations for decoder database.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000326 EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000327 .WillRepeatedly(Return(&info));
328
329 // Expectations for packet buffer.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000330 EXPECT_CALL(*mock_packet_buffer_, Empty())
331 .WillOnce(Return(false)); // Called once after first packet is inserted.
Ivo Creusen7b463c52020-11-25 11:32:40 +0100332 EXPECT_CALL(*mock_packet_buffer_, Flush(_)).Times(1);
333 EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _, _, _, _, _))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000334 .Times(2)
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100335 .WillRepeatedly(DoAll(SetArgPointee<2>(kPayloadType),
336 WithArg<0>(Invoke(DeletePacketsAndReturnOk))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000337 // SetArgPointee<2>(kPayloadType) means that the third argument (zero-based
338 // index) is a pointer, and the variable pointed to is set to kPayloadType.
339 // Also invoke the function DeletePacketsAndReturnOk to properly delete all
340 // packets in the list (to avoid memory leaks in the test).
ossu7a377612016-10-18 04:06:13 -0700341 EXPECT_CALL(*mock_packet_buffer_, PeekNextPacket())
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000342 .Times(1)
ossu7a377612016-10-18 04:06:13 -0700343 .WillOnce(Return(&fake_packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000344
345 // Expectations for DTMF buffer.
Jonas Olssona4d87372019-07-05 19:08:33 +0200346 EXPECT_CALL(*mock_dtmf_buffer_, Flush()).Times(1);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000347
348 // Expectations for delay manager.
349 {
350 // All expectations within this block must be called in this specific order.
351 InSequence sequence; // Dummy variable.
352 // Expectations when the first packet is inserted.
Ivo Creusena2b31c32020-10-14 17:54:22 +0200353 EXPECT_CALL(
354 *mock_neteq_controller_,
355 PacketArrived(
356 /*fs_hz*/ 8000,
357 /*should_update_stats*/ _,
358 /*info*/
359 AllOf(
360 Field(&NetEqController::PacketArrivedInfo::is_cng_or_dtmf,
361 false),
362 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
363 kFirstSequenceNumber),
364 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
365 kFirstTimestamp))));
366 EXPECT_CALL(
367 *mock_neteq_controller_,
368 PacketArrived(
369 /*fs_hz*/ 8000,
370 /*should_update_stats*/ _,
371 /*info*/
372 AllOf(
373 Field(&NetEqController::PacketArrivedInfo::is_cng_or_dtmf,
374 false),
375 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
376 kFirstSequenceNumber + 1),
377 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
378 kFirstTimestamp + 160))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000379 }
380
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000381 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200382 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000383
384 // Insert second packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700385 rtp_header.timestamp += 160;
386 rtp_header.sequenceNumber += 1;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200387 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000388}
389
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000390TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
391 UseNoMocks();
392 CreateInstance();
393
394 const int kPayloadLengthSamples = 80;
395 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
Jonas Olssona4d87372019-07-05 19:08:33 +0200396 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000397 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700398 RTPHeader rtp_header;
399 rtp_header.payloadType = kPayloadType;
400 rtp_header.sequenceNumber = 0x1234;
401 rtp_header.timestamp = 0x12345678;
402 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000403
Niels Möller05543682019-01-10 16:55:06 +0100404 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
405 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000406
407 // Insert packets. The buffer should not flush.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700408 for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) {
Karl Wiberg45eb1352019-10-10 14:23:00 +0200409 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700410 rtp_header.timestamp += kPayloadLengthSamples;
411 rtp_header.sequenceNumber += 1;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000412 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
413 }
414
415 // Insert one more packet and make sure the buffer got flushed. That is, it
416 // should only hold one single packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200417 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700418 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700419 const Packet* test_packet = packet_buffer_->PeekNextPacket();
henrik.lundin246ef3e2017-04-24 09:14:32 -0700420 EXPECT_EQ(rtp_header.timestamp, test_packet->timestamp);
421 EXPECT_EQ(rtp_header.sequenceNumber, test_packet->sequence_number);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000422}
423
solenberg2779bab2016-11-17 04:45:19 -0800424TEST_F(NetEqImplTest, TestDtmfPacketAVT) {
Niels Möller05543682019-01-10 16:55:06 +0100425 TestDtmfPacket(8000);
solenberg2779bab2016-11-17 04:45:19 -0800426}
solenberg99df6c02016-10-11 04:35:34 -0700427
solenberg2779bab2016-11-17 04:45:19 -0800428TEST_F(NetEqImplTest, TestDtmfPacketAVT16kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100429 TestDtmfPacket(16000);
solenberg2779bab2016-11-17 04:45:19 -0800430}
solenberg99df6c02016-10-11 04:35:34 -0700431
solenberg2779bab2016-11-17 04:45:19 -0800432TEST_F(NetEqImplTest, TestDtmfPacketAVT32kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100433 TestDtmfPacket(32000);
solenberg2779bab2016-11-17 04:45:19 -0800434}
solenberg99df6c02016-10-11 04:35:34 -0700435
solenberg2779bab2016-11-17 04:45:19 -0800436TEST_F(NetEqImplTest, TestDtmfPacketAVT48kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100437 TestDtmfPacket(48000);
solenberg99df6c02016-10-11 04:35:34 -0700438}
439
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000440// This test verifies that timestamps propagate from the incoming packets
441// through to the sync buffer and to the playout timestamp.
442TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000443 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000444 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700445 const size_t kPayloadLengthSamples =
446 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000447 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
448 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700449 RTPHeader rtp_header;
450 rtp_header.payloadType = kPayloadType;
451 rtp_header.sequenceNumber = 0x1234;
452 rtp_header.timestamp = 0x12345678;
453 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000454 rtp_header.numCSRCs = 3;
455 rtp_header.arrOfCSRCs[0] = 43;
456 rtp_header.arrOfCSRCs[1] = 65;
457 rtp_header.arrOfCSRCs[2] = 17;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000458
459 // This is a dummy decoder that produces as many output samples as the input
460 // has bytes. The output is an increasing series, starting at 1 for the first
461 // sample, and then increasing by 1 for each sample.
462 class CountingSamplesDecoder : public AudioDecoder {
463 public:
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000464 CountingSamplesDecoder() : next_value_(1) {}
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000465
Artem Titovd00ce742021-07-28 20:00:17 +0200466 // Produce as many samples as input bytes (`encoded_len`).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100467 int DecodeInternal(const uint8_t* encoded,
468 size_t encoded_len,
469 int /* sample_rate_hz */,
470 int16_t* decoded,
471 SpeechType* speech_type) override {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000472 for (size_t i = 0; i < encoded_len; ++i) {
473 decoded[i] = next_value_++;
474 }
475 *speech_type = kSpeech;
Mirko Bonadei737e0732017-10-19 09:00:17 +0200476 return rtc::checked_cast<int>(encoded_len);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000477 }
478
Karl Wiberg43766482015-08-27 15:22:11 +0200479 void Reset() override { next_value_ = 1; }
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000480
kwiberg347d3512016-06-16 01:59:09 -0700481 int SampleRateHz() const override { return kSampleRateHz; }
482
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000483 size_t Channels() const override { return 1; }
484
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000485 uint16_t next_value() const { return next_value_; }
486
487 private:
488 int16_t next_value_;
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000489 } decoder_;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000490
Tommi87f70902021-04-27 14:43:08 +0200491 auto decoder_factory =
492 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&decoder_);
Niels Möllerb7180c02018-12-06 13:07:11 +0100493
494 UseNoMocks();
495 CreateInstance(decoder_factory);
496
497 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
Niels Möllera1eb9c72018-12-07 15:24:42 +0100498 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000499
500 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000501 clock_.AdvanceTimeMilliseconds(123456);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200502 Timestamp expected_receive_time = clock_.CurrentTime();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200503 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000504
505 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700506 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800507 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700508 bool muted;
509 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
510 ASSERT_FALSE(muted);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800511 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
512 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800513 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000514
Artem Titovcfea2182021-08-10 01:22:31 +0200515 // Verify `output.packet_infos_`.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000516 ASSERT_THAT(output.packet_infos_, SizeIs(1));
517 {
518 const auto& packet_info = output.packet_infos_[0];
519 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
520 EXPECT_THAT(packet_info.csrcs(), ElementsAre(43, 65, 17));
521 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
522 EXPECT_FALSE(packet_info.audio_level().has_value());
Johannes Kronf7de74c2021-04-30 13:10:56 +0200523 EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000524 }
525
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000526 // Start with a simple check that the fake decoder is behaving as expected.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700527 EXPECT_EQ(kPayloadLengthSamples,
528 static_cast<size_t>(decoder_.next_value() - 1));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000529
530 // The value of the last of the output samples is the same as the number of
531 // samples played from the decoded packet. Thus, this number + the RTP
532 // timestamp should match the playout timestamp.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200533 // Wrap the expected value in an absl::optional to compare them as such.
henrik.lundin9a410dd2016-04-06 01:39:22 -0700534 EXPECT_EQ(
Danil Chapovalovb6021232018-06-19 13:26:36 +0200535 absl::optional<uint32_t>(rtp_header.timestamp +
536 output.data()[output.samples_per_channel_ - 1]),
henrik.lundin9a410dd2016-04-06 01:39:22 -0700537 neteq_->GetPlayoutTimestamp());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000538
539 // Check the timestamp for the last value in the sync buffer. This should
540 // be one full frame length ahead of the RTP timestamp.
541 const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
542 ASSERT_TRUE(sync_buffer != NULL);
henrik.lundin246ef3e2017-04-24 09:14:32 -0700543 EXPECT_EQ(rtp_header.timestamp + kPayloadLengthSamples,
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000544 sync_buffer->end_timestamp());
545
546 // Check that the number of samples still to play from the sync buffer add
547 // up with what was already played out.
henrik.lundin6d8e0112016-03-04 10:34:21 -0800548 EXPECT_EQ(
yujo36b1a5f2017-06-12 12:45:32 -0700549 kPayloadLengthSamples - output.data()[output.samples_per_channel_ - 1],
henrik.lundin6d8e0112016-03-04 10:34:21 -0800550 sync_buffer->FutureLength());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000551}
552
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000553TEST_F(NetEqImplTest, ReorderedPacket) {
554 UseNoMocks();
Minyue Li57d13102021-08-19 14:30:45 +0200555
Niels Möllera1eb9c72018-12-07 15:24:42 +0100556 // Create a mock decoder object.
557 MockAudioDecoder mock_decoder;
558
559 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +0200560 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000561
562 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000563 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700564 const size_t kPayloadLengthSamples =
565 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000566 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
567 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700568 RTPHeader rtp_header;
569 rtp_header.payloadType = kPayloadType;
570 rtp_header.sequenceNumber = 0x1234;
571 rtp_header.timestamp = 0x12345678;
572 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000573 rtp_header.extension.hasAudioLevel = true;
574 rtp_header.extension.audioLevel = 42;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000575
Karl Wiberg43766482015-08-27 15:22:11 +0200576 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700577 EXPECT_CALL(mock_decoder, SampleRateHz())
578 .WillRepeatedly(Return(kSampleRateHz));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000579 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin034154b2016-04-27 06:11:50 -0700580 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeiea7a3f82017-10-19 11:40:55 +0200581 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000582 int16_t dummy_output[kPayloadLengthSamples] = {0};
583 // The below expectation will make the mock decoder write
Artem Titovd00ce742021-07-28 20:00:17 +0200584 // `kPayloadLengthSamples` zeros to the output array, and mark it as speech.
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100585 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
586 kSampleRateHz, _, _))
587 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000588 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100589 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200590 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
Niels Möllera1eb9c72018-12-07 15:24:42 +0100591 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
592 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000593
594 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000595 clock_.AdvanceTimeMilliseconds(123456);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200596 Timestamp expected_receive_time = clock_.CurrentTime();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200597 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000598
599 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700600 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800601 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700602 bool muted;
603 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800604 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
605 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800606 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000607
Artem Titovcfea2182021-08-10 01:22:31 +0200608 // Verify `output.packet_infos_`.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000609 ASSERT_THAT(output.packet_infos_, SizeIs(1));
610 {
611 const auto& packet_info = output.packet_infos_[0];
612 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
613 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
614 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
615 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200616 EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000617 }
618
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000619 // Insert two more packets. The first one is out of order, and is already too
620 // old, the second one is the expected next packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700621 rtp_header.sequenceNumber -= 1;
622 rtp_header.timestamp -= kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000623 rtp_header.extension.audioLevel = 1;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000624 payload[0] = 1;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000625 clock_.AdvanceTimeMilliseconds(1000);
Karl Wiberg45eb1352019-10-10 14:23:00 +0200626 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700627 rtp_header.sequenceNumber += 2;
628 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000629 rtp_header.extension.audioLevel = 2;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000630 payload[0] = 2;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000631 clock_.AdvanceTimeMilliseconds(2000);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200632 expected_receive_time = clock_.CurrentTime();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200633 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000634
635 // Expect only the second packet to be decoded (the one with "2" as the first
636 // payload byte).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100637 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
638 kSampleRateHz, _, _))
639 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000640 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100641 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200642 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000643
644 // Pull audio once.
henrik.lundin7a926812016-05-12 13:51:28 -0700645 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800646 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
647 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800648 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000649
650 // Now check the packet buffer, and make sure it is empty, since the
651 // out-of-order packet should have been discarded.
652 EXPECT_TRUE(packet_buffer_->Empty());
653
Jakob Ivarsson1a5a8132022-05-25 22:00:14 +0200654 // NetEq `packets_discarded` should capture this packet discard.
655 EXPECT_EQ(1u, neteq_->GetLifetimeStatistics().packets_discarded);
Minyue Li57d13102021-08-19 14:30:45 +0200656
Artem Titovcfea2182021-08-10 01:22:31 +0200657 // Verify `output.packet_infos_`. Expect to only see the second packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000658 ASSERT_THAT(output.packet_infos_, SizeIs(1));
659 {
660 const auto& packet_info = output.packet_infos_[0];
661 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
662 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
663 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
664 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200665 EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000666 }
667
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000668 EXPECT_CALL(mock_decoder, Die());
669}
670
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000671// This test verifies that NetEq can handle the situation where the first
672// incoming packet is rejected.
henrik.lundin@webrtc.org6ff3ac12014-11-20 14:14:49 +0000673TEST_F(NetEqImplTest, FirstPacketUnknown) {
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000674 UseNoMocks();
675 CreateInstance();
676
677 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000678 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700679 const size_t kPayloadLengthSamples =
680 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundinc9ec8752016-10-13 02:43:34 -0700681 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000682 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700683 RTPHeader rtp_header;
684 rtp_header.payloadType = kPayloadType;
685 rtp_header.sequenceNumber = 0x1234;
686 rtp_header.timestamp = 0x12345678;
687 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000688
689 // Insert one packet. Note that we have not registered any payload type, so
690 // this packet will be rejected.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200691 EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000692
693 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700694 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800695 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700696 bool muted;
697 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800698 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
699 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
700 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800701 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000702 EXPECT_THAT(output.packet_infos_, IsEmpty());
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000703
704 // Register the payload type.
Niels Möller05543682019-01-10 16:55:06 +0100705 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
706 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000707
708 // Insert 10 packets.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700709 for (size_t i = 0; i < 10; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -0700710 rtp_header.sequenceNumber++;
711 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200712 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000713 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
714 }
715
716 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700717 for (size_t i = 0; i < 3; ++i) {
henrik.lundin7a926812016-05-12 13:51:28 -0700718 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800719 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
720 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
721 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800722 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000723 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000724 EXPECT_THAT(output.packet_infos_, SizeIs(1));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000725 }
726}
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000727
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200728// This test verifies that audio interruption is not logged for the initial
729// PLC period before the first packet is deocoded.
730// TODO(henrik.lundin) Maybe move this test to neteq_network_stats_unittest.cc.
Henrik Lundinfe047752019-11-19 12:58:11 +0100731// Make the test parametrized, so that we can test with different initial
732// sample rates in NetEq.
733class NetEqImplTestSampleRateParameter
734 : public NetEqImplTest,
735 public testing::WithParamInterface<int> {
736 protected:
737 NetEqImplTestSampleRateParameter()
738 : NetEqImplTest(), initial_sample_rate_hz_(GetParam()) {
739 config_.sample_rate_hz = initial_sample_rate_hz_;
740 }
741
742 const int initial_sample_rate_hz_;
743};
744
Jared Siskinf2ed4012021-06-18 10:45:16 -0700745class NetEqImplTestSdpFormatParameter
746 : public NetEqImplTest,
747 public testing::WithParamInterface<SdpAudioFormat> {
748 protected:
749 NetEqImplTestSdpFormatParameter()
750 : NetEqImplTest(), sdp_format_(GetParam()) {}
751 const SdpAudioFormat sdp_format_;
752};
753
Henrik Lundinfe047752019-11-19 12:58:11 +0100754// This test does the following:
755// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
756// sample rate of 16000.
757// 1. Start calling GetAudio before inserting any encoded audio. The audio
758// produced will be PLC.
759// 2. Insert a number of encoded audio packets.
760// 3. Keep calling GetAudio and verify that no audio interruption was logged.
761// Call GetAudio until NetEq runs out of data again; PLC starts.
762// 4. Insert one more packet.
763// 5. Call GetAudio until that packet is decoded and the PLC ends.
764
765TEST_P(NetEqImplTestSampleRateParameter,
766 NoAudioInterruptionLoggedBeforeFirstDecode) {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200767 UseNoMocks();
768 CreateInstance();
769
770 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundinfe047752019-11-19 12:58:11 +0100771 const int kPayloadSampleRateHz = 16000;
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200772 const size_t kPayloadLengthSamples =
Henrik Lundinfe047752019-11-19 12:58:11 +0100773 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200774 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
775 uint8_t payload[kPayloadLengthBytes] = {0};
776 RTPHeader rtp_header;
777 rtp_header.payloadType = kPayloadType;
778 rtp_header.sequenceNumber = 0x1234;
779 rtp_header.timestamp = 0x12345678;
780 rtp_header.ssrc = 0x87654321;
781
782 // Register the payload type.
Henrik Lundinfe047752019-11-19 12:58:11 +0100783 EXPECT_TRUE(neteq_->RegisterPayloadType(
784 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200785
786 // Pull audio several times. No packets have been inserted yet.
Henrik Lundinfe047752019-11-19 12:58:11 +0100787 const size_t initial_output_size =
788 static_cast<size_t>(10 * initial_sample_rate_hz_ / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200789 AudioFrame output;
790 bool muted;
791 for (int i = 0; i < 100; ++i) {
792 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100793 EXPECT_EQ(initial_output_size, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200794 EXPECT_EQ(1u, output.num_channels_);
795 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000796 EXPECT_THAT(output.packet_infos_, IsEmpty());
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200797 }
798
Henrik Lundinfe047752019-11-19 12:58:11 +0100799 // Lambda for inserting packets.
800 auto insert_packet = [&]() {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200801 rtp_header.sequenceNumber++;
802 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200803 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundinfe047752019-11-19 12:58:11 +0100804 };
805 // Insert 10 packets.
806 for (size_t i = 0; i < 10; ++i) {
807 insert_packet();
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200808 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
809 }
810
811 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Henrik Lundinfe047752019-11-19 12:58:11 +0100812 constexpr size_t kOutputSize =
813 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200814 for (size_t i = 0; i < 3; ++i) {
815 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100816 EXPECT_EQ(kOutputSize, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200817 EXPECT_EQ(1u, output.num_channels_);
818 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
819 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000820 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200821 }
822
Henrik Lundinfe047752019-11-19 12:58:11 +0100823 // Verify that no interruption was logged.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200824 auto lifetime_stats = neteq_->GetLifetimeStatistics();
Henrik Lundin44125fa2019-04-29 17:00:46 +0200825 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundinfe047752019-11-19 12:58:11 +0100826
827 // Keep pulling audio data until a new PLC period is started.
828 size_t count_loops = 0;
829 while (output.speech_type_ == AudioFrame::kNormalSpeech) {
830 // Make sure we don't hang the test if we never go to PLC.
831 ASSERT_LT(++count_loops, 100u);
832 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
833 }
834
Jakob Ivarsson80fb9782020-10-09 13:41:06 +0200835 // Insert a few packets to avoid postpone decoding after expand.
836 for (size_t i = 0; i < 5; ++i) {
837 insert_packet();
838 }
Henrik Lundinfe047752019-11-19 12:58:11 +0100839
840 // Pull audio until the newly inserted packet is decoded and the PLC ends.
841 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
842 // Make sure we don't hang the test if we never go to PLC.
843 ASSERT_LT(++count_loops, 100u);
844 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
845 }
846
847 // Verify that no interruption was logged.
848 lifetime_stats = neteq_->GetLifetimeStatistics();
849 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200850}
851
Henrik Lundinfe047752019-11-19 12:58:11 +0100852// This test does the following:
853// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
854// sample rate of 16000.
855// 1. Insert a number of encoded audio packets.
856// 2. Call GetAudio and verify that decoded audio is produced.
857// 3. Keep calling GetAudio until NetEq runs out of data; PLC starts.
858// 4. Keep calling GetAudio until PLC has been produced for at least 150 ms.
859// 5. Insert one more packet.
860// 6. Call GetAudio until that packet is decoded and the PLC ends.
861// 7. Verify that an interruption was logged.
862
863TEST_P(NetEqImplTestSampleRateParameter, AudioInterruptionLogged) {
864 UseNoMocks();
865 CreateInstance();
866
867 const uint8_t kPayloadType = 17; // Just an arbitrary number.
868 const int kPayloadSampleRateHz = 16000;
869 const size_t kPayloadLengthSamples =
870 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
871 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
872 uint8_t payload[kPayloadLengthBytes] = {0};
873 RTPHeader rtp_header;
874 rtp_header.payloadType = kPayloadType;
875 rtp_header.sequenceNumber = 0x1234;
876 rtp_header.timestamp = 0x12345678;
877 rtp_header.ssrc = 0x87654321;
878
879 // Register the payload type.
880 EXPECT_TRUE(neteq_->RegisterPayloadType(
881 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
882
883 // Lambda for inserting packets.
884 auto insert_packet = [&]() {
885 rtp_header.sequenceNumber++;
886 rtp_header.timestamp += kPayloadLengthSamples;
887 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
888 };
889 // Insert 10 packets.
890 for (size_t i = 0; i < 10; ++i) {
891 insert_packet();
892 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
893 }
894
895 AudioFrame output;
896 bool muted;
897 // Keep pulling audio data until a new PLC period is started.
898 size_t count_loops = 0;
899 do {
900 // Make sure we don't hang the test if we never go to PLC.
901 ASSERT_LT(++count_loops, 100u);
902 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
903 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
904
905 // Pull audio 15 times, which produces 150 ms of output audio. This should
906 // all be produced as PLC. The total length of the gap will then be 150 ms
907 // plus an initial fraction of 10 ms at the start and the end of the PLC
908 // period. In total, less than 170 ms.
909 for (size_t i = 0; i < 15; ++i) {
910 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
911 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
912 }
913
Jakob Ivarsson80fb9782020-10-09 13:41:06 +0200914 // Insert a few packets to avoid postpone decoding after expand.
915 for (size_t i = 0; i < 5; ++i) {
916 insert_packet();
917 }
Henrik Lundinfe047752019-11-19 12:58:11 +0100918
919 // Pull audio until the newly inserted packet is decoded and the PLC ends.
920 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
921 // Make sure we don't hang the test if we never go to PLC.
922 ASSERT_LT(++count_loops, 100u);
923 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
924 }
925
926 // Verify that the interruption was logged.
927 auto lifetime_stats = neteq_->GetLifetimeStatistics();
928 EXPECT_EQ(1, lifetime_stats.interruption_count);
929 EXPECT_GT(lifetime_stats.total_interruption_duration_ms, 150);
930 EXPECT_LT(lifetime_stats.total_interruption_duration_ms, 170);
931}
932
933INSTANTIATE_TEST_SUITE_P(SampleRates,
934 NetEqImplTestSampleRateParameter,
935 testing::Values(8000, 16000, 32000, 48000));
936
Jared Siskinf2ed4012021-06-18 10:45:16 -0700937TEST_P(NetEqImplTestSdpFormatParameter, GetNackListScaledTimestamp) {
938 UseNoMocks();
939 CreateInstance();
940
941 neteq_->EnableNack(128);
942
943 const uint8_t kPayloadType = 17; // Just an arbitrary number.
944 const int kPayloadSampleRateHz = sdp_format_.clockrate_hz;
945 const size_t kPayloadLengthSamples =
946 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
947 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
948 std::vector<uint8_t> payload(kPayloadLengthBytes, 0);
949 RTPHeader rtp_header;
950 rtp_header.payloadType = kPayloadType;
951 rtp_header.sequenceNumber = 0x1234;
952 rtp_header.timestamp = 0x12345678;
953 rtp_header.ssrc = 0x87654321;
954
955 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType, sdp_format_));
956
957 auto insert_packet = [&](bool lost = false) {
958 rtp_header.sequenceNumber++;
959 rtp_header.timestamp += kPayloadLengthSamples;
960 if (!lost)
961 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
962 };
963
964 // Insert and decode 10 packets.
965 for (size_t i = 0; i < 10; ++i) {
966 insert_packet();
967 }
968 AudioFrame output;
969 size_t count_loops = 0;
970 do {
971 bool muted;
972 // Make sure we don't hang the test if we never go to PLC.
973 ASSERT_LT(++count_loops, 100u);
974 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
975 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
976
977 insert_packet();
978
979 insert_packet(/*lost=*/true);
980
981 // Ensure packet gets marked as missing.
982 for (int i = 0; i < 5; ++i) {
983 insert_packet();
984 }
985
986 // Missing packet recoverable with 5ms RTT.
987 EXPECT_THAT(neteq_->GetNackList(5), Not(IsEmpty()));
988
989 // No packets should have TimeToPlay > 500ms.
990 EXPECT_THAT(neteq_->GetNackList(500), IsEmpty());
991}
992
993INSTANTIATE_TEST_SUITE_P(GetNackList,
994 NetEqImplTestSdpFormatParameter,
995 testing::Values(SdpAudioFormat("g722", 8000, 1),
996 SdpAudioFormat("opus", 48000, 2)));
997
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000998// This test verifies that NetEq can handle comfort noise and enters/quits codec
999// internal CNG mode properly.
1000TEST_F(NetEqImplTest, CodecInternalCng) {
1001 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +01001002 // Create a mock decoder object.
1003 MockAudioDecoder mock_decoder;
1004 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001005 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001006
1007 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001008 const int kSampleRateKhz = 48;
Peter Kastingdce40cf2015-08-24 14:52:23 -07001009 const size_t kPayloadLengthSamples =
1010 static_cast<size_t>(20 * kSampleRateKhz); // 20 ms.
1011 const size_t kPayloadLengthBytes = 10;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001012 uint8_t payload[kPayloadLengthBytes] = {0};
1013 int16_t dummy_output[kPayloadLengthSamples] = {0};
1014
henrik.lundin246ef3e2017-04-24 09:14:32 -07001015 RTPHeader rtp_header;
1016 rtp_header.payloadType = kPayloadType;
1017 rtp_header.sequenceNumber = 0x1234;
1018 rtp_header.timestamp = 0x12345678;
1019 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001020
Karl Wiberg43766482015-08-27 15:22:11 +02001021 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001022 EXPECT_CALL(mock_decoder, SampleRateHz())
1023 .WillRepeatedly(Return(kSampleRateKhz * 1000));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +00001024 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001025 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001026 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001027 // Packed duration when asking the decoder for more CNG data (without a new
1028 // packet).
1029 EXPECT_CALL(mock_decoder, PacketDuration(nullptr, 0))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001030 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001031
Jakob Ivarssonfa68ac02021-11-09 12:58:45 +01001032 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1033 SdpAudioFormat("opus", 48000, 2)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001034
Jakob Ivarssonfa68ac02021-11-09 12:58:45 +01001035 struct Packet {
1036 int sequence_number_delta;
1037 int timestamp_delta;
1038 AudioDecoder::SpeechType decoder_output_type;
1039 };
1040 std::vector<Packet> packets = {
1041 {0, 0, AudioDecoder::kSpeech},
1042 {1, kPayloadLengthSamples, AudioDecoder::kComfortNoise},
1043 {2, 2 * kPayloadLengthSamples, AudioDecoder::kSpeech},
1044 {1, kPayloadLengthSamples, AudioDecoder::kSpeech}};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001045
Jakob Ivarssonfa68ac02021-11-09 12:58:45 +01001046 for (size_t i = 0; i < packets.size(); ++i) {
1047 rtp_header.sequenceNumber += packets[i].sequence_number_delta;
1048 rtp_header.timestamp += packets[i].timestamp_delta;
1049 payload[0] = i;
1050 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
1051
1052 // Pointee(x) verifies that first byte of the payload equals x, this makes
1053 // it possible to verify that the correct payload is fed to Decode().
1054 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(i), kPayloadLengthBytes,
1055 kSampleRateKhz * 1000, _, _))
1056 .WillOnce(DoAll(SetArrayArgument<3>(
1057 dummy_output, dummy_output + kPayloadLengthSamples),
1058 SetArgPointee<4>(packets[i].decoder_output_type),
1059 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
1060 }
1061
1062 // Expect comfort noise to be returned by the decoder.
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001063 EXPECT_CALL(mock_decoder,
1064 DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
1065 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001066 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001067 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001068 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001069
Jakob Ivarssonfa68ac02021-11-09 12:58:45 +01001070 std::vector<AudioFrame::SpeechType> expected_output = {
1071 AudioFrame::kNormalSpeech, AudioFrame::kCNG, AudioFrame::kNormalSpeech};
1072 size_t output_index = 0;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001073
Jakob Ivarssonfa68ac02021-11-09 12:58:45 +01001074 int timeout_counter = 0;
1075 while (!packet_buffer_->Empty()) {
1076 ASSERT_LT(timeout_counter++, 20) << "Test timed out";
1077 AudioFrame output;
1078 bool muted;
1079 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
1080 if (output_index + 1 < expected_output.size() &&
1081 output.speech_type_ == expected_output[output_index + 1]) {
1082 ++output_index;
henrik.lundin0d96ab72016-04-06 12:28:26 -07001083 } else {
Jakob Ivarssonfa68ac02021-11-09 12:58:45 +01001084 EXPECT_EQ(output.speech_type_, expected_output[output_index]);
henrik.lundin0d96ab72016-04-06 12:28:26 -07001085 }
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001086 }
1087
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001088 EXPECT_CALL(mock_decoder, Die());
1089}
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001090
1091TEST_F(NetEqImplTest, UnsupportedDecoder) {
1092 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001093 ::testing::NiceMock<MockAudioDecoder> decoder;
1094
1095 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001096 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&decoder));
minyue5bd33972016-05-02 04:46:11 -07001097 static const size_t kNetEqMaxFrameSize = 5760; // 120 ms @ 48 kHz.
Peter Kasting69558702016-01-12 16:26:35 -08001098 static const size_t kChannels = 2;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001099
1100 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001101 const int kSampleRateHz = 8000;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001102
Peter Kastingdce40cf2015-08-24 14:52:23 -07001103 const size_t kPayloadLengthSamples =
1104 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001105 const size_t kPayloadLengthBytes = 1;
minyue5bd33972016-05-02 04:46:11 -07001106 uint8_t payload[kPayloadLengthBytes] = {0};
Minyue323b1322015-05-25 13:49:37 +02001107 int16_t dummy_output[kPayloadLengthSamples * kChannels] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001108 RTPHeader rtp_header;
1109 rtp_header.payloadType = kPayloadType;
1110 rtp_header.sequenceNumber = 0x1234;
1111 rtp_header.timestamp = 0x12345678;
1112 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001113
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001114 const uint8_t kFirstPayloadValue = 1;
1115 const uint8_t kSecondPayloadValue = 2;
1116
ossu61a208b2016-09-20 01:38:00 -07001117 EXPECT_CALL(decoder,
1118 PacketDuration(Pointee(kFirstPayloadValue), kPayloadLengthBytes))
1119 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001120 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize + 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001121
ossu61a208b2016-09-20 01:38:00 -07001122 EXPECT_CALL(decoder, DecodeInternal(Pointee(kFirstPayloadValue), _, _, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001123 .Times(0);
1124
ossu61a208b2016-09-20 01:38:00 -07001125 EXPECT_CALL(decoder, DecodeInternal(Pointee(kSecondPayloadValue),
1126 kPayloadLengthBytes, kSampleRateHz, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001127 .Times(1)
ossu61a208b2016-09-20 01:38:00 -07001128 .WillOnce(DoAll(
1129 SetArrayArgument<3>(dummy_output,
1130 dummy_output + kPayloadLengthSamples * kChannels),
1131 SetArgPointee<4>(AudioDecoder::kSpeech),
1132 Return(static_cast<int>(kPayloadLengthSamples * kChannels))));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001133
ossu61a208b2016-09-20 01:38:00 -07001134 EXPECT_CALL(decoder,
1135 PacketDuration(Pointee(kSecondPayloadValue), kPayloadLengthBytes))
1136 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001137 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize)));
ossu61a208b2016-09-20 01:38:00 -07001138
Jonas Olssona4d87372019-07-05 19:08:33 +02001139 EXPECT_CALL(decoder, SampleRateHz()).WillRepeatedly(Return(kSampleRateHz));
ossu61a208b2016-09-20 01:38:00 -07001140
Jonas Olssona4d87372019-07-05 19:08:33 +02001141 EXPECT_CALL(decoder, Channels()).WillRepeatedly(Return(kChannels));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001142
Niels Möllera1eb9c72018-12-07 15:24:42 +01001143 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1144 SdpAudioFormat("L16", 8000, 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001145
1146 // Insert one packet.
1147 payload[0] = kFirstPayloadValue; // This will make Decode() fail.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001148 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001149
1150 // Insert another packet.
1151 payload[0] = kSecondPayloadValue; // This will make Decode() successful.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001152 rtp_header.sequenceNumber++;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001153 // The second timestamp needs to be at least 30 ms after the first to make
1154 // the second packet get decoded.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001155 rtp_header.timestamp += 3 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001156 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001157
henrik.lundin6d8e0112016-03-04 10:34:21 -08001158 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001159 bool muted;
henrik.lundin6d8e0112016-03-04 10:34:21 -08001160 // First call to GetAudio will try to decode the "faulty" packet.
Henrik Lundinc417d9e2017-06-14 12:29:03 +02001161 // Expect kFail return value.
henrik.lundin7a926812016-05-12 13:51:28 -07001162 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001163 // Output size and number of channels should be correct.
1164 const size_t kExpectedOutputSize = 10 * (kSampleRateHz / 1000) * kChannels;
1165 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1166 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001167 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001168
henrik.lundin6d8e0112016-03-04 10:34:21 -08001169 // Second call to GetAudio will decode the packet that is ok. No errors are
1170 // expected.
henrik.lundin7a926812016-05-12 13:51:28 -07001171 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001172 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1173 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001174 EXPECT_THAT(output.packet_infos_, SizeIs(1));
ossu61a208b2016-09-20 01:38:00 -07001175
1176 // Die isn't called through NiceMock (since it's called by the
1177 // MockAudioDecoder constructor), so it needs to be mocked explicitly.
1178 EXPECT_CALL(decoder, Die());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001179}
1180
henrik.lundin116c84e2015-08-27 13:14:48 -07001181// This test inserts packets until the buffer is flushed. After that, it asks
1182// NetEq for the network statistics. The purpose of the test is to make sure
1183// that even though the buffer size increment is negative (which it becomes when
1184// the packet causing a flush is inserted), the packet length stored in the
1185// decision logic remains valid.
1186TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) {
1187 UseNoMocks();
1188 CreateInstance();
1189
1190 const size_t kPayloadLengthSamples = 80;
1191 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1192 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin116c84e2015-08-27 13:14:48 -07001193 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001194 RTPHeader rtp_header;
1195 rtp_header.payloadType = kPayloadType;
1196 rtp_header.sequenceNumber = 0x1234;
1197 rtp_header.timestamp = 0x12345678;
1198 rtp_header.ssrc = 0x87654321;
henrik.lundin116c84e2015-08-27 13:14:48 -07001199
Niels Möller05543682019-01-10 16:55:06 +01001200 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1201 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin116c84e2015-08-27 13:14:48 -07001202
1203 // Insert packets until the buffer flushes.
1204 for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) {
1205 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
Karl Wiberg45eb1352019-10-10 14:23:00 +02001206 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -07001207 rtp_header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples);
1208 ++rtp_header.sequenceNumber;
henrik.lundin116c84e2015-08-27 13:14:48 -07001209 }
1210 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
1211
1212 // Ask for network statistics. This should not crash.
1213 NetEqNetworkStatistics stats;
1214 EXPECT_EQ(NetEq::kOK, neteq_->NetworkStatistics(&stats));
1215}
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001216
1217TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
1218 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001219 // Create a mock decoder object.
1220 MockAudioDecoder mock_decoder;
1221
1222 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001223 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001224
1225 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001226 const int kSampleRateHz = 8000;
1227 const size_t kPayloadLengthSamples =
1228 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
1229 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples;
1230 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001231 RTPHeader rtp_header;
1232 rtp_header.payloadType = kPayloadType;
1233 rtp_header.sequenceNumber = 0x1234;
1234 rtp_header.timestamp = 0x12345678;
1235 rtp_header.ssrc = 0x87654321;
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001236
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001237 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001238 EXPECT_CALL(mock_decoder, SampleRateHz())
1239 .WillRepeatedly(Return(kSampleRateHz));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001240 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001241 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001242 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001243 int16_t dummy_output[kPayloadLengthSamples] = {0};
1244 // The below expectation will make the mock decoder write
Artem Titovd00ce742021-07-28 20:00:17 +02001245 // `kPayloadLengthSamples` - 5 zeros to the output array, and mark it as
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001246 // speech. That is, the decoded length is 5 samples shorter than the expected.
1247 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001248 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001249 .WillOnce(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001250 DoAll(SetArrayArgument<3>(dummy_output,
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001251 dummy_output + kPayloadLengthSamples - 5),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001252 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001253 Return(rtc::checked_cast<int>(kPayloadLengthSamples - 5))));
Niels Möllera1eb9c72018-12-07 15:24:42 +01001254 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1255 SdpAudioFormat("L16", 8000, 1)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001256
1257 // Insert one packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001258 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001259
1260 EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength());
1261
1262 // Pull audio once.
1263 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001264 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001265 bool muted;
1266 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001267 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1268 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001269 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001270 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001271
1272 EXPECT_CALL(mock_decoder, Die());
1273}
minyuel6d92bf52015-09-23 15:20:39 +02001274
1275// This test checks the behavior of NetEq when audio decoder fails.
1276TEST_F(NetEqImplTest, DecodingError) {
1277 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001278 // Create a mock decoder object.
1279 MockAudioDecoder mock_decoder;
1280
1281 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001282 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001283
1284 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001285 const int kSampleRateHz = 8000;
1286 const int kDecoderErrorCode = -97; // Any negative number.
1287
1288 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1289 const size_t kFrameLengthSamples =
1290 static_cast<size_t>(5 * kSampleRateHz / 1000);
1291
1292 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1293
1294 uint8_t payload[kPayloadLengthBytes] = {0};
1295
henrik.lundin246ef3e2017-04-24 09:14:32 -07001296 RTPHeader rtp_header;
1297 rtp_header.payloadType = kPayloadType;
1298 rtp_header.sequenceNumber = 0x1234;
1299 rtp_header.timestamp = 0x12345678;
1300 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001301
minyuel6d92bf52015-09-23 15:20:39 +02001302 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001303 EXPECT_CALL(mock_decoder, SampleRateHz())
1304 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001305 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001306 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001307 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001308 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
1309 EXPECT_CALL(mock_decoder, HasDecodePlc()).WillOnce(Return(false));
minyuel6d92bf52015-09-23 15:20:39 +02001310 int16_t dummy_output[kFrameLengthSamples] = {0};
1311
1312 {
1313 InSequence sequence; // Dummy variable.
1314 // Mock decoder works normally the first time.
1315 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001316 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001317 .Times(3)
1318 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001319 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001320 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001321 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001322 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001323 .RetiresOnSaturation();
1324
1325 // Then mock decoder fails. A common reason for failure can be buffer being
1326 // too short
1327 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001328 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001329 .WillOnce(Return(-1))
1330 .RetiresOnSaturation();
1331
1332 // Mock decoder finally returns to normal.
1333 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001334 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001335 .Times(2)
1336 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001337 DoAll(SetArrayArgument<3>(dummy_output,
1338 dummy_output + kFrameLengthSamples),
1339 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001340 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001341 }
1342
Niels Möllera1eb9c72018-12-07 15:24:42 +01001343 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1344 SdpAudioFormat("L16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001345
1346 // Insert packets.
Jakob Ivarsson80fb9782020-10-09 13:41:06 +02001347 for (int i = 0; i < 20; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001348 rtp_header.sequenceNumber += 1;
1349 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001350 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001351 }
1352
1353 // Pull audio.
1354 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001355 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001356 bool muted;
1357 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001358 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1359 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001360 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001361 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001362
1363 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001364 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001365 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1366 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001367 // We are not expecting anything for output.speech_type_, since an error was
1368 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001369
minyuel6d92bf52015-09-23 15:20:39 +02001370 // Pull audio again, should behave normal.
henrik.lundin7a926812016-05-12 13:51:28 -07001371 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001372 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1373 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001374 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001375 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001376
1377 EXPECT_CALL(mock_decoder, Die());
1378}
1379
1380// This test checks the behavior of NetEq when audio decoder fails during CNG.
1381TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
1382 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +01001383
1384 // Create a mock decoder object.
1385 MockAudioDecoder mock_decoder;
1386 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001387 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001388
1389 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001390 const int kSampleRateHz = 8000;
1391 const int kDecoderErrorCode = -97; // Any negative number.
1392
1393 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1394 const size_t kFrameLengthSamples =
1395 static_cast<size_t>(5 * kSampleRateHz / 1000);
1396
1397 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1398
1399 uint8_t payload[kPayloadLengthBytes] = {0};
1400
henrik.lundin246ef3e2017-04-24 09:14:32 -07001401 RTPHeader rtp_header;
1402 rtp_header.payloadType = kPayloadType;
1403 rtp_header.sequenceNumber = 0x1234;
1404 rtp_header.timestamp = 0x12345678;
1405 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001406
minyuel6d92bf52015-09-23 15:20:39 +02001407 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001408 EXPECT_CALL(mock_decoder, SampleRateHz())
1409 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001410 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001411 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001412 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001413 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
minyuel6d92bf52015-09-23 15:20:39 +02001414 int16_t dummy_output[kFrameLengthSamples] = {0};
1415
1416 {
1417 InSequence sequence; // Dummy variable.
1418 // Mock decoder works normally the first 2 times.
1419 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001420 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001421 .Times(2)
1422 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001423 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001424 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001425 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001426 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001427 .RetiresOnSaturation();
1428
1429 // Then mock decoder fails. A common reason for failure can be buffer being
1430 // too short
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001431 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001432 .WillOnce(Return(-1))
1433 .RetiresOnSaturation();
1434
1435 // Mock decoder finally returns to normal.
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001436 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001437 .Times(2)
1438 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001439 DoAll(SetArrayArgument<3>(dummy_output,
1440 dummy_output + kFrameLengthSamples),
1441 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001442 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001443 }
1444
Niels Möller50b66d52018-12-11 14:43:21 +01001445 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1446 SdpAudioFormat("l16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001447
1448 // Insert 2 packets. This will make netEq into codec internal CNG mode.
1449 for (int i = 0; i < 2; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001450 rtp_header.sequenceNumber += 1;
1451 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001452 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001453 }
1454
1455 // Pull audio.
1456 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001457 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001458 bool muted;
1459 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001460 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1461 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001462 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001463
1464 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001465 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001466 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1467 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001468 // We are not expecting anything for output.speech_type_, since an error was
1469 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001470
1471 // Pull audio again, should resume codec CNG.
henrik.lundin7a926812016-05-12 13:51:28 -07001472 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001473 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1474 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001475 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001476
1477 EXPECT_CALL(mock_decoder, Die());
1478}
1479
henrik.lundind89814b2015-11-23 06:49:25 -08001480// Tests that the return value from last_output_sample_rate_hz() is equal to the
1481// configured inital sample rate.
1482TEST_F(NetEqImplTest, InitialLastOutputSampleRate) {
1483 UseNoMocks();
1484 config_.sample_rate_hz = 48000;
1485 CreateInstance();
1486 EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz());
1487}
1488
henrik.lundined497212016-04-25 10:11:38 -07001489TEST_F(NetEqImplTest, TickTimerIncrement) {
1490 UseNoMocks();
1491 CreateInstance();
1492 ASSERT_TRUE(tick_timer_);
1493 EXPECT_EQ(0u, tick_timer_->ticks());
1494 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001495 bool muted;
1496 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundined497212016-04-25 10:11:38 -07001497 EXPECT_EQ(1u, tick_timer_->ticks());
1498}
1499
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001500TEST_F(NetEqImplTest, SetBaseMinimumDelay) {
1501 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001502 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001503 CreateInstance();
1504
Ivo Creusen53a31f72019-10-24 15:20:39 +02001505 EXPECT_CALL(*mock_neteq_controller_, SetBaseMinimumDelay(_))
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001506 .WillOnce(Return(true))
1507 .WillOnce(Return(false));
1508
1509 const int delay_ms = 200;
1510
1511 EXPECT_EQ(true, neteq_->SetBaseMinimumDelayMs(delay_ms));
1512 EXPECT_EQ(false, neteq_->SetBaseMinimumDelayMs(delay_ms));
1513}
1514
1515TEST_F(NetEqImplTest, GetBaseMinimumDelayMs) {
1516 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001517 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001518 CreateInstance();
1519
1520 const int delay_ms = 200;
1521
Ivo Creusen53a31f72019-10-24 15:20:39 +02001522 EXPECT_CALL(*mock_neteq_controller_, GetBaseMinimumDelay())
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001523 .WillOnce(Return(delay_ms));
1524
1525 EXPECT_EQ(delay_ms, neteq_->GetBaseMinimumDelayMs());
1526}
1527
henrik.lundin114c1b32017-04-26 07:47:32 -07001528TEST_F(NetEqImplTest, TargetDelayMs) {
1529 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001530 use_mock_neteq_controller_ = true;
henrik.lundin114c1b32017-04-26 07:47:32 -07001531 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001532 constexpr int kTargetLevelMs = 510;
1533 EXPECT_CALL(*mock_neteq_controller_, TargetLevelMs())
1534 .WillOnce(Return(kTargetLevelMs));
1535 EXPECT_EQ(510, neteq_->TargetDelayMs());
henrik.lundin114c1b32017-04-26 07:47:32 -07001536}
1537
henrik.lundinb8c55b12017-05-10 07:38:01 -07001538TEST_F(NetEqImplTest, InsertEmptyPacket) {
1539 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001540 use_mock_neteq_controller_ = true;
henrik.lundinb8c55b12017-05-10 07:38:01 -07001541 CreateInstance();
1542
1543 RTPHeader rtp_header;
1544 rtp_header.payloadType = 17;
1545 rtp_header.sequenceNumber = 0x1234;
1546 rtp_header.timestamp = 0x12345678;
1547 rtp_header.ssrc = 0x87654321;
1548
Ivo Creusen53a31f72019-10-24 15:20:39 +02001549 EXPECT_CALL(*mock_neteq_controller_, RegisterEmptyPacket());
henrik.lundinb8c55b12017-05-10 07:38:01 -07001550 neteq_->InsertEmptyPacket(rtp_header);
1551}
1552
Jakob Ivarsson7cca0162021-09-01 18:19:37 +02001553TEST_F(NetEqImplTest, NotifyControllerOfReorderedPacket) {
Ivo Creusena2b31c32020-10-14 17:54:22 +02001554 using ::testing::AllOf;
1555 using ::testing::Field;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001556 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001557 use_mock_neteq_controller_ = true;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001558 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001559 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001560 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001561 .WillOnce(Return(NetEq::Operation::kNormal));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001562
1563 const int kPayloadLengthSamples = 80;
1564 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1565 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001566 uint8_t payload[kPayloadLengthBytes] = {0};
1567 RTPHeader rtp_header;
1568 rtp_header.payloadType = kPayloadType;
1569 rtp_header.sequenceNumber = 0x1234;
1570 rtp_header.timestamp = 0x12345678;
1571 rtp_header.ssrc = 0x87654321;
1572
Niels Möller05543682019-01-10 16:55:06 +01001573 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1574 SdpAudioFormat("l16", 8000, 1)));
Karl Wiberg45eb1352019-10-10 14:23:00 +02001575 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001576 AudioFrame output;
1577 bool muted;
1578 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
1579
1580 // Insert second packet that was sent before the first packet.
1581 rtp_header.sequenceNumber -= 1;
1582 rtp_header.timestamp -= kPayloadLengthSamples;
Ivo Creusena2b31c32020-10-14 17:54:22 +02001583 EXPECT_CALL(
1584 *mock_neteq_controller_,
1585 PacketArrived(
1586 /*fs_hz*/ 8000,
Jakob Ivarsson7cca0162021-09-01 18:19:37 +02001587 /*should_update_stats*/ true,
Ivo Creusena2b31c32020-10-14 17:54:22 +02001588 /*info*/
1589 AllOf(
1590 Field(&NetEqController::PacketArrivedInfo::packet_length_samples,
1591 kPayloadLengthSamples),
1592 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
1593 rtp_header.sequenceNumber),
1594 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
1595 rtp_header.timestamp))));
Ivo Creusen53a31f72019-10-24 15:20:39 +02001596
Karl Wiberg45eb1352019-10-10 14:23:00 +02001597 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001598}
1599
Ivo Creusen500d6e72021-11-24 12:32:07 +00001600// When using a codec with 1000 channels, there should be no crashes.
1601TEST_F(NetEqImplTest, NoCrashWith1000Channels) {
1602 using ::testing::AllOf;
1603 using ::testing::Field;
1604 UseNoMocks();
1605 use_mock_decoder_database_ = true;
1606 enable_muted_state_ = true;
1607 CreateInstance();
1608 const size_t kPayloadLength = 100;
1609 const uint8_t kPayloadType = 0;
1610 const uint16_t kFirstSequenceNumber = 0x1234;
1611 const uint32_t kFirstTimestamp = 0x12345678;
1612 const uint32_t kSsrc = 0x87654321;
1613 uint8_t payload[kPayloadLength] = {0};
1614 RTPHeader rtp_header;
1615 rtp_header.payloadType = kPayloadType;
1616 rtp_header.sequenceNumber = kFirstSequenceNumber;
1617 rtp_header.timestamp = kFirstTimestamp;
1618 rtp_header.ssrc = kSsrc;
1619 Packet fake_packet;
1620 fake_packet.payload_type = kPayloadType;
1621 fake_packet.sequence_number = kFirstSequenceNumber;
1622 fake_packet.timestamp = kFirstTimestamp;
1623
1624 AudioDecoder* decoder = nullptr;
1625
1626 auto mock_decoder_factory = rtc::make_ref_counted<MockAudioDecoderFactory>();
1627 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _, _))
1628 .WillOnce(Invoke([&](const SdpAudioFormat& format,
1629 absl::optional<AudioCodecPairId> codec_pair_id,
1630 std::unique_ptr<AudioDecoder>* dec) {
1631 EXPECT_EQ("pcmu", format.name);
1632 *dec = std::make_unique<AudioDecoderPcmU>(1000);
1633 decoder = dec->get();
1634 }));
1635 DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Niels Möllerc7b69022022-04-21 15:06:35 +02001636 absl::nullopt, mock_decoder_factory.get());
Ivo Creusen500d6e72021-11-24 12:32:07 +00001637 // Expectations for decoder database.
1638 EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
1639 .WillRepeatedly(Return(&info));
1640 EXPECT_CALL(*mock_decoder_database_, GetActiveCngDecoder())
1641 .WillRepeatedly(ReturnNull());
1642 EXPECT_CALL(*mock_decoder_database_, GetActiveDecoder())
1643 .WillRepeatedly(Return(decoder));
1644 EXPECT_CALL(*mock_decoder_database_, SetActiveDecoder(_, _))
1645 .WillOnce(Invoke([](uint8_t rtp_payload_type, bool* new_decoder) {
1646 *new_decoder = true;
1647 return 0;
1648 }));
1649
1650 // Insert first packet.
1651 neteq_->InsertPacket(rtp_header, payload);
1652
1653 AudioFrame audio_frame;
1654 bool muted;
1655
1656 // Repeat 40 times to ensure we enter muted state.
1657 for (int i = 0; i < 40; i++) {
1658 // GetAudio should return an error, and not crash, even in muted state.
1659 EXPECT_NE(0, neteq_->GetAudio(&audio_frame, &muted));
1660 }
1661}
1662
minyue5bd33972016-05-02 04:46:11 -07001663class Decoder120ms : public AudioDecoder {
1664 public:
kwiberg347d3512016-06-16 01:59:09 -07001665 Decoder120ms(int sample_rate_hz, SpeechType speech_type)
1666 : sample_rate_hz_(sample_rate_hz),
1667 next_value_(1),
minyue5bd33972016-05-02 04:46:11 -07001668 speech_type_(speech_type) {}
1669
1670 int DecodeInternal(const uint8_t* encoded,
1671 size_t encoded_len,
1672 int sample_rate_hz,
1673 int16_t* decoded,
1674 SpeechType* speech_type) override {
kwiberg347d3512016-06-16 01:59:09 -07001675 EXPECT_EQ(sample_rate_hz_, sample_rate_hz);
minyue5bd33972016-05-02 04:46:11 -07001676 size_t decoded_len =
1677 rtc::CheckedDivExact(sample_rate_hz, 1000) * 120 * Channels();
1678 for (size_t i = 0; i < decoded_len; ++i) {
1679 decoded[i] = next_value_++;
1680 }
1681 *speech_type = speech_type_;
Mirko Bonadei737e0732017-10-19 09:00:17 +02001682 return rtc::checked_cast<int>(decoded_len);
minyue5bd33972016-05-02 04:46:11 -07001683 }
1684
1685 void Reset() override { next_value_ = 1; }
kwiberg347d3512016-06-16 01:59:09 -07001686 int SampleRateHz() const override { return sample_rate_hz_; }
minyue5bd33972016-05-02 04:46:11 -07001687 size_t Channels() const override { return 2; }
1688
1689 private:
kwiberg347d3512016-06-16 01:59:09 -07001690 int sample_rate_hz_;
minyue5bd33972016-05-02 04:46:11 -07001691 int16_t next_value_;
1692 SpeechType speech_type_;
1693};
1694
1695class NetEqImplTest120ms : public NetEqImplTest {
1696 protected:
1697 NetEqImplTest120ms() : NetEqImplTest() {}
1698 virtual ~NetEqImplTest120ms() {}
1699
1700 void CreateInstanceNoMocks() {
1701 UseNoMocks();
Niels Möllera0f44302018-11-30 10:45:12 +01001702 CreateInstance(decoder_factory_);
1703 EXPECT_TRUE(neteq_->RegisterPayloadType(
1704 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001705 }
1706
1707 void CreateInstanceWithDelayManagerMock() {
1708 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001709 use_mock_neteq_controller_ = true;
Niels Möllera0f44302018-11-30 10:45:12 +01001710 CreateInstance(decoder_factory_);
1711 EXPECT_TRUE(neteq_->RegisterPayloadType(
1712 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001713 }
1714
1715 uint32_t timestamp_diff_between_packets() const {
1716 return rtc::CheckedDivExact(kSamplingFreq_, 1000u) * 120;
1717 }
1718
1719 uint32_t first_timestamp() const { return 10u; }
1720
1721 void GetFirstPacket() {
henrik.lundin7a926812016-05-12 13:51:28 -07001722 bool muted;
minyue5bd33972016-05-02 04:46:11 -07001723 for (int i = 0; i < 12; i++) {
henrik.lundin7a926812016-05-12 13:51:28 -07001724 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
1725 EXPECT_FALSE(muted);
minyue5bd33972016-05-02 04:46:11 -07001726 }
1727 }
1728
1729 void InsertPacket(uint32_t timestamp) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001730 RTPHeader rtp_header;
1731 rtp_header.payloadType = kPayloadType;
1732 rtp_header.sequenceNumber = sequence_number_;
1733 rtp_header.timestamp = timestamp;
1734 rtp_header.ssrc = 15;
minyue5bd33972016-05-02 04:46:11 -07001735 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1736 uint8_t payload[kPayloadLengthBytes] = {0};
Karl Wiberg45eb1352019-10-10 14:23:00 +02001737 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue5bd33972016-05-02 04:46:11 -07001738 sequence_number_++;
1739 }
1740
1741 void Register120msCodec(AudioDecoder::SpeechType speech_type) {
Niels Möllera0f44302018-11-30 10:45:12 +01001742 const uint32_t sampling_freq = kSamplingFreq_;
Tommi87f70902021-04-27 14:43:08 +02001743 decoder_factory_ = rtc::make_ref_counted<test::FunctionAudioDecoderFactory>(
1744 [sampling_freq, speech_type]() {
1745 std::unique_ptr<AudioDecoder> decoder =
1746 std::make_unique<Decoder120ms>(sampling_freq, speech_type);
1747 RTC_CHECK_EQ(2, decoder->Channels());
1748 return decoder;
1749 });
minyue5bd33972016-05-02 04:46:11 -07001750 }
1751
Niels Möllera0f44302018-11-30 10:45:12 +01001752 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
minyue5bd33972016-05-02 04:46:11 -07001753 AudioFrame output_;
1754 const uint32_t kPayloadType = 17;
1755 const uint32_t kSamplingFreq_ = 48000;
1756 uint16_t sequence_number_ = 1;
1757};
1758
minyue5bd33972016-05-02 04:46:11 -07001759TEST_F(NetEqImplTest120ms, CodecInternalCng) {
minyue5bd33972016-05-02 04:46:11 -07001760 Register120msCodec(AudioDecoder::kComfortNoise);
Niels Möllera0f44302018-11-30 10:45:12 +01001761 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001762
1763 InsertPacket(first_timestamp());
1764 GetFirstPacket();
1765
henrik.lundin7a926812016-05-12 13:51:28 -07001766 bool muted;
1767 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001768 EXPECT_EQ(NetEq::Operation::kCodecInternalCng,
1769 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001770}
1771
1772TEST_F(NetEqImplTest120ms, Normal) {
minyue5bd33972016-05-02 04:46:11 -07001773 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001774 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001775
1776 InsertPacket(first_timestamp());
1777 GetFirstPacket();
1778
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001779 EXPECT_EQ(NetEq::Operation::kNormal, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001780}
1781
1782TEST_F(NetEqImplTest120ms, Merge) {
Niels Möllera0f44302018-11-30 10:45:12 +01001783 Register120msCodec(AudioDecoder::kSpeech);
minyue5bd33972016-05-02 04:46:11 -07001784 CreateInstanceWithDelayManagerMock();
1785
Ivo Creusen53a31f72019-10-24 15:20:39 +02001786 EXPECT_CALL(*mock_neteq_controller_, CngOff()).WillRepeatedly(Return(true));
minyue5bd33972016-05-02 04:46:11 -07001787 InsertPacket(first_timestamp());
1788
1789 GetFirstPacket();
henrik.lundin7a926812016-05-12 13:51:28 -07001790 bool muted;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001791 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001792 .WillOnce(Return(NetEq::Operation::kExpand));
henrik.lundin7a926812016-05-12 13:51:28 -07001793 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
minyue5bd33972016-05-02 04:46:11 -07001794
1795 InsertPacket(first_timestamp() + 2 * timestamp_diff_between_packets());
1796
Ivo Creusen53a31f72019-10-24 15:20:39 +02001797 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001798 .WillOnce(Return(NetEq::Operation::kMerge));
minyue5bd33972016-05-02 04:46:11 -07001799
henrik.lundin7a926812016-05-12 13:51:28 -07001800 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001801 EXPECT_EQ(NetEq::Operation::kMerge, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001802}
1803
1804TEST_F(NetEqImplTest120ms, Expand) {
minyue5bd33972016-05-02 04:46:11 -07001805 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001806 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001807
1808 InsertPacket(first_timestamp());
1809 GetFirstPacket();
1810
henrik.lundin7a926812016-05-12 13:51:28 -07001811 bool muted;
1812 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001813 EXPECT_EQ(NetEq::Operation::kExpand, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001814}
1815
1816TEST_F(NetEqImplTest120ms, FastAccelerate) {
minyue5bd33972016-05-02 04:46:11 -07001817 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001818 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001819
1820 InsertPacket(first_timestamp());
1821 GetFirstPacket();
1822 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1823
Ivo Creusen53a31f72019-10-24 15:20:39 +02001824 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001825 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001826 .WillOnce(Return(NetEq::Operation::kFastAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001827
henrik.lundin7a926812016-05-12 13:51:28 -07001828 bool muted;
1829 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001830 EXPECT_EQ(NetEq::Operation::kFastAccelerate,
1831 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001832}
1833
1834TEST_F(NetEqImplTest120ms, PreemptiveExpand) {
minyue5bd33972016-05-02 04:46:11 -07001835 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001836 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001837
1838 InsertPacket(first_timestamp());
1839 GetFirstPacket();
1840
1841 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1842
Ivo Creusen53a31f72019-10-24 15:20:39 +02001843 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001844 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001845 .WillOnce(Return(NetEq::Operation::kPreemptiveExpand));
minyue5bd33972016-05-02 04:46:11 -07001846
henrik.lundin7a926812016-05-12 13:51:28 -07001847 bool muted;
1848 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001849 EXPECT_EQ(NetEq::Operation::kPreemptiveExpand,
1850 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001851}
1852
1853TEST_F(NetEqImplTest120ms, Accelerate) {
minyue5bd33972016-05-02 04:46:11 -07001854 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001855 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001856
1857 InsertPacket(first_timestamp());
1858 GetFirstPacket();
1859
1860 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1861
Ivo Creusen53a31f72019-10-24 15:20:39 +02001862 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001863 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001864 .WillOnce(Return(NetEq::Operation::kAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001865
henrik.lundin7a926812016-05-12 13:51:28 -07001866 bool muted;
1867 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001868 EXPECT_EQ(NetEq::Operation::kAccelerate, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001869}
1870
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001871} // namespace webrtc