blob: 1731282fdce40b0d10911105aa90148151db2c03 [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"
21#include "api/test/neteq_factory_with_codecs.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "modules/audio_coding/neteq/accelerate.h"
Ivo Creusen53a31f72019-10-24 15:20:39 +020023#include "modules/audio_coding/neteq/decision_logic.h"
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 Creusen3ce44a32019-10-31 14:38:11 +0100255 std::unique_ptr<NetEqFactory> neteq_factory = CreateNetEqFactoryWithCodecs();
256 std::unique_ptr<NetEq> neteq = neteq_factory->CreateNetEq(config, &clock);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000257}
258
kwiberg5adaf732016-10-04 09:33:27 -0700259TEST_F(NetEqImplTest, RegisterPayloadType) {
260 CreateInstance();
261 constexpr int rtp_payload_type = 0;
262 const SdpAudioFormat format("pcmu", 8000, 1);
263 EXPECT_CALL(*mock_decoder_database_,
264 RegisterPayload(rtp_payload_type, format));
265 neteq_->RegisterPayloadType(rtp_payload_type, format);
266}
267
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000268TEST_F(NetEqImplTest, RemovePayloadType) {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000269 CreateInstance();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000270 uint8_t rtp_payload_type = 0;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000271 EXPECT_CALL(*mock_decoder_database_, Remove(rtp_payload_type))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000272 .WillOnce(Return(DecoderDatabase::kDecoderNotFound));
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200273 // Check that kOK is returned when database returns kDecoderNotFound, because
274 // removing a payload type that was never registered is not an error.
275 EXPECT_EQ(NetEq::kOK, neteq_->RemovePayloadType(rtp_payload_type));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000276}
277
kwiberg6b19b562016-09-20 04:02:25 -0700278TEST_F(NetEqImplTest, RemoveAllPayloadTypes) {
279 CreateInstance();
280 EXPECT_CALL(*mock_decoder_database_, RemoveAll()).WillOnce(Return());
281 neteq_->RemoveAllPayloadTypes();
282}
283
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000284TEST_F(NetEqImplTest, InsertPacket) {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000285 CreateInstance();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000286 const size_t kPayloadLength = 100;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000287 const uint8_t kPayloadType = 0;
288 const uint16_t kFirstSequenceNumber = 0x1234;
289 const uint32_t kFirstTimestamp = 0x12345678;
290 const uint32_t kSsrc = 0x87654321;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000291 uint8_t payload[kPayloadLength] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700292 RTPHeader rtp_header;
293 rtp_header.payloadType = kPayloadType;
294 rtp_header.sequenceNumber = kFirstSequenceNumber;
295 rtp_header.timestamp = kFirstTimestamp;
296 rtp_header.ssrc = kSsrc;
ossu7a377612016-10-18 04:06:13 -0700297 Packet fake_packet;
298 fake_packet.payload_type = kPayloadType;
299 fake_packet.sequence_number = kFirstSequenceNumber;
300 fake_packet.timestamp = kFirstTimestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000301
kwibergc0f2dcf2016-05-31 06:28:03 -0700302 rtc::scoped_refptr<MockAudioDecoderFactory> mock_decoder_factory(
303 new rtc::RefCountedObject<MockAudioDecoderFactory>);
Karl Wibergd6fbf2a2018-02-27 13:37:31 +0100304 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _, _))
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800305 .WillOnce(Invoke([&](const SdpAudioFormat& format,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200306 absl::optional<AudioCodecPairId> codec_pair_id,
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800307 std::unique_ptr<AudioDecoder>* dec) {
kwibergc0f2dcf2016-05-31 06:28:03 -0700308 EXPECT_EQ("pcmu", format.name);
309
310 std::unique_ptr<MockAudioDecoder> mock_decoder(new MockAudioDecoder);
311 EXPECT_CALL(*mock_decoder, Channels()).WillRepeatedly(Return(1));
312 EXPECT_CALL(*mock_decoder, SampleRateHz()).WillRepeatedly(Return(8000));
kwibergc0f2dcf2016-05-31 06:28:03 -0700313 EXPECT_CALL(*mock_decoder, Die()).Times(1); // Called when deleted.
314
315 *dec = std::move(mock_decoder);
316 }));
Niels Möller72899062019-01-11 09:36:13 +0100317 DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
318 absl::nullopt, mock_decoder_factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000319
320 // Expectations for decoder database.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000321 EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000322 .WillRepeatedly(Return(&info));
323
324 // Expectations for packet buffer.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000325 EXPECT_CALL(*mock_packet_buffer_, Empty())
326 .WillOnce(Return(false)); // Called once after first packet is inserted.
Jonas Olssona4d87372019-07-05 19:08:33 +0200327 EXPECT_CALL(*mock_packet_buffer_, Flush()).Times(1);
minyue-webrtc12d30842017-07-19 11:44:06 +0200328 EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _, _))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000329 .Times(2)
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100330 .WillRepeatedly(DoAll(SetArgPointee<2>(kPayloadType),
331 WithArg<0>(Invoke(DeletePacketsAndReturnOk))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000332 // SetArgPointee<2>(kPayloadType) means that the third argument (zero-based
333 // index) is a pointer, and the variable pointed to is set to kPayloadType.
334 // Also invoke the function DeletePacketsAndReturnOk to properly delete all
335 // packets in the list (to avoid memory leaks in the test).
ossu7a377612016-10-18 04:06:13 -0700336 EXPECT_CALL(*mock_packet_buffer_, PeekNextPacket())
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000337 .Times(1)
ossu7a377612016-10-18 04:06:13 -0700338 .WillOnce(Return(&fake_packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000339
340 // Expectations for DTMF buffer.
Jonas Olssona4d87372019-07-05 19:08:33 +0200341 EXPECT_CALL(*mock_dtmf_buffer_, Flush()).Times(1);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000342
343 // Expectations for delay manager.
344 {
345 // All expectations within this block must be called in this specific order.
346 InSequence sequence; // Dummy variable.
347 // Expectations when the first packet is inserted.
Ivo Creusen53a31f72019-10-24 15:20:39 +0200348 EXPECT_CALL(*mock_neteq_controller_,
349 PacketArrived(/*last_cng_or_dtmf*/ false,
350 /*packet_length_samples*/ _,
351 /*should_update_stats*/ _,
352 /*main_sequence_number*/ kFirstSequenceNumber,
353 /*main_timestamp*/ kFirstTimestamp,
354 /*fs_hz*/ 8000));
355 EXPECT_CALL(*mock_neteq_controller_,
356 PacketArrived(/*last_cng_or_dtmf*/ false,
357 /*packet_length_samples*/ _,
358 /*should_update_stats*/ _,
359 /*main_sequence_number*/ kFirstSequenceNumber + 1,
360 /*main_timestamp*/ kFirstTimestamp + 160,
361 /*fs_hz*/ 8000));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000362 }
363
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000364 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200365 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000366
367 // Insert second packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700368 rtp_header.timestamp += 160;
369 rtp_header.sequenceNumber += 1;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200370 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000371}
372
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000373TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
374 UseNoMocks();
375 CreateInstance();
376
377 const int kPayloadLengthSamples = 80;
378 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
Jonas Olssona4d87372019-07-05 19:08:33 +0200379 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000380 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700381 RTPHeader rtp_header;
382 rtp_header.payloadType = kPayloadType;
383 rtp_header.sequenceNumber = 0x1234;
384 rtp_header.timestamp = 0x12345678;
385 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000386
Niels Möller05543682019-01-10 16:55:06 +0100387 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
388 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000389
390 // Insert packets. The buffer should not flush.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700391 for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) {
Karl Wiberg45eb1352019-10-10 14:23:00 +0200392 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700393 rtp_header.timestamp += kPayloadLengthSamples;
394 rtp_header.sequenceNumber += 1;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000395 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
396 }
397
398 // Insert one more packet and make sure the buffer got flushed. That is, it
399 // should only hold one single packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200400 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700401 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700402 const Packet* test_packet = packet_buffer_->PeekNextPacket();
henrik.lundin246ef3e2017-04-24 09:14:32 -0700403 EXPECT_EQ(rtp_header.timestamp, test_packet->timestamp);
404 EXPECT_EQ(rtp_header.sequenceNumber, test_packet->sequence_number);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000405}
406
solenberg2779bab2016-11-17 04:45:19 -0800407TEST_F(NetEqImplTest, TestDtmfPacketAVT) {
Niels Möller05543682019-01-10 16:55:06 +0100408 TestDtmfPacket(8000);
solenberg2779bab2016-11-17 04:45:19 -0800409}
solenberg99df6c02016-10-11 04:35:34 -0700410
solenberg2779bab2016-11-17 04:45:19 -0800411TEST_F(NetEqImplTest, TestDtmfPacketAVT16kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100412 TestDtmfPacket(16000);
solenberg2779bab2016-11-17 04:45:19 -0800413}
solenberg99df6c02016-10-11 04:35:34 -0700414
solenberg2779bab2016-11-17 04:45:19 -0800415TEST_F(NetEqImplTest, TestDtmfPacketAVT32kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100416 TestDtmfPacket(32000);
solenberg2779bab2016-11-17 04:45:19 -0800417}
solenberg99df6c02016-10-11 04:35:34 -0700418
solenberg2779bab2016-11-17 04:45:19 -0800419TEST_F(NetEqImplTest, TestDtmfPacketAVT48kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100420 TestDtmfPacket(48000);
solenberg99df6c02016-10-11 04:35:34 -0700421}
422
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000423// This test verifies that timestamps propagate from the incoming packets
424// through to the sync buffer and to the playout timestamp.
425TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000426 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000427 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700428 const size_t kPayloadLengthSamples =
429 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000430 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
431 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700432 RTPHeader rtp_header;
433 rtp_header.payloadType = kPayloadType;
434 rtp_header.sequenceNumber = 0x1234;
435 rtp_header.timestamp = 0x12345678;
436 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000437 rtp_header.numCSRCs = 3;
438 rtp_header.arrOfCSRCs[0] = 43;
439 rtp_header.arrOfCSRCs[1] = 65;
440 rtp_header.arrOfCSRCs[2] = 17;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000441
442 // This is a dummy decoder that produces as many output samples as the input
443 // has bytes. The output is an increasing series, starting at 1 for the first
444 // sample, and then increasing by 1 for each sample.
445 class CountingSamplesDecoder : public AudioDecoder {
446 public:
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000447 CountingSamplesDecoder() : next_value_(1) {}
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000448
449 // Produce as many samples as input bytes (|encoded_len|).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100450 int DecodeInternal(const uint8_t* encoded,
451 size_t encoded_len,
452 int /* sample_rate_hz */,
453 int16_t* decoded,
454 SpeechType* speech_type) override {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000455 for (size_t i = 0; i < encoded_len; ++i) {
456 decoded[i] = next_value_++;
457 }
458 *speech_type = kSpeech;
Mirko Bonadei737e0732017-10-19 09:00:17 +0200459 return rtc::checked_cast<int>(encoded_len);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000460 }
461
Karl Wiberg43766482015-08-27 15:22:11 +0200462 void Reset() override { next_value_ = 1; }
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000463
kwiberg347d3512016-06-16 01:59:09 -0700464 int SampleRateHz() const override { return kSampleRateHz; }
465
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000466 size_t Channels() const override { return 1; }
467
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000468 uint16_t next_value() const { return next_value_; }
469
470 private:
471 int16_t next_value_;
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000472 } decoder_;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000473
Niels Möllerb7180c02018-12-06 13:07:11 +0100474 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory =
475 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&decoder_);
476
477 UseNoMocks();
478 CreateInstance(decoder_factory);
479
480 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
Niels Möllera1eb9c72018-12-07 15:24:42 +0100481 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000482
483 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000484 clock_.AdvanceTimeMilliseconds(123456);
485 int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200486 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000487
488 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700489 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800490 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700491 bool muted;
492 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
493 ASSERT_FALSE(muted);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800494 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
495 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800496 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000497
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000498 // Verify |output.packet_infos_|.
499 ASSERT_THAT(output.packet_infos_, SizeIs(1));
500 {
501 const auto& packet_info = output.packet_infos_[0];
502 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
503 EXPECT_THAT(packet_info.csrcs(), ElementsAre(43, 65, 17));
504 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
505 EXPECT_FALSE(packet_info.audio_level().has_value());
506 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
507 }
508
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000509 // Start with a simple check that the fake decoder is behaving as expected.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700510 EXPECT_EQ(kPayloadLengthSamples,
511 static_cast<size_t>(decoder_.next_value() - 1));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000512
513 // The value of the last of the output samples is the same as the number of
514 // samples played from the decoded packet. Thus, this number + the RTP
515 // timestamp should match the playout timestamp.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200516 // Wrap the expected value in an absl::optional to compare them as such.
henrik.lundin9a410dd2016-04-06 01:39:22 -0700517 EXPECT_EQ(
Danil Chapovalovb6021232018-06-19 13:26:36 +0200518 absl::optional<uint32_t>(rtp_header.timestamp +
519 output.data()[output.samples_per_channel_ - 1]),
henrik.lundin9a410dd2016-04-06 01:39:22 -0700520 neteq_->GetPlayoutTimestamp());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000521
522 // Check the timestamp for the last value in the sync buffer. This should
523 // be one full frame length ahead of the RTP timestamp.
524 const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
525 ASSERT_TRUE(sync_buffer != NULL);
henrik.lundin246ef3e2017-04-24 09:14:32 -0700526 EXPECT_EQ(rtp_header.timestamp + kPayloadLengthSamples,
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000527 sync_buffer->end_timestamp());
528
529 // Check that the number of samples still to play from the sync buffer add
530 // up with what was already played out.
henrik.lundin6d8e0112016-03-04 10:34:21 -0800531 EXPECT_EQ(
yujo36b1a5f2017-06-12 12:45:32 -0700532 kPayloadLengthSamples - output.data()[output.samples_per_channel_ - 1],
henrik.lundin6d8e0112016-03-04 10:34:21 -0800533 sync_buffer->FutureLength());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000534}
535
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000536TEST_F(NetEqImplTest, ReorderedPacket) {
537 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +0100538 // Create a mock decoder object.
539 MockAudioDecoder mock_decoder;
540
541 CreateInstance(
542 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000543
544 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000545 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700546 const size_t kPayloadLengthSamples =
547 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000548 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
549 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700550 RTPHeader rtp_header;
551 rtp_header.payloadType = kPayloadType;
552 rtp_header.sequenceNumber = 0x1234;
553 rtp_header.timestamp = 0x12345678;
554 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000555 rtp_header.extension.hasAudioLevel = true;
556 rtp_header.extension.audioLevel = 42;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000557
Karl Wiberg43766482015-08-27 15:22:11 +0200558 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700559 EXPECT_CALL(mock_decoder, SampleRateHz())
560 .WillRepeatedly(Return(kSampleRateHz));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000561 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin034154b2016-04-27 06:11:50 -0700562 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeiea7a3f82017-10-19 11:40:55 +0200563 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000564 int16_t dummy_output[kPayloadLengthSamples] = {0};
565 // The below expectation will make the mock decoder write
566 // |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100567 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
568 kSampleRateHz, _, _))
569 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000570 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100571 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200572 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
Niels Möllera1eb9c72018-12-07 15:24:42 +0100573 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
574 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000575
576 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000577 clock_.AdvanceTimeMilliseconds(123456);
578 int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200579 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000580
581 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700582 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800583 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700584 bool muted;
585 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800586 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
587 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800588 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000589
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000590 // Verify |output.packet_infos_|.
591 ASSERT_THAT(output.packet_infos_, SizeIs(1));
592 {
593 const auto& packet_info = output.packet_infos_[0];
594 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
595 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
596 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
597 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
598 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
599 }
600
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000601 // Insert two more packets. The first one is out of order, and is already too
602 // old, the second one is the expected next packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700603 rtp_header.sequenceNumber -= 1;
604 rtp_header.timestamp -= kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000605 rtp_header.extension.audioLevel = 1;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000606 payload[0] = 1;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000607 clock_.AdvanceTimeMilliseconds(1000);
Karl Wiberg45eb1352019-10-10 14:23:00 +0200608 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700609 rtp_header.sequenceNumber += 2;
610 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000611 rtp_header.extension.audioLevel = 2;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000612 payload[0] = 2;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000613 clock_.AdvanceTimeMilliseconds(2000);
614 expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200615 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000616
617 // Expect only the second packet to be decoded (the one with "2" as the first
618 // payload byte).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100619 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
620 kSampleRateHz, _, _))
621 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000622 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100623 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200624 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000625
626 // Pull audio once.
henrik.lundin7a926812016-05-12 13:51:28 -0700627 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800628 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
629 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800630 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000631
632 // Now check the packet buffer, and make sure it is empty, since the
633 // out-of-order packet should have been discarded.
634 EXPECT_TRUE(packet_buffer_->Empty());
635
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000636 // Verify |output.packet_infos_|. Expect to only see the second packet.
637 ASSERT_THAT(output.packet_infos_, SizeIs(1));
638 {
639 const auto& packet_info = output.packet_infos_[0];
640 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
641 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
642 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
643 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
644 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
645 }
646
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000647 EXPECT_CALL(mock_decoder, Die());
648}
649
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000650// This test verifies that NetEq can handle the situation where the first
651// incoming packet is rejected.
henrik.lundin@webrtc.org6ff3ac12014-11-20 14:14:49 +0000652TEST_F(NetEqImplTest, FirstPacketUnknown) {
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000653 UseNoMocks();
654 CreateInstance();
655
656 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000657 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700658 const size_t kPayloadLengthSamples =
659 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundinc9ec8752016-10-13 02:43:34 -0700660 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000661 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700662 RTPHeader rtp_header;
663 rtp_header.payloadType = kPayloadType;
664 rtp_header.sequenceNumber = 0x1234;
665 rtp_header.timestamp = 0x12345678;
666 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000667
668 // Insert one packet. Note that we have not registered any payload type, so
669 // this packet will be rejected.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200670 EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000671
672 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700673 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800674 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700675 bool muted;
676 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800677 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
678 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
679 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800680 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000681 EXPECT_THAT(output.packet_infos_, IsEmpty());
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000682
683 // Register the payload type.
Niels Möller05543682019-01-10 16:55:06 +0100684 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
685 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000686
687 // Insert 10 packets.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700688 for (size_t i = 0; i < 10; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -0700689 rtp_header.sequenceNumber++;
690 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200691 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000692 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
693 }
694
695 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700696 for (size_t i = 0; i < 3; ++i) {
henrik.lundin7a926812016-05-12 13:51:28 -0700697 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800698 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
699 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
700 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800701 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000702 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000703 EXPECT_THAT(output.packet_infos_, SizeIs(1));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000704 }
705}
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000706
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200707// This test verifies that audio interruption is not logged for the initial
708// PLC period before the first packet is deocoded.
709// TODO(henrik.lundin) Maybe move this test to neteq_network_stats_unittest.cc.
Henrik Lundinfe047752019-11-19 12:58:11 +0100710// Make the test parametrized, so that we can test with different initial
711// sample rates in NetEq.
712class NetEqImplTestSampleRateParameter
713 : public NetEqImplTest,
714 public testing::WithParamInterface<int> {
715 protected:
716 NetEqImplTestSampleRateParameter()
717 : NetEqImplTest(), initial_sample_rate_hz_(GetParam()) {
718 config_.sample_rate_hz = initial_sample_rate_hz_;
719 }
720
721 const int initial_sample_rate_hz_;
722};
723
724// This test does the following:
725// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
726// sample rate of 16000.
727// 1. Start calling GetAudio before inserting any encoded audio. The audio
728// produced will be PLC.
729// 2. Insert a number of encoded audio packets.
730// 3. Keep calling GetAudio and verify that no audio interruption was logged.
731// Call GetAudio until NetEq runs out of data again; PLC starts.
732// 4. Insert one more packet.
733// 5. Call GetAudio until that packet is decoded and the PLC ends.
734
735TEST_P(NetEqImplTestSampleRateParameter,
736 NoAudioInterruptionLoggedBeforeFirstDecode) {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200737 UseNoMocks();
738 CreateInstance();
739
740 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundinfe047752019-11-19 12:58:11 +0100741 const int kPayloadSampleRateHz = 16000;
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200742 const size_t kPayloadLengthSamples =
Henrik Lundinfe047752019-11-19 12:58:11 +0100743 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200744 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
745 uint8_t payload[kPayloadLengthBytes] = {0};
746 RTPHeader rtp_header;
747 rtp_header.payloadType = kPayloadType;
748 rtp_header.sequenceNumber = 0x1234;
749 rtp_header.timestamp = 0x12345678;
750 rtp_header.ssrc = 0x87654321;
751
752 // Register the payload type.
Henrik Lundinfe047752019-11-19 12:58:11 +0100753 EXPECT_TRUE(neteq_->RegisterPayloadType(
754 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200755
756 // Pull audio several times. No packets have been inserted yet.
Henrik Lundinfe047752019-11-19 12:58:11 +0100757 const size_t initial_output_size =
758 static_cast<size_t>(10 * initial_sample_rate_hz_ / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200759 AudioFrame output;
760 bool muted;
761 for (int i = 0; i < 100; ++i) {
762 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100763 EXPECT_EQ(initial_output_size, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200764 EXPECT_EQ(1u, output.num_channels_);
765 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000766 EXPECT_THAT(output.packet_infos_, IsEmpty());
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200767 }
768
Henrik Lundinfe047752019-11-19 12:58:11 +0100769 // Lambda for inserting packets.
770 auto insert_packet = [&]() {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200771 rtp_header.sequenceNumber++;
772 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200773 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundinfe047752019-11-19 12:58:11 +0100774 };
775 // Insert 10 packets.
776 for (size_t i = 0; i < 10; ++i) {
777 insert_packet();
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200778 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
779 }
780
781 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Henrik Lundinfe047752019-11-19 12:58:11 +0100782 constexpr size_t kOutputSize =
783 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200784 for (size_t i = 0; i < 3; ++i) {
785 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100786 EXPECT_EQ(kOutputSize, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200787 EXPECT_EQ(1u, output.num_channels_);
788 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
789 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000790 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200791 }
792
Henrik Lundinfe047752019-11-19 12:58:11 +0100793 // Verify that no interruption was logged.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200794 auto lifetime_stats = neteq_->GetLifetimeStatistics();
Henrik Lundin44125fa2019-04-29 17:00:46 +0200795 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundinfe047752019-11-19 12:58:11 +0100796
797 // Keep pulling audio data until a new PLC period is started.
798 size_t count_loops = 0;
799 while (output.speech_type_ == AudioFrame::kNormalSpeech) {
800 // Make sure we don't hang the test if we never go to PLC.
801 ASSERT_LT(++count_loops, 100u);
802 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
803 }
804
805 // Insert one more packet.
806 insert_packet();
807
808 // Pull audio until the newly inserted packet is decoded and the PLC ends.
809 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
810 // Make sure we don't hang the test if we never go to PLC.
811 ASSERT_LT(++count_loops, 100u);
812 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
813 }
814
815 // Verify that no interruption was logged.
816 lifetime_stats = neteq_->GetLifetimeStatistics();
817 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200818}
819
Henrik Lundinfe047752019-11-19 12:58:11 +0100820// This test does the following:
821// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
822// sample rate of 16000.
823// 1. Insert a number of encoded audio packets.
824// 2. Call GetAudio and verify that decoded audio is produced.
825// 3. Keep calling GetAudio until NetEq runs out of data; PLC starts.
826// 4. Keep calling GetAudio until PLC has been produced for at least 150 ms.
827// 5. Insert one more packet.
828// 6. Call GetAudio until that packet is decoded and the PLC ends.
829// 7. Verify that an interruption was logged.
830
831TEST_P(NetEqImplTestSampleRateParameter, AudioInterruptionLogged) {
832 UseNoMocks();
833 CreateInstance();
834
835 const uint8_t kPayloadType = 17; // Just an arbitrary number.
836 const int kPayloadSampleRateHz = 16000;
837 const size_t kPayloadLengthSamples =
838 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
839 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
840 uint8_t payload[kPayloadLengthBytes] = {0};
841 RTPHeader rtp_header;
842 rtp_header.payloadType = kPayloadType;
843 rtp_header.sequenceNumber = 0x1234;
844 rtp_header.timestamp = 0x12345678;
845 rtp_header.ssrc = 0x87654321;
846
847 // Register the payload type.
848 EXPECT_TRUE(neteq_->RegisterPayloadType(
849 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
850
851 // Lambda for inserting packets.
852 auto insert_packet = [&]() {
853 rtp_header.sequenceNumber++;
854 rtp_header.timestamp += kPayloadLengthSamples;
855 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
856 };
857 // Insert 10 packets.
858 for (size_t i = 0; i < 10; ++i) {
859 insert_packet();
860 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
861 }
862
863 AudioFrame output;
864 bool muted;
865 // Keep pulling audio data until a new PLC period is started.
866 size_t count_loops = 0;
867 do {
868 // Make sure we don't hang the test if we never go to PLC.
869 ASSERT_LT(++count_loops, 100u);
870 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
871 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
872
873 // Pull audio 15 times, which produces 150 ms of output audio. This should
874 // all be produced as PLC. The total length of the gap will then be 150 ms
875 // plus an initial fraction of 10 ms at the start and the end of the PLC
876 // period. In total, less than 170 ms.
877 for (size_t i = 0; i < 15; ++i) {
878 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
879 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
880 }
881
882 // Insert one more packet.
883 insert_packet();
884
885 // Pull audio until the newly inserted packet is decoded and the PLC ends.
886 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
887 // Make sure we don't hang the test if we never go to PLC.
888 ASSERT_LT(++count_loops, 100u);
889 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
890 }
891
892 // Verify that the interruption was logged.
893 auto lifetime_stats = neteq_->GetLifetimeStatistics();
894 EXPECT_EQ(1, lifetime_stats.interruption_count);
895 EXPECT_GT(lifetime_stats.total_interruption_duration_ms, 150);
896 EXPECT_LT(lifetime_stats.total_interruption_duration_ms, 170);
897}
898
899INSTANTIATE_TEST_SUITE_P(SampleRates,
900 NetEqImplTestSampleRateParameter,
901 testing::Values(8000, 16000, 32000, 48000));
902
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000903// This test verifies that NetEq can handle comfort noise and enters/quits codec
904// internal CNG mode properly.
905TEST_F(NetEqImplTest, CodecInternalCng) {
906 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +0100907 // Create a mock decoder object.
908 MockAudioDecoder mock_decoder;
909 CreateInstance(
910 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000911
912 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000913 const int kSampleRateKhz = 48;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700914 const size_t kPayloadLengthSamples =
915 static_cast<size_t>(20 * kSampleRateKhz); // 20 ms.
916 const size_t kPayloadLengthBytes = 10;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000917 uint8_t payload[kPayloadLengthBytes] = {0};
918 int16_t dummy_output[kPayloadLengthSamples] = {0};
919
henrik.lundin246ef3e2017-04-24 09:14:32 -0700920 RTPHeader rtp_header;
921 rtp_header.payloadType = kPayloadType;
922 rtp_header.sequenceNumber = 0x1234;
923 rtp_header.timestamp = 0x12345678;
924 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000925
Karl Wiberg43766482015-08-27 15:22:11 +0200926 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700927 EXPECT_CALL(mock_decoder, SampleRateHz())
928 .WillRepeatedly(Return(kSampleRateKhz * 1000));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000929 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin0d96ab72016-04-06 12:28:26 -0700930 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200931 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin0d96ab72016-04-06 12:28:26 -0700932 // Packed duration when asking the decoder for more CNG data (without a new
933 // packet).
934 EXPECT_CALL(mock_decoder, PacketDuration(nullptr, 0))
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200935 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000936
937 // Pointee(x) verifies that first byte of the payload equals x, this makes it
938 // possible to verify that the correct payload is fed to Decode().
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100939 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
940 kSampleRateKhz * 1000, _, _))
941 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000942 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100943 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200944 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000945
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100946 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes,
947 kSampleRateKhz * 1000, _, _))
948 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000949 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100950 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200951 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000952
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100953 EXPECT_CALL(mock_decoder,
954 DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
955 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000956 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100957 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200958 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000959
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100960 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
961 kSampleRateKhz * 1000, _, _))
962 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000963 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100964 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200965 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000966
Niels Möller50b66d52018-12-11 14:43:21 +0100967 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
968 SdpAudioFormat("opus", 48000, 2)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000969
970 // Insert one packet (decoder will return speech).
Karl Wiberg45eb1352019-10-10 14:23:00 +0200971 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000972
973 // Insert second packet (decoder will return CNG).
974 payload[0] = 1;
henrik.lundin246ef3e2017-04-24 09:14:32 -0700975 rtp_header.sequenceNumber++;
976 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200977 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000978
Peter Kastingdce40cf2015-08-24 14:52:23 -0700979 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800980 AudioFrame output;
henrik.lundin55480f52016-03-08 02:37:57 -0800981 AudioFrame::SpeechType expected_type[8] = {
Jonas Olssona4d87372019-07-05 19:08:33 +0200982 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech, AudioFrame::kCNG,
983 AudioFrame::kCNG, AudioFrame::kCNG, AudioFrame::kCNG,
984 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000985 int expected_timestamp_increment[8] = {
986 -1, // will not be used.
987 10 * kSampleRateKhz,
Jonas Olssona4d87372019-07-05 19:08:33 +0200988 -1,
989 -1, // timestamp will be empty during CNG mode; indicated by -1 here.
990 -1,
991 -1,
992 50 * kSampleRateKhz,
993 10 * kSampleRateKhz};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000994
henrik.lundin7a926812016-05-12 13:51:28 -0700995 bool muted;
996 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200997 absl::optional<uint32_t> last_timestamp = neteq_->GetPlayoutTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -0700998 ASSERT_TRUE(last_timestamp);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000999
henrik.lundin0d96ab72016-04-06 12:28:26 -07001000 // Lambda for verifying the timestamps.
1001 auto verify_timestamp = [&last_timestamp, &expected_timestamp_increment](
Danil Chapovalovb6021232018-06-19 13:26:36 +02001002 absl::optional<uint32_t> ts, size_t i) {
henrik.lundin0d96ab72016-04-06 12:28:26 -07001003 if (expected_timestamp_increment[i] == -1) {
1004 // Expect to get an empty timestamp value during CNG and PLC.
1005 EXPECT_FALSE(ts) << "i = " << i;
1006 } else {
1007 ASSERT_TRUE(ts) << "i = " << i;
1008 EXPECT_EQ(*ts, *last_timestamp + expected_timestamp_increment[i])
1009 << "i = " << i;
1010 last_timestamp = ts;
1011 }
1012 };
1013
Peter Kastingdce40cf2015-08-24 14:52:23 -07001014 for (size_t i = 1; i < 6; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001015 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1016 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001017 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001018 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001019 SCOPED_TRACE("");
1020 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001021 }
1022
1023 // Insert third packet, which leaves a gap from last packet.
1024 payload[0] = 2;
henrik.lundin246ef3e2017-04-24 09:14:32 -07001025 rtp_header.sequenceNumber += 2;
1026 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001027 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001028
Peter Kastingdce40cf2015-08-24 14:52:23 -07001029 for (size_t i = 6; i < 8; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001030 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1031 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001032 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001033 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001034 SCOPED_TRACE("");
1035 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001036 }
1037
1038 // Now check the packet buffer, and make sure it is empty.
1039 EXPECT_TRUE(packet_buffer_->Empty());
1040
1041 EXPECT_CALL(mock_decoder, Die());
1042}
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001043
1044TEST_F(NetEqImplTest, UnsupportedDecoder) {
1045 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001046 ::testing::NiceMock<MockAudioDecoder> decoder;
1047
1048 CreateInstance(
1049 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&decoder));
minyue5bd33972016-05-02 04:46:11 -07001050 static const size_t kNetEqMaxFrameSize = 5760; // 120 ms @ 48 kHz.
Peter Kasting69558702016-01-12 16:26:35 -08001051 static const size_t kChannels = 2;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001052
1053 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001054 const int kSampleRateHz = 8000;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001055
Peter Kastingdce40cf2015-08-24 14:52:23 -07001056 const size_t kPayloadLengthSamples =
1057 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001058 const size_t kPayloadLengthBytes = 1;
minyue5bd33972016-05-02 04:46:11 -07001059 uint8_t payload[kPayloadLengthBytes] = {0};
Minyue323b1322015-05-25 13:49:37 +02001060 int16_t dummy_output[kPayloadLengthSamples * kChannels] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001061 RTPHeader rtp_header;
1062 rtp_header.payloadType = kPayloadType;
1063 rtp_header.sequenceNumber = 0x1234;
1064 rtp_header.timestamp = 0x12345678;
1065 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001066
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001067 const uint8_t kFirstPayloadValue = 1;
1068 const uint8_t kSecondPayloadValue = 2;
1069
ossu61a208b2016-09-20 01:38:00 -07001070 EXPECT_CALL(decoder,
1071 PacketDuration(Pointee(kFirstPayloadValue), kPayloadLengthBytes))
1072 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001073 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize + 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001074
ossu61a208b2016-09-20 01:38:00 -07001075 EXPECT_CALL(decoder, DecodeInternal(Pointee(kFirstPayloadValue), _, _, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001076 .Times(0);
1077
ossu61a208b2016-09-20 01:38:00 -07001078 EXPECT_CALL(decoder, DecodeInternal(Pointee(kSecondPayloadValue),
1079 kPayloadLengthBytes, kSampleRateHz, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001080 .Times(1)
ossu61a208b2016-09-20 01:38:00 -07001081 .WillOnce(DoAll(
1082 SetArrayArgument<3>(dummy_output,
1083 dummy_output + kPayloadLengthSamples * kChannels),
1084 SetArgPointee<4>(AudioDecoder::kSpeech),
1085 Return(static_cast<int>(kPayloadLengthSamples * kChannels))));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001086
ossu61a208b2016-09-20 01:38:00 -07001087 EXPECT_CALL(decoder,
1088 PacketDuration(Pointee(kSecondPayloadValue), kPayloadLengthBytes))
1089 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001090 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize)));
ossu61a208b2016-09-20 01:38:00 -07001091
Jonas Olssona4d87372019-07-05 19:08:33 +02001092 EXPECT_CALL(decoder, SampleRateHz()).WillRepeatedly(Return(kSampleRateHz));
ossu61a208b2016-09-20 01:38:00 -07001093
Jonas Olssona4d87372019-07-05 19:08:33 +02001094 EXPECT_CALL(decoder, Channels()).WillRepeatedly(Return(kChannels));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001095
Niels Möllera1eb9c72018-12-07 15:24:42 +01001096 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1097 SdpAudioFormat("L16", 8000, 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001098
1099 // Insert one packet.
1100 payload[0] = kFirstPayloadValue; // This will make Decode() fail.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001101 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001102
1103 // Insert another packet.
1104 payload[0] = kSecondPayloadValue; // This will make Decode() successful.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001105 rtp_header.sequenceNumber++;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001106 // The second timestamp needs to be at least 30 ms after the first to make
1107 // the second packet get decoded.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001108 rtp_header.timestamp += 3 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001109 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001110
henrik.lundin6d8e0112016-03-04 10:34:21 -08001111 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001112 bool muted;
henrik.lundin6d8e0112016-03-04 10:34:21 -08001113 // First call to GetAudio will try to decode the "faulty" packet.
Henrik Lundinc417d9e2017-06-14 12:29:03 +02001114 // Expect kFail return value.
henrik.lundin7a926812016-05-12 13:51:28 -07001115 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001116 // Output size and number of channels should be correct.
1117 const size_t kExpectedOutputSize = 10 * (kSampleRateHz / 1000) * kChannels;
1118 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1119 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001120 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001121
henrik.lundin6d8e0112016-03-04 10:34:21 -08001122 // Second call to GetAudio will decode the packet that is ok. No errors are
1123 // expected.
henrik.lundin7a926812016-05-12 13:51:28 -07001124 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001125 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1126 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001127 EXPECT_THAT(output.packet_infos_, SizeIs(1));
ossu61a208b2016-09-20 01:38:00 -07001128
1129 // Die isn't called through NiceMock (since it's called by the
1130 // MockAudioDecoder constructor), so it needs to be mocked explicitly.
1131 EXPECT_CALL(decoder, Die());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001132}
1133
henrik.lundin116c84e2015-08-27 13:14:48 -07001134// This test inserts packets until the buffer is flushed. After that, it asks
1135// NetEq for the network statistics. The purpose of the test is to make sure
1136// that even though the buffer size increment is negative (which it becomes when
1137// the packet causing a flush is inserted), the packet length stored in the
1138// decision logic remains valid.
1139TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) {
1140 UseNoMocks();
1141 CreateInstance();
1142
1143 const size_t kPayloadLengthSamples = 80;
1144 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1145 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin116c84e2015-08-27 13:14:48 -07001146 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001147 RTPHeader rtp_header;
1148 rtp_header.payloadType = kPayloadType;
1149 rtp_header.sequenceNumber = 0x1234;
1150 rtp_header.timestamp = 0x12345678;
1151 rtp_header.ssrc = 0x87654321;
henrik.lundin116c84e2015-08-27 13:14:48 -07001152
Niels Möller05543682019-01-10 16:55:06 +01001153 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1154 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin116c84e2015-08-27 13:14:48 -07001155
1156 // Insert packets until the buffer flushes.
1157 for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) {
1158 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
Karl Wiberg45eb1352019-10-10 14:23:00 +02001159 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -07001160 rtp_header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples);
1161 ++rtp_header.sequenceNumber;
henrik.lundin116c84e2015-08-27 13:14:48 -07001162 }
1163 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
1164
1165 // Ask for network statistics. This should not crash.
1166 NetEqNetworkStatistics stats;
1167 EXPECT_EQ(NetEq::kOK, neteq_->NetworkStatistics(&stats));
1168}
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001169
1170TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
1171 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001172 // Create a mock decoder object.
1173 MockAudioDecoder mock_decoder;
1174
1175 CreateInstance(
1176 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001177
1178 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001179 const int kSampleRateHz = 8000;
1180 const size_t kPayloadLengthSamples =
1181 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
1182 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples;
1183 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001184 RTPHeader rtp_header;
1185 rtp_header.payloadType = kPayloadType;
1186 rtp_header.sequenceNumber = 0x1234;
1187 rtp_header.timestamp = 0x12345678;
1188 rtp_header.ssrc = 0x87654321;
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001189
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001190 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001191 EXPECT_CALL(mock_decoder, SampleRateHz())
1192 .WillRepeatedly(Return(kSampleRateHz));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001193 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001194 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001195 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001196 int16_t dummy_output[kPayloadLengthSamples] = {0};
1197 // The below expectation will make the mock decoder write
1198 // |kPayloadLengthSamples| - 5 zeros to the output array, and mark it as
1199 // speech. That is, the decoded length is 5 samples shorter than the expected.
1200 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001201 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001202 .WillOnce(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001203 DoAll(SetArrayArgument<3>(dummy_output,
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001204 dummy_output + kPayloadLengthSamples - 5),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001205 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001206 Return(rtc::checked_cast<int>(kPayloadLengthSamples - 5))));
Niels Möllera1eb9c72018-12-07 15:24:42 +01001207 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1208 SdpAudioFormat("L16", 8000, 1)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001209
1210 // Insert one packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001211 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001212
1213 EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength());
1214
1215 // Pull audio once.
1216 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001217 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001218 bool muted;
1219 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001220 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1221 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001222 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001223 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001224
1225 EXPECT_CALL(mock_decoder, Die());
1226}
minyuel6d92bf52015-09-23 15:20:39 +02001227
1228// This test checks the behavior of NetEq when audio decoder fails.
1229TEST_F(NetEqImplTest, DecodingError) {
1230 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001231 // Create a mock decoder object.
1232 MockAudioDecoder mock_decoder;
1233
1234 CreateInstance(
1235 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001236
1237 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001238 const int kSampleRateHz = 8000;
1239 const int kDecoderErrorCode = -97; // Any negative number.
1240
1241 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1242 const size_t kFrameLengthSamples =
1243 static_cast<size_t>(5 * kSampleRateHz / 1000);
1244
1245 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1246
1247 uint8_t payload[kPayloadLengthBytes] = {0};
1248
henrik.lundin246ef3e2017-04-24 09:14:32 -07001249 RTPHeader rtp_header;
1250 rtp_header.payloadType = kPayloadType;
1251 rtp_header.sequenceNumber = 0x1234;
1252 rtp_header.timestamp = 0x12345678;
1253 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001254
minyuel6d92bf52015-09-23 15:20:39 +02001255 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001256 EXPECT_CALL(mock_decoder, SampleRateHz())
1257 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001258 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001259 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001260 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001261 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
1262 EXPECT_CALL(mock_decoder, HasDecodePlc()).WillOnce(Return(false));
minyuel6d92bf52015-09-23 15:20:39 +02001263 int16_t dummy_output[kFrameLengthSamples] = {0};
1264
1265 {
1266 InSequence sequence; // Dummy variable.
1267 // Mock decoder works normally the first time.
1268 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001269 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001270 .Times(3)
1271 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001272 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001273 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001274 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001275 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001276 .RetiresOnSaturation();
1277
1278 // Then mock decoder fails. A common reason for failure can be buffer being
1279 // too short
1280 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001281 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001282 .WillOnce(Return(-1))
1283 .RetiresOnSaturation();
1284
1285 // Mock decoder finally returns to normal.
1286 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001287 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001288 .Times(2)
1289 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001290 DoAll(SetArrayArgument<3>(dummy_output,
1291 dummy_output + kFrameLengthSamples),
1292 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001293 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001294 }
1295
Niels Möllera1eb9c72018-12-07 15:24:42 +01001296 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1297 SdpAudioFormat("L16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001298
1299 // Insert packets.
1300 for (int i = 0; i < 6; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001301 rtp_header.sequenceNumber += 1;
1302 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001303 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001304 }
1305
1306 // Pull audio.
1307 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001308 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001309 bool muted;
1310 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001311 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1312 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001313 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001314 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001315
1316 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001317 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001318 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1319 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001320 // We are not expecting anything for output.speech_type_, since an error was
1321 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001322
1323 // Pull audio again, should continue an expansion.
henrik.lundin7a926812016-05-12 13:51:28 -07001324 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001325 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1326 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001327 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001328 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyuel6d92bf52015-09-23 15:20:39 +02001329
1330 // Pull audio again, should behave normal.
henrik.lundin7a926812016-05-12 13:51:28 -07001331 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001332 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1333 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001334 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001335 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001336
1337 EXPECT_CALL(mock_decoder, Die());
1338}
1339
1340// This test checks the behavior of NetEq when audio decoder fails during CNG.
1341TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
1342 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +01001343
1344 // Create a mock decoder object.
1345 MockAudioDecoder mock_decoder;
1346 CreateInstance(
1347 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001348
1349 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001350 const int kSampleRateHz = 8000;
1351 const int kDecoderErrorCode = -97; // Any negative number.
1352
1353 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1354 const size_t kFrameLengthSamples =
1355 static_cast<size_t>(5 * kSampleRateHz / 1000);
1356
1357 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1358
1359 uint8_t payload[kPayloadLengthBytes] = {0};
1360
henrik.lundin246ef3e2017-04-24 09:14:32 -07001361 RTPHeader rtp_header;
1362 rtp_header.payloadType = kPayloadType;
1363 rtp_header.sequenceNumber = 0x1234;
1364 rtp_header.timestamp = 0x12345678;
1365 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001366
minyuel6d92bf52015-09-23 15:20:39 +02001367 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001368 EXPECT_CALL(mock_decoder, SampleRateHz())
1369 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001370 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001371 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001372 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001373 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
minyuel6d92bf52015-09-23 15:20:39 +02001374 int16_t dummy_output[kFrameLengthSamples] = {0};
1375
1376 {
1377 InSequence sequence; // Dummy variable.
1378 // Mock decoder works normally the first 2 times.
1379 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001380 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001381 .Times(2)
1382 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001383 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001384 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001385 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001386 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001387 .RetiresOnSaturation();
1388
1389 // Then mock decoder fails. A common reason for failure can be buffer being
1390 // too short
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001391 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001392 .WillOnce(Return(-1))
1393 .RetiresOnSaturation();
1394
1395 // Mock decoder finally returns to normal.
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001396 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001397 .Times(2)
1398 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001399 DoAll(SetArrayArgument<3>(dummy_output,
1400 dummy_output + kFrameLengthSamples),
1401 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001402 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001403 }
1404
Niels Möller50b66d52018-12-11 14:43:21 +01001405 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1406 SdpAudioFormat("l16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001407
1408 // Insert 2 packets. This will make netEq into codec internal CNG mode.
1409 for (int i = 0; i < 2; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001410 rtp_header.sequenceNumber += 1;
1411 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001412 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001413 }
1414
1415 // Pull audio.
1416 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001417 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001418 bool muted;
1419 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001420 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1421 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001422 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001423
1424 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001425 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001426 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1427 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001428 // We are not expecting anything for output.speech_type_, since an error was
1429 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001430
1431 // Pull audio again, should resume codec CNG.
henrik.lundin7a926812016-05-12 13:51:28 -07001432 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001433 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1434 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001435 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001436
1437 EXPECT_CALL(mock_decoder, Die());
1438}
1439
henrik.lundind89814b2015-11-23 06:49:25 -08001440// Tests that the return value from last_output_sample_rate_hz() is equal to the
1441// configured inital sample rate.
1442TEST_F(NetEqImplTest, InitialLastOutputSampleRate) {
1443 UseNoMocks();
1444 config_.sample_rate_hz = 48000;
1445 CreateInstance();
1446 EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz());
1447}
1448
henrik.lundined497212016-04-25 10:11:38 -07001449TEST_F(NetEqImplTest, TickTimerIncrement) {
1450 UseNoMocks();
1451 CreateInstance();
1452 ASSERT_TRUE(tick_timer_);
1453 EXPECT_EQ(0u, tick_timer_->ticks());
1454 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001455 bool muted;
1456 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundined497212016-04-25 10:11:38 -07001457 EXPECT_EQ(1u, tick_timer_->ticks());
1458}
1459
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001460TEST_F(NetEqImplTest, SetBaseMinimumDelay) {
1461 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001462 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001463 CreateInstance();
1464
Ivo Creusen53a31f72019-10-24 15:20:39 +02001465 EXPECT_CALL(*mock_neteq_controller_, SetBaseMinimumDelay(_))
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001466 .WillOnce(Return(true))
1467 .WillOnce(Return(false));
1468
1469 const int delay_ms = 200;
1470
1471 EXPECT_EQ(true, neteq_->SetBaseMinimumDelayMs(delay_ms));
1472 EXPECT_EQ(false, neteq_->SetBaseMinimumDelayMs(delay_ms));
1473}
1474
1475TEST_F(NetEqImplTest, GetBaseMinimumDelayMs) {
1476 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001477 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001478 CreateInstance();
1479
1480 const int delay_ms = 200;
1481
Ivo Creusen53a31f72019-10-24 15:20:39 +02001482 EXPECT_CALL(*mock_neteq_controller_, GetBaseMinimumDelay())
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001483 .WillOnce(Return(delay_ms));
1484
1485 EXPECT_EQ(delay_ms, neteq_->GetBaseMinimumDelayMs());
1486}
1487
henrik.lundin114c1b32017-04-26 07:47:32 -07001488TEST_F(NetEqImplTest, TargetDelayMs) {
1489 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001490 use_mock_neteq_controller_ = true;
henrik.lundin114c1b32017-04-26 07:47:32 -07001491 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001492 constexpr int kTargetLevelMs = 510;
1493 EXPECT_CALL(*mock_neteq_controller_, TargetLevelMs())
1494 .WillOnce(Return(kTargetLevelMs));
1495 EXPECT_EQ(510, neteq_->TargetDelayMs());
henrik.lundin114c1b32017-04-26 07:47:32 -07001496}
1497
henrik.lundinb8c55b12017-05-10 07:38:01 -07001498TEST_F(NetEqImplTest, InsertEmptyPacket) {
1499 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001500 use_mock_neteq_controller_ = true;
henrik.lundinb8c55b12017-05-10 07:38:01 -07001501 CreateInstance();
1502
1503 RTPHeader rtp_header;
1504 rtp_header.payloadType = 17;
1505 rtp_header.sequenceNumber = 0x1234;
1506 rtp_header.timestamp = 0x12345678;
1507 rtp_header.ssrc = 0x87654321;
1508
Ivo Creusen53a31f72019-10-24 15:20:39 +02001509 EXPECT_CALL(*mock_neteq_controller_, RegisterEmptyPacket());
henrik.lundinb8c55b12017-05-10 07:38:01 -07001510 neteq_->InsertEmptyPacket(rtp_header);
1511}
1512
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001513TEST_F(NetEqImplTest, EnableRtxHandling) {
1514 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001515 use_mock_neteq_controller_ = true;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001516 config_.enable_rtx_handling = true;
1517 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001518 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001519 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001520 .WillOnce(Return(NetEq::Operation::kNormal));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001521
1522 const int kPayloadLengthSamples = 80;
1523 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1524 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001525 uint8_t payload[kPayloadLengthBytes] = {0};
1526 RTPHeader rtp_header;
1527 rtp_header.payloadType = kPayloadType;
1528 rtp_header.sequenceNumber = 0x1234;
1529 rtp_header.timestamp = 0x12345678;
1530 rtp_header.ssrc = 0x87654321;
1531
Niels Möller05543682019-01-10 16:55:06 +01001532 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1533 SdpAudioFormat("l16", 8000, 1)));
Karl Wiberg45eb1352019-10-10 14:23:00 +02001534 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001535 AudioFrame output;
1536 bool muted;
1537 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
1538
1539 // Insert second packet that was sent before the first packet.
1540 rtp_header.sequenceNumber -= 1;
1541 rtp_header.timestamp -= kPayloadLengthSamples;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001542 EXPECT_CALL(*mock_neteq_controller_,
1543 PacketArrived(
1544 /*last_cng_or_dtmf*/ _,
1545 /*packet_length_samples*/ kPayloadLengthSamples,
1546 /*should_update_stats*/ _,
1547 /*main_sequence_number*/ rtp_header.sequenceNumber,
1548 /*main_timestamp*/ rtp_header.timestamp,
1549 /*fs_hz*/ 8000));
1550
Karl Wiberg45eb1352019-10-10 14:23:00 +02001551 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001552}
1553
minyue5bd33972016-05-02 04:46:11 -07001554class Decoder120ms : public AudioDecoder {
1555 public:
kwiberg347d3512016-06-16 01:59:09 -07001556 Decoder120ms(int sample_rate_hz, SpeechType speech_type)
1557 : sample_rate_hz_(sample_rate_hz),
1558 next_value_(1),
minyue5bd33972016-05-02 04:46:11 -07001559 speech_type_(speech_type) {}
1560
1561 int DecodeInternal(const uint8_t* encoded,
1562 size_t encoded_len,
1563 int sample_rate_hz,
1564 int16_t* decoded,
1565 SpeechType* speech_type) override {
kwiberg347d3512016-06-16 01:59:09 -07001566 EXPECT_EQ(sample_rate_hz_, sample_rate_hz);
minyue5bd33972016-05-02 04:46:11 -07001567 size_t decoded_len =
1568 rtc::CheckedDivExact(sample_rate_hz, 1000) * 120 * Channels();
1569 for (size_t i = 0; i < decoded_len; ++i) {
1570 decoded[i] = next_value_++;
1571 }
1572 *speech_type = speech_type_;
Mirko Bonadei737e0732017-10-19 09:00:17 +02001573 return rtc::checked_cast<int>(decoded_len);
minyue5bd33972016-05-02 04:46:11 -07001574 }
1575
1576 void Reset() override { next_value_ = 1; }
kwiberg347d3512016-06-16 01:59:09 -07001577 int SampleRateHz() const override { return sample_rate_hz_; }
minyue5bd33972016-05-02 04:46:11 -07001578 size_t Channels() const override { return 2; }
1579
1580 private:
kwiberg347d3512016-06-16 01:59:09 -07001581 int sample_rate_hz_;
minyue5bd33972016-05-02 04:46:11 -07001582 int16_t next_value_;
1583 SpeechType speech_type_;
1584};
1585
1586class NetEqImplTest120ms : public NetEqImplTest {
1587 protected:
1588 NetEqImplTest120ms() : NetEqImplTest() {}
1589 virtual ~NetEqImplTest120ms() {}
1590
1591 void CreateInstanceNoMocks() {
1592 UseNoMocks();
Niels Möllera0f44302018-11-30 10:45:12 +01001593 CreateInstance(decoder_factory_);
1594 EXPECT_TRUE(neteq_->RegisterPayloadType(
1595 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001596 }
1597
1598 void CreateInstanceWithDelayManagerMock() {
1599 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001600 use_mock_neteq_controller_ = true;
Niels Möllera0f44302018-11-30 10:45:12 +01001601 CreateInstance(decoder_factory_);
1602 EXPECT_TRUE(neteq_->RegisterPayloadType(
1603 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001604 }
1605
1606 uint32_t timestamp_diff_between_packets() const {
1607 return rtc::CheckedDivExact(kSamplingFreq_, 1000u) * 120;
1608 }
1609
1610 uint32_t first_timestamp() const { return 10u; }
1611
1612 void GetFirstPacket() {
henrik.lundin7a926812016-05-12 13:51:28 -07001613 bool muted;
minyue5bd33972016-05-02 04:46:11 -07001614 for (int i = 0; i < 12; i++) {
henrik.lundin7a926812016-05-12 13:51:28 -07001615 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
1616 EXPECT_FALSE(muted);
minyue5bd33972016-05-02 04:46:11 -07001617 }
1618 }
1619
1620 void InsertPacket(uint32_t timestamp) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001621 RTPHeader rtp_header;
1622 rtp_header.payloadType = kPayloadType;
1623 rtp_header.sequenceNumber = sequence_number_;
1624 rtp_header.timestamp = timestamp;
1625 rtp_header.ssrc = 15;
minyue5bd33972016-05-02 04:46:11 -07001626 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1627 uint8_t payload[kPayloadLengthBytes] = {0};
Karl Wiberg45eb1352019-10-10 14:23:00 +02001628 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue5bd33972016-05-02 04:46:11 -07001629 sequence_number_++;
1630 }
1631
1632 void Register120msCodec(AudioDecoder::SpeechType speech_type) {
Niels Möllera0f44302018-11-30 10:45:12 +01001633 const uint32_t sampling_freq = kSamplingFreq_;
1634 decoder_factory_ =
1635 new rtc::RefCountedObject<test::FunctionAudioDecoderFactory>(
1636 [sampling_freq, speech_type]() {
1637 std::unique_ptr<AudioDecoder> decoder =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001638 std::make_unique<Decoder120ms>(sampling_freq, speech_type);
Niels Möllera0f44302018-11-30 10:45:12 +01001639 RTC_CHECK_EQ(2, decoder->Channels());
1640 return decoder;
1641 });
minyue5bd33972016-05-02 04:46:11 -07001642 }
1643
Niels Möllera0f44302018-11-30 10:45:12 +01001644 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
minyue5bd33972016-05-02 04:46:11 -07001645 AudioFrame output_;
1646 const uint32_t kPayloadType = 17;
1647 const uint32_t kSamplingFreq_ = 48000;
1648 uint16_t sequence_number_ = 1;
1649};
1650
minyue5bd33972016-05-02 04:46:11 -07001651TEST_F(NetEqImplTest120ms, CodecInternalCng) {
minyue5bd33972016-05-02 04:46:11 -07001652 Register120msCodec(AudioDecoder::kComfortNoise);
Niels Möllera0f44302018-11-30 10:45:12 +01001653 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001654
1655 InsertPacket(first_timestamp());
1656 GetFirstPacket();
1657
henrik.lundin7a926812016-05-12 13:51:28 -07001658 bool muted;
1659 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001660 EXPECT_EQ(NetEq::Operation::kCodecInternalCng,
1661 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001662}
1663
1664TEST_F(NetEqImplTest120ms, Normal) {
minyue5bd33972016-05-02 04:46:11 -07001665 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001666 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001667
1668 InsertPacket(first_timestamp());
1669 GetFirstPacket();
1670
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001671 EXPECT_EQ(NetEq::Operation::kNormal, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001672}
1673
1674TEST_F(NetEqImplTest120ms, Merge) {
Niels Möllera0f44302018-11-30 10:45:12 +01001675 Register120msCodec(AudioDecoder::kSpeech);
minyue5bd33972016-05-02 04:46:11 -07001676 CreateInstanceWithDelayManagerMock();
1677
Ivo Creusen53a31f72019-10-24 15:20:39 +02001678 EXPECT_CALL(*mock_neteq_controller_, CngOff()).WillRepeatedly(Return(true));
minyue5bd33972016-05-02 04:46:11 -07001679 InsertPacket(first_timestamp());
1680
1681 GetFirstPacket();
henrik.lundin7a926812016-05-12 13:51:28 -07001682 bool muted;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001683 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001684 .WillOnce(Return(NetEq::Operation::kExpand));
henrik.lundin7a926812016-05-12 13:51:28 -07001685 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
minyue5bd33972016-05-02 04:46:11 -07001686
1687 InsertPacket(first_timestamp() + 2 * timestamp_diff_between_packets());
1688
Ivo Creusen53a31f72019-10-24 15:20:39 +02001689 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001690 .WillOnce(Return(NetEq::Operation::kMerge));
minyue5bd33972016-05-02 04:46:11 -07001691
henrik.lundin7a926812016-05-12 13:51:28 -07001692 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001693 EXPECT_EQ(NetEq::Operation::kMerge, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001694}
1695
1696TEST_F(NetEqImplTest120ms, Expand) {
minyue5bd33972016-05-02 04:46:11 -07001697 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001698 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001699
1700 InsertPacket(first_timestamp());
1701 GetFirstPacket();
1702
henrik.lundin7a926812016-05-12 13:51:28 -07001703 bool muted;
1704 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001705 EXPECT_EQ(NetEq::Operation::kExpand, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001706}
1707
1708TEST_F(NetEqImplTest120ms, FastAccelerate) {
minyue5bd33972016-05-02 04:46:11 -07001709 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001710 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001711
1712 InsertPacket(first_timestamp());
1713 GetFirstPacket();
1714 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1715
Ivo Creusen53a31f72019-10-24 15:20:39 +02001716 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001717 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001718 .WillOnce(Return(NetEq::Operation::kFastAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001719
henrik.lundin7a926812016-05-12 13:51:28 -07001720 bool muted;
1721 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001722 EXPECT_EQ(NetEq::Operation::kFastAccelerate,
1723 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001724}
1725
1726TEST_F(NetEqImplTest120ms, PreemptiveExpand) {
minyue5bd33972016-05-02 04:46:11 -07001727 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001728 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001729
1730 InsertPacket(first_timestamp());
1731 GetFirstPacket();
1732
1733 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1734
Ivo Creusen53a31f72019-10-24 15:20:39 +02001735 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001736 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001737 .WillOnce(Return(NetEq::Operation::kPreemptiveExpand));
minyue5bd33972016-05-02 04:46:11 -07001738
henrik.lundin7a926812016-05-12 13:51:28 -07001739 bool muted;
1740 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001741 EXPECT_EQ(NetEq::Operation::kPreemptiveExpand,
1742 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001743}
1744
1745TEST_F(NetEqImplTest120ms, Accelerate) {
minyue5bd33972016-05-02 04:46:11 -07001746 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001747 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001748
1749 InsertPacket(first_timestamp());
1750 GetFirstPacket();
1751
1752 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1753
Ivo Creusen53a31f72019-10-24 15:20:39 +02001754 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001755 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001756 .WillOnce(Return(NetEq::Operation::kAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001757
henrik.lundin7a926812016-05-12 13:51:28 -07001758 bool muted;
1759 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001760 EXPECT_EQ(NetEq::Operation::kAccelerate, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001761}
1762
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001763} // namespace webrtc