blob: 875e62c92bacd1bf7a7cd5c53757c28fa4d75ac7 [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;
125 controller_config.enable_rtx_handling = config_.enable_rtx_handling;
126 controller_config.allow_time_stretching = true;
127 controller_config.max_packets_in_buffer = config_.max_packets_in_buffer;
Ivo Creusen88636c62020-01-24 11:04:56 +0100128 controller_config.clock = &clock_;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200129 deps.neteq_controller =
130 std::make_unique<DecisionLogic>(std::move(controller_config));
131 }
132 neteq_controller_ = deps.neteq_controller.get();
133
henrik.lundin1d9061e2016-04-26 12:19:34 -0700134 if (use_mock_payload_splitter_) {
ossua70695a2016-09-22 02:06:28 -0700135 std::unique_ptr<MockRedPayloadSplitter> mock(new MockRedPayloadSplitter);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700136 mock_payload_splitter_ = mock.get();
ossua70695a2016-09-22 02:06:28 -0700137 deps.red_payload_splitter = std::move(mock);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700138 }
ossua70695a2016-09-22 02:06:28 -0700139 red_payload_splitter_ = deps.red_payload_splitter.get();
henrik.lundin1d9061e2016-04-26 12:19:34 -0700140
141 deps.timestamp_scaler = std::unique_ptr<TimestampScaler>(
142 new TimestampScaler(*deps.decoder_database.get()));
143
144 neteq_.reset(new NetEqImpl(config_, std::move(deps)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000145 ASSERT_TRUE(neteq_ != NULL);
146 }
147
Niels Möllera0f44302018-11-30 10:45:12 +0100148 void CreateInstance() { CreateInstance(CreateBuiltinAudioDecoderFactory()); }
149
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000150 void UseNoMocks() {
151 ASSERT_TRUE(neteq_ == NULL) << "Must call UseNoMocks before CreateInstance";
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000152 use_mock_decoder_database_ = false;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200153 use_mock_neteq_controller_ = false;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000154 use_mock_dtmf_buffer_ = false;
155 use_mock_dtmf_tone_generator_ = false;
156 use_mock_packet_buffer_ = false;
157 use_mock_payload_splitter_ = false;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000158 }
159
160 virtual ~NetEqImplTest() {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000161 if (use_mock_decoder_database_) {
162 EXPECT_CALL(*mock_decoder_database_, Die()).Times(1);
163 }
Ivo Creusen53a31f72019-10-24 15:20:39 +0200164 if (use_mock_neteq_controller_) {
165 EXPECT_CALL(*mock_neteq_controller_, Die()).Times(1);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000166 }
167 if (use_mock_dtmf_buffer_) {
168 EXPECT_CALL(*mock_dtmf_buffer_, Die()).Times(1);
169 }
170 if (use_mock_dtmf_tone_generator_) {
171 EXPECT_CALL(*mock_dtmf_tone_generator_, Die()).Times(1);
172 }
173 if (use_mock_packet_buffer_) {
174 EXPECT_CALL(*mock_packet_buffer_, Die()).Times(1);
175 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000176 }
177
Niels Möller05543682019-01-10 16:55:06 +0100178 void TestDtmfPacket(int sample_rate_hz) {
solenberg2779bab2016-11-17 04:45:19 -0800179 const size_t kPayloadLength = 4;
180 const uint8_t kPayloadType = 110;
solenberg2779bab2016-11-17 04:45:19 -0800181 const int kSampleRateHz = 16000;
182 config_.sample_rate_hz = kSampleRateHz;
183 UseNoMocks();
184 CreateInstance();
185 // Event: 2, E bit, Volume: 17, Length: 4336.
Jonas Olssona4d87372019-07-05 19:08:33 +0200186 uint8_t payload[kPayloadLength] = {0x02, 0x80 + 0x11, 0x10, 0xF0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700187 RTPHeader rtp_header;
188 rtp_header.payloadType = kPayloadType;
189 rtp_header.sequenceNumber = 0x1234;
190 rtp_header.timestamp = 0x12345678;
191 rtp_header.ssrc = 0x87654321;
solenberg2779bab2016-11-17 04:45:19 -0800192
Niels Möller05543682019-01-10 16:55:06 +0100193 EXPECT_TRUE(neteq_->RegisterPayloadType(
194 kPayloadType, SdpAudioFormat("telephone-event", sample_rate_hz, 1)));
solenberg2779bab2016-11-17 04:45:19 -0800195
196 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200197 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
solenberg2779bab2016-11-17 04:45:19 -0800198
199 // Pull audio once.
200 const size_t kMaxOutputSize =
201 static_cast<size_t>(10 * kSampleRateHz / 1000);
202 AudioFrame output;
203 bool muted;
204 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
205 ASSERT_FALSE(muted);
206 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
207 EXPECT_EQ(1u, output.num_channels_);
208 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
209
Artem Titovd00ce742021-07-28 20:00:17 +0200210 // DTMF packets are immediately consumed by `InsertPacket()` and won't be
211 // returned by `GetAudio()`.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000212 EXPECT_THAT(output.packet_infos_, IsEmpty());
213
solenberg2779bab2016-11-17 04:45:19 -0800214 // Verify first 64 samples of actual output.
Jonas Olssona4d87372019-07-05 19:08:33 +0200215 const std::vector<int16_t> kOutput(
216 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 -1578, -2816, -3460, -3403, -2709, -1594, -363, 671, 1269, 1328,
218 908, 202, -513, -964, -955, -431, 504, 1617, 2602, 3164,
219 3101, 2364, 1073, -511, -2047, -3198, -3721, -3525, -2688, -1440,
220 -99, 1015, 1663, 1744, 1319, 588, -171, -680, -747, -315,
221 515, 1512, 2378, 2828, 2674, 1877, 568, -986, -2446, -3482,
222 -3864, -3516, -2534, -1163});
solenberg2779bab2016-11-17 04:45:19 -0800223 ASSERT_GE(kMaxOutputSize, kOutput.size());
yujo36b1a5f2017-06-12 12:45:32 -0700224 EXPECT_TRUE(std::equal(kOutput.begin(), kOutput.end(), output.data()));
solenberg2779bab2016-11-17 04:45:19 -0800225 }
226
henrik.lundin1d9061e2016-04-26 12:19:34 -0700227 std::unique_ptr<NetEqImpl> neteq_;
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000228 NetEq::Config config_;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000229 SimulatedClock clock_;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700230 TickTimer* tick_timer_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700231 MockDecoderDatabase* mock_decoder_database_ = nullptr;
232 DecoderDatabase* decoder_database_ = nullptr;
233 bool use_mock_decoder_database_ = true;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200234 MockNetEqController* mock_neteq_controller_ = nullptr;
235 NetEqController* neteq_controller_ = nullptr;
236 bool use_mock_neteq_controller_ = true;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700237 MockDtmfBuffer* mock_dtmf_buffer_ = nullptr;
238 DtmfBuffer* dtmf_buffer_ = nullptr;
239 bool use_mock_dtmf_buffer_ = true;
240 MockDtmfToneGenerator* mock_dtmf_tone_generator_ = nullptr;
241 DtmfToneGenerator* dtmf_tone_generator_ = nullptr;
242 bool use_mock_dtmf_tone_generator_ = true;
243 MockPacketBuffer* mock_packet_buffer_ = nullptr;
244 PacketBuffer* packet_buffer_ = nullptr;
245 bool use_mock_packet_buffer_ = true;
ossua70695a2016-09-22 02:06:28 -0700246 MockRedPayloadSplitter* mock_payload_splitter_ = nullptr;
247 RedPayloadSplitter* red_payload_splitter_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700248 bool use_mock_payload_splitter_ = true;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000249};
250
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000251// This tests the interface class NetEq.
252// TODO(hlundin): Move to separate file?
253TEST(NetEq, CreateAndDestroy) {
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000254 NetEq::Config config;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000255 SimulatedClock clock(0);
Ivo Creusen39cf3c72019-11-28 14:07:14 +0100256 auto decoder_factory = CreateBuiltinAudioDecoderFactory();
257 std::unique_ptr<NetEq> neteq =
258 DefaultNetEqFactory().CreateNetEq(config, decoder_factory, &clock);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000259}
260
kwiberg5adaf732016-10-04 09:33:27 -0700261TEST_F(NetEqImplTest, RegisterPayloadType) {
262 CreateInstance();
263 constexpr int rtp_payload_type = 0;
264 const SdpAudioFormat format("pcmu", 8000, 1);
265 EXPECT_CALL(*mock_decoder_database_,
266 RegisterPayload(rtp_payload_type, format));
267 neteq_->RegisterPayloadType(rtp_payload_type, format);
268}
269
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000270TEST_F(NetEqImplTest, RemovePayloadType) {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000271 CreateInstance();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000272 uint8_t rtp_payload_type = 0;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000273 EXPECT_CALL(*mock_decoder_database_, Remove(rtp_payload_type))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000274 .WillOnce(Return(DecoderDatabase::kDecoderNotFound));
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200275 // Check that kOK is returned when database returns kDecoderNotFound, because
276 // removing a payload type that was never registered is not an error.
277 EXPECT_EQ(NetEq::kOK, neteq_->RemovePayloadType(rtp_payload_type));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000278}
279
kwiberg6b19b562016-09-20 04:02:25 -0700280TEST_F(NetEqImplTest, RemoveAllPayloadTypes) {
281 CreateInstance();
282 EXPECT_CALL(*mock_decoder_database_, RemoveAll()).WillOnce(Return());
283 neteq_->RemoveAllPayloadTypes();
284}
285
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000286TEST_F(NetEqImplTest, InsertPacket) {
Ivo Creusena2b31c32020-10-14 17:54:22 +0200287 using ::testing::AllOf;
288 using ::testing::Field;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000289 CreateInstance();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000290 const size_t kPayloadLength = 100;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000291 const uint8_t kPayloadType = 0;
292 const uint16_t kFirstSequenceNumber = 0x1234;
293 const uint32_t kFirstTimestamp = 0x12345678;
294 const uint32_t kSsrc = 0x87654321;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000295 uint8_t payload[kPayloadLength] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700296 RTPHeader rtp_header;
297 rtp_header.payloadType = kPayloadType;
298 rtp_header.sequenceNumber = kFirstSequenceNumber;
299 rtp_header.timestamp = kFirstTimestamp;
300 rtp_header.ssrc = kSsrc;
ossu7a377612016-10-18 04:06:13 -0700301 Packet fake_packet;
302 fake_packet.payload_type = kPayloadType;
303 fake_packet.sequence_number = kFirstSequenceNumber;
304 fake_packet.timestamp = kFirstTimestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000305
Tommi87f70902021-04-27 14:43:08 +0200306 auto mock_decoder_factory = rtc::make_ref_counted<MockAudioDecoderFactory>();
Karl Wibergd6fbf2a2018-02-27 13:37:31 +0100307 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _, _))
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800308 .WillOnce(Invoke([&](const SdpAudioFormat& format,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200309 absl::optional<AudioCodecPairId> codec_pair_id,
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800310 std::unique_ptr<AudioDecoder>* dec) {
kwibergc0f2dcf2016-05-31 06:28:03 -0700311 EXPECT_EQ("pcmu", format.name);
312
313 std::unique_ptr<MockAudioDecoder> mock_decoder(new MockAudioDecoder);
314 EXPECT_CALL(*mock_decoder, Channels()).WillRepeatedly(Return(1));
315 EXPECT_CALL(*mock_decoder, SampleRateHz()).WillRepeatedly(Return(8000));
kwibergc0f2dcf2016-05-31 06:28:03 -0700316 EXPECT_CALL(*mock_decoder, Die()).Times(1); // Called when deleted.
317
318 *dec = std::move(mock_decoder);
319 }));
Niels Möller72899062019-01-11 09:36:13 +0100320 DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
321 absl::nullopt, mock_decoder_factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000322
323 // Expectations for decoder database.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000324 EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000325 .WillRepeatedly(Return(&info));
326
327 // Expectations for packet buffer.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000328 EXPECT_CALL(*mock_packet_buffer_, Empty())
329 .WillOnce(Return(false)); // Called once after first packet is inserted.
Ivo Creusen7b463c52020-11-25 11:32:40 +0100330 EXPECT_CALL(*mock_packet_buffer_, Flush(_)).Times(1);
331 EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _, _, _, _, _))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000332 .Times(2)
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100333 .WillRepeatedly(DoAll(SetArgPointee<2>(kPayloadType),
334 WithArg<0>(Invoke(DeletePacketsAndReturnOk))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000335 // SetArgPointee<2>(kPayloadType) means that the third argument (zero-based
336 // index) is a pointer, and the variable pointed to is set to kPayloadType.
337 // Also invoke the function DeletePacketsAndReturnOk to properly delete all
338 // packets in the list (to avoid memory leaks in the test).
ossu7a377612016-10-18 04:06:13 -0700339 EXPECT_CALL(*mock_packet_buffer_, PeekNextPacket())
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000340 .Times(1)
ossu7a377612016-10-18 04:06:13 -0700341 .WillOnce(Return(&fake_packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000342
343 // Expectations for DTMF buffer.
Jonas Olssona4d87372019-07-05 19:08:33 +0200344 EXPECT_CALL(*mock_dtmf_buffer_, Flush()).Times(1);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000345
346 // Expectations for delay manager.
347 {
348 // All expectations within this block must be called in this specific order.
349 InSequence sequence; // Dummy variable.
350 // Expectations when the first packet is inserted.
Ivo Creusena2b31c32020-10-14 17:54:22 +0200351 EXPECT_CALL(
352 *mock_neteq_controller_,
353 PacketArrived(
354 /*fs_hz*/ 8000,
355 /*should_update_stats*/ _,
356 /*info*/
357 AllOf(
358 Field(&NetEqController::PacketArrivedInfo::is_cng_or_dtmf,
359 false),
360 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
361 kFirstSequenceNumber),
362 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
363 kFirstTimestamp))));
364 EXPECT_CALL(
365 *mock_neteq_controller_,
366 PacketArrived(
367 /*fs_hz*/ 8000,
368 /*should_update_stats*/ _,
369 /*info*/
370 AllOf(
371 Field(&NetEqController::PacketArrivedInfo::is_cng_or_dtmf,
372 false),
373 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
374 kFirstSequenceNumber + 1),
375 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
376 kFirstTimestamp + 160))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000377 }
378
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000379 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200380 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000381
382 // Insert second packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700383 rtp_header.timestamp += 160;
384 rtp_header.sequenceNumber += 1;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200385 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000386}
387
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000388TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
389 UseNoMocks();
390 CreateInstance();
391
392 const int kPayloadLengthSamples = 80;
393 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
Jonas Olssona4d87372019-07-05 19:08:33 +0200394 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000395 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700396 RTPHeader rtp_header;
397 rtp_header.payloadType = kPayloadType;
398 rtp_header.sequenceNumber = 0x1234;
399 rtp_header.timestamp = 0x12345678;
400 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000401
Niels Möller05543682019-01-10 16:55:06 +0100402 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
403 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000404
405 // Insert packets. The buffer should not flush.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700406 for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) {
Karl Wiberg45eb1352019-10-10 14:23:00 +0200407 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700408 rtp_header.timestamp += kPayloadLengthSamples;
409 rtp_header.sequenceNumber += 1;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000410 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
411 }
412
413 // Insert one more packet and make sure the buffer got flushed. That is, it
414 // should only hold one single packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200415 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700416 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700417 const Packet* test_packet = packet_buffer_->PeekNextPacket();
henrik.lundin246ef3e2017-04-24 09:14:32 -0700418 EXPECT_EQ(rtp_header.timestamp, test_packet->timestamp);
419 EXPECT_EQ(rtp_header.sequenceNumber, test_packet->sequence_number);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000420}
421
solenberg2779bab2016-11-17 04:45:19 -0800422TEST_F(NetEqImplTest, TestDtmfPacketAVT) {
Niels Möller05543682019-01-10 16:55:06 +0100423 TestDtmfPacket(8000);
solenberg2779bab2016-11-17 04:45:19 -0800424}
solenberg99df6c02016-10-11 04:35:34 -0700425
solenberg2779bab2016-11-17 04:45:19 -0800426TEST_F(NetEqImplTest, TestDtmfPacketAVT16kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100427 TestDtmfPacket(16000);
solenberg2779bab2016-11-17 04:45:19 -0800428}
solenberg99df6c02016-10-11 04:35:34 -0700429
solenberg2779bab2016-11-17 04:45:19 -0800430TEST_F(NetEqImplTest, TestDtmfPacketAVT32kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100431 TestDtmfPacket(32000);
solenberg2779bab2016-11-17 04:45:19 -0800432}
solenberg99df6c02016-10-11 04:35:34 -0700433
solenberg2779bab2016-11-17 04:45:19 -0800434TEST_F(NetEqImplTest, TestDtmfPacketAVT48kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100435 TestDtmfPacket(48000);
solenberg99df6c02016-10-11 04:35:34 -0700436}
437
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000438// This test verifies that timestamps propagate from the incoming packets
439// through to the sync buffer and to the playout timestamp.
440TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000441 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000442 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700443 const size_t kPayloadLengthSamples =
444 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000445 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
446 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700447 RTPHeader rtp_header;
448 rtp_header.payloadType = kPayloadType;
449 rtp_header.sequenceNumber = 0x1234;
450 rtp_header.timestamp = 0x12345678;
451 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000452 rtp_header.numCSRCs = 3;
453 rtp_header.arrOfCSRCs[0] = 43;
454 rtp_header.arrOfCSRCs[1] = 65;
455 rtp_header.arrOfCSRCs[2] = 17;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000456
457 // This is a dummy decoder that produces as many output samples as the input
458 // has bytes. The output is an increasing series, starting at 1 for the first
459 // sample, and then increasing by 1 for each sample.
460 class CountingSamplesDecoder : public AudioDecoder {
461 public:
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000462 CountingSamplesDecoder() : next_value_(1) {}
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000463
Artem Titovd00ce742021-07-28 20:00:17 +0200464 // Produce as many samples as input bytes (`encoded_len`).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100465 int DecodeInternal(const uint8_t* encoded,
466 size_t encoded_len,
467 int /* sample_rate_hz */,
468 int16_t* decoded,
469 SpeechType* speech_type) override {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000470 for (size_t i = 0; i < encoded_len; ++i) {
471 decoded[i] = next_value_++;
472 }
473 *speech_type = kSpeech;
Mirko Bonadei737e0732017-10-19 09:00:17 +0200474 return rtc::checked_cast<int>(encoded_len);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000475 }
476
Karl Wiberg43766482015-08-27 15:22:11 +0200477 void Reset() override { next_value_ = 1; }
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000478
kwiberg347d3512016-06-16 01:59:09 -0700479 int SampleRateHz() const override { return kSampleRateHz; }
480
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000481 size_t Channels() const override { return 1; }
482
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000483 uint16_t next_value() const { return next_value_; }
484
485 private:
486 int16_t next_value_;
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000487 } decoder_;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000488
Tommi87f70902021-04-27 14:43:08 +0200489 auto decoder_factory =
490 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&decoder_);
Niels Möllerb7180c02018-12-06 13:07:11 +0100491
492 UseNoMocks();
493 CreateInstance(decoder_factory);
494
495 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
Niels Möllera1eb9c72018-12-07 15:24:42 +0100496 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000497
498 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000499 clock_.AdvanceTimeMilliseconds(123456);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200500 Timestamp expected_receive_time = clock_.CurrentTime();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200501 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000502
503 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700504 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800505 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700506 bool muted;
507 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
508 ASSERT_FALSE(muted);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800509 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
510 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800511 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000512
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000513 // Verify |output.packet_infos_|.
514 ASSERT_THAT(output.packet_infos_, SizeIs(1));
515 {
516 const auto& packet_info = output.packet_infos_[0];
517 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
518 EXPECT_THAT(packet_info.csrcs(), ElementsAre(43, 65, 17));
519 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
520 EXPECT_FALSE(packet_info.audio_level().has_value());
Johannes Kronf7de74c2021-04-30 13:10:56 +0200521 EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000522 }
523
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000524 // Start with a simple check that the fake decoder is behaving as expected.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700525 EXPECT_EQ(kPayloadLengthSamples,
526 static_cast<size_t>(decoder_.next_value() - 1));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000527
528 // The value of the last of the output samples is the same as the number of
529 // samples played from the decoded packet. Thus, this number + the RTP
530 // timestamp should match the playout timestamp.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200531 // Wrap the expected value in an absl::optional to compare them as such.
henrik.lundin9a410dd2016-04-06 01:39:22 -0700532 EXPECT_EQ(
Danil Chapovalovb6021232018-06-19 13:26:36 +0200533 absl::optional<uint32_t>(rtp_header.timestamp +
534 output.data()[output.samples_per_channel_ - 1]),
henrik.lundin9a410dd2016-04-06 01:39:22 -0700535 neteq_->GetPlayoutTimestamp());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000536
537 // Check the timestamp for the last value in the sync buffer. This should
538 // be one full frame length ahead of the RTP timestamp.
539 const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
540 ASSERT_TRUE(sync_buffer != NULL);
henrik.lundin246ef3e2017-04-24 09:14:32 -0700541 EXPECT_EQ(rtp_header.timestamp + kPayloadLengthSamples,
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000542 sync_buffer->end_timestamp());
543
544 // Check that the number of samples still to play from the sync buffer add
545 // up with what was already played out.
henrik.lundin6d8e0112016-03-04 10:34:21 -0800546 EXPECT_EQ(
yujo36b1a5f2017-06-12 12:45:32 -0700547 kPayloadLengthSamples - output.data()[output.samples_per_channel_ - 1],
henrik.lundin6d8e0112016-03-04 10:34:21 -0800548 sync_buffer->FutureLength());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000549}
550
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000551TEST_F(NetEqImplTest, ReorderedPacket) {
552 UseNoMocks();
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
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000605 // Verify |output.packet_infos_|.
606 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
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000651 // Verify |output.packet_infos_|. Expect to only see the second packet.
652 ASSERT_THAT(output.packet_infos_, SizeIs(1));
653 {
654 const auto& packet_info = output.packet_infos_[0];
655 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
656 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
657 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
658 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
Johannes Kronf7de74c2021-04-30 13:10:56 +0200659 EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000660 }
661
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000662 EXPECT_CALL(mock_decoder, Die());
663}
664
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000665// This test verifies that NetEq can handle the situation where the first
666// incoming packet is rejected.
henrik.lundin@webrtc.org6ff3ac12014-11-20 14:14:49 +0000667TEST_F(NetEqImplTest, FirstPacketUnknown) {
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000668 UseNoMocks();
669 CreateInstance();
670
671 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000672 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700673 const size_t kPayloadLengthSamples =
674 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundinc9ec8752016-10-13 02:43:34 -0700675 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000676 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700677 RTPHeader rtp_header;
678 rtp_header.payloadType = kPayloadType;
679 rtp_header.sequenceNumber = 0x1234;
680 rtp_header.timestamp = 0x12345678;
681 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000682
683 // Insert one packet. Note that we have not registered any payload type, so
684 // this packet will be rejected.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200685 EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000686
687 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700688 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800689 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700690 bool muted;
691 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800692 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
693 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
694 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800695 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000696 EXPECT_THAT(output.packet_infos_, IsEmpty());
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000697
698 // Register the payload type.
Niels Möller05543682019-01-10 16:55:06 +0100699 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
700 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000701
702 // Insert 10 packets.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700703 for (size_t i = 0; i < 10; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -0700704 rtp_header.sequenceNumber++;
705 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200706 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000707 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
708 }
709
710 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700711 for (size_t i = 0; i < 3; ++i) {
henrik.lundin7a926812016-05-12 13:51:28 -0700712 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800713 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
714 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
715 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800716 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000717 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000718 EXPECT_THAT(output.packet_infos_, SizeIs(1));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000719 }
720}
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000721
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200722// This test verifies that audio interruption is not logged for the initial
723// PLC period before the first packet is deocoded.
724// TODO(henrik.lundin) Maybe move this test to neteq_network_stats_unittest.cc.
Henrik Lundinfe047752019-11-19 12:58:11 +0100725// Make the test parametrized, so that we can test with different initial
726// sample rates in NetEq.
727class NetEqImplTestSampleRateParameter
728 : public NetEqImplTest,
729 public testing::WithParamInterface<int> {
730 protected:
731 NetEqImplTestSampleRateParameter()
732 : NetEqImplTest(), initial_sample_rate_hz_(GetParam()) {
733 config_.sample_rate_hz = initial_sample_rate_hz_;
734 }
735
736 const int initial_sample_rate_hz_;
737};
738
Jared Siskinf2ed4012021-06-18 10:45:16 -0700739class NetEqImplTestSdpFormatParameter
740 : public NetEqImplTest,
741 public testing::WithParamInterface<SdpAudioFormat> {
742 protected:
743 NetEqImplTestSdpFormatParameter()
744 : NetEqImplTest(), sdp_format_(GetParam()) {}
745 const SdpAudioFormat sdp_format_;
746};
747
Henrik Lundinfe047752019-11-19 12:58:11 +0100748// This test does the following:
749// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
750// sample rate of 16000.
751// 1. Start calling GetAudio before inserting any encoded audio. The audio
752// produced will be PLC.
753// 2. Insert a number of encoded audio packets.
754// 3. Keep calling GetAudio and verify that no audio interruption was logged.
755// Call GetAudio until NetEq runs out of data again; PLC starts.
756// 4. Insert one more packet.
757// 5. Call GetAudio until that packet is decoded and the PLC ends.
758
759TEST_P(NetEqImplTestSampleRateParameter,
760 NoAudioInterruptionLoggedBeforeFirstDecode) {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200761 UseNoMocks();
762 CreateInstance();
763
764 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundinfe047752019-11-19 12:58:11 +0100765 const int kPayloadSampleRateHz = 16000;
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200766 const size_t kPayloadLengthSamples =
Henrik Lundinfe047752019-11-19 12:58:11 +0100767 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200768 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
769 uint8_t payload[kPayloadLengthBytes] = {0};
770 RTPHeader rtp_header;
771 rtp_header.payloadType = kPayloadType;
772 rtp_header.sequenceNumber = 0x1234;
773 rtp_header.timestamp = 0x12345678;
774 rtp_header.ssrc = 0x87654321;
775
776 // Register the payload type.
Henrik Lundinfe047752019-11-19 12:58:11 +0100777 EXPECT_TRUE(neteq_->RegisterPayloadType(
778 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200779
780 // Pull audio several times. No packets have been inserted yet.
Henrik Lundinfe047752019-11-19 12:58:11 +0100781 const size_t initial_output_size =
782 static_cast<size_t>(10 * initial_sample_rate_hz_ / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200783 AudioFrame output;
784 bool muted;
785 for (int i = 0; i < 100; ++i) {
786 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100787 EXPECT_EQ(initial_output_size, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200788 EXPECT_EQ(1u, output.num_channels_);
789 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000790 EXPECT_THAT(output.packet_infos_, IsEmpty());
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200791 }
792
Henrik Lundinfe047752019-11-19 12:58:11 +0100793 // Lambda for inserting packets.
794 auto insert_packet = [&]() {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200795 rtp_header.sequenceNumber++;
796 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200797 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundinfe047752019-11-19 12:58:11 +0100798 };
799 // Insert 10 packets.
800 for (size_t i = 0; i < 10; ++i) {
801 insert_packet();
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200802 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
803 }
804
805 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Henrik Lundinfe047752019-11-19 12:58:11 +0100806 constexpr size_t kOutputSize =
807 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200808 for (size_t i = 0; i < 3; ++i) {
809 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100810 EXPECT_EQ(kOutputSize, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200811 EXPECT_EQ(1u, output.num_channels_);
812 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
813 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000814 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200815 }
816
Henrik Lundinfe047752019-11-19 12:58:11 +0100817 // Verify that no interruption was logged.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200818 auto lifetime_stats = neteq_->GetLifetimeStatistics();
Henrik Lundin44125fa2019-04-29 17:00:46 +0200819 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundinfe047752019-11-19 12:58:11 +0100820
821 // Keep pulling audio data until a new PLC period is started.
822 size_t count_loops = 0;
823 while (output.speech_type_ == AudioFrame::kNormalSpeech) {
824 // Make sure we don't hang the test if we never go to PLC.
825 ASSERT_LT(++count_loops, 100u);
826 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
827 }
828
Jakob Ivarsson80fb9782020-10-09 13:41:06 +0200829 // Insert a few packets to avoid postpone decoding after expand.
830 for (size_t i = 0; i < 5; ++i) {
831 insert_packet();
832 }
Henrik Lundinfe047752019-11-19 12:58:11 +0100833
834 // Pull audio until the newly inserted packet is decoded and the PLC ends.
835 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
836 // Make sure we don't hang the test if we never go to PLC.
837 ASSERT_LT(++count_loops, 100u);
838 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
839 }
840
841 // Verify that no interruption was logged.
842 lifetime_stats = neteq_->GetLifetimeStatistics();
843 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200844}
845
Henrik Lundinfe047752019-11-19 12:58:11 +0100846// This test does the following:
847// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
848// sample rate of 16000.
849// 1. Insert a number of encoded audio packets.
850// 2. Call GetAudio and verify that decoded audio is produced.
851// 3. Keep calling GetAudio until NetEq runs out of data; PLC starts.
852// 4. Keep calling GetAudio until PLC has been produced for at least 150 ms.
853// 5. Insert one more packet.
854// 6. Call GetAudio until that packet is decoded and the PLC ends.
855// 7. Verify that an interruption was logged.
856
857TEST_P(NetEqImplTestSampleRateParameter, AudioInterruptionLogged) {
858 UseNoMocks();
859 CreateInstance();
860
861 const uint8_t kPayloadType = 17; // Just an arbitrary number.
862 const int kPayloadSampleRateHz = 16000;
863 const size_t kPayloadLengthSamples =
864 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
865 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
866 uint8_t payload[kPayloadLengthBytes] = {0};
867 RTPHeader rtp_header;
868 rtp_header.payloadType = kPayloadType;
869 rtp_header.sequenceNumber = 0x1234;
870 rtp_header.timestamp = 0x12345678;
871 rtp_header.ssrc = 0x87654321;
872
873 // Register the payload type.
874 EXPECT_TRUE(neteq_->RegisterPayloadType(
875 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
876
877 // Lambda for inserting packets.
878 auto insert_packet = [&]() {
879 rtp_header.sequenceNumber++;
880 rtp_header.timestamp += kPayloadLengthSamples;
881 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
882 };
883 // Insert 10 packets.
884 for (size_t i = 0; i < 10; ++i) {
885 insert_packet();
886 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
887 }
888
889 AudioFrame output;
890 bool muted;
891 // Keep pulling audio data until a new PLC period is started.
892 size_t count_loops = 0;
893 do {
894 // Make sure we don't hang the test if we never go to PLC.
895 ASSERT_LT(++count_loops, 100u);
896 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
897 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
898
899 // Pull audio 15 times, which produces 150 ms of output audio. This should
900 // all be produced as PLC. The total length of the gap will then be 150 ms
901 // plus an initial fraction of 10 ms at the start and the end of the PLC
902 // period. In total, less than 170 ms.
903 for (size_t i = 0; i < 15; ++i) {
904 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
905 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
906 }
907
Jakob Ivarsson80fb9782020-10-09 13:41:06 +0200908 // Insert a few packets to avoid postpone decoding after expand.
909 for (size_t i = 0; i < 5; ++i) {
910 insert_packet();
911 }
Henrik Lundinfe047752019-11-19 12:58:11 +0100912
913 // Pull audio until the newly inserted packet is decoded and the PLC ends.
914 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
915 // Make sure we don't hang the test if we never go to PLC.
916 ASSERT_LT(++count_loops, 100u);
917 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
918 }
919
920 // Verify that the interruption was logged.
921 auto lifetime_stats = neteq_->GetLifetimeStatistics();
922 EXPECT_EQ(1, lifetime_stats.interruption_count);
923 EXPECT_GT(lifetime_stats.total_interruption_duration_ms, 150);
924 EXPECT_LT(lifetime_stats.total_interruption_duration_ms, 170);
925}
926
927INSTANTIATE_TEST_SUITE_P(SampleRates,
928 NetEqImplTestSampleRateParameter,
929 testing::Values(8000, 16000, 32000, 48000));
930
Jared Siskinf2ed4012021-06-18 10:45:16 -0700931TEST_P(NetEqImplTestSdpFormatParameter, GetNackListScaledTimestamp) {
932 UseNoMocks();
933 CreateInstance();
934
935 neteq_->EnableNack(128);
936
937 const uint8_t kPayloadType = 17; // Just an arbitrary number.
938 const int kPayloadSampleRateHz = sdp_format_.clockrate_hz;
939 const size_t kPayloadLengthSamples =
940 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
941 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
942 std::vector<uint8_t> payload(kPayloadLengthBytes, 0);
943 RTPHeader rtp_header;
944 rtp_header.payloadType = kPayloadType;
945 rtp_header.sequenceNumber = 0x1234;
946 rtp_header.timestamp = 0x12345678;
947 rtp_header.ssrc = 0x87654321;
948
949 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType, sdp_format_));
950
951 auto insert_packet = [&](bool lost = false) {
952 rtp_header.sequenceNumber++;
953 rtp_header.timestamp += kPayloadLengthSamples;
954 if (!lost)
955 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
956 };
957
958 // Insert and decode 10 packets.
959 for (size_t i = 0; i < 10; ++i) {
960 insert_packet();
961 }
962 AudioFrame output;
963 size_t count_loops = 0;
964 do {
965 bool muted;
966 // Make sure we don't hang the test if we never go to PLC.
967 ASSERT_LT(++count_loops, 100u);
968 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
969 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
970
971 insert_packet();
972
973 insert_packet(/*lost=*/true);
974
975 // Ensure packet gets marked as missing.
976 for (int i = 0; i < 5; ++i) {
977 insert_packet();
978 }
979
980 // Missing packet recoverable with 5ms RTT.
981 EXPECT_THAT(neteq_->GetNackList(5), Not(IsEmpty()));
982
983 // No packets should have TimeToPlay > 500ms.
984 EXPECT_THAT(neteq_->GetNackList(500), IsEmpty());
985}
986
987INSTANTIATE_TEST_SUITE_P(GetNackList,
988 NetEqImplTestSdpFormatParameter,
989 testing::Values(SdpAudioFormat("g722", 8000, 1),
990 SdpAudioFormat("opus", 48000, 2)));
991
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000992// This test verifies that NetEq can handle comfort noise and enters/quits codec
993// internal CNG mode properly.
994TEST_F(NetEqImplTest, CodecInternalCng) {
995 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +0100996 // Create a mock decoder object.
997 MockAudioDecoder mock_decoder;
998 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +0200999 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001000
1001 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001002 const int kSampleRateKhz = 48;
Peter Kastingdce40cf2015-08-24 14:52:23 -07001003 const size_t kPayloadLengthSamples =
1004 static_cast<size_t>(20 * kSampleRateKhz); // 20 ms.
1005 const size_t kPayloadLengthBytes = 10;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001006 uint8_t payload[kPayloadLengthBytes] = {0};
1007 int16_t dummy_output[kPayloadLengthSamples] = {0};
1008
henrik.lundin246ef3e2017-04-24 09:14:32 -07001009 RTPHeader rtp_header;
1010 rtp_header.payloadType = kPayloadType;
1011 rtp_header.sequenceNumber = 0x1234;
1012 rtp_header.timestamp = 0x12345678;
1013 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001014
Karl Wiberg43766482015-08-27 15:22:11 +02001015 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001016 EXPECT_CALL(mock_decoder, SampleRateHz())
1017 .WillRepeatedly(Return(kSampleRateKhz * 1000));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +00001018 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001019 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001020 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001021 // Packed duration when asking the decoder for more CNG data (without a new
1022 // packet).
1023 EXPECT_CALL(mock_decoder, PacketDuration(nullptr, 0))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001024 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001025
1026 // Pointee(x) verifies that first byte of the payload equals x, this makes it
1027 // possible to verify that the correct payload is fed to Decode().
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001028 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
1029 kSampleRateKhz * 1000, _, _))
1030 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001031 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001032 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001033 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001034
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001035 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes,
1036 kSampleRateKhz * 1000, _, _))
1037 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001038 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001039 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001040 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001041
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001042 EXPECT_CALL(mock_decoder,
1043 DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
1044 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001045 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001046 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001047 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001048
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001049 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
1050 kSampleRateKhz * 1000, _, _))
1051 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001052 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001053 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001054 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001055
Niels Möller50b66d52018-12-11 14:43:21 +01001056 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1057 SdpAudioFormat("opus", 48000, 2)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001058
Peter Kastingdce40cf2015-08-24 14:52:23 -07001059 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001060 AudioFrame output;
henrik.lundin55480f52016-03-08 02:37:57 -08001061 AudioFrame::SpeechType expected_type[8] = {
Jonas Olssona4d87372019-07-05 19:08:33 +02001062 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech, AudioFrame::kCNG,
1063 AudioFrame::kCNG, AudioFrame::kCNG, AudioFrame::kCNG,
1064 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001065 int expected_timestamp_increment[8] = {
1066 -1, // will not be used.
1067 10 * kSampleRateKhz,
Jonas Olssona4d87372019-07-05 19:08:33 +02001068 -1,
1069 -1, // timestamp will be empty during CNG mode; indicated by -1 here.
1070 -1,
1071 -1,
1072 50 * kSampleRateKhz,
1073 10 * kSampleRateKhz};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001074
Jakob Ivarssond723da12021-01-15 17:44:56 +01001075 // Insert one packet (decoder will return speech).
1076 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
1077
henrik.lundin7a926812016-05-12 13:51:28 -07001078 bool muted;
1079 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Danil Chapovalovb6021232018-06-19 13:26:36 +02001080 absl::optional<uint32_t> last_timestamp = neteq_->GetPlayoutTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -07001081 ASSERT_TRUE(last_timestamp);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001082
Jakob Ivarssond723da12021-01-15 17:44:56 +01001083 // Insert second packet (decoder will return CNG).
1084 payload[0] = 1;
1085 rtp_header.sequenceNumber++;
1086 rtp_header.timestamp += kPayloadLengthSamples;
1087 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
1088
henrik.lundin0d96ab72016-04-06 12:28:26 -07001089 // Lambda for verifying the timestamps.
1090 auto verify_timestamp = [&last_timestamp, &expected_timestamp_increment](
Danil Chapovalovb6021232018-06-19 13:26:36 +02001091 absl::optional<uint32_t> ts, size_t i) {
henrik.lundin0d96ab72016-04-06 12:28:26 -07001092 if (expected_timestamp_increment[i] == -1) {
1093 // Expect to get an empty timestamp value during CNG and PLC.
1094 EXPECT_FALSE(ts) << "i = " << i;
1095 } else {
1096 ASSERT_TRUE(ts) << "i = " << i;
1097 EXPECT_EQ(*ts, *last_timestamp + expected_timestamp_increment[i])
1098 << "i = " << i;
1099 last_timestamp = ts;
1100 }
1101 };
1102
Peter Kastingdce40cf2015-08-24 14:52:23 -07001103 for (size_t i = 1; i < 6; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001104 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1105 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001106 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001107 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001108 SCOPED_TRACE("");
1109 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001110 }
1111
1112 // Insert third packet, which leaves a gap from last packet.
1113 payload[0] = 2;
henrik.lundin246ef3e2017-04-24 09:14:32 -07001114 rtp_header.sequenceNumber += 2;
1115 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001116 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001117
Peter Kastingdce40cf2015-08-24 14:52:23 -07001118 for (size_t i = 6; i < 8; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001119 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1120 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001121 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001122 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001123 SCOPED_TRACE("");
1124 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001125 }
1126
1127 // Now check the packet buffer, and make sure it is empty.
1128 EXPECT_TRUE(packet_buffer_->Empty());
1129
1130 EXPECT_CALL(mock_decoder, Die());
1131}
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001132
1133TEST_F(NetEqImplTest, UnsupportedDecoder) {
1134 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001135 ::testing::NiceMock<MockAudioDecoder> decoder;
1136
1137 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001138 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&decoder));
minyue5bd33972016-05-02 04:46:11 -07001139 static const size_t kNetEqMaxFrameSize = 5760; // 120 ms @ 48 kHz.
Peter Kasting69558702016-01-12 16:26:35 -08001140 static const size_t kChannels = 2;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001141
1142 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001143 const int kSampleRateHz = 8000;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001144
Peter Kastingdce40cf2015-08-24 14:52:23 -07001145 const size_t kPayloadLengthSamples =
1146 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001147 const size_t kPayloadLengthBytes = 1;
minyue5bd33972016-05-02 04:46:11 -07001148 uint8_t payload[kPayloadLengthBytes] = {0};
Minyue323b1322015-05-25 13:49:37 +02001149 int16_t dummy_output[kPayloadLengthSamples * kChannels] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001150 RTPHeader rtp_header;
1151 rtp_header.payloadType = kPayloadType;
1152 rtp_header.sequenceNumber = 0x1234;
1153 rtp_header.timestamp = 0x12345678;
1154 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001155
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001156 const uint8_t kFirstPayloadValue = 1;
1157 const uint8_t kSecondPayloadValue = 2;
1158
ossu61a208b2016-09-20 01:38:00 -07001159 EXPECT_CALL(decoder,
1160 PacketDuration(Pointee(kFirstPayloadValue), kPayloadLengthBytes))
1161 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001162 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize + 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001163
ossu61a208b2016-09-20 01:38:00 -07001164 EXPECT_CALL(decoder, DecodeInternal(Pointee(kFirstPayloadValue), _, _, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001165 .Times(0);
1166
ossu61a208b2016-09-20 01:38:00 -07001167 EXPECT_CALL(decoder, DecodeInternal(Pointee(kSecondPayloadValue),
1168 kPayloadLengthBytes, kSampleRateHz, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001169 .Times(1)
ossu61a208b2016-09-20 01:38:00 -07001170 .WillOnce(DoAll(
1171 SetArrayArgument<3>(dummy_output,
1172 dummy_output + kPayloadLengthSamples * kChannels),
1173 SetArgPointee<4>(AudioDecoder::kSpeech),
1174 Return(static_cast<int>(kPayloadLengthSamples * kChannels))));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001175
ossu61a208b2016-09-20 01:38:00 -07001176 EXPECT_CALL(decoder,
1177 PacketDuration(Pointee(kSecondPayloadValue), kPayloadLengthBytes))
1178 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001179 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize)));
ossu61a208b2016-09-20 01:38:00 -07001180
Jonas Olssona4d87372019-07-05 19:08:33 +02001181 EXPECT_CALL(decoder, SampleRateHz()).WillRepeatedly(Return(kSampleRateHz));
ossu61a208b2016-09-20 01:38:00 -07001182
Jonas Olssona4d87372019-07-05 19:08:33 +02001183 EXPECT_CALL(decoder, Channels()).WillRepeatedly(Return(kChannels));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001184
Niels Möllera1eb9c72018-12-07 15:24:42 +01001185 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1186 SdpAudioFormat("L16", 8000, 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001187
1188 // Insert one packet.
1189 payload[0] = kFirstPayloadValue; // This will make Decode() fail.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001190 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001191
1192 // Insert another packet.
1193 payload[0] = kSecondPayloadValue; // This will make Decode() successful.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001194 rtp_header.sequenceNumber++;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001195 // The second timestamp needs to be at least 30 ms after the first to make
1196 // the second packet get decoded.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001197 rtp_header.timestamp += 3 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001198 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001199
henrik.lundin6d8e0112016-03-04 10:34:21 -08001200 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001201 bool muted;
henrik.lundin6d8e0112016-03-04 10:34:21 -08001202 // First call to GetAudio will try to decode the "faulty" packet.
Henrik Lundinc417d9e2017-06-14 12:29:03 +02001203 // Expect kFail return value.
henrik.lundin7a926812016-05-12 13:51:28 -07001204 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001205 // Output size and number of channels should be correct.
1206 const size_t kExpectedOutputSize = 10 * (kSampleRateHz / 1000) * kChannels;
1207 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1208 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001209 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001210
henrik.lundin6d8e0112016-03-04 10:34:21 -08001211 // Second call to GetAudio will decode the packet that is ok. No errors are
1212 // expected.
henrik.lundin7a926812016-05-12 13:51:28 -07001213 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001214 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1215 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001216 EXPECT_THAT(output.packet_infos_, SizeIs(1));
ossu61a208b2016-09-20 01:38:00 -07001217
1218 // Die isn't called through NiceMock (since it's called by the
1219 // MockAudioDecoder constructor), so it needs to be mocked explicitly.
1220 EXPECT_CALL(decoder, Die());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001221}
1222
henrik.lundin116c84e2015-08-27 13:14:48 -07001223// This test inserts packets until the buffer is flushed. After that, it asks
1224// NetEq for the network statistics. The purpose of the test is to make sure
1225// that even though the buffer size increment is negative (which it becomes when
1226// the packet causing a flush is inserted), the packet length stored in the
1227// decision logic remains valid.
1228TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) {
1229 UseNoMocks();
1230 CreateInstance();
1231
1232 const size_t kPayloadLengthSamples = 80;
1233 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1234 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin116c84e2015-08-27 13:14:48 -07001235 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001236 RTPHeader rtp_header;
1237 rtp_header.payloadType = kPayloadType;
1238 rtp_header.sequenceNumber = 0x1234;
1239 rtp_header.timestamp = 0x12345678;
1240 rtp_header.ssrc = 0x87654321;
henrik.lundin116c84e2015-08-27 13:14:48 -07001241
Niels Möller05543682019-01-10 16:55:06 +01001242 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1243 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin116c84e2015-08-27 13:14:48 -07001244
1245 // Insert packets until the buffer flushes.
1246 for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) {
1247 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
Karl Wiberg45eb1352019-10-10 14:23:00 +02001248 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -07001249 rtp_header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples);
1250 ++rtp_header.sequenceNumber;
henrik.lundin116c84e2015-08-27 13:14:48 -07001251 }
1252 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
1253
1254 // Ask for network statistics. This should not crash.
1255 NetEqNetworkStatistics stats;
1256 EXPECT_EQ(NetEq::kOK, neteq_->NetworkStatistics(&stats));
1257}
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001258
1259TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
1260 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001261 // Create a mock decoder object.
1262 MockAudioDecoder mock_decoder;
1263
1264 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001265 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001266
1267 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001268 const int kSampleRateHz = 8000;
1269 const size_t kPayloadLengthSamples =
1270 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
1271 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples;
1272 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001273 RTPHeader rtp_header;
1274 rtp_header.payloadType = kPayloadType;
1275 rtp_header.sequenceNumber = 0x1234;
1276 rtp_header.timestamp = 0x12345678;
1277 rtp_header.ssrc = 0x87654321;
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001278
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001279 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001280 EXPECT_CALL(mock_decoder, SampleRateHz())
1281 .WillRepeatedly(Return(kSampleRateHz));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001282 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001283 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001284 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001285 int16_t dummy_output[kPayloadLengthSamples] = {0};
1286 // The below expectation will make the mock decoder write
Artem Titovd00ce742021-07-28 20:00:17 +02001287 // `kPayloadLengthSamples` - 5 zeros to the output array, and mark it as
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001288 // speech. That is, the decoded length is 5 samples shorter than the expected.
1289 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001290 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001291 .WillOnce(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001292 DoAll(SetArrayArgument<3>(dummy_output,
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001293 dummy_output + kPayloadLengthSamples - 5),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001294 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001295 Return(rtc::checked_cast<int>(kPayloadLengthSamples - 5))));
Niels Möllera1eb9c72018-12-07 15:24:42 +01001296 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1297 SdpAudioFormat("L16", 8000, 1)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001298
1299 // Insert one packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001300 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001301
1302 EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength());
1303
1304 // Pull audio once.
1305 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001306 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001307 bool muted;
1308 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001309 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1310 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001311 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001312 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001313
1314 EXPECT_CALL(mock_decoder, Die());
1315}
minyuel6d92bf52015-09-23 15:20:39 +02001316
1317// This test checks the behavior of NetEq when audio decoder fails.
1318TEST_F(NetEqImplTest, DecodingError) {
1319 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001320 // Create a mock decoder object.
1321 MockAudioDecoder mock_decoder;
1322
1323 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001324 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001325
1326 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001327 const int kSampleRateHz = 8000;
1328 const int kDecoderErrorCode = -97; // Any negative number.
1329
1330 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1331 const size_t kFrameLengthSamples =
1332 static_cast<size_t>(5 * kSampleRateHz / 1000);
1333
1334 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1335
1336 uint8_t payload[kPayloadLengthBytes] = {0};
1337
henrik.lundin246ef3e2017-04-24 09:14:32 -07001338 RTPHeader rtp_header;
1339 rtp_header.payloadType = kPayloadType;
1340 rtp_header.sequenceNumber = 0x1234;
1341 rtp_header.timestamp = 0x12345678;
1342 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001343
minyuel6d92bf52015-09-23 15:20:39 +02001344 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001345 EXPECT_CALL(mock_decoder, SampleRateHz())
1346 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001347 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001348 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001349 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001350 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
1351 EXPECT_CALL(mock_decoder, HasDecodePlc()).WillOnce(Return(false));
minyuel6d92bf52015-09-23 15:20:39 +02001352 int16_t dummy_output[kFrameLengthSamples] = {0};
1353
1354 {
1355 InSequence sequence; // Dummy variable.
1356 // Mock decoder works normally the first time.
1357 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001358 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001359 .Times(3)
1360 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001361 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001362 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001363 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001364 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001365 .RetiresOnSaturation();
1366
1367 // Then mock decoder fails. A common reason for failure can be buffer being
1368 // too short
1369 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001370 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001371 .WillOnce(Return(-1))
1372 .RetiresOnSaturation();
1373
1374 // Mock decoder finally returns to normal.
1375 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001376 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001377 .Times(2)
1378 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001379 DoAll(SetArrayArgument<3>(dummy_output,
1380 dummy_output + kFrameLengthSamples),
1381 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001382 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001383 }
1384
Niels Möllera1eb9c72018-12-07 15:24:42 +01001385 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1386 SdpAudioFormat("L16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001387
1388 // Insert packets.
Jakob Ivarsson80fb9782020-10-09 13:41:06 +02001389 for (int i = 0; i < 20; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001390 rtp_header.sequenceNumber += 1;
1391 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001392 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001393 }
1394
1395 // Pull audio.
1396 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001397 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001398 bool muted;
1399 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001400 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1401 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001402 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001403 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001404
1405 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001406 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001407 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1408 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001409 // We are not expecting anything for output.speech_type_, since an error was
1410 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001411
1412 // Pull audio again, should continue an expansion.
henrik.lundin7a926812016-05-12 13:51:28 -07001413 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001414 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1415 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001416 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001417 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyuel6d92bf52015-09-23 15:20:39 +02001418
1419 // Pull audio again, should behave normal.
henrik.lundin7a926812016-05-12 13:51:28 -07001420 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001421 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1422 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001423 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001424 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001425
1426 EXPECT_CALL(mock_decoder, Die());
1427}
1428
1429// This test checks the behavior of NetEq when audio decoder fails during CNG.
1430TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
1431 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +01001432
1433 // Create a mock decoder object.
1434 MockAudioDecoder mock_decoder;
1435 CreateInstance(
Tommi87f70902021-04-27 14:43:08 +02001436 rtc::make_ref_counted<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001437
1438 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001439 const int kSampleRateHz = 8000;
1440 const int kDecoderErrorCode = -97; // Any negative number.
1441
1442 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1443 const size_t kFrameLengthSamples =
1444 static_cast<size_t>(5 * kSampleRateHz / 1000);
1445
1446 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1447
1448 uint8_t payload[kPayloadLengthBytes] = {0};
1449
henrik.lundin246ef3e2017-04-24 09:14:32 -07001450 RTPHeader rtp_header;
1451 rtp_header.payloadType = kPayloadType;
1452 rtp_header.sequenceNumber = 0x1234;
1453 rtp_header.timestamp = 0x12345678;
1454 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001455
minyuel6d92bf52015-09-23 15:20:39 +02001456 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001457 EXPECT_CALL(mock_decoder, SampleRateHz())
1458 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001459 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001460 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001461 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001462 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
minyuel6d92bf52015-09-23 15:20:39 +02001463 int16_t dummy_output[kFrameLengthSamples] = {0};
1464
1465 {
1466 InSequence sequence; // Dummy variable.
1467 // Mock decoder works normally the first 2 times.
1468 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001469 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001470 .Times(2)
1471 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001472 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001473 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001474 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001475 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001476 .RetiresOnSaturation();
1477
1478 // Then mock decoder fails. A common reason for failure can be buffer being
1479 // too short
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001480 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001481 .WillOnce(Return(-1))
1482 .RetiresOnSaturation();
1483
1484 // Mock decoder finally returns to normal.
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001485 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001486 .Times(2)
1487 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001488 DoAll(SetArrayArgument<3>(dummy_output,
1489 dummy_output + kFrameLengthSamples),
1490 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001491 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001492 }
1493
Niels Möller50b66d52018-12-11 14:43:21 +01001494 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1495 SdpAudioFormat("l16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001496
1497 // Insert 2 packets. This will make netEq into codec internal CNG mode.
1498 for (int i = 0; i < 2; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001499 rtp_header.sequenceNumber += 1;
1500 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001501 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001502 }
1503
1504 // Pull audio.
1505 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001506 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001507 bool muted;
1508 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001509 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1510 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001511 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001512
1513 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001514 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001515 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1516 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001517 // We are not expecting anything for output.speech_type_, since an error was
1518 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001519
1520 // Pull audio again, should resume codec CNG.
henrik.lundin7a926812016-05-12 13:51:28 -07001521 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001522 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1523 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001524 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001525
1526 EXPECT_CALL(mock_decoder, Die());
1527}
1528
henrik.lundind89814b2015-11-23 06:49:25 -08001529// Tests that the return value from last_output_sample_rate_hz() is equal to the
1530// configured inital sample rate.
1531TEST_F(NetEqImplTest, InitialLastOutputSampleRate) {
1532 UseNoMocks();
1533 config_.sample_rate_hz = 48000;
1534 CreateInstance();
1535 EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz());
1536}
1537
henrik.lundined497212016-04-25 10:11:38 -07001538TEST_F(NetEqImplTest, TickTimerIncrement) {
1539 UseNoMocks();
1540 CreateInstance();
1541 ASSERT_TRUE(tick_timer_);
1542 EXPECT_EQ(0u, tick_timer_->ticks());
1543 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001544 bool muted;
1545 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundined497212016-04-25 10:11:38 -07001546 EXPECT_EQ(1u, tick_timer_->ticks());
1547}
1548
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001549TEST_F(NetEqImplTest, SetBaseMinimumDelay) {
1550 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001551 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001552 CreateInstance();
1553
Ivo Creusen53a31f72019-10-24 15:20:39 +02001554 EXPECT_CALL(*mock_neteq_controller_, SetBaseMinimumDelay(_))
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001555 .WillOnce(Return(true))
1556 .WillOnce(Return(false));
1557
1558 const int delay_ms = 200;
1559
1560 EXPECT_EQ(true, neteq_->SetBaseMinimumDelayMs(delay_ms));
1561 EXPECT_EQ(false, neteq_->SetBaseMinimumDelayMs(delay_ms));
1562}
1563
1564TEST_F(NetEqImplTest, GetBaseMinimumDelayMs) {
1565 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001566 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001567 CreateInstance();
1568
1569 const int delay_ms = 200;
1570
Ivo Creusen53a31f72019-10-24 15:20:39 +02001571 EXPECT_CALL(*mock_neteq_controller_, GetBaseMinimumDelay())
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001572 .WillOnce(Return(delay_ms));
1573
1574 EXPECT_EQ(delay_ms, neteq_->GetBaseMinimumDelayMs());
1575}
1576
henrik.lundin114c1b32017-04-26 07:47:32 -07001577TEST_F(NetEqImplTest, TargetDelayMs) {
1578 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001579 use_mock_neteq_controller_ = true;
henrik.lundin114c1b32017-04-26 07:47:32 -07001580 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001581 constexpr int kTargetLevelMs = 510;
1582 EXPECT_CALL(*mock_neteq_controller_, TargetLevelMs())
1583 .WillOnce(Return(kTargetLevelMs));
1584 EXPECT_EQ(510, neteq_->TargetDelayMs());
henrik.lundin114c1b32017-04-26 07:47:32 -07001585}
1586
henrik.lundinb8c55b12017-05-10 07:38:01 -07001587TEST_F(NetEqImplTest, InsertEmptyPacket) {
1588 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001589 use_mock_neteq_controller_ = true;
henrik.lundinb8c55b12017-05-10 07:38:01 -07001590 CreateInstance();
1591
1592 RTPHeader rtp_header;
1593 rtp_header.payloadType = 17;
1594 rtp_header.sequenceNumber = 0x1234;
1595 rtp_header.timestamp = 0x12345678;
1596 rtp_header.ssrc = 0x87654321;
1597
Ivo Creusen53a31f72019-10-24 15:20:39 +02001598 EXPECT_CALL(*mock_neteq_controller_, RegisterEmptyPacket());
henrik.lundinb8c55b12017-05-10 07:38:01 -07001599 neteq_->InsertEmptyPacket(rtp_header);
1600}
1601
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001602TEST_F(NetEqImplTest, EnableRtxHandling) {
Ivo Creusena2b31c32020-10-14 17:54:22 +02001603 using ::testing::AllOf;
1604 using ::testing::Field;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001605 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001606 use_mock_neteq_controller_ = true;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001607 config_.enable_rtx_handling = true;
1608 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001609 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001610 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001611 .WillOnce(Return(NetEq::Operation::kNormal));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001612
1613 const int kPayloadLengthSamples = 80;
1614 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1615 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001616 uint8_t payload[kPayloadLengthBytes] = {0};
1617 RTPHeader rtp_header;
1618 rtp_header.payloadType = kPayloadType;
1619 rtp_header.sequenceNumber = 0x1234;
1620 rtp_header.timestamp = 0x12345678;
1621 rtp_header.ssrc = 0x87654321;
1622
Niels Möller05543682019-01-10 16:55:06 +01001623 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1624 SdpAudioFormat("l16", 8000, 1)));
Karl Wiberg45eb1352019-10-10 14:23:00 +02001625 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001626 AudioFrame output;
1627 bool muted;
1628 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
1629
1630 // Insert second packet that was sent before the first packet.
1631 rtp_header.sequenceNumber -= 1;
1632 rtp_header.timestamp -= kPayloadLengthSamples;
Ivo Creusena2b31c32020-10-14 17:54:22 +02001633 EXPECT_CALL(
1634 *mock_neteq_controller_,
1635 PacketArrived(
1636 /*fs_hz*/ 8000,
1637 /*should_update_stats*/ _,
1638 /*info*/
1639 AllOf(
1640 Field(&NetEqController::PacketArrivedInfo::packet_length_samples,
1641 kPayloadLengthSamples),
1642 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
1643 rtp_header.sequenceNumber),
1644 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
1645 rtp_header.timestamp))));
Ivo Creusen53a31f72019-10-24 15:20:39 +02001646
Karl Wiberg45eb1352019-10-10 14:23:00 +02001647 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001648}
1649
minyue5bd33972016-05-02 04:46:11 -07001650class Decoder120ms : public AudioDecoder {
1651 public:
kwiberg347d3512016-06-16 01:59:09 -07001652 Decoder120ms(int sample_rate_hz, SpeechType speech_type)
1653 : sample_rate_hz_(sample_rate_hz),
1654 next_value_(1),
minyue5bd33972016-05-02 04:46:11 -07001655 speech_type_(speech_type) {}
1656
1657 int DecodeInternal(const uint8_t* encoded,
1658 size_t encoded_len,
1659 int sample_rate_hz,
1660 int16_t* decoded,
1661 SpeechType* speech_type) override {
kwiberg347d3512016-06-16 01:59:09 -07001662 EXPECT_EQ(sample_rate_hz_, sample_rate_hz);
minyue5bd33972016-05-02 04:46:11 -07001663 size_t decoded_len =
1664 rtc::CheckedDivExact(sample_rate_hz, 1000) * 120 * Channels();
1665 for (size_t i = 0; i < decoded_len; ++i) {
1666 decoded[i] = next_value_++;
1667 }
1668 *speech_type = speech_type_;
Mirko Bonadei737e0732017-10-19 09:00:17 +02001669 return rtc::checked_cast<int>(decoded_len);
minyue5bd33972016-05-02 04:46:11 -07001670 }
1671
1672 void Reset() override { next_value_ = 1; }
kwiberg347d3512016-06-16 01:59:09 -07001673 int SampleRateHz() const override { return sample_rate_hz_; }
minyue5bd33972016-05-02 04:46:11 -07001674 size_t Channels() const override { return 2; }
1675
1676 private:
kwiberg347d3512016-06-16 01:59:09 -07001677 int sample_rate_hz_;
minyue5bd33972016-05-02 04:46:11 -07001678 int16_t next_value_;
1679 SpeechType speech_type_;
1680};
1681
1682class NetEqImplTest120ms : public NetEqImplTest {
1683 protected:
1684 NetEqImplTest120ms() : NetEqImplTest() {}
1685 virtual ~NetEqImplTest120ms() {}
1686
1687 void CreateInstanceNoMocks() {
1688 UseNoMocks();
Niels Möllera0f44302018-11-30 10:45:12 +01001689 CreateInstance(decoder_factory_);
1690 EXPECT_TRUE(neteq_->RegisterPayloadType(
1691 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001692 }
1693
1694 void CreateInstanceWithDelayManagerMock() {
1695 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001696 use_mock_neteq_controller_ = true;
Niels Möllera0f44302018-11-30 10:45:12 +01001697 CreateInstance(decoder_factory_);
1698 EXPECT_TRUE(neteq_->RegisterPayloadType(
1699 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001700 }
1701
1702 uint32_t timestamp_diff_between_packets() const {
1703 return rtc::CheckedDivExact(kSamplingFreq_, 1000u) * 120;
1704 }
1705
1706 uint32_t first_timestamp() const { return 10u; }
1707
1708 void GetFirstPacket() {
henrik.lundin7a926812016-05-12 13:51:28 -07001709 bool muted;
minyue5bd33972016-05-02 04:46:11 -07001710 for (int i = 0; i < 12; i++) {
henrik.lundin7a926812016-05-12 13:51:28 -07001711 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
1712 EXPECT_FALSE(muted);
minyue5bd33972016-05-02 04:46:11 -07001713 }
1714 }
1715
1716 void InsertPacket(uint32_t timestamp) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001717 RTPHeader rtp_header;
1718 rtp_header.payloadType = kPayloadType;
1719 rtp_header.sequenceNumber = sequence_number_;
1720 rtp_header.timestamp = timestamp;
1721 rtp_header.ssrc = 15;
minyue5bd33972016-05-02 04:46:11 -07001722 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1723 uint8_t payload[kPayloadLengthBytes] = {0};
Karl Wiberg45eb1352019-10-10 14:23:00 +02001724 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue5bd33972016-05-02 04:46:11 -07001725 sequence_number_++;
1726 }
1727
1728 void Register120msCodec(AudioDecoder::SpeechType speech_type) {
Niels Möllera0f44302018-11-30 10:45:12 +01001729 const uint32_t sampling_freq = kSamplingFreq_;
Tommi87f70902021-04-27 14:43:08 +02001730 decoder_factory_ = rtc::make_ref_counted<test::FunctionAudioDecoderFactory>(
1731 [sampling_freq, speech_type]() {
1732 std::unique_ptr<AudioDecoder> decoder =
1733 std::make_unique<Decoder120ms>(sampling_freq, speech_type);
1734 RTC_CHECK_EQ(2, decoder->Channels());
1735 return decoder;
1736 });
minyue5bd33972016-05-02 04:46:11 -07001737 }
1738
Niels Möllera0f44302018-11-30 10:45:12 +01001739 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
minyue5bd33972016-05-02 04:46:11 -07001740 AudioFrame output_;
1741 const uint32_t kPayloadType = 17;
1742 const uint32_t kSamplingFreq_ = 48000;
1743 uint16_t sequence_number_ = 1;
1744};
1745
minyue5bd33972016-05-02 04:46:11 -07001746TEST_F(NetEqImplTest120ms, CodecInternalCng) {
minyue5bd33972016-05-02 04:46:11 -07001747 Register120msCodec(AudioDecoder::kComfortNoise);
Niels Möllera0f44302018-11-30 10:45:12 +01001748 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001749
1750 InsertPacket(first_timestamp());
1751 GetFirstPacket();
1752
henrik.lundin7a926812016-05-12 13:51:28 -07001753 bool muted;
1754 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001755 EXPECT_EQ(NetEq::Operation::kCodecInternalCng,
1756 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001757}
1758
1759TEST_F(NetEqImplTest120ms, Normal) {
minyue5bd33972016-05-02 04:46:11 -07001760 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001761 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001762
1763 InsertPacket(first_timestamp());
1764 GetFirstPacket();
1765
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001766 EXPECT_EQ(NetEq::Operation::kNormal, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001767}
1768
1769TEST_F(NetEqImplTest120ms, Merge) {
Niels Möllera0f44302018-11-30 10:45:12 +01001770 Register120msCodec(AudioDecoder::kSpeech);
minyue5bd33972016-05-02 04:46:11 -07001771 CreateInstanceWithDelayManagerMock();
1772
Ivo Creusen53a31f72019-10-24 15:20:39 +02001773 EXPECT_CALL(*mock_neteq_controller_, CngOff()).WillRepeatedly(Return(true));
minyue5bd33972016-05-02 04:46:11 -07001774 InsertPacket(first_timestamp());
1775
1776 GetFirstPacket();
henrik.lundin7a926812016-05-12 13:51:28 -07001777 bool muted;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001778 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001779 .WillOnce(Return(NetEq::Operation::kExpand));
henrik.lundin7a926812016-05-12 13:51:28 -07001780 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
minyue5bd33972016-05-02 04:46:11 -07001781
1782 InsertPacket(first_timestamp() + 2 * timestamp_diff_between_packets());
1783
Ivo Creusen53a31f72019-10-24 15:20:39 +02001784 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001785 .WillOnce(Return(NetEq::Operation::kMerge));
minyue5bd33972016-05-02 04:46:11 -07001786
henrik.lundin7a926812016-05-12 13:51:28 -07001787 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001788 EXPECT_EQ(NetEq::Operation::kMerge, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001789}
1790
1791TEST_F(NetEqImplTest120ms, Expand) {
minyue5bd33972016-05-02 04:46:11 -07001792 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001793 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001794
1795 InsertPacket(first_timestamp());
1796 GetFirstPacket();
1797
henrik.lundin7a926812016-05-12 13:51:28 -07001798 bool muted;
1799 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001800 EXPECT_EQ(NetEq::Operation::kExpand, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001801}
1802
1803TEST_F(NetEqImplTest120ms, FastAccelerate) {
minyue5bd33972016-05-02 04:46:11 -07001804 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001805 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001806
1807 InsertPacket(first_timestamp());
1808 GetFirstPacket();
1809 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1810
Ivo Creusen53a31f72019-10-24 15:20:39 +02001811 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001812 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001813 .WillOnce(Return(NetEq::Operation::kFastAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001814
henrik.lundin7a926812016-05-12 13:51:28 -07001815 bool muted;
1816 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001817 EXPECT_EQ(NetEq::Operation::kFastAccelerate,
1818 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001819}
1820
1821TEST_F(NetEqImplTest120ms, PreemptiveExpand) {
minyue5bd33972016-05-02 04:46:11 -07001822 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001823 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001824
1825 InsertPacket(first_timestamp());
1826 GetFirstPacket();
1827
1828 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1829
Ivo Creusen53a31f72019-10-24 15:20:39 +02001830 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001831 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001832 .WillOnce(Return(NetEq::Operation::kPreemptiveExpand));
minyue5bd33972016-05-02 04:46:11 -07001833
henrik.lundin7a926812016-05-12 13:51:28 -07001834 bool muted;
1835 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001836 EXPECT_EQ(NetEq::Operation::kPreemptiveExpand,
1837 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001838}
1839
1840TEST_F(NetEqImplTest120ms, Accelerate) {
minyue5bd33972016-05-02 04:46:11 -07001841 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001842 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001843
1844 InsertPacket(first_timestamp());
1845 GetFirstPacket();
1846
1847 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1848
Ivo Creusen53a31f72019-10-24 15:20:39 +02001849 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001850 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001851 .WillOnce(Return(NetEq::Operation::kAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001852
henrik.lundin7a926812016-05-12 13:51:28 -07001853 bool muted;
1854 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001855 EXPECT_EQ(NetEq::Operation::kAccelerate, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001856}
1857
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001858} // namespace webrtc