blob: 7010adfa402bc6c1add8bd85a63c21bbc7f41981 [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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/audio_coding/neteq/accelerate.h"
Ivo Creusen53a31f72019-10-24 15:20:39 +020022#include "modules/audio_coding/neteq/decision_logic.h"
Ivo Creusen39cf3c72019-11-28 14:07:14 +010023#include "modules/audio_coding/neteq/default_neteq_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "modules/audio_coding/neteq/expand.h"
Jakob Ivarsson1eb3d7e2019-02-21 15:42:31 +010025#include "modules/audio_coding/neteq/histogram.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/audio_coding/neteq/mock/mock_dtmf_buffer.h"
28#include "modules/audio_coding/neteq/mock/mock_dtmf_tone_generator.h"
Ivo Creusen53a31f72019-10-24 15:20:39 +020029#include "modules/audio_coding/neteq/mock/mock_neteq_controller.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "modules/audio_coding/neteq/mock/mock_packet_buffer.h"
31#include "modules/audio_coding/neteq/mock/mock_red_payload_splitter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "modules/audio_coding/neteq/preemptive_expand.h"
Jakob Ivarsson44507082019-03-05 16:59:03 +010033#include "modules/audio_coding/neteq/statistics_calculator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "modules/audio_coding/neteq/sync_buffer.h"
35#include "modules/audio_coding/neteq/timestamp_scaler.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010036#include "rtc_base/numerics/safe_conversions.h"
Alessio Bazzica8f319a32019-07-24 16:47:02 +000037#include "system_wrappers/include/clock.h"
Niels Möllerb7180c02018-12-06 13:07:11 +010038#include "test/audio_decoder_proxy_factory.h"
Niels Möllera0f44302018-11-30 10:45:12 +010039#include "test/function_audio_decoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020040#include "test/gmock.h"
41#include "test/gtest.h"
42#include "test/mock_audio_decoder.h"
43#include "test/mock_audio_decoder_factory.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000044
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000045using ::testing::_;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010046using ::testing::AtLeast;
47using ::testing::DoAll;
Alessio Bazzica8f319a32019-07-24 16:47:02 +000048using ::testing::ElementsAre;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000049using ::testing::InSequence;
50using ::testing::Invoke;
Alessio Bazzica8f319a32019-07-24 16:47:02 +000051using ::testing::IsEmpty;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +000052using ::testing::IsNull;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010053using ::testing::Pointee;
54using ::testing::Return;
55using ::testing::ReturnNull;
56using ::testing::SetArgPointee;
57using ::testing::SetArrayArgument;
Alessio Bazzica8f319a32019-07-24 16:47:02 +000058using ::testing::SizeIs;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010059using ::testing::WithArg;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000060
61namespace webrtc {
62
63// This function is called when inserting a packet list into the mock packet
64// buffer. The purpose is to delete all inserted packets properly, to avoid
65// memory leaks in the test.
66int DeletePacketsAndReturnOk(PacketList* packet_list) {
ossua73f6c92016-10-24 08:25:28 -070067 packet_list->clear();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000068 return PacketBuffer::kOK;
69}
70
71class NetEqImplTest : public ::testing::Test {
72 protected:
Alessio Bazzica8f319a32019-07-24 16:47:02 +000073 NetEqImplTest() : clock_(0) { config_.sample_rate_hz = 8000; }
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000074
Niels Möllera0f44302018-11-30 10:45:12 +010075 void CreateInstance(
76 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) {
77 ASSERT_TRUE(decoder_factory);
Ivo Creusen3ce44a32019-10-31 14:38:11 +010078 NetEqImpl::Dependencies deps(config_, &clock_, decoder_factory,
79 DefaultNetEqControllerFactory());
henrik.lundin1d9061e2016-04-26 12:19:34 -070080
81 // Get a local pointer to NetEq's TickTimer object.
82 tick_timer_ = deps.tick_timer.get();
83
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000084 if (use_mock_decoder_database_) {
henrik.lundin1d9061e2016-04-26 12:19:34 -070085 std::unique_ptr<MockDecoderDatabase> mock(new MockDecoderDatabase);
86 mock_decoder_database_ = mock.get();
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000087 EXPECT_CALL(*mock_decoder_database_, GetActiveCngDecoder())
88 .WillOnce(ReturnNull());
henrik.lundin1d9061e2016-04-26 12:19:34 -070089 deps.decoder_database = std::move(mock);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000090 }
henrik.lundin1d9061e2016-04-26 12:19:34 -070091 decoder_database_ = deps.decoder_database.get();
henrik.lundin@webrtc.orgd9faa462014-01-14 10:18:45 +000092
henrik.lundin1d9061e2016-04-26 12:19:34 -070093 if (use_mock_dtmf_buffer_) {
94 std::unique_ptr<MockDtmfBuffer> mock(
95 new MockDtmfBuffer(config_.sample_rate_hz));
96 mock_dtmf_buffer_ = mock.get();
97 deps.dtmf_buffer = std::move(mock);
98 }
99 dtmf_buffer_ = deps.dtmf_buffer.get();
100
101 if (use_mock_dtmf_tone_generator_) {
102 std::unique_ptr<MockDtmfToneGenerator> mock(new MockDtmfToneGenerator);
103 mock_dtmf_tone_generator_ = mock.get();
104 deps.dtmf_tone_generator = std::move(mock);
105 }
106 dtmf_tone_generator_ = deps.dtmf_tone_generator.get();
107
108 if (use_mock_packet_buffer_) {
109 std::unique_ptr<MockPacketBuffer> mock(
110 new MockPacketBuffer(config_.max_packets_in_buffer, tick_timer_));
111 mock_packet_buffer_ = mock.get();
112 deps.packet_buffer = std::move(mock);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700113 }
114 packet_buffer_ = deps.packet_buffer.get();
115
Ivo Creusen53a31f72019-10-24 15:20:39 +0200116 if (use_mock_neteq_controller_) {
117 std::unique_ptr<MockNetEqController> mock(new MockNetEqController());
118 mock_neteq_controller_ = mock.get();
119 deps.neteq_controller = std::move(mock);
120 } else {
121 deps.stats = std::make_unique<StatisticsCalculator>();
122 NetEqController::Config controller_config;
123 controller_config.tick_timer = tick_timer_;
124 controller_config.base_min_delay_ms = config_.min_delay_ms;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200125 controller_config.allow_time_stretching = true;
126 controller_config.max_packets_in_buffer = config_.max_packets_in_buffer;
Ivo Creusen88636c62020-01-24 11:04:56 +0100127 controller_config.clock = &clock_;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200128 deps.neteq_controller =
129 std::make_unique<DecisionLogic>(std::move(controller_config));
130 }
131 neteq_controller_ = deps.neteq_controller.get();
132
henrik.lundin1d9061e2016-04-26 12:19:34 -0700133 if (use_mock_payload_splitter_) {
ossua70695a2016-09-22 02:06:28 -0700134 std::unique_ptr<MockRedPayloadSplitter> mock(new MockRedPayloadSplitter);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700135 mock_payload_splitter_ = mock.get();
ossua70695a2016-09-22 02:06:28 -0700136 deps.red_payload_splitter = std::move(mock);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700137 }
ossua70695a2016-09-22 02:06:28 -0700138 red_payload_splitter_ = deps.red_payload_splitter.get();
henrik.lundin1d9061e2016-04-26 12:19:34 -0700139
140 deps.timestamp_scaler = std::unique_ptr<TimestampScaler>(
141 new TimestampScaler(*deps.decoder_database.get()));
142
143 neteq_.reset(new NetEqImpl(config_, std::move(deps)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000144 ASSERT_TRUE(neteq_ != NULL);
145 }
146
Niels Möllera0f44302018-11-30 10:45:12 +0100147 void CreateInstance() { CreateInstance(CreateBuiltinAudioDecoderFactory()); }
148
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000149 void UseNoMocks() {
150 ASSERT_TRUE(neteq_ == NULL) << "Must call UseNoMocks before CreateInstance";
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000151 use_mock_decoder_database_ = false;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200152 use_mock_neteq_controller_ = false;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000153 use_mock_dtmf_buffer_ = false;
154 use_mock_dtmf_tone_generator_ = false;
155 use_mock_packet_buffer_ = false;
156 use_mock_payload_splitter_ = false;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000157 }
158
159 virtual ~NetEqImplTest() {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000160 if (use_mock_decoder_database_) {
161 EXPECT_CALL(*mock_decoder_database_, Die()).Times(1);
162 }
Ivo Creusen53a31f72019-10-24 15:20:39 +0200163 if (use_mock_neteq_controller_) {
164 EXPECT_CALL(*mock_neteq_controller_, Die()).Times(1);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000165 }
166 if (use_mock_dtmf_buffer_) {
167 EXPECT_CALL(*mock_dtmf_buffer_, Die()).Times(1);
168 }
169 if (use_mock_dtmf_tone_generator_) {
170 EXPECT_CALL(*mock_dtmf_tone_generator_, Die()).Times(1);
171 }
172 if (use_mock_packet_buffer_) {
173 EXPECT_CALL(*mock_packet_buffer_, Die()).Times(1);
174 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000175 }
176
Niels Möller05543682019-01-10 16:55:06 +0100177 void TestDtmfPacket(int sample_rate_hz) {
solenberg2779bab2016-11-17 04:45:19 -0800178 const size_t kPayloadLength = 4;
179 const uint8_t kPayloadType = 110;
solenberg2779bab2016-11-17 04:45:19 -0800180 const int kSampleRateHz = 16000;
181 config_.sample_rate_hz = kSampleRateHz;
182 UseNoMocks();
183 CreateInstance();
184 // Event: 2, E bit, Volume: 17, Length: 4336.
Jonas Olssona4d87372019-07-05 19:08:33 +0200185 uint8_t payload[kPayloadLength] = {0x02, 0x80 + 0x11, 0x10, 0xF0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700186 RTPHeader rtp_header;
187 rtp_header.payloadType = kPayloadType;
188 rtp_header.sequenceNumber = 0x1234;
189 rtp_header.timestamp = 0x12345678;
190 rtp_header.ssrc = 0x87654321;
solenberg2779bab2016-11-17 04:45:19 -0800191
Niels Möller05543682019-01-10 16:55:06 +0100192 EXPECT_TRUE(neteq_->RegisterPayloadType(
193 kPayloadType, SdpAudioFormat("telephone-event", sample_rate_hz, 1)));
solenberg2779bab2016-11-17 04:45:19 -0800194
195 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200196 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
solenberg2779bab2016-11-17 04:45:19 -0800197
198 // Pull audio once.
199 const size_t kMaxOutputSize =
200 static_cast<size_t>(10 * kSampleRateHz / 1000);
201 AudioFrame output;
202 bool muted;
203 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
204 ASSERT_FALSE(muted);
205 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
206 EXPECT_EQ(1u, output.num_channels_);
207 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
208
Artem Titovd00ce742021-07-28 20:00:17 +0200209 // DTMF packets are immediately consumed by `InsertPacket()` and won't be
210 // returned by `GetAudio()`.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000211 EXPECT_THAT(output.packet_infos_, IsEmpty());
212
solenberg2779bab2016-11-17 04:45:19 -0800213 // Verify first 64 samples of actual output.
Jonas Olssona4d87372019-07-05 19:08:33 +0200214 const std::vector<int16_t> kOutput(
215 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
216 -1578, -2816, -3460, -3403, -2709, -1594, -363, 671, 1269, 1328,
217 908, 202, -513, -964, -955, -431, 504, 1617, 2602, 3164,
218 3101, 2364, 1073, -511, -2047, -3198, -3721, -3525, -2688, -1440,
219 -99, 1015, 1663, 1744, 1319, 588, -171, -680, -747, -315,
220 515, 1512, 2378, 2828, 2674, 1877, 568, -986, -2446, -3482,
221 -3864, -3516, -2534, -1163});
solenberg2779bab2016-11-17 04:45:19 -0800222 ASSERT_GE(kMaxOutputSize, kOutput.size());
yujo36b1a5f2017-06-12 12:45:32 -0700223 EXPECT_TRUE(std::equal(kOutput.begin(), kOutput.end(), output.data()));
solenberg2779bab2016-11-17 04:45:19 -0800224 }
225
henrik.lundin1d9061e2016-04-26 12:19:34 -0700226 std::unique_ptr<NetEqImpl> neteq_;
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000227 NetEq::Config config_;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000228 SimulatedClock clock_;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700229 TickTimer* tick_timer_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700230 MockDecoderDatabase* mock_decoder_database_ = nullptr;
231 DecoderDatabase* decoder_database_ = nullptr;
232 bool use_mock_decoder_database_ = true;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200233 MockNetEqController* mock_neteq_controller_ = nullptr;
234 NetEqController* neteq_controller_ = nullptr;
235 bool use_mock_neteq_controller_ = true;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700236 MockDtmfBuffer* mock_dtmf_buffer_ = nullptr;
237 DtmfBuffer* dtmf_buffer_ = nullptr;
238 bool use_mock_dtmf_buffer_ = true;
239 MockDtmfToneGenerator* mock_dtmf_tone_generator_ = nullptr;
240 DtmfToneGenerator* dtmf_tone_generator_ = nullptr;
241 bool use_mock_dtmf_tone_generator_ = true;
242 MockPacketBuffer* mock_packet_buffer_ = nullptr;
243 PacketBuffer* packet_buffer_ = nullptr;
244 bool use_mock_packet_buffer_ = true;
ossua70695a2016-09-22 02:06:28 -0700245 MockRedPayloadSplitter* mock_payload_splitter_ = nullptr;
246 RedPayloadSplitter* red_payload_splitter_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700247 bool use_mock_payload_splitter_ = true;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000248};
249
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000250// This tests the interface class NetEq.
251// TODO(hlundin): Move to separate file?
252TEST(NetEq, CreateAndDestroy) {
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000253 NetEq::Config config;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000254 SimulatedClock clock(0);
Ivo Creusen39cf3c72019-11-28 14:07:14 +0100255 auto decoder_factory = CreateBuiltinAudioDecoderFactory();
256 std::unique_ptr<NetEq> neteq =
257 DefaultNetEqFactory().CreateNetEq(config, decoder_factory, &clock);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000258}
259
kwiberg5adaf732016-10-04 09:33:27 -0700260TEST_F(NetEqImplTest, RegisterPayloadType) {
261 CreateInstance();
262 constexpr int rtp_payload_type = 0;
263 const SdpAudioFormat format("pcmu", 8000, 1);
264 EXPECT_CALL(*mock_decoder_database_,
265 RegisterPayload(rtp_payload_type, format));
266 neteq_->RegisterPayloadType(rtp_payload_type, format);
267}
268
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000269TEST_F(NetEqImplTest, RemovePayloadType) {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000270 CreateInstance();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000271 uint8_t rtp_payload_type = 0;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000272 EXPECT_CALL(*mock_decoder_database_, Remove(rtp_payload_type))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000273 .WillOnce(Return(DecoderDatabase::kDecoderNotFound));
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200274 // Check that kOK is returned when database returns kDecoderNotFound, because
275 // removing a payload type that was never registered is not an error.
276 EXPECT_EQ(NetEq::kOK, neteq_->RemovePayloadType(rtp_payload_type));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000277}
278
kwiberg6b19b562016-09-20 04:02:25 -0700279TEST_F(NetEqImplTest, RemoveAllPayloadTypes) {
280 CreateInstance();
281 EXPECT_CALL(*mock_decoder_database_, RemoveAll()).WillOnce(Return());
282 neteq_->RemoveAllPayloadTypes();
283}
284
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000285TEST_F(NetEqImplTest, InsertPacket) {
Ivo Creusena2b31c32020-10-14 17:54:22 +0200286 using ::testing::AllOf;
287 using ::testing::Field;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000288 CreateInstance();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000289 const size_t kPayloadLength = 100;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000290 const uint8_t kPayloadType = 0;
291 const uint16_t kFirstSequenceNumber = 0x1234;
292 const uint32_t kFirstTimestamp = 0x12345678;
293 const uint32_t kSsrc = 0x87654321;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000294 uint8_t payload[kPayloadLength] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700295 RTPHeader rtp_header;
296 rtp_header.payloadType = kPayloadType;
297 rtp_header.sequenceNumber = kFirstSequenceNumber;
298 rtp_header.timestamp = kFirstTimestamp;
299 rtp_header.ssrc = kSsrc;
ossu7a377612016-10-18 04:06:13 -0700300 Packet fake_packet;
301 fake_packet.payload_type = kPayloadType;
302 fake_packet.sequence_number = kFirstSequenceNumber;
303 fake_packet.timestamp = kFirstTimestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000304
Tommi87f70902021-04-27 14:43:08 +0200305 auto mock_decoder_factory = rtc::make_ref_counted<MockAudioDecoderFactory>();
Karl Wibergd6fbf2a2018-02-27 13:37:31 +0100306 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _, _))
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800307 .WillOnce(Invoke([&](const SdpAudioFormat& format,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200308 absl::optional<AudioCodecPairId> codec_pair_id,
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800309 std::unique_ptr<AudioDecoder>* dec) {
kwibergc0f2dcf2016-05-31 06:28:03 -0700310 EXPECT_EQ("pcmu", format.name);
311
312 std::unique_ptr<MockAudioDecoder> mock_decoder(new MockAudioDecoder);
313 EXPECT_CALL(*mock_decoder, Channels()).WillRepeatedly(Return(1));
314 EXPECT_CALL(*mock_decoder, SampleRateHz()).WillRepeatedly(Return(8000));
kwibergc0f2dcf2016-05-31 06:28:03 -0700315 EXPECT_CALL(*mock_decoder, Die()).Times(1); // Called when deleted.
316
317 *dec = std::move(mock_decoder);
318 }));
Niels Möller72899062019-01-11 09:36:13 +0100319 DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
320 absl::nullopt, mock_decoder_factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000321
322 // Expectations for decoder database.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000323 EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000324 .WillRepeatedly(Return(&info));
325
326 // Expectations for packet buffer.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000327 EXPECT_CALL(*mock_packet_buffer_, Empty())
328 .WillOnce(Return(false)); // Called once after first packet is inserted.
Ivo Creusen7b463c52020-11-25 11:32:40 +0100329 EXPECT_CALL(*mock_packet_buffer_, Flush(_)).Times(1);
330 EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _, _, _, _, _))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000331 .Times(2)
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100332 .WillRepeatedly(DoAll(SetArgPointee<2>(kPayloadType),
333 WithArg<0>(Invoke(DeletePacketsAndReturnOk))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000334 // SetArgPointee<2>(kPayloadType) means that the third argument (zero-based
335 // index) is a pointer, and the variable pointed to is set to kPayloadType.
336 // Also invoke the function DeletePacketsAndReturnOk to properly delete all
337 // packets in the list (to avoid memory leaks in the test).
ossu7a377612016-10-18 04:06:13 -0700338 EXPECT_CALL(*mock_packet_buffer_, PeekNextPacket())
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000339 .Times(1)
ossu7a377612016-10-18 04:06:13 -0700340 .WillOnce(Return(&fake_packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000341
342 // Expectations for DTMF buffer.
Jonas Olssona4d87372019-07-05 19:08:33 +0200343 EXPECT_CALL(*mock_dtmf_buffer_, Flush()).Times(1);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000344
345 // Expectations for delay manager.
346 {
347 // All expectations within this block must be called in this specific order.
348 InSequence sequence; // Dummy variable.
349 // Expectations when the first packet is inserted.
Ivo Creusena2b31c32020-10-14 17:54:22 +0200350 EXPECT_CALL(
351 *mock_neteq_controller_,
352 PacketArrived(
353 /*fs_hz*/ 8000,
354 /*should_update_stats*/ _,
355 /*info*/
356 AllOf(
357 Field(&NetEqController::PacketArrivedInfo::is_cng_or_dtmf,
358 false),
359 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
360 kFirstSequenceNumber),
361 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
362 kFirstTimestamp))));
363 EXPECT_CALL(
364 *mock_neteq_controller_,
365 PacketArrived(
366 /*fs_hz*/ 8000,
367 /*should_update_stats*/ _,
368 /*info*/
369 AllOf(
370 Field(&NetEqController::PacketArrivedInfo::is_cng_or_dtmf,
371 false),
372 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
373 kFirstSequenceNumber + 1),
374 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
375 kFirstTimestamp + 160))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000376 }
377
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000378 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200379 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000380
381 // Insert second packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700382 rtp_header.timestamp += 160;
383 rtp_header.sequenceNumber += 1;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200384 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000385}
386
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000387TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
388 UseNoMocks();
389 CreateInstance();
390
391 const int kPayloadLengthSamples = 80;
392 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
Jonas Olssona4d87372019-07-05 19:08:33 +0200393 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000394 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700395 RTPHeader rtp_header;
396 rtp_header.payloadType = kPayloadType;
397 rtp_header.sequenceNumber = 0x1234;
398 rtp_header.timestamp = 0x12345678;
399 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000400
Niels Möller05543682019-01-10 16:55:06 +0100401 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
402 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000403
404 // Insert packets. The buffer should not flush.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700405 for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) {
Karl Wiberg45eb1352019-10-10 14:23:00 +0200406 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700407 rtp_header.timestamp += kPayloadLengthSamples;
408 rtp_header.sequenceNumber += 1;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000409 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
410 }
411
412 // Insert one more packet and make sure the buffer got flushed. That is, it
413 // should only hold one single packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200414 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700415 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700416 const Packet* test_packet = packet_buffer_->PeekNextPacket();
henrik.lundin246ef3e2017-04-24 09:14:32 -0700417 EXPECT_EQ(rtp_header.timestamp, test_packet->timestamp);
418 EXPECT_EQ(rtp_header.sequenceNumber, test_packet->sequence_number);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000419}
420
solenberg2779bab2016-11-17 04:45:19 -0800421TEST_F(NetEqImplTest, TestDtmfPacketAVT) {
Niels Möller05543682019-01-10 16:55:06 +0100422 TestDtmfPacket(8000);
solenberg2779bab2016-11-17 04:45:19 -0800423}
solenberg99df6c02016-10-11 04:35:34 -0700424
solenberg2779bab2016-11-17 04:45:19 -0800425TEST_F(NetEqImplTest, TestDtmfPacketAVT16kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100426 TestDtmfPacket(16000);
solenberg2779bab2016-11-17 04:45:19 -0800427}
solenberg99df6c02016-10-11 04:35:34 -0700428
solenberg2779bab2016-11-17 04:45:19 -0800429TEST_F(NetEqImplTest, TestDtmfPacketAVT32kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100430 TestDtmfPacket(32000);
solenberg2779bab2016-11-17 04:45:19 -0800431}
solenberg99df6c02016-10-11 04:35:34 -0700432
solenberg2779bab2016-11-17 04:45:19 -0800433TEST_F(NetEqImplTest, TestDtmfPacketAVT48kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100434 TestDtmfPacket(48000);
solenberg99df6c02016-10-11 04:35:34 -0700435}
436
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000437// This test verifies that timestamps propagate from the incoming packets
438// through to the sync buffer and to the playout timestamp.
439TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000440 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000441 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700442 const size_t kPayloadLengthSamples =
443 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000444 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
445 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700446 RTPHeader rtp_header;
447 rtp_header.payloadType = kPayloadType;
448 rtp_header.sequenceNumber = 0x1234;
449 rtp_header.timestamp = 0x12345678;
450 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000451 rtp_header.numCSRCs = 3;
452 rtp_header.arrOfCSRCs[0] = 43;
453 rtp_header.arrOfCSRCs[1] = 65;
454 rtp_header.arrOfCSRCs[2] = 17;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000455
456 // This is a dummy decoder that produces as many output samples as the input
457 // has bytes. The output is an increasing series, starting at 1 for the first
458 // sample, and then increasing by 1 for each sample.
459 class CountingSamplesDecoder : public AudioDecoder {
460 public:
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000461 CountingSamplesDecoder() : next_value_(1) {}
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000462
Artem Titovd00ce742021-07-28 20:00:17 +0200463 // Produce as many samples as input bytes (`encoded_len`).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100464 int DecodeInternal(const uint8_t* encoded,
465 size_t encoded_len,
466 int /* sample_rate_hz */,
467 int16_t* decoded,
468 SpeechType* speech_type) override {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000469 for (size_t i = 0; i < encoded_len; ++i) {
470 decoded[i] = next_value_++;
471 }
472 *speech_type = kSpeech;
Mirko Bonadei737e0732017-10-19 09:00:17 +0200473 return rtc::checked_cast<int>(encoded_len);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000474 }
475
Karl Wiberg43766482015-08-27 15:22:11 +0200476 void Reset() override { next_value_ = 1; }
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000477
kwiberg347d3512016-06-16 01:59:09 -0700478 int SampleRateHz() const override { return kSampleRateHz; }
479
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000480 size_t Channels() const override { return 1; }
481
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000482 uint16_t next_value() const { return next_value_; }
483
484 private:
485 int16_t next_value_;
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000486 } decoder_;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000487
Tommi87f70902021-04-27 14:43:08 +0200488 auto decoder_factory =
489 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&decoder_);
Niels Möllerb7180c02018-12-06 13:07:11 +0100490
491 UseNoMocks();
492 CreateInstance(decoder_factory);
493
494 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
Niels Möllera1eb9c72018-12-07 15:24:42 +0100495 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000496
497 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000498 clock_.AdvanceTimeMilliseconds(123456);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200499 Timestamp expected_receive_time = clock_.CurrentTime();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200500 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000501
502 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700503 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800504 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700505 bool muted;
506 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
507 ASSERT_FALSE(muted);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800508 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
509 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800510 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000511
Artem Titovcfea2182021-08-10 01:22:31 +0200512 // Verify `output.packet_infos_`.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000513 ASSERT_THAT(output.packet_infos_, SizeIs(1));
514 {
515 const auto& packet_info = output.packet_infos_[0];
516 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
517 EXPECT_THAT(packet_info.csrcs(), ElementsAre(43, 65, 17));
518 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
519 EXPECT_FALSE(packet_info.audio_level().has_value());
Johannes Kronf7de74c2021-04-30 13:10:56 +0200520 EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000521 }
522
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000523 // Start with a simple check that the fake decoder is behaving as expected.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700524 EXPECT_EQ(kPayloadLengthSamples,
525 static_cast<size_t>(decoder_.next_value() - 1));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000526
527 // The value of the last of the output samples is the same as the number of
528 // samples played from the decoded packet. Thus, this number + the RTP
529 // timestamp should match the playout timestamp.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200530 // Wrap the expected value in an absl::optional to compare them as such.
henrik.lundin9a410dd2016-04-06 01:39:22 -0700531 EXPECT_EQ(
Danil Chapovalovb6021232018-06-19 13:26:36 +0200532 absl::optional<uint32_t>(rtp_header.timestamp +
533 output.data()[output.samples_per_channel_ - 1]),
henrik.lundin9a410dd2016-04-06 01:39:22 -0700534 neteq_->GetPlayoutTimestamp());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000535
536 // Check the timestamp for the last value in the sync buffer. This should
537 // be one full frame length ahead of the RTP timestamp.
538 const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
539 ASSERT_TRUE(sync_buffer != NULL);
henrik.lundin246ef3e2017-04-24 09:14:32 -0700540 EXPECT_EQ(rtp_header.timestamp + kPayloadLengthSamples,
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000541 sync_buffer->end_timestamp());
542
543 // Check that the number of samples still to play from the sync buffer add
544 // up with what was already played out.
henrik.lundin6d8e0112016-03-04 10:34:21 -0800545 EXPECT_EQ(
yujo36b1a5f2017-06-12 12:45:32 -0700546 kPayloadLengthSamples - output.data()[output.samples_per_channel_ - 1],
henrik.lundin6d8e0112016-03-04 10:34:21 -0800547 sync_buffer->FutureLength());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000548}
549
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000550TEST_F(NetEqImplTest, ReorderedPacket) {
551 UseNoMocks();
Minyue Li57d13102021-08-19 14:30:45 +0200552
Niels Möllera1eb9c72018-12-07 15:24:42 +0100553 // Create a mock decoder object.
554 MockAudioDecoder mock_decoder;
555
556 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +0200557 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000558
559 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000560 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700561 const size_t kPayloadLengthSamples =
562 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000563 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
564 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700565 RTPHeader rtp_header;
566 rtp_header.payloadType = kPayloadType;
567 rtp_header.sequenceNumber = 0x1234;
568 rtp_header.timestamp = 0x12345678;
569 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000570 rtp_header.extension.hasAudioLevel = true;
571 rtp_header.extension.audioLevel = 42;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000572
Karl Wiberg43766482015-08-27 15:22:11 +0200573 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700574 EXPECT_CALL(mock_decoder, SampleRateHz())
575 .WillRepeatedly(Return(kSampleRateHz));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000576 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin034154b2016-04-27 06:11:50 -0700577 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeiea7a3f82017-10-19 11:40:55 +0200578 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000579 int16_t dummy_output[kPayloadLengthSamples] = {0};
580 // The below expectation will make the mock decoder write
Artem Titovd00ce742021-07-28 20:00:17 +0200581 // `kPayloadLengthSamples` zeros to the output array, and mark it as speech.
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100582 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
583 kSampleRateHz, _, _))
584 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000585 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100586 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200587 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
Niels Möllera1eb9c72018-12-07 15:24:42 +0100588 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
589 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000590
591 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000592 clock_.AdvanceTimeMilliseconds(123456);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200593 Timestamp expected_receive_time = clock_.CurrentTime();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200594 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000595
596 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700597 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800598 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700599 bool muted;
600 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800601 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
602 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800603 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000604
Artem Titovcfea2182021-08-10 01:22:31 +0200605 // Verify `output.packet_infos_`.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000606 ASSERT_THAT(output.packet_infos_, SizeIs(1));
607 {
608 const auto& packet_info = output.packet_infos_[0];
609 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
610 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
611 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
612 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200613 EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000614 }
615
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000616 // Insert two more packets. The first one is out of order, and is already too
617 // old, the second one is the expected next packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700618 rtp_header.sequenceNumber -= 1;
619 rtp_header.timestamp -= kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000620 rtp_header.extension.audioLevel = 1;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000621 payload[0] = 1;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000622 clock_.AdvanceTimeMilliseconds(1000);
Karl Wiberg45eb1352019-10-10 14:23:00 +0200623 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700624 rtp_header.sequenceNumber += 2;
625 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000626 rtp_header.extension.audioLevel = 2;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000627 payload[0] = 2;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000628 clock_.AdvanceTimeMilliseconds(2000);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200629 expected_receive_time = clock_.CurrentTime();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200630 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000631
632 // Expect only the second packet to be decoded (the one with "2" as the first
633 // payload byte).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100634 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
635 kSampleRateHz, _, _))
636 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000637 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100638 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200639 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000640
641 // Pull audio once.
henrik.lundin7a926812016-05-12 13:51:28 -0700642 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800643 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
644 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800645 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000646
647 // Now check the packet buffer, and make sure it is empty, since the
648 // out-of-order packet should have been discarded.
649 EXPECT_TRUE(packet_buffer_->Empty());
650
Minyue Li57d13102021-08-19 14:30:45 +0200651 // NetEq `discarded_primary_packets` should capture this packet discard.
652 EXPECT_EQ(1u, neteq_->GetOperationsAndState().discarded_primary_packets);
653
Artem Titovcfea2182021-08-10 01:22:31 +0200654 // Verify `output.packet_infos_`. Expect to only see the second packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000655 ASSERT_THAT(output.packet_infos_, SizeIs(1));
656 {
657 const auto& packet_info = output.packet_infos_[0];
658 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
659 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
660 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
661 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200662 EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000663 }
664
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000665 EXPECT_CALL(mock_decoder, Die());
666}
667
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000668// This test verifies that NetEq can handle the situation where the first
669// incoming packet is rejected.
henrik.lundin@webrtc.org6ff3ac12014-11-20 14:14:49 +0000670TEST_F(NetEqImplTest, FirstPacketUnknown) {
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000671 UseNoMocks();
672 CreateInstance();
673
674 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000675 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700676 const size_t kPayloadLengthSamples =
677 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundinc9ec8752016-10-13 02:43:34 -0700678 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000679 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700680 RTPHeader rtp_header;
681 rtp_header.payloadType = kPayloadType;
682 rtp_header.sequenceNumber = 0x1234;
683 rtp_header.timestamp = 0x12345678;
684 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000685
686 // Insert one packet. Note that we have not registered any payload type, so
687 // this packet will be rejected.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200688 EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000689
690 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700691 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800692 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700693 bool muted;
694 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800695 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
696 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
697 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800698 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000699 EXPECT_THAT(output.packet_infos_, IsEmpty());
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000700
701 // Register the payload type.
Niels Möller05543682019-01-10 16:55:06 +0100702 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
703 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000704
705 // Insert 10 packets.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700706 for (size_t i = 0; i < 10; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -0700707 rtp_header.sequenceNumber++;
708 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200709 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000710 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
711 }
712
713 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700714 for (size_t i = 0; i < 3; ++i) {
henrik.lundin7a926812016-05-12 13:51:28 -0700715 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800716 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
717 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
718 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800719 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000720 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000721 EXPECT_THAT(output.packet_infos_, SizeIs(1));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000722 }
723}
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000724
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200725// This test verifies that audio interruption is not logged for the initial
726// PLC period before the first packet is deocoded.
727// TODO(henrik.lundin) Maybe move this test to neteq_network_stats_unittest.cc.
Henrik Lundinfe047752019-11-19 12:58:11 +0100728// Make the test parametrized, so that we can test with different initial
729// sample rates in NetEq.
730class NetEqImplTestSampleRateParameter
731 : public NetEqImplTest,
732 public testing::WithParamInterface<int> {
733 protected:
734 NetEqImplTestSampleRateParameter()
735 : NetEqImplTest(), initial_sample_rate_hz_(GetParam()) {
736 config_.sample_rate_hz = initial_sample_rate_hz_;
737 }
738
739 const int initial_sample_rate_hz_;
740};
741
Jared Siskinf2ed4012021-06-18 10:45:16 -0700742class NetEqImplTestSdpFormatParameter
743 : public NetEqImplTest,
744 public testing::WithParamInterface<SdpAudioFormat> {
745 protected:
746 NetEqImplTestSdpFormatParameter()
747 : NetEqImplTest(), sdp_format_(GetParam()) {}
748 const SdpAudioFormat sdp_format_;
749};
750
Henrik Lundinfe047752019-11-19 12:58:11 +0100751// This test does the following:
752// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
753// sample rate of 16000.
754// 1. Start calling GetAudio before inserting any encoded audio. The audio
755// produced will be PLC.
756// 2. Insert a number of encoded audio packets.
757// 3. Keep calling GetAudio and verify that no audio interruption was logged.
758// Call GetAudio until NetEq runs out of data again; PLC starts.
759// 4. Insert one more packet.
760// 5. Call GetAudio until that packet is decoded and the PLC ends.
761
762TEST_P(NetEqImplTestSampleRateParameter,
763 NoAudioInterruptionLoggedBeforeFirstDecode) {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200764 UseNoMocks();
765 CreateInstance();
766
767 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundinfe047752019-11-19 12:58:11 +0100768 const int kPayloadSampleRateHz = 16000;
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200769 const size_t kPayloadLengthSamples =
Henrik Lundinfe047752019-11-19 12:58:11 +0100770 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200771 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
772 uint8_t payload[kPayloadLengthBytes] = {0};
773 RTPHeader rtp_header;
774 rtp_header.payloadType = kPayloadType;
775 rtp_header.sequenceNumber = 0x1234;
776 rtp_header.timestamp = 0x12345678;
777 rtp_header.ssrc = 0x87654321;
778
779 // Register the payload type.
Henrik Lundinfe047752019-11-19 12:58:11 +0100780 EXPECT_TRUE(neteq_->RegisterPayloadType(
781 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200782
783 // Pull audio several times. No packets have been inserted yet.
Henrik Lundinfe047752019-11-19 12:58:11 +0100784 const size_t initial_output_size =
785 static_cast<size_t>(10 * initial_sample_rate_hz_ / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200786 AudioFrame output;
787 bool muted;
788 for (int i = 0; i < 100; ++i) {
789 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100790 EXPECT_EQ(initial_output_size, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200791 EXPECT_EQ(1u, output.num_channels_);
792 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000793 EXPECT_THAT(output.packet_infos_, IsEmpty());
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200794 }
795
Henrik Lundinfe047752019-11-19 12:58:11 +0100796 // Lambda for inserting packets.
797 auto insert_packet = [&]() {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200798 rtp_header.sequenceNumber++;
799 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200800 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundinfe047752019-11-19 12:58:11 +0100801 };
802 // Insert 10 packets.
803 for (size_t i = 0; i < 10; ++i) {
804 insert_packet();
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200805 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
806 }
807
808 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Henrik Lundinfe047752019-11-19 12:58:11 +0100809 constexpr size_t kOutputSize =
810 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200811 for (size_t i = 0; i < 3; ++i) {
812 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100813 EXPECT_EQ(kOutputSize, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200814 EXPECT_EQ(1u, output.num_channels_);
815 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
816 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000817 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200818 }
819
Henrik Lundinfe047752019-11-19 12:58:11 +0100820 // Verify that no interruption was logged.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200821 auto lifetime_stats = neteq_->GetLifetimeStatistics();
Henrik Lundin44125fa2019-04-29 17:00:46 +0200822 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundinfe047752019-11-19 12:58:11 +0100823
824 // Keep pulling audio data until a new PLC period is started.
825 size_t count_loops = 0;
826 while (output.speech_type_ == AudioFrame::kNormalSpeech) {
827 // Make sure we don't hang the test if we never go to PLC.
828 ASSERT_LT(++count_loops, 100u);
829 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
830 }
831
Jakob Ivarsson80fb9782020-10-09 13:41:06 +0200832 // Insert a few packets to avoid postpone decoding after expand.
833 for (size_t i = 0; i < 5; ++i) {
834 insert_packet();
835 }
Henrik Lundinfe047752019-11-19 12:58:11 +0100836
837 // Pull audio until the newly inserted packet is decoded and the PLC ends.
838 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
839 // Make sure we don't hang the test if we never go to PLC.
840 ASSERT_LT(++count_loops, 100u);
841 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
842 }
843
844 // Verify that no interruption was logged.
845 lifetime_stats = neteq_->GetLifetimeStatistics();
846 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200847}
848
Henrik Lundinfe047752019-11-19 12:58:11 +0100849// This test does the following:
850// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
851// sample rate of 16000.
852// 1. Insert a number of encoded audio packets.
853// 2. Call GetAudio and verify that decoded audio is produced.
854// 3. Keep calling GetAudio until NetEq runs out of data; PLC starts.
855// 4. Keep calling GetAudio until PLC has been produced for at least 150 ms.
856// 5. Insert one more packet.
857// 6. Call GetAudio until that packet is decoded and the PLC ends.
858// 7. Verify that an interruption was logged.
859
860TEST_P(NetEqImplTestSampleRateParameter, AudioInterruptionLogged) {
861 UseNoMocks();
862 CreateInstance();
863
864 const uint8_t kPayloadType = 17; // Just an arbitrary number.
865 const int kPayloadSampleRateHz = 16000;
866 const size_t kPayloadLengthSamples =
867 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
868 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
869 uint8_t payload[kPayloadLengthBytes] = {0};
870 RTPHeader rtp_header;
871 rtp_header.payloadType = kPayloadType;
872 rtp_header.sequenceNumber = 0x1234;
873 rtp_header.timestamp = 0x12345678;
874 rtp_header.ssrc = 0x87654321;
875
876 // Register the payload type.
877 EXPECT_TRUE(neteq_->RegisterPayloadType(
878 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
879
880 // Lambda for inserting packets.
881 auto insert_packet = [&]() {
882 rtp_header.sequenceNumber++;
883 rtp_header.timestamp += kPayloadLengthSamples;
884 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
885 };
886 // Insert 10 packets.
887 for (size_t i = 0; i < 10; ++i) {
888 insert_packet();
889 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
890 }
891
892 AudioFrame output;
893 bool muted;
894 // Keep pulling audio data until a new PLC period is started.
895 size_t count_loops = 0;
896 do {
897 // Make sure we don't hang the test if we never go to PLC.
898 ASSERT_LT(++count_loops, 100u);
899 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
900 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
901
902 // Pull audio 15 times, which produces 150 ms of output audio. This should
903 // all be produced as PLC. The total length of the gap will then be 150 ms
904 // plus an initial fraction of 10 ms at the start and the end of the PLC
905 // period. In total, less than 170 ms.
906 for (size_t i = 0; i < 15; ++i) {
907 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
908 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
909 }
910
Jakob Ivarsson80fb9782020-10-09 13:41:06 +0200911 // Insert a few packets to avoid postpone decoding after expand.
912 for (size_t i = 0; i < 5; ++i) {
913 insert_packet();
914 }
Henrik Lundinfe047752019-11-19 12:58:11 +0100915
916 // Pull audio until the newly inserted packet is decoded and the PLC ends.
917 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
918 // Make sure we don't hang the test if we never go to PLC.
919 ASSERT_LT(++count_loops, 100u);
920 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
921 }
922
923 // Verify that the interruption was logged.
924 auto lifetime_stats = neteq_->GetLifetimeStatistics();
925 EXPECT_EQ(1, lifetime_stats.interruption_count);
926 EXPECT_GT(lifetime_stats.total_interruption_duration_ms, 150);
927 EXPECT_LT(lifetime_stats.total_interruption_duration_ms, 170);
928}
929
930INSTANTIATE_TEST_SUITE_P(SampleRates,
931 NetEqImplTestSampleRateParameter,
932 testing::Values(8000, 16000, 32000, 48000));
933
Jared Siskinf2ed4012021-06-18 10:45:16 -0700934TEST_P(NetEqImplTestSdpFormatParameter, GetNackListScaledTimestamp) {
935 UseNoMocks();
936 CreateInstance();
937
938 neteq_->EnableNack(128);
939
940 const uint8_t kPayloadType = 17; // Just an arbitrary number.
941 const int kPayloadSampleRateHz = sdp_format_.clockrate_hz;
942 const size_t kPayloadLengthSamples =
943 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
944 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
945 std::vector<uint8_t> payload(kPayloadLengthBytes, 0);
946 RTPHeader rtp_header;
947 rtp_header.payloadType = kPayloadType;
948 rtp_header.sequenceNumber = 0x1234;
949 rtp_header.timestamp = 0x12345678;
950 rtp_header.ssrc = 0x87654321;
951
952 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType, sdp_format_));
953
954 auto insert_packet = [&](bool lost = false) {
955 rtp_header.sequenceNumber++;
956 rtp_header.timestamp += kPayloadLengthSamples;
957 if (!lost)
958 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
959 };
960
961 // Insert and decode 10 packets.
962 for (size_t i = 0; i < 10; ++i) {
963 insert_packet();
964 }
965 AudioFrame output;
966 size_t count_loops = 0;
967 do {
968 bool muted;
969 // Make sure we don't hang the test if we never go to PLC.
970 ASSERT_LT(++count_loops, 100u);
971 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
972 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
973
974 insert_packet();
975
976 insert_packet(/*lost=*/true);
977
978 // Ensure packet gets marked as missing.
979 for (int i = 0; i < 5; ++i) {
980 insert_packet();
981 }
982
983 // Missing packet recoverable with 5ms RTT.
984 EXPECT_THAT(neteq_->GetNackList(5), Not(IsEmpty()));
985
986 // No packets should have TimeToPlay > 500ms.
987 EXPECT_THAT(neteq_->GetNackList(500), IsEmpty());
988}
989
990INSTANTIATE_TEST_SUITE_P(GetNackList,
991 NetEqImplTestSdpFormatParameter,
992 testing::Values(SdpAudioFormat("g722", 8000, 1),
993 SdpAudioFormat("opus", 48000, 2)));
994
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000995// This test verifies that NetEq can handle comfort noise and enters/quits codec
996// internal CNG mode properly.
997TEST_F(NetEqImplTest, CodecInternalCng) {
998 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +0100999 // Create a mock decoder object.
1000 MockAudioDecoder mock_decoder;
1001 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001002 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001003
1004 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001005 const int kSampleRateKhz = 48;
Peter Kastingdce40cf2015-08-24 14:52:23 -07001006 const size_t kPayloadLengthSamples =
1007 static_cast<size_t>(20 * kSampleRateKhz); // 20 ms.
1008 const size_t kPayloadLengthBytes = 10;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001009 uint8_t payload[kPayloadLengthBytes] = {0};
1010 int16_t dummy_output[kPayloadLengthSamples] = {0};
1011
henrik.lundin246ef3e2017-04-24 09:14:32 -07001012 RTPHeader rtp_header;
1013 rtp_header.payloadType = kPayloadType;
1014 rtp_header.sequenceNumber = 0x1234;
1015 rtp_header.timestamp = 0x12345678;
1016 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001017
Karl Wiberg43766482015-08-27 15:22:11 +02001018 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001019 EXPECT_CALL(mock_decoder, SampleRateHz())
1020 .WillRepeatedly(Return(kSampleRateKhz * 1000));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +00001021 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001022 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001023 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001024 // Packed duration when asking the decoder for more CNG data (without a new
1025 // packet).
1026 EXPECT_CALL(mock_decoder, PacketDuration(nullptr, 0))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001027 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001028
1029 // Pointee(x) verifies that first byte of the payload equals x, this makes it
1030 // possible to verify that the correct payload is fed to Decode().
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001031 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
1032 kSampleRateKhz * 1000, _, _))
1033 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001034 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001035 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001036 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001037
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001038 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes,
1039 kSampleRateKhz * 1000, _, _))
1040 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001041 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001042 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001043 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001044
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001045 EXPECT_CALL(mock_decoder,
1046 DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
1047 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001048 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001049 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001050 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001051
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001052 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
1053 kSampleRateKhz * 1000, _, _))
1054 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001055 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001056 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001057 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001058
Niels Möller50b66d52018-12-11 14:43:21 +01001059 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1060 SdpAudioFormat("opus", 48000, 2)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001061
Peter Kastingdce40cf2015-08-24 14:52:23 -07001062 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001063 AudioFrame output;
henrik.lundin55480f52016-03-08 02:37:57 -08001064 AudioFrame::SpeechType expected_type[8] = {
Jonas Olssona4d87372019-07-05 19:08:33 +02001065 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech, AudioFrame::kCNG,
1066 AudioFrame::kCNG, AudioFrame::kCNG, AudioFrame::kCNG,
1067 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001068 int expected_timestamp_increment[8] = {
1069 -1, // will not be used.
1070 10 * kSampleRateKhz,
Jonas Olssona4d87372019-07-05 19:08:33 +02001071 -1,
1072 -1, // timestamp will be empty during CNG mode; indicated by -1 here.
1073 -1,
1074 -1,
1075 50 * kSampleRateKhz,
1076 10 * kSampleRateKhz};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001077
Jakob Ivarssond723da12021-01-15 17:44:56 +01001078 // Insert one packet (decoder will return speech).
1079 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
1080
henrik.lundin7a926812016-05-12 13:51:28 -07001081 bool muted;
1082 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Danil Chapovalovb6021232018-06-19 13:26:36 +02001083 absl::optional<uint32_t> last_timestamp = neteq_->GetPlayoutTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -07001084 ASSERT_TRUE(last_timestamp);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001085
Jakob Ivarssond723da12021-01-15 17:44:56 +01001086 // Insert second packet (decoder will return CNG).
1087 payload[0] = 1;
1088 rtp_header.sequenceNumber++;
1089 rtp_header.timestamp += kPayloadLengthSamples;
1090 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
1091
henrik.lundin0d96ab72016-04-06 12:28:26 -07001092 // Lambda for verifying the timestamps.
1093 auto verify_timestamp = [&last_timestamp, &expected_timestamp_increment](
Danil Chapovalovb6021232018-06-19 13:26:36 +02001094 absl::optional<uint32_t> ts, size_t i) {
henrik.lundin0d96ab72016-04-06 12:28:26 -07001095 if (expected_timestamp_increment[i] == -1) {
1096 // Expect to get an empty timestamp value during CNG and PLC.
1097 EXPECT_FALSE(ts) << "i = " << i;
1098 } else {
1099 ASSERT_TRUE(ts) << "i = " << i;
1100 EXPECT_EQ(*ts, *last_timestamp + expected_timestamp_increment[i])
1101 << "i = " << i;
1102 last_timestamp = ts;
1103 }
1104 };
1105
Peter Kastingdce40cf2015-08-24 14:52:23 -07001106 for (size_t i = 1; i < 6; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001107 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1108 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001109 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001110 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001111 SCOPED_TRACE("");
1112 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001113 }
1114
1115 // Insert third packet, which leaves a gap from last packet.
1116 payload[0] = 2;
henrik.lundin246ef3e2017-04-24 09:14:32 -07001117 rtp_header.sequenceNumber += 2;
1118 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001119 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001120
Peter Kastingdce40cf2015-08-24 14:52:23 -07001121 for (size_t i = 6; i < 8; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001122 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1123 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001124 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001125 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001126 SCOPED_TRACE("");
1127 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001128 }
1129
1130 // Now check the packet buffer, and make sure it is empty.
1131 EXPECT_TRUE(packet_buffer_->Empty());
1132
1133 EXPECT_CALL(mock_decoder, Die());
1134}
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001135
1136TEST_F(NetEqImplTest, UnsupportedDecoder) {
1137 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001138 ::testing::NiceMock<MockAudioDecoder> decoder;
1139
1140 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001141 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&decoder));
minyue5bd33972016-05-02 04:46:11 -07001142 static const size_t kNetEqMaxFrameSize = 5760; // 120 ms @ 48 kHz.
Peter Kasting69558702016-01-12 16:26:35 -08001143 static const size_t kChannels = 2;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001144
1145 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001146 const int kSampleRateHz = 8000;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001147
Peter Kastingdce40cf2015-08-24 14:52:23 -07001148 const size_t kPayloadLengthSamples =
1149 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001150 const size_t kPayloadLengthBytes = 1;
minyue5bd33972016-05-02 04:46:11 -07001151 uint8_t payload[kPayloadLengthBytes] = {0};
Minyue323b1322015-05-25 13:49:37 +02001152 int16_t dummy_output[kPayloadLengthSamples * kChannels] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001153 RTPHeader rtp_header;
1154 rtp_header.payloadType = kPayloadType;
1155 rtp_header.sequenceNumber = 0x1234;
1156 rtp_header.timestamp = 0x12345678;
1157 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001158
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001159 const uint8_t kFirstPayloadValue = 1;
1160 const uint8_t kSecondPayloadValue = 2;
1161
ossu61a208b2016-09-20 01:38:00 -07001162 EXPECT_CALL(decoder,
1163 PacketDuration(Pointee(kFirstPayloadValue), kPayloadLengthBytes))
1164 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001165 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize + 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001166
ossu61a208b2016-09-20 01:38:00 -07001167 EXPECT_CALL(decoder, DecodeInternal(Pointee(kFirstPayloadValue), _, _, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001168 .Times(0);
1169
ossu61a208b2016-09-20 01:38:00 -07001170 EXPECT_CALL(decoder, DecodeInternal(Pointee(kSecondPayloadValue),
1171 kPayloadLengthBytes, kSampleRateHz, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001172 .Times(1)
ossu61a208b2016-09-20 01:38:00 -07001173 .WillOnce(DoAll(
1174 SetArrayArgument<3>(dummy_output,
1175 dummy_output + kPayloadLengthSamples * kChannels),
1176 SetArgPointee<4>(AudioDecoder::kSpeech),
1177 Return(static_cast<int>(kPayloadLengthSamples * kChannels))));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001178
ossu61a208b2016-09-20 01:38:00 -07001179 EXPECT_CALL(decoder,
1180 PacketDuration(Pointee(kSecondPayloadValue), kPayloadLengthBytes))
1181 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001182 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize)));
ossu61a208b2016-09-20 01:38:00 -07001183
Jonas Olssona4d87372019-07-05 19:08:33 +02001184 EXPECT_CALL(decoder, SampleRateHz()).WillRepeatedly(Return(kSampleRateHz));
ossu61a208b2016-09-20 01:38:00 -07001185
Jonas Olssona4d87372019-07-05 19:08:33 +02001186 EXPECT_CALL(decoder, Channels()).WillRepeatedly(Return(kChannels));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001187
Niels Möllera1eb9c72018-12-07 15:24:42 +01001188 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1189 SdpAudioFormat("L16", 8000, 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001190
1191 // Insert one packet.
1192 payload[0] = kFirstPayloadValue; // This will make Decode() fail.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001193 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001194
1195 // Insert another packet.
1196 payload[0] = kSecondPayloadValue; // This will make Decode() successful.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001197 rtp_header.sequenceNumber++;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001198 // The second timestamp needs to be at least 30 ms after the first to make
1199 // the second packet get decoded.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001200 rtp_header.timestamp += 3 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001201 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001202
henrik.lundin6d8e0112016-03-04 10:34:21 -08001203 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001204 bool muted;
henrik.lundin6d8e0112016-03-04 10:34:21 -08001205 // First call to GetAudio will try to decode the "faulty" packet.
Henrik Lundinc417d9e2017-06-14 12:29:03 +02001206 // Expect kFail return value.
henrik.lundin7a926812016-05-12 13:51:28 -07001207 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001208 // Output size and number of channels should be correct.
1209 const size_t kExpectedOutputSize = 10 * (kSampleRateHz / 1000) * kChannels;
1210 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1211 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001212 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001213
henrik.lundin6d8e0112016-03-04 10:34:21 -08001214 // Second call to GetAudio will decode the packet that is ok. No errors are
1215 // expected.
henrik.lundin7a926812016-05-12 13:51:28 -07001216 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001217 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1218 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001219 EXPECT_THAT(output.packet_infos_, SizeIs(1));
ossu61a208b2016-09-20 01:38:00 -07001220
1221 // Die isn't called through NiceMock (since it's called by the
1222 // MockAudioDecoder constructor), so it needs to be mocked explicitly.
1223 EXPECT_CALL(decoder, Die());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001224}
1225
henrik.lundin116c84e2015-08-27 13:14:48 -07001226// This test inserts packets until the buffer is flushed. After that, it asks
1227// NetEq for the network statistics. The purpose of the test is to make sure
1228// that even though the buffer size increment is negative (which it becomes when
1229// the packet causing a flush is inserted), the packet length stored in the
1230// decision logic remains valid.
1231TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) {
1232 UseNoMocks();
1233 CreateInstance();
1234
1235 const size_t kPayloadLengthSamples = 80;
1236 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1237 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin116c84e2015-08-27 13:14:48 -07001238 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001239 RTPHeader rtp_header;
1240 rtp_header.payloadType = kPayloadType;
1241 rtp_header.sequenceNumber = 0x1234;
1242 rtp_header.timestamp = 0x12345678;
1243 rtp_header.ssrc = 0x87654321;
henrik.lundin116c84e2015-08-27 13:14:48 -07001244
Niels Möller05543682019-01-10 16:55:06 +01001245 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1246 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin116c84e2015-08-27 13:14:48 -07001247
1248 // Insert packets until the buffer flushes.
1249 for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) {
1250 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
Karl Wiberg45eb1352019-10-10 14:23:00 +02001251 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -07001252 rtp_header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples);
1253 ++rtp_header.sequenceNumber;
henrik.lundin116c84e2015-08-27 13:14:48 -07001254 }
1255 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
1256
1257 // Ask for network statistics. This should not crash.
1258 NetEqNetworkStatistics stats;
1259 EXPECT_EQ(NetEq::kOK, neteq_->NetworkStatistics(&stats));
1260}
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001261
1262TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
1263 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001264 // Create a mock decoder object.
1265 MockAudioDecoder mock_decoder;
1266
1267 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001268 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001269
1270 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001271 const int kSampleRateHz = 8000;
1272 const size_t kPayloadLengthSamples =
1273 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
1274 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples;
1275 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001276 RTPHeader rtp_header;
1277 rtp_header.payloadType = kPayloadType;
1278 rtp_header.sequenceNumber = 0x1234;
1279 rtp_header.timestamp = 0x12345678;
1280 rtp_header.ssrc = 0x87654321;
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001281
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001282 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001283 EXPECT_CALL(mock_decoder, SampleRateHz())
1284 .WillRepeatedly(Return(kSampleRateHz));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001285 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001286 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001287 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001288 int16_t dummy_output[kPayloadLengthSamples] = {0};
1289 // The below expectation will make the mock decoder write
Artem Titovd00ce742021-07-28 20:00:17 +02001290 // `kPayloadLengthSamples` - 5 zeros to the output array, and mark it as
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001291 // speech. That is, the decoded length is 5 samples shorter than the expected.
1292 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001293 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001294 .WillOnce(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001295 DoAll(SetArrayArgument<3>(dummy_output,
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001296 dummy_output + kPayloadLengthSamples - 5),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001297 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001298 Return(rtc::checked_cast<int>(kPayloadLengthSamples - 5))));
Niels Möllera1eb9c72018-12-07 15:24:42 +01001299 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1300 SdpAudioFormat("L16", 8000, 1)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001301
1302 // Insert one packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001303 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001304
1305 EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength());
1306
1307 // Pull audio once.
1308 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001309 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001310 bool muted;
1311 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001312 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1313 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001314 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001315 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001316
1317 EXPECT_CALL(mock_decoder, Die());
1318}
minyuel6d92bf52015-09-23 15:20:39 +02001319
1320// This test checks the behavior of NetEq when audio decoder fails.
1321TEST_F(NetEqImplTest, DecodingError) {
1322 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001323 // Create a mock decoder object.
1324 MockAudioDecoder mock_decoder;
1325
1326 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001327 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001328
1329 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001330 const int kSampleRateHz = 8000;
1331 const int kDecoderErrorCode = -97; // Any negative number.
1332
1333 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1334 const size_t kFrameLengthSamples =
1335 static_cast<size_t>(5 * kSampleRateHz / 1000);
1336
1337 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1338
1339 uint8_t payload[kPayloadLengthBytes] = {0};
1340
henrik.lundin246ef3e2017-04-24 09:14:32 -07001341 RTPHeader rtp_header;
1342 rtp_header.payloadType = kPayloadType;
1343 rtp_header.sequenceNumber = 0x1234;
1344 rtp_header.timestamp = 0x12345678;
1345 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001346
minyuel6d92bf52015-09-23 15:20:39 +02001347 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001348 EXPECT_CALL(mock_decoder, SampleRateHz())
1349 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001350 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001351 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001352 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001353 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
1354 EXPECT_CALL(mock_decoder, HasDecodePlc()).WillOnce(Return(false));
minyuel6d92bf52015-09-23 15:20:39 +02001355 int16_t dummy_output[kFrameLengthSamples] = {0};
1356
1357 {
1358 InSequence sequence; // Dummy variable.
1359 // Mock decoder works normally the first time.
1360 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001361 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001362 .Times(3)
1363 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001364 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001365 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001366 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001367 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001368 .RetiresOnSaturation();
1369
1370 // Then mock decoder fails. A common reason for failure can be buffer being
1371 // too short
1372 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001373 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001374 .WillOnce(Return(-1))
1375 .RetiresOnSaturation();
1376
1377 // Mock decoder finally returns to normal.
1378 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001379 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001380 .Times(2)
1381 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001382 DoAll(SetArrayArgument<3>(dummy_output,
1383 dummy_output + kFrameLengthSamples),
1384 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001385 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001386 }
1387
Niels Möllera1eb9c72018-12-07 15:24:42 +01001388 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1389 SdpAudioFormat("L16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001390
1391 // Insert packets.
Jakob Ivarsson80fb9782020-10-09 13:41:06 +02001392 for (int i = 0; i < 20; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001393 rtp_header.sequenceNumber += 1;
1394 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001395 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001396 }
1397
1398 // Pull audio.
1399 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001400 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001401 bool muted;
1402 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001403 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1404 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001405 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001406 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001407
1408 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001409 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001410 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1411 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001412 // We are not expecting anything for output.speech_type_, since an error was
1413 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001414
1415 // Pull audio again, should continue an expansion.
henrik.lundin7a926812016-05-12 13:51:28 -07001416 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001417 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1418 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001419 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001420 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyuel6d92bf52015-09-23 15:20:39 +02001421
1422 // Pull audio again, should behave normal.
henrik.lundin7a926812016-05-12 13:51:28 -07001423 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001424 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1425 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001426 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001427 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001428
1429 EXPECT_CALL(mock_decoder, Die());
1430}
1431
1432// This test checks the behavior of NetEq when audio decoder fails during CNG.
1433TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
1434 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +01001435
1436 // Create a mock decoder object.
1437 MockAudioDecoder mock_decoder;
1438 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001439 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001440
1441 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001442 const int kSampleRateHz = 8000;
1443 const int kDecoderErrorCode = -97; // Any negative number.
1444
1445 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1446 const size_t kFrameLengthSamples =
1447 static_cast<size_t>(5 * kSampleRateHz / 1000);
1448
1449 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1450
1451 uint8_t payload[kPayloadLengthBytes] = {0};
1452
henrik.lundin246ef3e2017-04-24 09:14:32 -07001453 RTPHeader rtp_header;
1454 rtp_header.payloadType = kPayloadType;
1455 rtp_header.sequenceNumber = 0x1234;
1456 rtp_header.timestamp = 0x12345678;
1457 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001458
minyuel6d92bf52015-09-23 15:20:39 +02001459 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001460 EXPECT_CALL(mock_decoder, SampleRateHz())
1461 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001462 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001463 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001464 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001465 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
minyuel6d92bf52015-09-23 15:20:39 +02001466 int16_t dummy_output[kFrameLengthSamples] = {0};
1467
1468 {
1469 InSequence sequence; // Dummy variable.
1470 // Mock decoder works normally the first 2 times.
1471 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001472 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001473 .Times(2)
1474 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001475 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001476 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001477 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001478 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001479 .RetiresOnSaturation();
1480
1481 // Then mock decoder fails. A common reason for failure can be buffer being
1482 // too short
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001483 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001484 .WillOnce(Return(-1))
1485 .RetiresOnSaturation();
1486
1487 // Mock decoder finally returns to normal.
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001488 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001489 .Times(2)
1490 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001491 DoAll(SetArrayArgument<3>(dummy_output,
1492 dummy_output + kFrameLengthSamples),
1493 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001494 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001495 }
1496
Niels Möller50b66d52018-12-11 14:43:21 +01001497 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1498 SdpAudioFormat("l16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001499
1500 // Insert 2 packets. This will make netEq into codec internal CNG mode.
1501 for (int i = 0; i < 2; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001502 rtp_header.sequenceNumber += 1;
1503 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001504 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001505 }
1506
1507 // Pull audio.
1508 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001509 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001510 bool muted;
1511 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001512 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1513 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001514 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001515
1516 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001517 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001518 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1519 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001520 // We are not expecting anything for output.speech_type_, since an error was
1521 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001522
1523 // Pull audio again, should resume codec CNG.
henrik.lundin7a926812016-05-12 13:51:28 -07001524 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001525 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1526 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001527 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001528
1529 EXPECT_CALL(mock_decoder, Die());
1530}
1531
henrik.lundind89814b2015-11-23 06:49:25 -08001532// Tests that the return value from last_output_sample_rate_hz() is equal to the
1533// configured inital sample rate.
1534TEST_F(NetEqImplTest, InitialLastOutputSampleRate) {
1535 UseNoMocks();
1536 config_.sample_rate_hz = 48000;
1537 CreateInstance();
1538 EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz());
1539}
1540
henrik.lundined497212016-04-25 10:11:38 -07001541TEST_F(NetEqImplTest, TickTimerIncrement) {
1542 UseNoMocks();
1543 CreateInstance();
1544 ASSERT_TRUE(tick_timer_);
1545 EXPECT_EQ(0u, tick_timer_->ticks());
1546 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001547 bool muted;
1548 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundined497212016-04-25 10:11:38 -07001549 EXPECT_EQ(1u, tick_timer_->ticks());
1550}
1551
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001552TEST_F(NetEqImplTest, SetBaseMinimumDelay) {
1553 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001554 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001555 CreateInstance();
1556
Ivo Creusen53a31f72019-10-24 15:20:39 +02001557 EXPECT_CALL(*mock_neteq_controller_, SetBaseMinimumDelay(_))
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001558 .WillOnce(Return(true))
1559 .WillOnce(Return(false));
1560
1561 const int delay_ms = 200;
1562
1563 EXPECT_EQ(true, neteq_->SetBaseMinimumDelayMs(delay_ms));
1564 EXPECT_EQ(false, neteq_->SetBaseMinimumDelayMs(delay_ms));
1565}
1566
1567TEST_F(NetEqImplTest, GetBaseMinimumDelayMs) {
1568 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001569 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001570 CreateInstance();
1571
1572 const int delay_ms = 200;
1573
Ivo Creusen53a31f72019-10-24 15:20:39 +02001574 EXPECT_CALL(*mock_neteq_controller_, GetBaseMinimumDelay())
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001575 .WillOnce(Return(delay_ms));
1576
1577 EXPECT_EQ(delay_ms, neteq_->GetBaseMinimumDelayMs());
1578}
1579
henrik.lundin114c1b32017-04-26 07:47:32 -07001580TEST_F(NetEqImplTest, TargetDelayMs) {
1581 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001582 use_mock_neteq_controller_ = true;
henrik.lundin114c1b32017-04-26 07:47:32 -07001583 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001584 constexpr int kTargetLevelMs = 510;
1585 EXPECT_CALL(*mock_neteq_controller_, TargetLevelMs())
1586 .WillOnce(Return(kTargetLevelMs));
1587 EXPECT_EQ(510, neteq_->TargetDelayMs());
henrik.lundin114c1b32017-04-26 07:47:32 -07001588}
1589
henrik.lundinb8c55b12017-05-10 07:38:01 -07001590TEST_F(NetEqImplTest, InsertEmptyPacket) {
1591 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001592 use_mock_neteq_controller_ = true;
henrik.lundinb8c55b12017-05-10 07:38:01 -07001593 CreateInstance();
1594
1595 RTPHeader rtp_header;
1596 rtp_header.payloadType = 17;
1597 rtp_header.sequenceNumber = 0x1234;
1598 rtp_header.timestamp = 0x12345678;
1599 rtp_header.ssrc = 0x87654321;
1600
Ivo Creusen53a31f72019-10-24 15:20:39 +02001601 EXPECT_CALL(*mock_neteq_controller_, RegisterEmptyPacket());
henrik.lundinb8c55b12017-05-10 07:38:01 -07001602 neteq_->InsertEmptyPacket(rtp_header);
1603}
1604
Jakob Ivarsson7cca0162021-09-01 18:19:37 +02001605TEST_F(NetEqImplTest, NotifyControllerOfReorderedPacket) {
Ivo Creusena2b31c32020-10-14 17:54:22 +02001606 using ::testing::AllOf;
1607 using ::testing::Field;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001608 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001609 use_mock_neteq_controller_ = true;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001610 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001611 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001612 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001613 .WillOnce(Return(NetEq::Operation::kNormal));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001614
1615 const int kPayloadLengthSamples = 80;
1616 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1617 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001618 uint8_t payload[kPayloadLengthBytes] = {0};
1619 RTPHeader rtp_header;
1620 rtp_header.payloadType = kPayloadType;
1621 rtp_header.sequenceNumber = 0x1234;
1622 rtp_header.timestamp = 0x12345678;
1623 rtp_header.ssrc = 0x87654321;
1624
Niels Möller05543682019-01-10 16:55:06 +01001625 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1626 SdpAudioFormat("l16", 8000, 1)));
Karl Wiberg45eb1352019-10-10 14:23:00 +02001627 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001628 AudioFrame output;
1629 bool muted;
1630 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
1631
1632 // Insert second packet that was sent before the first packet.
1633 rtp_header.sequenceNumber -= 1;
1634 rtp_header.timestamp -= kPayloadLengthSamples;
Ivo Creusena2b31c32020-10-14 17:54:22 +02001635 EXPECT_CALL(
1636 *mock_neteq_controller_,
1637 PacketArrived(
1638 /*fs_hz*/ 8000,
Jakob Ivarsson7cca0162021-09-01 18:19:37 +02001639 /*should_update_stats*/ true,
Ivo Creusena2b31c32020-10-14 17:54:22 +02001640 /*info*/
1641 AllOf(
1642 Field(&NetEqController::PacketArrivedInfo::packet_length_samples,
1643 kPayloadLengthSamples),
1644 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
1645 rtp_header.sequenceNumber),
1646 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
1647 rtp_header.timestamp))));
Ivo Creusen53a31f72019-10-24 15:20:39 +02001648
Karl Wiberg45eb1352019-10-10 14:23:00 +02001649 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001650}
1651
minyue5bd33972016-05-02 04:46:11 -07001652class Decoder120ms : public AudioDecoder {
1653 public:
kwiberg347d3512016-06-16 01:59:09 -07001654 Decoder120ms(int sample_rate_hz, SpeechType speech_type)
1655 : sample_rate_hz_(sample_rate_hz),
1656 next_value_(1),
minyue5bd33972016-05-02 04:46:11 -07001657 speech_type_(speech_type) {}
1658
1659 int DecodeInternal(const uint8_t* encoded,
1660 size_t encoded_len,
1661 int sample_rate_hz,
1662 int16_t* decoded,
1663 SpeechType* speech_type) override {
kwiberg347d3512016-06-16 01:59:09 -07001664 EXPECT_EQ(sample_rate_hz_, sample_rate_hz);
minyue5bd33972016-05-02 04:46:11 -07001665 size_t decoded_len =
1666 rtc::CheckedDivExact(sample_rate_hz, 1000) * 120 * Channels();
1667 for (size_t i = 0; i < decoded_len; ++i) {
1668 decoded[i] = next_value_++;
1669 }
1670 *speech_type = speech_type_;
Mirko Bonadei737e0732017-10-19 09:00:17 +02001671 return rtc::checked_cast<int>(decoded_len);
minyue5bd33972016-05-02 04:46:11 -07001672 }
1673
1674 void Reset() override { next_value_ = 1; }
kwiberg347d3512016-06-16 01:59:09 -07001675 int SampleRateHz() const override { return sample_rate_hz_; }
minyue5bd33972016-05-02 04:46:11 -07001676 size_t Channels() const override { return 2; }
1677
1678 private:
kwiberg347d3512016-06-16 01:59:09 -07001679 int sample_rate_hz_;
minyue5bd33972016-05-02 04:46:11 -07001680 int16_t next_value_;
1681 SpeechType speech_type_;
1682};
1683
1684class NetEqImplTest120ms : public NetEqImplTest {
1685 protected:
1686 NetEqImplTest120ms() : NetEqImplTest() {}
1687 virtual ~NetEqImplTest120ms() {}
1688
1689 void CreateInstanceNoMocks() {
1690 UseNoMocks();
Niels Möllera0f44302018-11-30 10:45:12 +01001691 CreateInstance(decoder_factory_);
1692 EXPECT_TRUE(neteq_->RegisterPayloadType(
1693 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001694 }
1695
1696 void CreateInstanceWithDelayManagerMock() {
1697 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001698 use_mock_neteq_controller_ = true;
Niels Möllera0f44302018-11-30 10:45:12 +01001699 CreateInstance(decoder_factory_);
1700 EXPECT_TRUE(neteq_->RegisterPayloadType(
1701 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001702 }
1703
1704 uint32_t timestamp_diff_between_packets() const {
1705 return rtc::CheckedDivExact(kSamplingFreq_, 1000u) * 120;
1706 }
1707
1708 uint32_t first_timestamp() const { return 10u; }
1709
1710 void GetFirstPacket() {
henrik.lundin7a926812016-05-12 13:51:28 -07001711 bool muted;
minyue5bd33972016-05-02 04:46:11 -07001712 for (int i = 0; i < 12; i++) {
henrik.lundin7a926812016-05-12 13:51:28 -07001713 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
1714 EXPECT_FALSE(muted);
minyue5bd33972016-05-02 04:46:11 -07001715 }
1716 }
1717
1718 void InsertPacket(uint32_t timestamp) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001719 RTPHeader rtp_header;
1720 rtp_header.payloadType = kPayloadType;
1721 rtp_header.sequenceNumber = sequence_number_;
1722 rtp_header.timestamp = timestamp;
1723 rtp_header.ssrc = 15;
minyue5bd33972016-05-02 04:46:11 -07001724 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1725 uint8_t payload[kPayloadLengthBytes] = {0};
Karl Wiberg45eb1352019-10-10 14:23:00 +02001726 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue5bd33972016-05-02 04:46:11 -07001727 sequence_number_++;
1728 }
1729
1730 void Register120msCodec(AudioDecoder::SpeechType speech_type) {
Niels Möllera0f44302018-11-30 10:45:12 +01001731 const uint32_t sampling_freq = kSamplingFreq_;
Tommi87f70902021-04-27 14:43:08 +02001732 decoder_factory_ = rtc::make_ref_counted<test::FunctionAudioDecoderFactory>(
1733 [sampling_freq, speech_type]() {
1734 std::unique_ptr<AudioDecoder> decoder =
1735 std::make_unique<Decoder120ms>(sampling_freq, speech_type);
1736 RTC_CHECK_EQ(2, decoder->Channels());
1737 return decoder;
1738 });
minyue5bd33972016-05-02 04:46:11 -07001739 }
1740
Niels Möllera0f44302018-11-30 10:45:12 +01001741 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
minyue5bd33972016-05-02 04:46:11 -07001742 AudioFrame output_;
1743 const uint32_t kPayloadType = 17;
1744 const uint32_t kSamplingFreq_ = 48000;
1745 uint16_t sequence_number_ = 1;
1746};
1747
minyue5bd33972016-05-02 04:46:11 -07001748TEST_F(NetEqImplTest120ms, CodecInternalCng) {
minyue5bd33972016-05-02 04:46:11 -07001749 Register120msCodec(AudioDecoder::kComfortNoise);
Niels Möllera0f44302018-11-30 10:45:12 +01001750 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001751
1752 InsertPacket(first_timestamp());
1753 GetFirstPacket();
1754
henrik.lundin7a926812016-05-12 13:51:28 -07001755 bool muted;
1756 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001757 EXPECT_EQ(NetEq::Operation::kCodecInternalCng,
1758 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001759}
1760
1761TEST_F(NetEqImplTest120ms, Normal) {
minyue5bd33972016-05-02 04:46:11 -07001762 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001763 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001764
1765 InsertPacket(first_timestamp());
1766 GetFirstPacket();
1767
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001768 EXPECT_EQ(NetEq::Operation::kNormal, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001769}
1770
1771TEST_F(NetEqImplTest120ms, Merge) {
Niels Möllera0f44302018-11-30 10:45:12 +01001772 Register120msCodec(AudioDecoder::kSpeech);
minyue5bd33972016-05-02 04:46:11 -07001773 CreateInstanceWithDelayManagerMock();
1774
Ivo Creusen53a31f72019-10-24 15:20:39 +02001775 EXPECT_CALL(*mock_neteq_controller_, CngOff()).WillRepeatedly(Return(true));
minyue5bd33972016-05-02 04:46:11 -07001776 InsertPacket(first_timestamp());
1777
1778 GetFirstPacket();
henrik.lundin7a926812016-05-12 13:51:28 -07001779 bool muted;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001780 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001781 .WillOnce(Return(NetEq::Operation::kExpand));
henrik.lundin7a926812016-05-12 13:51:28 -07001782 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
minyue5bd33972016-05-02 04:46:11 -07001783
1784 InsertPacket(first_timestamp() + 2 * timestamp_diff_between_packets());
1785
Ivo Creusen53a31f72019-10-24 15:20:39 +02001786 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001787 .WillOnce(Return(NetEq::Operation::kMerge));
minyue5bd33972016-05-02 04:46:11 -07001788
henrik.lundin7a926812016-05-12 13:51:28 -07001789 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001790 EXPECT_EQ(NetEq::Operation::kMerge, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001791}
1792
1793TEST_F(NetEqImplTest120ms, Expand) {
minyue5bd33972016-05-02 04:46:11 -07001794 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001795 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001796
1797 InsertPacket(first_timestamp());
1798 GetFirstPacket();
1799
henrik.lundin7a926812016-05-12 13:51:28 -07001800 bool muted;
1801 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001802 EXPECT_EQ(NetEq::Operation::kExpand, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001803}
1804
1805TEST_F(NetEqImplTest120ms, FastAccelerate) {
minyue5bd33972016-05-02 04:46:11 -07001806 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001807 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001808
1809 InsertPacket(first_timestamp());
1810 GetFirstPacket();
1811 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1812
Ivo Creusen53a31f72019-10-24 15:20:39 +02001813 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001814 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001815 .WillOnce(Return(NetEq::Operation::kFastAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001816
henrik.lundin7a926812016-05-12 13:51:28 -07001817 bool muted;
1818 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001819 EXPECT_EQ(NetEq::Operation::kFastAccelerate,
1820 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001821}
1822
1823TEST_F(NetEqImplTest120ms, PreemptiveExpand) {
minyue5bd33972016-05-02 04:46:11 -07001824 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001825 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001826
1827 InsertPacket(first_timestamp());
1828 GetFirstPacket();
1829
1830 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1831
Ivo Creusen53a31f72019-10-24 15:20:39 +02001832 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001833 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001834 .WillOnce(Return(NetEq::Operation::kPreemptiveExpand));
minyue5bd33972016-05-02 04:46:11 -07001835
henrik.lundin7a926812016-05-12 13:51:28 -07001836 bool muted;
1837 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001838 EXPECT_EQ(NetEq::Operation::kPreemptiveExpand,
1839 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001840}
1841
1842TEST_F(NetEqImplTest120ms, Accelerate) {
minyue5bd33972016-05-02 04:46:11 -07001843 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001844 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001845
1846 InsertPacket(first_timestamp());
1847 GetFirstPacket();
1848
1849 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1850
Ivo Creusen53a31f72019-10-24 15:20:39 +02001851 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001852 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001853 .WillOnce(Return(NetEq::Operation::kAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001854
henrik.lundin7a926812016-05-12 13:51:28 -07001855 bool muted;
1856 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001857 EXPECT_EQ(NetEq::Operation::kAccelerate, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001858}
1859
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001860} // namespace webrtc