blob: 33e3d8d2d275d34d18aeb2532e31b34387373318 [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;
128 deps.neteq_controller =
129 std::make_unique<DecisionLogic>(std::move(controller_config));
130 }
131 neteq_controller_ = deps.neteq_controller.get();
132
henrik.lundin1d9061e2016-04-26 12:19:34 -0700133 if (use_mock_payload_splitter_) {
ossua70695a2016-09-22 02:06:28 -0700134 std::unique_ptr<MockRedPayloadSplitter> mock(new MockRedPayloadSplitter);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700135 mock_payload_splitter_ = mock.get();
ossua70695a2016-09-22 02:06:28 -0700136 deps.red_payload_splitter = std::move(mock);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700137 }
ossua70695a2016-09-22 02:06:28 -0700138 red_payload_splitter_ = deps.red_payload_splitter.get();
henrik.lundin1d9061e2016-04-26 12:19:34 -0700139
140 deps.timestamp_scaler = std::unique_ptr<TimestampScaler>(
141 new TimestampScaler(*deps.decoder_database.get()));
142
143 neteq_.reset(new NetEqImpl(config_, std::move(deps)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000144 ASSERT_TRUE(neteq_ != NULL);
145 }
146
Niels Möllera0f44302018-11-30 10:45:12 +0100147 void CreateInstance() { CreateInstance(CreateBuiltinAudioDecoderFactory()); }
148
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000149 void UseNoMocks() {
150 ASSERT_TRUE(neteq_ == NULL) << "Must call UseNoMocks before CreateInstance";
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000151 use_mock_decoder_database_ = false;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200152 use_mock_neteq_controller_ = false;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000153 use_mock_dtmf_buffer_ = false;
154 use_mock_dtmf_tone_generator_ = false;
155 use_mock_packet_buffer_ = false;
156 use_mock_payload_splitter_ = false;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000157 }
158
159 virtual ~NetEqImplTest() {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000160 if (use_mock_decoder_database_) {
161 EXPECT_CALL(*mock_decoder_database_, Die()).Times(1);
162 }
Ivo Creusen53a31f72019-10-24 15:20:39 +0200163 if (use_mock_neteq_controller_) {
164 EXPECT_CALL(*mock_neteq_controller_, Die()).Times(1);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000165 }
166 if (use_mock_dtmf_buffer_) {
167 EXPECT_CALL(*mock_dtmf_buffer_, Die()).Times(1);
168 }
169 if (use_mock_dtmf_tone_generator_) {
170 EXPECT_CALL(*mock_dtmf_tone_generator_, Die()).Times(1);
171 }
172 if (use_mock_packet_buffer_) {
173 EXPECT_CALL(*mock_packet_buffer_, Die()).Times(1);
174 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000175 }
176
Niels Möller05543682019-01-10 16:55:06 +0100177 void TestDtmfPacket(int sample_rate_hz) {
solenberg2779bab2016-11-17 04:45:19 -0800178 const size_t kPayloadLength = 4;
179 const uint8_t kPayloadType = 110;
solenberg2779bab2016-11-17 04:45:19 -0800180 const int kSampleRateHz = 16000;
181 config_.sample_rate_hz = kSampleRateHz;
182 UseNoMocks();
183 CreateInstance();
184 // Event: 2, E bit, Volume: 17, Length: 4336.
Jonas Olssona4d87372019-07-05 19:08:33 +0200185 uint8_t payload[kPayloadLength] = {0x02, 0x80 + 0x11, 0x10, 0xF0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700186 RTPHeader rtp_header;
187 rtp_header.payloadType = kPayloadType;
188 rtp_header.sequenceNumber = 0x1234;
189 rtp_header.timestamp = 0x12345678;
190 rtp_header.ssrc = 0x87654321;
solenberg2779bab2016-11-17 04:45:19 -0800191
Niels Möller05543682019-01-10 16:55:06 +0100192 EXPECT_TRUE(neteq_->RegisterPayloadType(
193 kPayloadType, SdpAudioFormat("telephone-event", sample_rate_hz, 1)));
solenberg2779bab2016-11-17 04:45:19 -0800194
195 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200196 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
solenberg2779bab2016-11-17 04:45:19 -0800197
198 // Pull audio once.
199 const size_t kMaxOutputSize =
200 static_cast<size_t>(10 * kSampleRateHz / 1000);
201 AudioFrame output;
202 bool muted;
203 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
204 ASSERT_FALSE(muted);
205 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
206 EXPECT_EQ(1u, output.num_channels_);
207 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
208
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000209 // DTMF packets are immediately consumed by |InsertPacket()| and won't be
210 // returned by |GetAudio()|.
211 EXPECT_THAT(output.packet_infos_, IsEmpty());
212
solenberg2779bab2016-11-17 04:45:19 -0800213 // Verify first 64 samples of actual output.
Jonas Olssona4d87372019-07-05 19:08:33 +0200214 const std::vector<int16_t> kOutput(
215 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
216 -1578, -2816, -3460, -3403, -2709, -1594, -363, 671, 1269, 1328,
217 908, 202, -513, -964, -955, -431, 504, 1617, 2602, 3164,
218 3101, 2364, 1073, -511, -2047, -3198, -3721, -3525, -2688, -1440,
219 -99, 1015, 1663, 1744, 1319, 588, -171, -680, -747, -315,
220 515, 1512, 2378, 2828, 2674, 1877, 568, -986, -2446, -3482,
221 -3864, -3516, -2534, -1163});
solenberg2779bab2016-11-17 04:45:19 -0800222 ASSERT_GE(kMaxOutputSize, kOutput.size());
yujo36b1a5f2017-06-12 12:45:32 -0700223 EXPECT_TRUE(std::equal(kOutput.begin(), kOutput.end(), output.data()));
solenberg2779bab2016-11-17 04:45:19 -0800224 }
225
henrik.lundin1d9061e2016-04-26 12:19:34 -0700226 std::unique_ptr<NetEqImpl> neteq_;
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000227 NetEq::Config config_;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000228 SimulatedClock clock_;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700229 TickTimer* tick_timer_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700230 MockDecoderDatabase* mock_decoder_database_ = nullptr;
231 DecoderDatabase* decoder_database_ = nullptr;
232 bool use_mock_decoder_database_ = true;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200233 MockNetEqController* mock_neteq_controller_ = nullptr;
234 NetEqController* neteq_controller_ = nullptr;
235 bool use_mock_neteq_controller_ = true;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700236 MockDtmfBuffer* mock_dtmf_buffer_ = nullptr;
237 DtmfBuffer* dtmf_buffer_ = nullptr;
238 bool use_mock_dtmf_buffer_ = true;
239 MockDtmfToneGenerator* mock_dtmf_tone_generator_ = nullptr;
240 DtmfToneGenerator* dtmf_tone_generator_ = nullptr;
241 bool use_mock_dtmf_tone_generator_ = true;
242 MockPacketBuffer* mock_packet_buffer_ = nullptr;
243 PacketBuffer* packet_buffer_ = nullptr;
244 bool use_mock_packet_buffer_ = true;
ossua70695a2016-09-22 02:06:28 -0700245 MockRedPayloadSplitter* mock_payload_splitter_ = nullptr;
246 RedPayloadSplitter* red_payload_splitter_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700247 bool use_mock_payload_splitter_ = true;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000248};
249
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000250// This tests the interface class NetEq.
251// TODO(hlundin): Move to separate file?
252TEST(NetEq, CreateAndDestroy) {
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000253 NetEq::Config config;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000254 SimulatedClock clock(0);
Ivo Creusen39cf3c72019-11-28 14:07:14 +0100255 auto decoder_factory = CreateBuiltinAudioDecoderFactory();
256 std::unique_ptr<NetEq> neteq =
257 DefaultNetEqFactory().CreateNetEq(config, decoder_factory, &clock);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000258}
259
kwiberg5adaf732016-10-04 09:33:27 -0700260TEST_F(NetEqImplTest, RegisterPayloadType) {
261 CreateInstance();
262 constexpr int rtp_payload_type = 0;
263 const SdpAudioFormat format("pcmu", 8000, 1);
264 EXPECT_CALL(*mock_decoder_database_,
265 RegisterPayload(rtp_payload_type, format));
266 neteq_->RegisterPayloadType(rtp_payload_type, format);
267}
268
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000269TEST_F(NetEqImplTest, RemovePayloadType) {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000270 CreateInstance();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000271 uint8_t rtp_payload_type = 0;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000272 EXPECT_CALL(*mock_decoder_database_, Remove(rtp_payload_type))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000273 .WillOnce(Return(DecoderDatabase::kDecoderNotFound));
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200274 // Check that kOK is returned when database returns kDecoderNotFound, because
275 // removing a payload type that was never registered is not an error.
276 EXPECT_EQ(NetEq::kOK, neteq_->RemovePayloadType(rtp_payload_type));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000277}
278
kwiberg6b19b562016-09-20 04:02:25 -0700279TEST_F(NetEqImplTest, RemoveAllPayloadTypes) {
280 CreateInstance();
281 EXPECT_CALL(*mock_decoder_database_, RemoveAll()).WillOnce(Return());
282 neteq_->RemoveAllPayloadTypes();
283}
284
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000285TEST_F(NetEqImplTest, InsertPacket) {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000286 CreateInstance();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000287 const size_t kPayloadLength = 100;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000288 const uint8_t kPayloadType = 0;
289 const uint16_t kFirstSequenceNumber = 0x1234;
290 const uint32_t kFirstTimestamp = 0x12345678;
291 const uint32_t kSsrc = 0x87654321;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000292 uint8_t payload[kPayloadLength] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700293 RTPHeader rtp_header;
294 rtp_header.payloadType = kPayloadType;
295 rtp_header.sequenceNumber = kFirstSequenceNumber;
296 rtp_header.timestamp = kFirstTimestamp;
297 rtp_header.ssrc = kSsrc;
ossu7a377612016-10-18 04:06:13 -0700298 Packet fake_packet;
299 fake_packet.payload_type = kPayloadType;
300 fake_packet.sequence_number = kFirstSequenceNumber;
301 fake_packet.timestamp = kFirstTimestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000302
kwibergc0f2dcf2016-05-31 06:28:03 -0700303 rtc::scoped_refptr<MockAudioDecoderFactory> mock_decoder_factory(
304 new rtc::RefCountedObject<MockAudioDecoderFactory>);
Karl Wibergd6fbf2a2018-02-27 13:37:31 +0100305 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _, _))
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800306 .WillOnce(Invoke([&](const SdpAudioFormat& format,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200307 absl::optional<AudioCodecPairId> codec_pair_id,
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800308 std::unique_ptr<AudioDecoder>* dec) {
kwibergc0f2dcf2016-05-31 06:28:03 -0700309 EXPECT_EQ("pcmu", format.name);
310
311 std::unique_ptr<MockAudioDecoder> mock_decoder(new MockAudioDecoder);
312 EXPECT_CALL(*mock_decoder, Channels()).WillRepeatedly(Return(1));
313 EXPECT_CALL(*mock_decoder, SampleRateHz()).WillRepeatedly(Return(8000));
kwibergc0f2dcf2016-05-31 06:28:03 -0700314 EXPECT_CALL(*mock_decoder, Die()).Times(1); // Called when deleted.
315
316 *dec = std::move(mock_decoder);
317 }));
Niels Möller72899062019-01-11 09:36:13 +0100318 DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
319 absl::nullopt, mock_decoder_factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000320
321 // Expectations for decoder database.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000322 EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000323 .WillRepeatedly(Return(&info));
324
325 // Expectations for packet buffer.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000326 EXPECT_CALL(*mock_packet_buffer_, Empty())
327 .WillOnce(Return(false)); // Called once after first packet is inserted.
Jonas Olssona4d87372019-07-05 19:08:33 +0200328 EXPECT_CALL(*mock_packet_buffer_, Flush()).Times(1);
minyue-webrtc12d30842017-07-19 11:44:06 +0200329 EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _, _))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000330 .Times(2)
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100331 .WillRepeatedly(DoAll(SetArgPointee<2>(kPayloadType),
332 WithArg<0>(Invoke(DeletePacketsAndReturnOk))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000333 // SetArgPointee<2>(kPayloadType) means that the third argument (zero-based
334 // index) is a pointer, and the variable pointed to is set to kPayloadType.
335 // Also invoke the function DeletePacketsAndReturnOk to properly delete all
336 // packets in the list (to avoid memory leaks in the test).
ossu7a377612016-10-18 04:06:13 -0700337 EXPECT_CALL(*mock_packet_buffer_, PeekNextPacket())
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000338 .Times(1)
ossu7a377612016-10-18 04:06:13 -0700339 .WillOnce(Return(&fake_packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000340
341 // Expectations for DTMF buffer.
Jonas Olssona4d87372019-07-05 19:08:33 +0200342 EXPECT_CALL(*mock_dtmf_buffer_, Flush()).Times(1);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000343
344 // Expectations for delay manager.
345 {
346 // All expectations within this block must be called in this specific order.
347 InSequence sequence; // Dummy variable.
348 // Expectations when the first packet is inserted.
Ivo Creusen53a31f72019-10-24 15:20:39 +0200349 EXPECT_CALL(*mock_neteq_controller_,
350 PacketArrived(/*last_cng_or_dtmf*/ false,
351 /*packet_length_samples*/ _,
352 /*should_update_stats*/ _,
353 /*main_sequence_number*/ kFirstSequenceNumber,
354 /*main_timestamp*/ kFirstTimestamp,
355 /*fs_hz*/ 8000));
356 EXPECT_CALL(*mock_neteq_controller_,
357 PacketArrived(/*last_cng_or_dtmf*/ false,
358 /*packet_length_samples*/ _,
359 /*should_update_stats*/ _,
360 /*main_sequence_number*/ kFirstSequenceNumber + 1,
361 /*main_timestamp*/ kFirstTimestamp + 160,
362 /*fs_hz*/ 8000));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000363 }
364
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000365 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200366 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000367
368 // Insert second packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700369 rtp_header.timestamp += 160;
370 rtp_header.sequenceNumber += 1;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200371 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000372}
373
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000374TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
375 UseNoMocks();
376 CreateInstance();
377
378 const int kPayloadLengthSamples = 80;
379 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
Jonas Olssona4d87372019-07-05 19:08:33 +0200380 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000381 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700382 RTPHeader rtp_header;
383 rtp_header.payloadType = kPayloadType;
384 rtp_header.sequenceNumber = 0x1234;
385 rtp_header.timestamp = 0x12345678;
386 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000387
Niels Möller05543682019-01-10 16:55:06 +0100388 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
389 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000390
391 // Insert packets. The buffer should not flush.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700392 for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) {
Karl Wiberg45eb1352019-10-10 14:23:00 +0200393 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700394 rtp_header.timestamp += kPayloadLengthSamples;
395 rtp_header.sequenceNumber += 1;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000396 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
397 }
398
399 // Insert one more packet and make sure the buffer got flushed. That is, it
400 // should only hold one single packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200401 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700402 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700403 const Packet* test_packet = packet_buffer_->PeekNextPacket();
henrik.lundin246ef3e2017-04-24 09:14:32 -0700404 EXPECT_EQ(rtp_header.timestamp, test_packet->timestamp);
405 EXPECT_EQ(rtp_header.sequenceNumber, test_packet->sequence_number);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000406}
407
solenberg2779bab2016-11-17 04:45:19 -0800408TEST_F(NetEqImplTest, TestDtmfPacketAVT) {
Niels Möller05543682019-01-10 16:55:06 +0100409 TestDtmfPacket(8000);
solenberg2779bab2016-11-17 04:45:19 -0800410}
solenberg99df6c02016-10-11 04:35:34 -0700411
solenberg2779bab2016-11-17 04:45:19 -0800412TEST_F(NetEqImplTest, TestDtmfPacketAVT16kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100413 TestDtmfPacket(16000);
solenberg2779bab2016-11-17 04:45:19 -0800414}
solenberg99df6c02016-10-11 04:35:34 -0700415
solenberg2779bab2016-11-17 04:45:19 -0800416TEST_F(NetEqImplTest, TestDtmfPacketAVT32kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100417 TestDtmfPacket(32000);
solenberg2779bab2016-11-17 04:45:19 -0800418}
solenberg99df6c02016-10-11 04:35:34 -0700419
solenberg2779bab2016-11-17 04:45:19 -0800420TEST_F(NetEqImplTest, TestDtmfPacketAVT48kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100421 TestDtmfPacket(48000);
solenberg99df6c02016-10-11 04:35:34 -0700422}
423
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000424// This test verifies that timestamps propagate from the incoming packets
425// through to the sync buffer and to the playout timestamp.
426TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000427 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000428 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700429 const size_t kPayloadLengthSamples =
430 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000431 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
432 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700433 RTPHeader rtp_header;
434 rtp_header.payloadType = kPayloadType;
435 rtp_header.sequenceNumber = 0x1234;
436 rtp_header.timestamp = 0x12345678;
437 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000438 rtp_header.numCSRCs = 3;
439 rtp_header.arrOfCSRCs[0] = 43;
440 rtp_header.arrOfCSRCs[1] = 65;
441 rtp_header.arrOfCSRCs[2] = 17;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000442
443 // This is a dummy decoder that produces as many output samples as the input
444 // has bytes. The output is an increasing series, starting at 1 for the first
445 // sample, and then increasing by 1 for each sample.
446 class CountingSamplesDecoder : public AudioDecoder {
447 public:
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000448 CountingSamplesDecoder() : next_value_(1) {}
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000449
450 // Produce as many samples as input bytes (|encoded_len|).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100451 int DecodeInternal(const uint8_t* encoded,
452 size_t encoded_len,
453 int /* sample_rate_hz */,
454 int16_t* decoded,
455 SpeechType* speech_type) override {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000456 for (size_t i = 0; i < encoded_len; ++i) {
457 decoded[i] = next_value_++;
458 }
459 *speech_type = kSpeech;
Mirko Bonadei737e0732017-10-19 09:00:17 +0200460 return rtc::checked_cast<int>(encoded_len);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000461 }
462
Karl Wiberg43766482015-08-27 15:22:11 +0200463 void Reset() override { next_value_ = 1; }
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000464
kwiberg347d3512016-06-16 01:59:09 -0700465 int SampleRateHz() const override { return kSampleRateHz; }
466
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000467 size_t Channels() const override { return 1; }
468
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000469 uint16_t next_value() const { return next_value_; }
470
471 private:
472 int16_t next_value_;
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000473 } decoder_;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000474
Niels Möllerb7180c02018-12-06 13:07:11 +0100475 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory =
476 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&decoder_);
477
478 UseNoMocks();
479 CreateInstance(decoder_factory);
480
481 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
Niels Möllera1eb9c72018-12-07 15:24:42 +0100482 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000483
484 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000485 clock_.AdvanceTimeMilliseconds(123456);
486 int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200487 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000488
489 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700490 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800491 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700492 bool muted;
493 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
494 ASSERT_FALSE(muted);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800495 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
496 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800497 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000498
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000499 // Verify |output.packet_infos_|.
500 ASSERT_THAT(output.packet_infos_, SizeIs(1));
501 {
502 const auto& packet_info = output.packet_infos_[0];
503 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
504 EXPECT_THAT(packet_info.csrcs(), ElementsAre(43, 65, 17));
505 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
506 EXPECT_FALSE(packet_info.audio_level().has_value());
507 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
508 }
509
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000510 // Start with a simple check that the fake decoder is behaving as expected.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700511 EXPECT_EQ(kPayloadLengthSamples,
512 static_cast<size_t>(decoder_.next_value() - 1));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000513
514 // The value of the last of the output samples is the same as the number of
515 // samples played from the decoded packet. Thus, this number + the RTP
516 // timestamp should match the playout timestamp.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200517 // Wrap the expected value in an absl::optional to compare them as such.
henrik.lundin9a410dd2016-04-06 01:39:22 -0700518 EXPECT_EQ(
Danil Chapovalovb6021232018-06-19 13:26:36 +0200519 absl::optional<uint32_t>(rtp_header.timestamp +
520 output.data()[output.samples_per_channel_ - 1]),
henrik.lundin9a410dd2016-04-06 01:39:22 -0700521 neteq_->GetPlayoutTimestamp());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000522
523 // Check the timestamp for the last value in the sync buffer. This should
524 // be one full frame length ahead of the RTP timestamp.
525 const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
526 ASSERT_TRUE(sync_buffer != NULL);
henrik.lundin246ef3e2017-04-24 09:14:32 -0700527 EXPECT_EQ(rtp_header.timestamp + kPayloadLengthSamples,
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000528 sync_buffer->end_timestamp());
529
530 // Check that the number of samples still to play from the sync buffer add
531 // up with what was already played out.
henrik.lundin6d8e0112016-03-04 10:34:21 -0800532 EXPECT_EQ(
yujo36b1a5f2017-06-12 12:45:32 -0700533 kPayloadLengthSamples - output.data()[output.samples_per_channel_ - 1],
henrik.lundin6d8e0112016-03-04 10:34:21 -0800534 sync_buffer->FutureLength());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000535}
536
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000537TEST_F(NetEqImplTest, ReorderedPacket) {
538 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +0100539 // Create a mock decoder object.
540 MockAudioDecoder mock_decoder;
541
542 CreateInstance(
543 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000544
545 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000546 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700547 const size_t kPayloadLengthSamples =
548 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000549 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
550 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700551 RTPHeader rtp_header;
552 rtp_header.payloadType = kPayloadType;
553 rtp_header.sequenceNumber = 0x1234;
554 rtp_header.timestamp = 0x12345678;
555 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000556 rtp_header.extension.hasAudioLevel = true;
557 rtp_header.extension.audioLevel = 42;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000558
Karl Wiberg43766482015-08-27 15:22:11 +0200559 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700560 EXPECT_CALL(mock_decoder, SampleRateHz())
561 .WillRepeatedly(Return(kSampleRateHz));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000562 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin034154b2016-04-27 06:11:50 -0700563 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeiea7a3f82017-10-19 11:40:55 +0200564 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000565 int16_t dummy_output[kPayloadLengthSamples] = {0};
566 // The below expectation will make the mock decoder write
567 // |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100568 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
569 kSampleRateHz, _, _))
570 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000571 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100572 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200573 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
Niels Möllera1eb9c72018-12-07 15:24:42 +0100574 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
575 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000576
577 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000578 clock_.AdvanceTimeMilliseconds(123456);
579 int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200580 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000581
582 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700583 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800584 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700585 bool muted;
586 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800587 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
588 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800589 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000590
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000591 // Verify |output.packet_infos_|.
592 ASSERT_THAT(output.packet_infos_, SizeIs(1));
593 {
594 const auto& packet_info = output.packet_infos_[0];
595 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
596 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
597 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
598 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
599 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
600 }
601
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000602 // Insert two more packets. The first one is out of order, and is already too
603 // old, the second one is the expected next packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700604 rtp_header.sequenceNumber -= 1;
605 rtp_header.timestamp -= kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000606 rtp_header.extension.audioLevel = 1;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000607 payload[0] = 1;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000608 clock_.AdvanceTimeMilliseconds(1000);
Karl Wiberg45eb1352019-10-10 14:23:00 +0200609 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700610 rtp_header.sequenceNumber += 2;
611 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000612 rtp_header.extension.audioLevel = 2;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000613 payload[0] = 2;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000614 clock_.AdvanceTimeMilliseconds(2000);
615 expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200616 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000617
618 // Expect only the second packet to be decoded (the one with "2" as the first
619 // payload byte).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100620 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
621 kSampleRateHz, _, _))
622 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000623 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100624 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200625 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000626
627 // Pull audio once.
henrik.lundin7a926812016-05-12 13:51:28 -0700628 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800629 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
630 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800631 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000632
633 // Now check the packet buffer, and make sure it is empty, since the
634 // out-of-order packet should have been discarded.
635 EXPECT_TRUE(packet_buffer_->Empty());
636
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000637 // Verify |output.packet_infos_|. Expect to only see the second packet.
638 ASSERT_THAT(output.packet_infos_, SizeIs(1));
639 {
640 const auto& packet_info = output.packet_infos_[0];
641 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
642 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
643 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
644 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
645 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
646 }
647
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000648 EXPECT_CALL(mock_decoder, Die());
649}
650
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000651// This test verifies that NetEq can handle the situation where the first
652// incoming packet is rejected.
henrik.lundin@webrtc.org6ff3ac12014-11-20 14:14:49 +0000653TEST_F(NetEqImplTest, FirstPacketUnknown) {
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000654 UseNoMocks();
655 CreateInstance();
656
657 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000658 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700659 const size_t kPayloadLengthSamples =
660 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundinc9ec8752016-10-13 02:43:34 -0700661 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000662 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700663 RTPHeader rtp_header;
664 rtp_header.payloadType = kPayloadType;
665 rtp_header.sequenceNumber = 0x1234;
666 rtp_header.timestamp = 0x12345678;
667 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000668
669 // Insert one packet. Note that we have not registered any payload type, so
670 // this packet will be rejected.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200671 EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000672
673 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700674 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800675 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700676 bool muted;
677 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800678 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
679 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
680 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800681 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000682 EXPECT_THAT(output.packet_infos_, IsEmpty());
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000683
684 // Register the payload type.
Niels Möller05543682019-01-10 16:55:06 +0100685 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
686 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000687
688 // Insert 10 packets.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700689 for (size_t i = 0; i < 10; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -0700690 rtp_header.sequenceNumber++;
691 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200692 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000693 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
694 }
695
696 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700697 for (size_t i = 0; i < 3; ++i) {
henrik.lundin7a926812016-05-12 13:51:28 -0700698 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800699 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
700 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
701 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800702 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000703 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000704 EXPECT_THAT(output.packet_infos_, SizeIs(1));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000705 }
706}
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000707
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200708// This test verifies that audio interruption is not logged for the initial
709// PLC period before the first packet is deocoded.
710// TODO(henrik.lundin) Maybe move this test to neteq_network_stats_unittest.cc.
Henrik Lundinfe047752019-11-19 12:58:11 +0100711// Make the test parametrized, so that we can test with different initial
712// sample rates in NetEq.
713class NetEqImplTestSampleRateParameter
714 : public NetEqImplTest,
715 public testing::WithParamInterface<int> {
716 protected:
717 NetEqImplTestSampleRateParameter()
718 : NetEqImplTest(), initial_sample_rate_hz_(GetParam()) {
719 config_.sample_rate_hz = initial_sample_rate_hz_;
720 }
721
722 const int initial_sample_rate_hz_;
723};
724
725// This test does the following:
726// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
727// sample rate of 16000.
728// 1. Start calling GetAudio before inserting any encoded audio. The audio
729// produced will be PLC.
730// 2. Insert a number of encoded audio packets.
731// 3. Keep calling GetAudio and verify that no audio interruption was logged.
732// Call GetAudio until NetEq runs out of data again; PLC starts.
733// 4. Insert one more packet.
734// 5. Call GetAudio until that packet is decoded and the PLC ends.
735
736TEST_P(NetEqImplTestSampleRateParameter,
737 NoAudioInterruptionLoggedBeforeFirstDecode) {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200738 UseNoMocks();
739 CreateInstance();
740
741 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundinfe047752019-11-19 12:58:11 +0100742 const int kPayloadSampleRateHz = 16000;
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200743 const size_t kPayloadLengthSamples =
Henrik Lundinfe047752019-11-19 12:58:11 +0100744 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200745 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
746 uint8_t payload[kPayloadLengthBytes] = {0};
747 RTPHeader rtp_header;
748 rtp_header.payloadType = kPayloadType;
749 rtp_header.sequenceNumber = 0x1234;
750 rtp_header.timestamp = 0x12345678;
751 rtp_header.ssrc = 0x87654321;
752
753 // Register the payload type.
Henrik Lundinfe047752019-11-19 12:58:11 +0100754 EXPECT_TRUE(neteq_->RegisterPayloadType(
755 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200756
757 // Pull audio several times. No packets have been inserted yet.
Henrik Lundinfe047752019-11-19 12:58:11 +0100758 const size_t initial_output_size =
759 static_cast<size_t>(10 * initial_sample_rate_hz_ / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200760 AudioFrame output;
761 bool muted;
762 for (int i = 0; i < 100; ++i) {
763 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100764 EXPECT_EQ(initial_output_size, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200765 EXPECT_EQ(1u, output.num_channels_);
766 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000767 EXPECT_THAT(output.packet_infos_, IsEmpty());
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200768 }
769
Henrik Lundinfe047752019-11-19 12:58:11 +0100770 // Lambda for inserting packets.
771 auto insert_packet = [&]() {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200772 rtp_header.sequenceNumber++;
773 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200774 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundinfe047752019-11-19 12:58:11 +0100775 };
776 // Insert 10 packets.
777 for (size_t i = 0; i < 10; ++i) {
778 insert_packet();
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200779 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
780 }
781
782 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Henrik Lundinfe047752019-11-19 12:58:11 +0100783 constexpr size_t kOutputSize =
784 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200785 for (size_t i = 0; i < 3; ++i) {
786 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100787 EXPECT_EQ(kOutputSize, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200788 EXPECT_EQ(1u, output.num_channels_);
789 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
790 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000791 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200792 }
793
Henrik Lundinfe047752019-11-19 12:58:11 +0100794 // Verify that no interruption was logged.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200795 auto lifetime_stats = neteq_->GetLifetimeStatistics();
Henrik Lundin44125fa2019-04-29 17:00:46 +0200796 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundinfe047752019-11-19 12:58:11 +0100797
798 // Keep pulling audio data until a new PLC period is started.
799 size_t count_loops = 0;
800 while (output.speech_type_ == AudioFrame::kNormalSpeech) {
801 // Make sure we don't hang the test if we never go to PLC.
802 ASSERT_LT(++count_loops, 100u);
803 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
804 }
805
806 // Insert one more packet.
807 insert_packet();
808
809 // Pull audio until the newly inserted packet is decoded and the PLC ends.
810 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
811 // Make sure we don't hang the test if we never go to PLC.
812 ASSERT_LT(++count_loops, 100u);
813 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
814 }
815
816 // Verify that no interruption was logged.
817 lifetime_stats = neteq_->GetLifetimeStatistics();
818 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200819}
820
Henrik Lundinfe047752019-11-19 12:58:11 +0100821// This test does the following:
822// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
823// sample rate of 16000.
824// 1. Insert a number of encoded audio packets.
825// 2. Call GetAudio and verify that decoded audio is produced.
826// 3. Keep calling GetAudio until NetEq runs out of data; PLC starts.
827// 4. Keep calling GetAudio until PLC has been produced for at least 150 ms.
828// 5. Insert one more packet.
829// 6. Call GetAudio until that packet is decoded and the PLC ends.
830// 7. Verify that an interruption was logged.
831
832TEST_P(NetEqImplTestSampleRateParameter, AudioInterruptionLogged) {
833 UseNoMocks();
834 CreateInstance();
835
836 const uint8_t kPayloadType = 17; // Just an arbitrary number.
837 const int kPayloadSampleRateHz = 16000;
838 const size_t kPayloadLengthSamples =
839 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
840 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
841 uint8_t payload[kPayloadLengthBytes] = {0};
842 RTPHeader rtp_header;
843 rtp_header.payloadType = kPayloadType;
844 rtp_header.sequenceNumber = 0x1234;
845 rtp_header.timestamp = 0x12345678;
846 rtp_header.ssrc = 0x87654321;
847
848 // Register the payload type.
849 EXPECT_TRUE(neteq_->RegisterPayloadType(
850 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
851
852 // Lambda for inserting packets.
853 auto insert_packet = [&]() {
854 rtp_header.sequenceNumber++;
855 rtp_header.timestamp += kPayloadLengthSamples;
856 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
857 };
858 // Insert 10 packets.
859 for (size_t i = 0; i < 10; ++i) {
860 insert_packet();
861 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
862 }
863
864 AudioFrame output;
865 bool muted;
866 // Keep pulling audio data until a new PLC period is started.
867 size_t count_loops = 0;
868 do {
869 // Make sure we don't hang the test if we never go to PLC.
870 ASSERT_LT(++count_loops, 100u);
871 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
872 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
873
874 // Pull audio 15 times, which produces 150 ms of output audio. This should
875 // all be produced as PLC. The total length of the gap will then be 150 ms
876 // plus an initial fraction of 10 ms at the start and the end of the PLC
877 // period. In total, less than 170 ms.
878 for (size_t i = 0; i < 15; ++i) {
879 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
880 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
881 }
882
883 // Insert one more packet.
884 insert_packet();
885
886 // Pull audio until the newly inserted packet is decoded and the PLC ends.
887 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
888 // Make sure we don't hang the test if we never go to PLC.
889 ASSERT_LT(++count_loops, 100u);
890 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
891 }
892
893 // Verify that the interruption was logged.
894 auto lifetime_stats = neteq_->GetLifetimeStatistics();
895 EXPECT_EQ(1, lifetime_stats.interruption_count);
896 EXPECT_GT(lifetime_stats.total_interruption_duration_ms, 150);
897 EXPECT_LT(lifetime_stats.total_interruption_duration_ms, 170);
898}
899
900INSTANTIATE_TEST_SUITE_P(SampleRates,
901 NetEqImplTestSampleRateParameter,
902 testing::Values(8000, 16000, 32000, 48000));
903
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000904// This test verifies that NetEq can handle comfort noise and enters/quits codec
905// internal CNG mode properly.
906TEST_F(NetEqImplTest, CodecInternalCng) {
907 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +0100908 // Create a mock decoder object.
909 MockAudioDecoder mock_decoder;
910 CreateInstance(
911 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000912
913 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000914 const int kSampleRateKhz = 48;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700915 const size_t kPayloadLengthSamples =
916 static_cast<size_t>(20 * kSampleRateKhz); // 20 ms.
917 const size_t kPayloadLengthBytes = 10;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000918 uint8_t payload[kPayloadLengthBytes] = {0};
919 int16_t dummy_output[kPayloadLengthSamples] = {0};
920
henrik.lundin246ef3e2017-04-24 09:14:32 -0700921 RTPHeader rtp_header;
922 rtp_header.payloadType = kPayloadType;
923 rtp_header.sequenceNumber = 0x1234;
924 rtp_header.timestamp = 0x12345678;
925 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000926
Karl Wiberg43766482015-08-27 15:22:11 +0200927 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700928 EXPECT_CALL(mock_decoder, SampleRateHz())
929 .WillRepeatedly(Return(kSampleRateKhz * 1000));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000930 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin0d96ab72016-04-06 12:28:26 -0700931 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200932 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin0d96ab72016-04-06 12:28:26 -0700933 // Packed duration when asking the decoder for more CNG data (without a new
934 // packet).
935 EXPECT_CALL(mock_decoder, PacketDuration(nullptr, 0))
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200936 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000937
938 // Pointee(x) verifies that first byte of the payload equals x, this makes it
939 // possible to verify that the correct payload is fed to Decode().
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100940 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
941 kSampleRateKhz * 1000, _, _))
942 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000943 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100944 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200945 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000946
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100947 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes,
948 kSampleRateKhz * 1000, _, _))
949 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000950 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100951 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200952 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000953
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100954 EXPECT_CALL(mock_decoder,
955 DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
956 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000957 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100958 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200959 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000960
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100961 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
962 kSampleRateKhz * 1000, _, _))
963 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000964 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100965 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200966 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000967
Niels Möller50b66d52018-12-11 14:43:21 +0100968 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
969 SdpAudioFormat("opus", 48000, 2)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000970
971 // Insert one packet (decoder will return speech).
Karl Wiberg45eb1352019-10-10 14:23:00 +0200972 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000973
974 // Insert second packet (decoder will return CNG).
975 payload[0] = 1;
henrik.lundin246ef3e2017-04-24 09:14:32 -0700976 rtp_header.sequenceNumber++;
977 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200978 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000979
Peter Kastingdce40cf2015-08-24 14:52:23 -0700980 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800981 AudioFrame output;
henrik.lundin55480f52016-03-08 02:37:57 -0800982 AudioFrame::SpeechType expected_type[8] = {
Jonas Olssona4d87372019-07-05 19:08:33 +0200983 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech, AudioFrame::kCNG,
984 AudioFrame::kCNG, AudioFrame::kCNG, AudioFrame::kCNG,
985 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000986 int expected_timestamp_increment[8] = {
987 -1, // will not be used.
988 10 * kSampleRateKhz,
Jonas Olssona4d87372019-07-05 19:08:33 +0200989 -1,
990 -1, // timestamp will be empty during CNG mode; indicated by -1 here.
991 -1,
992 -1,
993 50 * kSampleRateKhz,
994 10 * kSampleRateKhz};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000995
henrik.lundin7a926812016-05-12 13:51:28 -0700996 bool muted;
997 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200998 absl::optional<uint32_t> last_timestamp = neteq_->GetPlayoutTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700999 ASSERT_TRUE(last_timestamp);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001000
henrik.lundin0d96ab72016-04-06 12:28:26 -07001001 // Lambda for verifying the timestamps.
1002 auto verify_timestamp = [&last_timestamp, &expected_timestamp_increment](
Danil Chapovalovb6021232018-06-19 13:26:36 +02001003 absl::optional<uint32_t> ts, size_t i) {
henrik.lundin0d96ab72016-04-06 12:28:26 -07001004 if (expected_timestamp_increment[i] == -1) {
1005 // Expect to get an empty timestamp value during CNG and PLC.
1006 EXPECT_FALSE(ts) << "i = " << i;
1007 } else {
1008 ASSERT_TRUE(ts) << "i = " << i;
1009 EXPECT_EQ(*ts, *last_timestamp + expected_timestamp_increment[i])
1010 << "i = " << i;
1011 last_timestamp = ts;
1012 }
1013 };
1014
Peter Kastingdce40cf2015-08-24 14:52:23 -07001015 for (size_t i = 1; i < 6; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001016 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1017 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001018 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001019 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001020 SCOPED_TRACE("");
1021 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001022 }
1023
1024 // Insert third packet, which leaves a gap from last packet.
1025 payload[0] = 2;
henrik.lundin246ef3e2017-04-24 09:14:32 -07001026 rtp_header.sequenceNumber += 2;
1027 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001028 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001029
Peter Kastingdce40cf2015-08-24 14:52:23 -07001030 for (size_t i = 6; i < 8; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001031 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1032 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001033 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001034 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001035 SCOPED_TRACE("");
1036 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001037 }
1038
1039 // Now check the packet buffer, and make sure it is empty.
1040 EXPECT_TRUE(packet_buffer_->Empty());
1041
1042 EXPECT_CALL(mock_decoder, Die());
1043}
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001044
1045TEST_F(NetEqImplTest, UnsupportedDecoder) {
1046 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001047 ::testing::NiceMock<MockAudioDecoder> decoder;
1048
1049 CreateInstance(
1050 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&decoder));
minyue5bd33972016-05-02 04:46:11 -07001051 static const size_t kNetEqMaxFrameSize = 5760; // 120 ms @ 48 kHz.
Peter Kasting69558702016-01-12 16:26:35 -08001052 static const size_t kChannels = 2;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001053
1054 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001055 const int kSampleRateHz = 8000;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001056
Peter Kastingdce40cf2015-08-24 14:52:23 -07001057 const size_t kPayloadLengthSamples =
1058 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001059 const size_t kPayloadLengthBytes = 1;
minyue5bd33972016-05-02 04:46:11 -07001060 uint8_t payload[kPayloadLengthBytes] = {0};
Minyue323b1322015-05-25 13:49:37 +02001061 int16_t dummy_output[kPayloadLengthSamples * kChannels] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001062 RTPHeader rtp_header;
1063 rtp_header.payloadType = kPayloadType;
1064 rtp_header.sequenceNumber = 0x1234;
1065 rtp_header.timestamp = 0x12345678;
1066 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001067
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001068 const uint8_t kFirstPayloadValue = 1;
1069 const uint8_t kSecondPayloadValue = 2;
1070
ossu61a208b2016-09-20 01:38:00 -07001071 EXPECT_CALL(decoder,
1072 PacketDuration(Pointee(kFirstPayloadValue), kPayloadLengthBytes))
1073 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001074 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize + 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001075
ossu61a208b2016-09-20 01:38:00 -07001076 EXPECT_CALL(decoder, DecodeInternal(Pointee(kFirstPayloadValue), _, _, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001077 .Times(0);
1078
ossu61a208b2016-09-20 01:38:00 -07001079 EXPECT_CALL(decoder, DecodeInternal(Pointee(kSecondPayloadValue),
1080 kPayloadLengthBytes, kSampleRateHz, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001081 .Times(1)
ossu61a208b2016-09-20 01:38:00 -07001082 .WillOnce(DoAll(
1083 SetArrayArgument<3>(dummy_output,
1084 dummy_output + kPayloadLengthSamples * kChannels),
1085 SetArgPointee<4>(AudioDecoder::kSpeech),
1086 Return(static_cast<int>(kPayloadLengthSamples * kChannels))));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001087
ossu61a208b2016-09-20 01:38:00 -07001088 EXPECT_CALL(decoder,
1089 PacketDuration(Pointee(kSecondPayloadValue), kPayloadLengthBytes))
1090 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001091 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize)));
ossu61a208b2016-09-20 01:38:00 -07001092
Jonas Olssona4d87372019-07-05 19:08:33 +02001093 EXPECT_CALL(decoder, SampleRateHz()).WillRepeatedly(Return(kSampleRateHz));
ossu61a208b2016-09-20 01:38:00 -07001094
Jonas Olssona4d87372019-07-05 19:08:33 +02001095 EXPECT_CALL(decoder, Channels()).WillRepeatedly(Return(kChannels));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001096
Niels Möllera1eb9c72018-12-07 15:24:42 +01001097 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1098 SdpAudioFormat("L16", 8000, 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001099
1100 // Insert one packet.
1101 payload[0] = kFirstPayloadValue; // This will make Decode() fail.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001102 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001103
1104 // Insert another packet.
1105 payload[0] = kSecondPayloadValue; // This will make Decode() successful.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001106 rtp_header.sequenceNumber++;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001107 // The second timestamp needs to be at least 30 ms after the first to make
1108 // the second packet get decoded.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001109 rtp_header.timestamp += 3 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001110 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001111
henrik.lundin6d8e0112016-03-04 10:34:21 -08001112 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001113 bool muted;
henrik.lundin6d8e0112016-03-04 10:34:21 -08001114 // First call to GetAudio will try to decode the "faulty" packet.
Henrik Lundinc417d9e2017-06-14 12:29:03 +02001115 // Expect kFail return value.
henrik.lundin7a926812016-05-12 13:51:28 -07001116 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001117 // Output size and number of channels should be correct.
1118 const size_t kExpectedOutputSize = 10 * (kSampleRateHz / 1000) * kChannels;
1119 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1120 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001121 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001122
henrik.lundin6d8e0112016-03-04 10:34:21 -08001123 // Second call to GetAudio will decode the packet that is ok. No errors are
1124 // expected.
henrik.lundin7a926812016-05-12 13:51:28 -07001125 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001126 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1127 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001128 EXPECT_THAT(output.packet_infos_, SizeIs(1));
ossu61a208b2016-09-20 01:38:00 -07001129
1130 // Die isn't called through NiceMock (since it's called by the
1131 // MockAudioDecoder constructor), so it needs to be mocked explicitly.
1132 EXPECT_CALL(decoder, Die());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001133}
1134
henrik.lundin116c84e2015-08-27 13:14:48 -07001135// This test inserts packets until the buffer is flushed. After that, it asks
1136// NetEq for the network statistics. The purpose of the test is to make sure
1137// that even though the buffer size increment is negative (which it becomes when
1138// the packet causing a flush is inserted), the packet length stored in the
1139// decision logic remains valid.
1140TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) {
1141 UseNoMocks();
1142 CreateInstance();
1143
1144 const size_t kPayloadLengthSamples = 80;
1145 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1146 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin116c84e2015-08-27 13:14:48 -07001147 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001148 RTPHeader rtp_header;
1149 rtp_header.payloadType = kPayloadType;
1150 rtp_header.sequenceNumber = 0x1234;
1151 rtp_header.timestamp = 0x12345678;
1152 rtp_header.ssrc = 0x87654321;
henrik.lundin116c84e2015-08-27 13:14:48 -07001153
Niels Möller05543682019-01-10 16:55:06 +01001154 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1155 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin116c84e2015-08-27 13:14:48 -07001156
1157 // Insert packets until the buffer flushes.
1158 for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) {
1159 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
Karl Wiberg45eb1352019-10-10 14:23:00 +02001160 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -07001161 rtp_header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples);
1162 ++rtp_header.sequenceNumber;
henrik.lundin116c84e2015-08-27 13:14:48 -07001163 }
1164 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
1165
1166 // Ask for network statistics. This should not crash.
1167 NetEqNetworkStatistics stats;
1168 EXPECT_EQ(NetEq::kOK, neteq_->NetworkStatistics(&stats));
1169}
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001170
1171TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
1172 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001173 // Create a mock decoder object.
1174 MockAudioDecoder mock_decoder;
1175
1176 CreateInstance(
1177 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001178
1179 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001180 const int kSampleRateHz = 8000;
1181 const size_t kPayloadLengthSamples =
1182 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
1183 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples;
1184 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001185 RTPHeader rtp_header;
1186 rtp_header.payloadType = kPayloadType;
1187 rtp_header.sequenceNumber = 0x1234;
1188 rtp_header.timestamp = 0x12345678;
1189 rtp_header.ssrc = 0x87654321;
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001190
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001191 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001192 EXPECT_CALL(mock_decoder, SampleRateHz())
1193 .WillRepeatedly(Return(kSampleRateHz));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001194 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001195 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001196 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001197 int16_t dummy_output[kPayloadLengthSamples] = {0};
1198 // The below expectation will make the mock decoder write
1199 // |kPayloadLengthSamples| - 5 zeros to the output array, and mark it as
1200 // speech. That is, the decoded length is 5 samples shorter than the expected.
1201 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001202 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001203 .WillOnce(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001204 DoAll(SetArrayArgument<3>(dummy_output,
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001205 dummy_output + kPayloadLengthSamples - 5),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001206 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001207 Return(rtc::checked_cast<int>(kPayloadLengthSamples - 5))));
Niels Möllera1eb9c72018-12-07 15:24:42 +01001208 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1209 SdpAudioFormat("L16", 8000, 1)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001210
1211 // Insert one packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001212 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001213
1214 EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength());
1215
1216 // Pull audio once.
1217 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001218 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001219 bool muted;
1220 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001221 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1222 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001223 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001224 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001225
1226 EXPECT_CALL(mock_decoder, Die());
1227}
minyuel6d92bf52015-09-23 15:20:39 +02001228
1229// This test checks the behavior of NetEq when audio decoder fails.
1230TEST_F(NetEqImplTest, DecodingError) {
1231 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001232 // Create a mock decoder object.
1233 MockAudioDecoder mock_decoder;
1234
1235 CreateInstance(
1236 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001237
1238 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001239 const int kSampleRateHz = 8000;
1240 const int kDecoderErrorCode = -97; // Any negative number.
1241
1242 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1243 const size_t kFrameLengthSamples =
1244 static_cast<size_t>(5 * kSampleRateHz / 1000);
1245
1246 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1247
1248 uint8_t payload[kPayloadLengthBytes] = {0};
1249
henrik.lundin246ef3e2017-04-24 09:14:32 -07001250 RTPHeader rtp_header;
1251 rtp_header.payloadType = kPayloadType;
1252 rtp_header.sequenceNumber = 0x1234;
1253 rtp_header.timestamp = 0x12345678;
1254 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001255
minyuel6d92bf52015-09-23 15:20:39 +02001256 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001257 EXPECT_CALL(mock_decoder, SampleRateHz())
1258 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001259 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001260 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001261 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001262 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
1263 EXPECT_CALL(mock_decoder, HasDecodePlc()).WillOnce(Return(false));
minyuel6d92bf52015-09-23 15:20:39 +02001264 int16_t dummy_output[kFrameLengthSamples] = {0};
1265
1266 {
1267 InSequence sequence; // Dummy variable.
1268 // Mock decoder works normally the first time.
1269 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001270 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001271 .Times(3)
1272 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001273 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001274 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001275 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001276 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001277 .RetiresOnSaturation();
1278
1279 // Then mock decoder fails. A common reason for failure can be buffer being
1280 // too short
1281 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001282 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001283 .WillOnce(Return(-1))
1284 .RetiresOnSaturation();
1285
1286 // Mock decoder finally returns to normal.
1287 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001288 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001289 .Times(2)
1290 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001291 DoAll(SetArrayArgument<3>(dummy_output,
1292 dummy_output + kFrameLengthSamples),
1293 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001294 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001295 }
1296
Niels Möllera1eb9c72018-12-07 15:24:42 +01001297 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1298 SdpAudioFormat("L16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001299
1300 // Insert packets.
1301 for (int i = 0; i < 6; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001302 rtp_header.sequenceNumber += 1;
1303 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001304 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001305 }
1306
1307 // Pull audio.
1308 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001309 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001310 bool muted;
1311 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001312 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1313 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001314 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001315 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001316
1317 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001318 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001319 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1320 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001321 // We are not expecting anything for output.speech_type_, since an error was
1322 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001323
1324 // Pull audio again, should continue an expansion.
henrik.lundin7a926812016-05-12 13:51:28 -07001325 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001326 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1327 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001328 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001329 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyuel6d92bf52015-09-23 15:20:39 +02001330
1331 // Pull audio again, should behave normal.
henrik.lundin7a926812016-05-12 13:51:28 -07001332 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001333 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1334 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001335 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001336 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001337
1338 EXPECT_CALL(mock_decoder, Die());
1339}
1340
1341// This test checks the behavior of NetEq when audio decoder fails during CNG.
1342TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
1343 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +01001344
1345 // Create a mock decoder object.
1346 MockAudioDecoder mock_decoder;
1347 CreateInstance(
1348 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001349
1350 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001351 const int kSampleRateHz = 8000;
1352 const int kDecoderErrorCode = -97; // Any negative number.
1353
1354 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1355 const size_t kFrameLengthSamples =
1356 static_cast<size_t>(5 * kSampleRateHz / 1000);
1357
1358 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1359
1360 uint8_t payload[kPayloadLengthBytes] = {0};
1361
henrik.lundin246ef3e2017-04-24 09:14:32 -07001362 RTPHeader rtp_header;
1363 rtp_header.payloadType = kPayloadType;
1364 rtp_header.sequenceNumber = 0x1234;
1365 rtp_header.timestamp = 0x12345678;
1366 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001367
minyuel6d92bf52015-09-23 15:20:39 +02001368 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001369 EXPECT_CALL(mock_decoder, SampleRateHz())
1370 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001371 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001372 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001373 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001374 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
minyuel6d92bf52015-09-23 15:20:39 +02001375 int16_t dummy_output[kFrameLengthSamples] = {0};
1376
1377 {
1378 InSequence sequence; // Dummy variable.
1379 // Mock decoder works normally the first 2 times.
1380 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001381 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001382 .Times(2)
1383 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001384 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001385 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001386 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001387 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001388 .RetiresOnSaturation();
1389
1390 // Then mock decoder fails. A common reason for failure can be buffer being
1391 // too short
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001392 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001393 .WillOnce(Return(-1))
1394 .RetiresOnSaturation();
1395
1396 // Mock decoder finally returns to normal.
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001397 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001398 .Times(2)
1399 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001400 DoAll(SetArrayArgument<3>(dummy_output,
1401 dummy_output + kFrameLengthSamples),
1402 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001403 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001404 }
1405
Niels Möller50b66d52018-12-11 14:43:21 +01001406 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1407 SdpAudioFormat("l16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001408
1409 // Insert 2 packets. This will make netEq into codec internal CNG mode.
1410 for (int i = 0; i < 2; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001411 rtp_header.sequenceNumber += 1;
1412 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001413 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001414 }
1415
1416 // Pull audio.
1417 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001418 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001419 bool muted;
1420 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::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001424
1425 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001426 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001427 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1428 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001429 // We are not expecting anything for output.speech_type_, since an error was
1430 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001431
1432 // Pull audio again, should resume codec CNG.
henrik.lundin7a926812016-05-12 13:51:28 -07001433 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001434 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1435 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001436 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001437
1438 EXPECT_CALL(mock_decoder, Die());
1439}
1440
henrik.lundind89814b2015-11-23 06:49:25 -08001441// Tests that the return value from last_output_sample_rate_hz() is equal to the
1442// configured inital sample rate.
1443TEST_F(NetEqImplTest, InitialLastOutputSampleRate) {
1444 UseNoMocks();
1445 config_.sample_rate_hz = 48000;
1446 CreateInstance();
1447 EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz());
1448}
1449
henrik.lundined497212016-04-25 10:11:38 -07001450TEST_F(NetEqImplTest, TickTimerIncrement) {
1451 UseNoMocks();
1452 CreateInstance();
1453 ASSERT_TRUE(tick_timer_);
1454 EXPECT_EQ(0u, tick_timer_->ticks());
1455 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001456 bool muted;
1457 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundined497212016-04-25 10:11:38 -07001458 EXPECT_EQ(1u, tick_timer_->ticks());
1459}
1460
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001461TEST_F(NetEqImplTest, SetBaseMinimumDelay) {
1462 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001463 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001464 CreateInstance();
1465
Ivo Creusen53a31f72019-10-24 15:20:39 +02001466 EXPECT_CALL(*mock_neteq_controller_, SetBaseMinimumDelay(_))
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001467 .WillOnce(Return(true))
1468 .WillOnce(Return(false));
1469
1470 const int delay_ms = 200;
1471
1472 EXPECT_EQ(true, neteq_->SetBaseMinimumDelayMs(delay_ms));
1473 EXPECT_EQ(false, neteq_->SetBaseMinimumDelayMs(delay_ms));
1474}
1475
1476TEST_F(NetEqImplTest, GetBaseMinimumDelayMs) {
1477 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001478 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001479 CreateInstance();
1480
1481 const int delay_ms = 200;
1482
Ivo Creusen53a31f72019-10-24 15:20:39 +02001483 EXPECT_CALL(*mock_neteq_controller_, GetBaseMinimumDelay())
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001484 .WillOnce(Return(delay_ms));
1485
1486 EXPECT_EQ(delay_ms, neteq_->GetBaseMinimumDelayMs());
1487}
1488
henrik.lundin114c1b32017-04-26 07:47:32 -07001489TEST_F(NetEqImplTest, TargetDelayMs) {
1490 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001491 use_mock_neteq_controller_ = true;
henrik.lundin114c1b32017-04-26 07:47:32 -07001492 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001493 constexpr int kTargetLevelMs = 510;
1494 EXPECT_CALL(*mock_neteq_controller_, TargetLevelMs())
1495 .WillOnce(Return(kTargetLevelMs));
1496 EXPECT_EQ(510, neteq_->TargetDelayMs());
henrik.lundin114c1b32017-04-26 07:47:32 -07001497}
1498
henrik.lundinb8c55b12017-05-10 07:38:01 -07001499TEST_F(NetEqImplTest, InsertEmptyPacket) {
1500 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001501 use_mock_neteq_controller_ = true;
henrik.lundinb8c55b12017-05-10 07:38:01 -07001502 CreateInstance();
1503
1504 RTPHeader rtp_header;
1505 rtp_header.payloadType = 17;
1506 rtp_header.sequenceNumber = 0x1234;
1507 rtp_header.timestamp = 0x12345678;
1508 rtp_header.ssrc = 0x87654321;
1509
Ivo Creusen53a31f72019-10-24 15:20:39 +02001510 EXPECT_CALL(*mock_neteq_controller_, RegisterEmptyPacket());
henrik.lundinb8c55b12017-05-10 07:38:01 -07001511 neteq_->InsertEmptyPacket(rtp_header);
1512}
1513
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001514TEST_F(NetEqImplTest, EnableRtxHandling) {
1515 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001516 use_mock_neteq_controller_ = true;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001517 config_.enable_rtx_handling = true;
1518 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001519 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001520 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001521 .WillOnce(Return(NetEq::Operation::kNormal));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001522
1523 const int kPayloadLengthSamples = 80;
1524 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1525 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001526 uint8_t payload[kPayloadLengthBytes] = {0};
1527 RTPHeader rtp_header;
1528 rtp_header.payloadType = kPayloadType;
1529 rtp_header.sequenceNumber = 0x1234;
1530 rtp_header.timestamp = 0x12345678;
1531 rtp_header.ssrc = 0x87654321;
1532
Niels Möller05543682019-01-10 16:55:06 +01001533 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1534 SdpAudioFormat("l16", 8000, 1)));
Karl Wiberg45eb1352019-10-10 14:23:00 +02001535 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001536 AudioFrame output;
1537 bool muted;
1538 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
1539
1540 // Insert second packet that was sent before the first packet.
1541 rtp_header.sequenceNumber -= 1;
1542 rtp_header.timestamp -= kPayloadLengthSamples;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001543 EXPECT_CALL(*mock_neteq_controller_,
1544 PacketArrived(
1545 /*last_cng_or_dtmf*/ _,
1546 /*packet_length_samples*/ kPayloadLengthSamples,
1547 /*should_update_stats*/ _,
1548 /*main_sequence_number*/ rtp_header.sequenceNumber,
1549 /*main_timestamp*/ rtp_header.timestamp,
1550 /*fs_hz*/ 8000));
1551
Karl Wiberg45eb1352019-10-10 14:23:00 +02001552 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001553}
1554
minyue5bd33972016-05-02 04:46:11 -07001555class Decoder120ms : public AudioDecoder {
1556 public:
kwiberg347d3512016-06-16 01:59:09 -07001557 Decoder120ms(int sample_rate_hz, SpeechType speech_type)
1558 : sample_rate_hz_(sample_rate_hz),
1559 next_value_(1),
minyue5bd33972016-05-02 04:46:11 -07001560 speech_type_(speech_type) {}
1561
1562 int DecodeInternal(const uint8_t* encoded,
1563 size_t encoded_len,
1564 int sample_rate_hz,
1565 int16_t* decoded,
1566 SpeechType* speech_type) override {
kwiberg347d3512016-06-16 01:59:09 -07001567 EXPECT_EQ(sample_rate_hz_, sample_rate_hz);
minyue5bd33972016-05-02 04:46:11 -07001568 size_t decoded_len =
1569 rtc::CheckedDivExact(sample_rate_hz, 1000) * 120 * Channels();
1570 for (size_t i = 0; i < decoded_len; ++i) {
1571 decoded[i] = next_value_++;
1572 }
1573 *speech_type = speech_type_;
Mirko Bonadei737e0732017-10-19 09:00:17 +02001574 return rtc::checked_cast<int>(decoded_len);
minyue5bd33972016-05-02 04:46:11 -07001575 }
1576
1577 void Reset() override { next_value_ = 1; }
kwiberg347d3512016-06-16 01:59:09 -07001578 int SampleRateHz() const override { return sample_rate_hz_; }
minyue5bd33972016-05-02 04:46:11 -07001579 size_t Channels() const override { return 2; }
1580
1581 private:
kwiberg347d3512016-06-16 01:59:09 -07001582 int sample_rate_hz_;
minyue5bd33972016-05-02 04:46:11 -07001583 int16_t next_value_;
1584 SpeechType speech_type_;
1585};
1586
1587class NetEqImplTest120ms : public NetEqImplTest {
1588 protected:
1589 NetEqImplTest120ms() : NetEqImplTest() {}
1590 virtual ~NetEqImplTest120ms() {}
1591
1592 void CreateInstanceNoMocks() {
1593 UseNoMocks();
Niels Möllera0f44302018-11-30 10:45:12 +01001594 CreateInstance(decoder_factory_);
1595 EXPECT_TRUE(neteq_->RegisterPayloadType(
1596 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001597 }
1598
1599 void CreateInstanceWithDelayManagerMock() {
1600 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001601 use_mock_neteq_controller_ = true;
Niels Möllera0f44302018-11-30 10:45:12 +01001602 CreateInstance(decoder_factory_);
1603 EXPECT_TRUE(neteq_->RegisterPayloadType(
1604 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001605 }
1606
1607 uint32_t timestamp_diff_between_packets() const {
1608 return rtc::CheckedDivExact(kSamplingFreq_, 1000u) * 120;
1609 }
1610
1611 uint32_t first_timestamp() const { return 10u; }
1612
1613 void GetFirstPacket() {
henrik.lundin7a926812016-05-12 13:51:28 -07001614 bool muted;
minyue5bd33972016-05-02 04:46:11 -07001615 for (int i = 0; i < 12; i++) {
henrik.lundin7a926812016-05-12 13:51:28 -07001616 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
1617 EXPECT_FALSE(muted);
minyue5bd33972016-05-02 04:46:11 -07001618 }
1619 }
1620
1621 void InsertPacket(uint32_t timestamp) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001622 RTPHeader rtp_header;
1623 rtp_header.payloadType = kPayloadType;
1624 rtp_header.sequenceNumber = sequence_number_;
1625 rtp_header.timestamp = timestamp;
1626 rtp_header.ssrc = 15;
minyue5bd33972016-05-02 04:46:11 -07001627 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1628 uint8_t payload[kPayloadLengthBytes] = {0};
Karl Wiberg45eb1352019-10-10 14:23:00 +02001629 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue5bd33972016-05-02 04:46:11 -07001630 sequence_number_++;
1631 }
1632
1633 void Register120msCodec(AudioDecoder::SpeechType speech_type) {
Niels Möllera0f44302018-11-30 10:45:12 +01001634 const uint32_t sampling_freq = kSamplingFreq_;
1635 decoder_factory_ =
1636 new rtc::RefCountedObject<test::FunctionAudioDecoderFactory>(
1637 [sampling_freq, speech_type]() {
1638 std::unique_ptr<AudioDecoder> decoder =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001639 std::make_unique<Decoder120ms>(sampling_freq, speech_type);
Niels Möllera0f44302018-11-30 10:45:12 +01001640 RTC_CHECK_EQ(2, decoder->Channels());
1641 return decoder;
1642 });
minyue5bd33972016-05-02 04:46:11 -07001643 }
1644
Niels Möllera0f44302018-11-30 10:45:12 +01001645 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
minyue5bd33972016-05-02 04:46:11 -07001646 AudioFrame output_;
1647 const uint32_t kPayloadType = 17;
1648 const uint32_t kSamplingFreq_ = 48000;
1649 uint16_t sequence_number_ = 1;
1650};
1651
minyue5bd33972016-05-02 04:46:11 -07001652TEST_F(NetEqImplTest120ms, CodecInternalCng) {
minyue5bd33972016-05-02 04:46:11 -07001653 Register120msCodec(AudioDecoder::kComfortNoise);
Niels Möllera0f44302018-11-30 10:45:12 +01001654 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001655
1656 InsertPacket(first_timestamp());
1657 GetFirstPacket();
1658
henrik.lundin7a926812016-05-12 13:51:28 -07001659 bool muted;
1660 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001661 EXPECT_EQ(NetEq::Operation::kCodecInternalCng,
1662 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001663}
1664
1665TEST_F(NetEqImplTest120ms, Normal) {
minyue5bd33972016-05-02 04:46:11 -07001666 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001667 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001668
1669 InsertPacket(first_timestamp());
1670 GetFirstPacket();
1671
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001672 EXPECT_EQ(NetEq::Operation::kNormal, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001673}
1674
1675TEST_F(NetEqImplTest120ms, Merge) {
Niels Möllera0f44302018-11-30 10:45:12 +01001676 Register120msCodec(AudioDecoder::kSpeech);
minyue5bd33972016-05-02 04:46:11 -07001677 CreateInstanceWithDelayManagerMock();
1678
Ivo Creusen53a31f72019-10-24 15:20:39 +02001679 EXPECT_CALL(*mock_neteq_controller_, CngOff()).WillRepeatedly(Return(true));
minyue5bd33972016-05-02 04:46:11 -07001680 InsertPacket(first_timestamp());
1681
1682 GetFirstPacket();
henrik.lundin7a926812016-05-12 13:51:28 -07001683 bool muted;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001684 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001685 .WillOnce(Return(NetEq::Operation::kExpand));
henrik.lundin7a926812016-05-12 13:51:28 -07001686 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
minyue5bd33972016-05-02 04:46:11 -07001687
1688 InsertPacket(first_timestamp() + 2 * timestamp_diff_between_packets());
1689
Ivo Creusen53a31f72019-10-24 15:20:39 +02001690 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001691 .WillOnce(Return(NetEq::Operation::kMerge));
minyue5bd33972016-05-02 04:46:11 -07001692
henrik.lundin7a926812016-05-12 13:51:28 -07001693 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001694 EXPECT_EQ(NetEq::Operation::kMerge, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001695}
1696
1697TEST_F(NetEqImplTest120ms, Expand) {
minyue5bd33972016-05-02 04:46:11 -07001698 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001699 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001700
1701 InsertPacket(first_timestamp());
1702 GetFirstPacket();
1703
henrik.lundin7a926812016-05-12 13:51:28 -07001704 bool muted;
1705 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001706 EXPECT_EQ(NetEq::Operation::kExpand, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001707}
1708
1709TEST_F(NetEqImplTest120ms, FastAccelerate) {
minyue5bd33972016-05-02 04:46:11 -07001710 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001711 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001712
1713 InsertPacket(first_timestamp());
1714 GetFirstPacket();
1715 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1716
Ivo Creusen53a31f72019-10-24 15:20:39 +02001717 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001718 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001719 .WillOnce(Return(NetEq::Operation::kFastAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001720
henrik.lundin7a926812016-05-12 13:51:28 -07001721 bool muted;
1722 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001723 EXPECT_EQ(NetEq::Operation::kFastAccelerate,
1724 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001725}
1726
1727TEST_F(NetEqImplTest120ms, PreemptiveExpand) {
minyue5bd33972016-05-02 04:46:11 -07001728 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001729 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001730
1731 InsertPacket(first_timestamp());
1732 GetFirstPacket();
1733
1734 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1735
Ivo Creusen53a31f72019-10-24 15:20:39 +02001736 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001737 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001738 .WillOnce(Return(NetEq::Operation::kPreemptiveExpand));
minyue5bd33972016-05-02 04:46:11 -07001739
henrik.lundin7a926812016-05-12 13:51:28 -07001740 bool muted;
1741 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001742 EXPECT_EQ(NetEq::Operation::kPreemptiveExpand,
1743 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001744}
1745
1746TEST_F(NetEqImplTest120ms, Accelerate) {
minyue5bd33972016-05-02 04:46:11 -07001747 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001748 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001749
1750 InsertPacket(first_timestamp());
1751 GetFirstPacket();
1752
1753 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1754
Ivo Creusen53a31f72019-10-24 15:20:39 +02001755 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001756 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001757 .WillOnce(Return(NetEq::Operation::kAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001758
henrik.lundin7a926812016-05-12 13:51:28 -07001759 bool muted;
1760 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001761 EXPECT_EQ(NetEq::Operation::kAccelerate, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001762}
1763
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001764} // namespace webrtc