blob: 5c7259f00bd1fba3b8f4ac96f9801d110beac0f4 [file] [log] [blame]
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/audio_coding/neteq/neteq_impl.h"
12
kwiberg84be5112016-04-27 01:19:58 -070013#include <memory>
Alessio Bazzica8f319a32019-07-24 16:47:02 +000014#include <utility>
15#include <vector>
kwiberg84be5112016-04-27 01:19:58 -070016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Ivo Creusen3ce44a32019-10-31 14:38:11 +010018#include "api/neteq/default_neteq_controller_factory.h"
19#include "api/neteq/neteq.h"
20#include "api/neteq/neteq_controller.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/audio_coding/neteq/accelerate.h"
Ivo Creusen53a31f72019-10-24 15:20:39 +020022#include "modules/audio_coding/neteq/decision_logic.h"
Ivo Creusen39cf3c72019-11-28 14:07:14 +010023#include "modules/audio_coding/neteq/default_neteq_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "modules/audio_coding/neteq/expand.h"
Jakob Ivarsson1eb3d7e2019-02-21 15:42:31 +010025#include "modules/audio_coding/neteq/histogram.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/audio_coding/neteq/mock/mock_dtmf_buffer.h"
28#include "modules/audio_coding/neteq/mock/mock_dtmf_tone_generator.h"
Ivo Creusen53a31f72019-10-24 15:20:39 +020029#include "modules/audio_coding/neteq/mock/mock_neteq_controller.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "modules/audio_coding/neteq/mock/mock_packet_buffer.h"
31#include "modules/audio_coding/neteq/mock/mock_red_payload_splitter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "modules/audio_coding/neteq/preemptive_expand.h"
Jakob Ivarsson44507082019-03-05 16:59:03 +010033#include "modules/audio_coding/neteq/statistics_calculator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "modules/audio_coding/neteq/sync_buffer.h"
35#include "modules/audio_coding/neteq/timestamp_scaler.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010036#include "rtc_base/numerics/safe_conversions.h"
Alessio Bazzica8f319a32019-07-24 16:47:02 +000037#include "system_wrappers/include/clock.h"
Niels Möllerb7180c02018-12-06 13:07:11 +010038#include "test/audio_decoder_proxy_factory.h"
Niels Möllera0f44302018-11-30 10:45:12 +010039#include "test/function_audio_decoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020040#include "test/gmock.h"
41#include "test/gtest.h"
42#include "test/mock_audio_decoder.h"
43#include "test/mock_audio_decoder_factory.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000044
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000045using ::testing::_;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010046using ::testing::AtLeast;
47using ::testing::DoAll;
Alessio Bazzica8f319a32019-07-24 16:47:02 +000048using ::testing::ElementsAre;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000049using ::testing::InSequence;
50using ::testing::Invoke;
Alessio Bazzica8f319a32019-07-24 16:47:02 +000051using ::testing::IsEmpty;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +000052using ::testing::IsNull;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010053using ::testing::Pointee;
54using ::testing::Return;
55using ::testing::ReturnNull;
56using ::testing::SetArgPointee;
57using ::testing::SetArrayArgument;
Alessio Bazzica8f319a32019-07-24 16:47:02 +000058using ::testing::SizeIs;
Mirko Bonadeie46f5db2019-03-26 20:14:46 +010059using ::testing::WithArg;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000060
61namespace webrtc {
62
63// This function is called when inserting a packet list into the mock packet
64// buffer. The purpose is to delete all inserted packets properly, to avoid
65// memory leaks in the test.
66int DeletePacketsAndReturnOk(PacketList* packet_list) {
ossua73f6c92016-10-24 08:25:28 -070067 packet_list->clear();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000068 return PacketBuffer::kOK;
69}
70
71class NetEqImplTest : public ::testing::Test {
72 protected:
Alessio Bazzica8f319a32019-07-24 16:47:02 +000073 NetEqImplTest() : clock_(0) { config_.sample_rate_hz = 8000; }
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000074
Niels Möllera0f44302018-11-30 10:45:12 +010075 void CreateInstance(
76 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) {
77 ASSERT_TRUE(decoder_factory);
Ivo Creusen3ce44a32019-10-31 14:38:11 +010078 NetEqImpl::Dependencies deps(config_, &clock_, decoder_factory,
79 DefaultNetEqControllerFactory());
henrik.lundin1d9061e2016-04-26 12:19:34 -070080
81 // Get a local pointer to NetEq's TickTimer object.
82 tick_timer_ = deps.tick_timer.get();
83
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000084 if (use_mock_decoder_database_) {
henrik.lundin1d9061e2016-04-26 12:19:34 -070085 std::unique_ptr<MockDecoderDatabase> mock(new MockDecoderDatabase);
86 mock_decoder_database_ = mock.get();
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000087 EXPECT_CALL(*mock_decoder_database_, GetActiveCngDecoder())
88 .WillOnce(ReturnNull());
henrik.lundin1d9061e2016-04-26 12:19:34 -070089 deps.decoder_database = std::move(mock);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +000090 }
henrik.lundin1d9061e2016-04-26 12:19:34 -070091 decoder_database_ = deps.decoder_database.get();
henrik.lundin@webrtc.orgd9faa462014-01-14 10:18:45 +000092
henrik.lundin1d9061e2016-04-26 12:19:34 -070093 if (use_mock_dtmf_buffer_) {
94 std::unique_ptr<MockDtmfBuffer> mock(
95 new MockDtmfBuffer(config_.sample_rate_hz));
96 mock_dtmf_buffer_ = mock.get();
97 deps.dtmf_buffer = std::move(mock);
98 }
99 dtmf_buffer_ = deps.dtmf_buffer.get();
100
101 if (use_mock_dtmf_tone_generator_) {
102 std::unique_ptr<MockDtmfToneGenerator> mock(new MockDtmfToneGenerator);
103 mock_dtmf_tone_generator_ = mock.get();
104 deps.dtmf_tone_generator = std::move(mock);
105 }
106 dtmf_tone_generator_ = deps.dtmf_tone_generator.get();
107
108 if (use_mock_packet_buffer_) {
109 std::unique_ptr<MockPacketBuffer> mock(
110 new MockPacketBuffer(config_.max_packets_in_buffer, tick_timer_));
111 mock_packet_buffer_ = mock.get();
112 deps.packet_buffer = std::move(mock);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700113 }
114 packet_buffer_ = deps.packet_buffer.get();
115
Ivo Creusen53a31f72019-10-24 15:20:39 +0200116 if (use_mock_neteq_controller_) {
117 std::unique_ptr<MockNetEqController> mock(new MockNetEqController());
118 mock_neteq_controller_ = mock.get();
119 deps.neteq_controller = std::move(mock);
120 } else {
121 deps.stats = std::make_unique<StatisticsCalculator>();
122 NetEqController::Config controller_config;
123 controller_config.tick_timer = tick_timer_;
124 controller_config.base_min_delay_ms = config_.min_delay_ms;
125 controller_config.enable_rtx_handling = config_.enable_rtx_handling;
126 controller_config.allow_time_stretching = true;
127 controller_config.max_packets_in_buffer = config_.max_packets_in_buffer;
Ivo Creusen88636c62020-01-24 11:04:56 +0100128 controller_config.clock = &clock_;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200129 deps.neteq_controller =
130 std::make_unique<DecisionLogic>(std::move(controller_config));
131 }
132 neteq_controller_ = deps.neteq_controller.get();
133
henrik.lundin1d9061e2016-04-26 12:19:34 -0700134 if (use_mock_payload_splitter_) {
ossua70695a2016-09-22 02:06:28 -0700135 std::unique_ptr<MockRedPayloadSplitter> mock(new MockRedPayloadSplitter);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700136 mock_payload_splitter_ = mock.get();
ossua70695a2016-09-22 02:06:28 -0700137 deps.red_payload_splitter = std::move(mock);
henrik.lundin1d9061e2016-04-26 12:19:34 -0700138 }
ossua70695a2016-09-22 02:06:28 -0700139 red_payload_splitter_ = deps.red_payload_splitter.get();
henrik.lundin1d9061e2016-04-26 12:19:34 -0700140
141 deps.timestamp_scaler = std::unique_ptr<TimestampScaler>(
142 new TimestampScaler(*deps.decoder_database.get()));
143
144 neteq_.reset(new NetEqImpl(config_, std::move(deps)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000145 ASSERT_TRUE(neteq_ != NULL);
146 }
147
Niels Möllera0f44302018-11-30 10:45:12 +0100148 void CreateInstance() { CreateInstance(CreateBuiltinAudioDecoderFactory()); }
149
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000150 void UseNoMocks() {
151 ASSERT_TRUE(neteq_ == NULL) << "Must call UseNoMocks before CreateInstance";
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000152 use_mock_decoder_database_ = false;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200153 use_mock_neteq_controller_ = false;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000154 use_mock_dtmf_buffer_ = false;
155 use_mock_dtmf_tone_generator_ = false;
156 use_mock_packet_buffer_ = false;
157 use_mock_payload_splitter_ = false;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000158 }
159
160 virtual ~NetEqImplTest() {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000161 if (use_mock_decoder_database_) {
162 EXPECT_CALL(*mock_decoder_database_, Die()).Times(1);
163 }
Ivo Creusen53a31f72019-10-24 15:20:39 +0200164 if (use_mock_neteq_controller_) {
165 EXPECT_CALL(*mock_neteq_controller_, Die()).Times(1);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000166 }
167 if (use_mock_dtmf_buffer_) {
168 EXPECT_CALL(*mock_dtmf_buffer_, Die()).Times(1);
169 }
170 if (use_mock_dtmf_tone_generator_) {
171 EXPECT_CALL(*mock_dtmf_tone_generator_, Die()).Times(1);
172 }
173 if (use_mock_packet_buffer_) {
174 EXPECT_CALL(*mock_packet_buffer_, Die()).Times(1);
175 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000176 }
177
Niels Möller05543682019-01-10 16:55:06 +0100178 void TestDtmfPacket(int sample_rate_hz) {
solenberg2779bab2016-11-17 04:45:19 -0800179 const size_t kPayloadLength = 4;
180 const uint8_t kPayloadType = 110;
solenberg2779bab2016-11-17 04:45:19 -0800181 const int kSampleRateHz = 16000;
182 config_.sample_rate_hz = kSampleRateHz;
183 UseNoMocks();
184 CreateInstance();
185 // Event: 2, E bit, Volume: 17, Length: 4336.
Jonas Olssona4d87372019-07-05 19:08:33 +0200186 uint8_t payload[kPayloadLength] = {0x02, 0x80 + 0x11, 0x10, 0xF0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700187 RTPHeader rtp_header;
188 rtp_header.payloadType = kPayloadType;
189 rtp_header.sequenceNumber = 0x1234;
190 rtp_header.timestamp = 0x12345678;
191 rtp_header.ssrc = 0x87654321;
solenberg2779bab2016-11-17 04:45:19 -0800192
Niels Möller05543682019-01-10 16:55:06 +0100193 EXPECT_TRUE(neteq_->RegisterPayloadType(
194 kPayloadType, SdpAudioFormat("telephone-event", sample_rate_hz, 1)));
solenberg2779bab2016-11-17 04:45:19 -0800195
196 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200197 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
solenberg2779bab2016-11-17 04:45:19 -0800198
199 // Pull audio once.
200 const size_t kMaxOutputSize =
201 static_cast<size_t>(10 * kSampleRateHz / 1000);
202 AudioFrame output;
203 bool muted;
204 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
205 ASSERT_FALSE(muted);
206 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
207 EXPECT_EQ(1u, output.num_channels_);
208 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
209
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000210 // DTMF packets are immediately consumed by |InsertPacket()| and won't be
211 // returned by |GetAudio()|.
212 EXPECT_THAT(output.packet_infos_, IsEmpty());
213
solenberg2779bab2016-11-17 04:45:19 -0800214 // Verify first 64 samples of actual output.
Jonas Olssona4d87372019-07-05 19:08:33 +0200215 const std::vector<int16_t> kOutput(
216 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 -1578, -2816, -3460, -3403, -2709, -1594, -363, 671, 1269, 1328,
218 908, 202, -513, -964, -955, -431, 504, 1617, 2602, 3164,
219 3101, 2364, 1073, -511, -2047, -3198, -3721, -3525, -2688, -1440,
220 -99, 1015, 1663, 1744, 1319, 588, -171, -680, -747, -315,
221 515, 1512, 2378, 2828, 2674, 1877, 568, -986, -2446, -3482,
222 -3864, -3516, -2534, -1163});
solenberg2779bab2016-11-17 04:45:19 -0800223 ASSERT_GE(kMaxOutputSize, kOutput.size());
yujo36b1a5f2017-06-12 12:45:32 -0700224 EXPECT_TRUE(std::equal(kOutput.begin(), kOutput.end(), output.data()));
solenberg2779bab2016-11-17 04:45:19 -0800225 }
226
henrik.lundin1d9061e2016-04-26 12:19:34 -0700227 std::unique_ptr<NetEqImpl> neteq_;
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000228 NetEq::Config config_;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000229 SimulatedClock clock_;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700230 TickTimer* tick_timer_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700231 MockDecoderDatabase* mock_decoder_database_ = nullptr;
232 DecoderDatabase* decoder_database_ = nullptr;
233 bool use_mock_decoder_database_ = true;
Ivo Creusen53a31f72019-10-24 15:20:39 +0200234 MockNetEqController* mock_neteq_controller_ = nullptr;
235 NetEqController* neteq_controller_ = nullptr;
236 bool use_mock_neteq_controller_ = true;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700237 MockDtmfBuffer* mock_dtmf_buffer_ = nullptr;
238 DtmfBuffer* dtmf_buffer_ = nullptr;
239 bool use_mock_dtmf_buffer_ = true;
240 MockDtmfToneGenerator* mock_dtmf_tone_generator_ = nullptr;
241 DtmfToneGenerator* dtmf_tone_generator_ = nullptr;
242 bool use_mock_dtmf_tone_generator_ = true;
243 MockPacketBuffer* mock_packet_buffer_ = nullptr;
244 PacketBuffer* packet_buffer_ = nullptr;
245 bool use_mock_packet_buffer_ = true;
ossua70695a2016-09-22 02:06:28 -0700246 MockRedPayloadSplitter* mock_payload_splitter_ = nullptr;
247 RedPayloadSplitter* red_payload_splitter_ = nullptr;
henrik.lundin1d9061e2016-04-26 12:19:34 -0700248 bool use_mock_payload_splitter_ = true;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000249};
250
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000251// This tests the interface class NetEq.
252// TODO(hlundin): Move to separate file?
253TEST(NetEq, CreateAndDestroy) {
henrik.lundin@webrtc.org35ead382014-04-14 18:49:17 +0000254 NetEq::Config config;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000255 SimulatedClock clock(0);
Ivo Creusen39cf3c72019-11-28 14:07:14 +0100256 auto decoder_factory = CreateBuiltinAudioDecoderFactory();
257 std::unique_ptr<NetEq> neteq =
258 DefaultNetEqFactory().CreateNetEq(config, decoder_factory, &clock);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000259}
260
kwiberg5adaf732016-10-04 09:33:27 -0700261TEST_F(NetEqImplTest, RegisterPayloadType) {
262 CreateInstance();
263 constexpr int rtp_payload_type = 0;
264 const SdpAudioFormat format("pcmu", 8000, 1);
265 EXPECT_CALL(*mock_decoder_database_,
266 RegisterPayload(rtp_payload_type, format));
267 neteq_->RegisterPayloadType(rtp_payload_type, format);
268}
269
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000270TEST_F(NetEqImplTest, RemovePayloadType) {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000271 CreateInstance();
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000272 uint8_t rtp_payload_type = 0;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000273 EXPECT_CALL(*mock_decoder_database_, Remove(rtp_payload_type))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000274 .WillOnce(Return(DecoderDatabase::kDecoderNotFound));
Henrik Lundinc417d9e2017-06-14 12:29:03 +0200275 // Check that kOK is returned when database returns kDecoderNotFound, because
276 // removing a payload type that was never registered is not an error.
277 EXPECT_EQ(NetEq::kOK, neteq_->RemovePayloadType(rtp_payload_type));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000278}
279
kwiberg6b19b562016-09-20 04:02:25 -0700280TEST_F(NetEqImplTest, RemoveAllPayloadTypes) {
281 CreateInstance();
282 EXPECT_CALL(*mock_decoder_database_, RemoveAll()).WillOnce(Return());
283 neteq_->RemoveAllPayloadTypes();
284}
285
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000286TEST_F(NetEqImplTest, InsertPacket) {
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000287 CreateInstance();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000288 const size_t kPayloadLength = 100;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000289 const uint8_t kPayloadType = 0;
290 const uint16_t kFirstSequenceNumber = 0x1234;
291 const uint32_t kFirstTimestamp = 0x12345678;
292 const uint32_t kSsrc = 0x87654321;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000293 uint8_t payload[kPayloadLength] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700294 RTPHeader rtp_header;
295 rtp_header.payloadType = kPayloadType;
296 rtp_header.sequenceNumber = kFirstSequenceNumber;
297 rtp_header.timestamp = kFirstTimestamp;
298 rtp_header.ssrc = kSsrc;
ossu7a377612016-10-18 04:06:13 -0700299 Packet fake_packet;
300 fake_packet.payload_type = kPayloadType;
301 fake_packet.sequence_number = kFirstSequenceNumber;
302 fake_packet.timestamp = kFirstTimestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000303
kwibergc0f2dcf2016-05-31 06:28:03 -0700304 rtc::scoped_refptr<MockAudioDecoderFactory> mock_decoder_factory(
305 new rtc::RefCountedObject<MockAudioDecoderFactory>);
Karl Wibergd6fbf2a2018-02-27 13:37:31 +0100306 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _, _))
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800307 .WillOnce(Invoke([&](const SdpAudioFormat& format,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200308 absl::optional<AudioCodecPairId> codec_pair_id,
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800309 std::unique_ptr<AudioDecoder>* dec) {
kwibergc0f2dcf2016-05-31 06:28:03 -0700310 EXPECT_EQ("pcmu", format.name);
311
312 std::unique_ptr<MockAudioDecoder> mock_decoder(new MockAudioDecoder);
313 EXPECT_CALL(*mock_decoder, Channels()).WillRepeatedly(Return(1));
314 EXPECT_CALL(*mock_decoder, SampleRateHz()).WillRepeatedly(Return(8000));
kwibergc0f2dcf2016-05-31 06:28:03 -0700315 EXPECT_CALL(*mock_decoder, Die()).Times(1); // Called when deleted.
316
317 *dec = std::move(mock_decoder);
318 }));
Niels Möller72899062019-01-11 09:36:13 +0100319 DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
320 absl::nullopt, mock_decoder_factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000321
322 // Expectations for decoder database.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000323 EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000324 .WillRepeatedly(Return(&info));
325
326 // Expectations for packet buffer.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000327 EXPECT_CALL(*mock_packet_buffer_, Empty())
328 .WillOnce(Return(false)); // Called once after first packet is inserted.
Jonas Olssona4d87372019-07-05 19:08:33 +0200329 EXPECT_CALL(*mock_packet_buffer_, Flush()).Times(1);
minyue-webrtc12d30842017-07-19 11:44:06 +0200330 EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _, _))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000331 .Times(2)
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100332 .WillRepeatedly(DoAll(SetArgPointee<2>(kPayloadType),
333 WithArg<0>(Invoke(DeletePacketsAndReturnOk))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000334 // SetArgPointee<2>(kPayloadType) means that the third argument (zero-based
335 // index) is a pointer, and the variable pointed to is set to kPayloadType.
336 // Also invoke the function DeletePacketsAndReturnOk to properly delete all
337 // packets in the list (to avoid memory leaks in the test).
ossu7a377612016-10-18 04:06:13 -0700338 EXPECT_CALL(*mock_packet_buffer_, PeekNextPacket())
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000339 .Times(1)
ossu7a377612016-10-18 04:06:13 -0700340 .WillOnce(Return(&fake_packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000341
342 // Expectations for DTMF buffer.
Jonas Olssona4d87372019-07-05 19:08:33 +0200343 EXPECT_CALL(*mock_dtmf_buffer_, Flush()).Times(1);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000344
345 // Expectations for delay manager.
346 {
347 // All expectations within this block must be called in this specific order.
348 InSequence sequence; // Dummy variable.
349 // Expectations when the first packet is inserted.
Ivo Creusen53a31f72019-10-24 15:20:39 +0200350 EXPECT_CALL(*mock_neteq_controller_,
351 PacketArrived(/*last_cng_or_dtmf*/ false,
352 /*packet_length_samples*/ _,
353 /*should_update_stats*/ _,
354 /*main_sequence_number*/ kFirstSequenceNumber,
355 /*main_timestamp*/ kFirstTimestamp,
356 /*fs_hz*/ 8000));
357 EXPECT_CALL(*mock_neteq_controller_,
358 PacketArrived(/*last_cng_or_dtmf*/ false,
359 /*packet_length_samples*/ _,
360 /*should_update_stats*/ _,
361 /*main_sequence_number*/ kFirstSequenceNumber + 1,
362 /*main_timestamp*/ kFirstTimestamp + 160,
363 /*fs_hz*/ 8000));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000364 }
365
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000366 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200367 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000368
369 // Insert second packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700370 rtp_header.timestamp += 160;
371 rtp_header.sequenceNumber += 1;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200372 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000373}
374
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000375TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
376 UseNoMocks();
377 CreateInstance();
378
379 const int kPayloadLengthSamples = 80;
380 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
Jonas Olssona4d87372019-07-05 19:08:33 +0200381 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000382 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700383 RTPHeader rtp_header;
384 rtp_header.payloadType = kPayloadType;
385 rtp_header.sequenceNumber = 0x1234;
386 rtp_header.timestamp = 0x12345678;
387 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000388
Niels Möller05543682019-01-10 16:55:06 +0100389 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
390 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000391
392 // Insert packets. The buffer should not flush.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700393 for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) {
Karl Wiberg45eb1352019-10-10 14:23:00 +0200394 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700395 rtp_header.timestamp += kPayloadLengthSamples;
396 rtp_header.sequenceNumber += 1;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000397 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
398 }
399
400 // Insert one more packet and make sure the buffer got flushed. That is, it
401 // should only hold one single packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200402 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700403 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700404 const Packet* test_packet = packet_buffer_->PeekNextPacket();
henrik.lundin246ef3e2017-04-24 09:14:32 -0700405 EXPECT_EQ(rtp_header.timestamp, test_packet->timestamp);
406 EXPECT_EQ(rtp_header.sequenceNumber, test_packet->sequence_number);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000407}
408
solenberg2779bab2016-11-17 04:45:19 -0800409TEST_F(NetEqImplTest, TestDtmfPacketAVT) {
Niels Möller05543682019-01-10 16:55:06 +0100410 TestDtmfPacket(8000);
solenberg2779bab2016-11-17 04:45:19 -0800411}
solenberg99df6c02016-10-11 04:35:34 -0700412
solenberg2779bab2016-11-17 04:45:19 -0800413TEST_F(NetEqImplTest, TestDtmfPacketAVT16kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100414 TestDtmfPacket(16000);
solenberg2779bab2016-11-17 04:45:19 -0800415}
solenberg99df6c02016-10-11 04:35:34 -0700416
solenberg2779bab2016-11-17 04:45:19 -0800417TEST_F(NetEqImplTest, TestDtmfPacketAVT32kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100418 TestDtmfPacket(32000);
solenberg2779bab2016-11-17 04:45:19 -0800419}
solenberg99df6c02016-10-11 04:35:34 -0700420
solenberg2779bab2016-11-17 04:45:19 -0800421TEST_F(NetEqImplTest, TestDtmfPacketAVT48kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100422 TestDtmfPacket(48000);
solenberg99df6c02016-10-11 04:35:34 -0700423}
424
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000425// This test verifies that timestamps propagate from the incoming packets
426// through to the sync buffer and to the playout timestamp.
427TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000428 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000429 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700430 const size_t kPayloadLengthSamples =
431 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000432 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
433 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700434 RTPHeader rtp_header;
435 rtp_header.payloadType = kPayloadType;
436 rtp_header.sequenceNumber = 0x1234;
437 rtp_header.timestamp = 0x12345678;
438 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000439 rtp_header.numCSRCs = 3;
440 rtp_header.arrOfCSRCs[0] = 43;
441 rtp_header.arrOfCSRCs[1] = 65;
442 rtp_header.arrOfCSRCs[2] = 17;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000443
444 // This is a dummy decoder that produces as many output samples as the input
445 // has bytes. The output is an increasing series, starting at 1 for the first
446 // sample, and then increasing by 1 for each sample.
447 class CountingSamplesDecoder : public AudioDecoder {
448 public:
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000449 CountingSamplesDecoder() : next_value_(1) {}
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000450
451 // Produce as many samples as input bytes (|encoded_len|).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100452 int DecodeInternal(const uint8_t* encoded,
453 size_t encoded_len,
454 int /* sample_rate_hz */,
455 int16_t* decoded,
456 SpeechType* speech_type) override {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000457 for (size_t i = 0; i < encoded_len; ++i) {
458 decoded[i] = next_value_++;
459 }
460 *speech_type = kSpeech;
Mirko Bonadei737e0732017-10-19 09:00:17 +0200461 return rtc::checked_cast<int>(encoded_len);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000462 }
463
Karl Wiberg43766482015-08-27 15:22:11 +0200464 void Reset() override { next_value_ = 1; }
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000465
kwiberg347d3512016-06-16 01:59:09 -0700466 int SampleRateHz() const override { return kSampleRateHz; }
467
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000468 size_t Channels() const override { return 1; }
469
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000470 uint16_t next_value() const { return next_value_; }
471
472 private:
473 int16_t next_value_;
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000474 } decoder_;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000475
Niels Möllerb7180c02018-12-06 13:07:11 +0100476 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory =
477 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&decoder_);
478
479 UseNoMocks();
480 CreateInstance(decoder_factory);
481
482 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
Niels Möllera1eb9c72018-12-07 15:24:42 +0100483 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000484
485 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000486 clock_.AdvanceTimeMilliseconds(123456);
487 int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200488 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000489
490 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700491 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800492 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700493 bool muted;
494 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
495 ASSERT_FALSE(muted);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800496 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
497 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800498 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000499
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000500 // Verify |output.packet_infos_|.
501 ASSERT_THAT(output.packet_infos_, SizeIs(1));
502 {
503 const auto& packet_info = output.packet_infos_[0];
504 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
505 EXPECT_THAT(packet_info.csrcs(), ElementsAre(43, 65, 17));
506 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
507 EXPECT_FALSE(packet_info.audio_level().has_value());
508 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
509 }
510
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000511 // Start with a simple check that the fake decoder is behaving as expected.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700512 EXPECT_EQ(kPayloadLengthSamples,
513 static_cast<size_t>(decoder_.next_value() - 1));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000514
515 // The value of the last of the output samples is the same as the number of
516 // samples played from the decoded packet. Thus, this number + the RTP
517 // timestamp should match the playout timestamp.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200518 // Wrap the expected value in an absl::optional to compare them as such.
henrik.lundin9a410dd2016-04-06 01:39:22 -0700519 EXPECT_EQ(
Danil Chapovalovb6021232018-06-19 13:26:36 +0200520 absl::optional<uint32_t>(rtp_header.timestamp +
521 output.data()[output.samples_per_channel_ - 1]),
henrik.lundin9a410dd2016-04-06 01:39:22 -0700522 neteq_->GetPlayoutTimestamp());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000523
524 // Check the timestamp for the last value in the sync buffer. This should
525 // be one full frame length ahead of the RTP timestamp.
526 const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
527 ASSERT_TRUE(sync_buffer != NULL);
henrik.lundin246ef3e2017-04-24 09:14:32 -0700528 EXPECT_EQ(rtp_header.timestamp + kPayloadLengthSamples,
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000529 sync_buffer->end_timestamp());
530
531 // Check that the number of samples still to play from the sync buffer add
532 // up with what was already played out.
henrik.lundin6d8e0112016-03-04 10:34:21 -0800533 EXPECT_EQ(
yujo36b1a5f2017-06-12 12:45:32 -0700534 kPayloadLengthSamples - output.data()[output.samples_per_channel_ - 1],
henrik.lundin6d8e0112016-03-04 10:34:21 -0800535 sync_buffer->FutureLength());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000536}
537
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000538TEST_F(NetEqImplTest, ReorderedPacket) {
539 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +0100540 // Create a mock decoder object.
541 MockAudioDecoder mock_decoder;
542
543 CreateInstance(
544 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000545
546 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000547 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700548 const size_t kPayloadLengthSamples =
549 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000550 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
551 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700552 RTPHeader rtp_header;
553 rtp_header.payloadType = kPayloadType;
554 rtp_header.sequenceNumber = 0x1234;
555 rtp_header.timestamp = 0x12345678;
556 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000557 rtp_header.extension.hasAudioLevel = true;
558 rtp_header.extension.audioLevel = 42;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000559
Karl Wiberg43766482015-08-27 15:22:11 +0200560 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700561 EXPECT_CALL(mock_decoder, SampleRateHz())
562 .WillRepeatedly(Return(kSampleRateHz));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000563 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin034154b2016-04-27 06:11:50 -0700564 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeiea7a3f82017-10-19 11:40:55 +0200565 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000566 int16_t dummy_output[kPayloadLengthSamples] = {0};
567 // The below expectation will make the mock decoder write
568 // |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100569 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
570 kSampleRateHz, _, _))
571 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000572 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100573 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200574 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
Niels Möllera1eb9c72018-12-07 15:24:42 +0100575 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
576 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000577
578 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000579 clock_.AdvanceTimeMilliseconds(123456);
580 int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200581 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000582
583 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700584 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800585 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700586 bool muted;
587 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800588 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
589 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800590 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000591
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000592 // Verify |output.packet_infos_|.
593 ASSERT_THAT(output.packet_infos_, SizeIs(1));
594 {
595 const auto& packet_info = output.packet_infos_[0];
596 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
597 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
598 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
599 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
600 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
601 }
602
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000603 // Insert two more packets. The first one is out of order, and is already too
604 // old, the second one is the expected next packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700605 rtp_header.sequenceNumber -= 1;
606 rtp_header.timestamp -= kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000607 rtp_header.extension.audioLevel = 1;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000608 payload[0] = 1;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000609 clock_.AdvanceTimeMilliseconds(1000);
Karl Wiberg45eb1352019-10-10 14:23:00 +0200610 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700611 rtp_header.sequenceNumber += 2;
612 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000613 rtp_header.extension.audioLevel = 2;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000614 payload[0] = 2;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000615 clock_.AdvanceTimeMilliseconds(2000);
616 expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200617 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000618
619 // Expect only the second packet to be decoded (the one with "2" as the first
620 // payload byte).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100621 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
622 kSampleRateHz, _, _))
623 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000624 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100625 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200626 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000627
628 // Pull audio once.
henrik.lundin7a926812016-05-12 13:51:28 -0700629 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800630 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
631 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800632 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000633
634 // Now check the packet buffer, and make sure it is empty, since the
635 // out-of-order packet should have been discarded.
636 EXPECT_TRUE(packet_buffer_->Empty());
637
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000638 // Verify |output.packet_infos_|. Expect to only see the second packet.
639 ASSERT_THAT(output.packet_infos_, SizeIs(1));
640 {
641 const auto& packet_info = output.packet_infos_[0];
642 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
643 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
644 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
645 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
646 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
647 }
648
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000649 EXPECT_CALL(mock_decoder, Die());
650}
651
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000652// This test verifies that NetEq can handle the situation where the first
653// incoming packet is rejected.
henrik.lundin@webrtc.org6ff3ac12014-11-20 14:14:49 +0000654TEST_F(NetEqImplTest, FirstPacketUnknown) {
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000655 UseNoMocks();
656 CreateInstance();
657
658 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000659 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700660 const size_t kPayloadLengthSamples =
661 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundinc9ec8752016-10-13 02:43:34 -0700662 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000663 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700664 RTPHeader rtp_header;
665 rtp_header.payloadType = kPayloadType;
666 rtp_header.sequenceNumber = 0x1234;
667 rtp_header.timestamp = 0x12345678;
668 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000669
670 // Insert one packet. Note that we have not registered any payload type, so
671 // this packet will be rejected.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200672 EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000673
674 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700675 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800676 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700677 bool muted;
678 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800679 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
680 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
681 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800682 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000683 EXPECT_THAT(output.packet_infos_, IsEmpty());
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000684
685 // Register the payload type.
Niels Möller05543682019-01-10 16:55:06 +0100686 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
687 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000688
689 // Insert 10 packets.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700690 for (size_t i = 0; i < 10; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -0700691 rtp_header.sequenceNumber++;
692 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200693 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000694 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
695 }
696
697 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700698 for (size_t i = 0; i < 3; ++i) {
henrik.lundin7a926812016-05-12 13:51:28 -0700699 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800700 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
701 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
702 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800703 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000704 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000705 EXPECT_THAT(output.packet_infos_, SizeIs(1));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000706 }
707}
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000708
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200709// This test verifies that audio interruption is not logged for the initial
710// PLC period before the first packet is deocoded.
711// TODO(henrik.lundin) Maybe move this test to neteq_network_stats_unittest.cc.
Henrik Lundinfe047752019-11-19 12:58:11 +0100712// Make the test parametrized, so that we can test with different initial
713// sample rates in NetEq.
714class NetEqImplTestSampleRateParameter
715 : public NetEqImplTest,
716 public testing::WithParamInterface<int> {
717 protected:
718 NetEqImplTestSampleRateParameter()
719 : NetEqImplTest(), initial_sample_rate_hz_(GetParam()) {
720 config_.sample_rate_hz = initial_sample_rate_hz_;
721 }
722
723 const int initial_sample_rate_hz_;
724};
725
726// This test does the following:
727// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
728// sample rate of 16000.
729// 1. Start calling GetAudio before inserting any encoded audio. The audio
730// produced will be PLC.
731// 2. Insert a number of encoded audio packets.
732// 3. Keep calling GetAudio and verify that no audio interruption was logged.
733// Call GetAudio until NetEq runs out of data again; PLC starts.
734// 4. Insert one more packet.
735// 5. Call GetAudio until that packet is decoded and the PLC ends.
736
737TEST_P(NetEqImplTestSampleRateParameter,
738 NoAudioInterruptionLoggedBeforeFirstDecode) {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200739 UseNoMocks();
740 CreateInstance();
741
742 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundinfe047752019-11-19 12:58:11 +0100743 const int kPayloadSampleRateHz = 16000;
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200744 const size_t kPayloadLengthSamples =
Henrik Lundinfe047752019-11-19 12:58:11 +0100745 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200746 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
747 uint8_t payload[kPayloadLengthBytes] = {0};
748 RTPHeader rtp_header;
749 rtp_header.payloadType = kPayloadType;
750 rtp_header.sequenceNumber = 0x1234;
751 rtp_header.timestamp = 0x12345678;
752 rtp_header.ssrc = 0x87654321;
753
754 // Register the payload type.
Henrik Lundinfe047752019-11-19 12:58:11 +0100755 EXPECT_TRUE(neteq_->RegisterPayloadType(
756 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200757
758 // Pull audio several times. No packets have been inserted yet.
Henrik Lundinfe047752019-11-19 12:58:11 +0100759 const size_t initial_output_size =
760 static_cast<size_t>(10 * initial_sample_rate_hz_ / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200761 AudioFrame output;
762 bool muted;
763 for (int i = 0; i < 100; ++i) {
764 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100765 EXPECT_EQ(initial_output_size, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200766 EXPECT_EQ(1u, output.num_channels_);
767 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000768 EXPECT_THAT(output.packet_infos_, IsEmpty());
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200769 }
770
Henrik Lundinfe047752019-11-19 12:58:11 +0100771 // Lambda for inserting packets.
772 auto insert_packet = [&]() {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200773 rtp_header.sequenceNumber++;
774 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200775 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundinfe047752019-11-19 12:58:11 +0100776 };
777 // Insert 10 packets.
778 for (size_t i = 0; i < 10; ++i) {
779 insert_packet();
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200780 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
781 }
782
783 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Henrik Lundinfe047752019-11-19 12:58:11 +0100784 constexpr size_t kOutputSize =
785 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200786 for (size_t i = 0; i < 3; ++i) {
787 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100788 EXPECT_EQ(kOutputSize, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200789 EXPECT_EQ(1u, output.num_channels_);
790 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
791 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000792 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200793 }
794
Henrik Lundinfe047752019-11-19 12:58:11 +0100795 // Verify that no interruption was logged.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200796 auto lifetime_stats = neteq_->GetLifetimeStatistics();
Henrik Lundin44125fa2019-04-29 17:00:46 +0200797 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundinfe047752019-11-19 12:58:11 +0100798
799 // Keep pulling audio data until a new PLC period is started.
800 size_t count_loops = 0;
801 while (output.speech_type_ == AudioFrame::kNormalSpeech) {
802 // Make sure we don't hang the test if we never go to PLC.
803 ASSERT_LT(++count_loops, 100u);
804 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
805 }
806
807 // Insert one more packet.
808 insert_packet();
809
810 // Pull audio until the newly inserted packet is decoded and the PLC ends.
811 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
812 // Make sure we don't hang the test if we never go to PLC.
813 ASSERT_LT(++count_loops, 100u);
814 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
815 }
816
817 // Verify that no interruption was logged.
818 lifetime_stats = neteq_->GetLifetimeStatistics();
819 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200820}
821
Henrik Lundinfe047752019-11-19 12:58:11 +0100822// This test does the following:
823// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
824// sample rate of 16000.
825// 1. Insert a number of encoded audio packets.
826// 2. Call GetAudio and verify that decoded audio is produced.
827// 3. Keep calling GetAudio until NetEq runs out of data; PLC starts.
828// 4. Keep calling GetAudio until PLC has been produced for at least 150 ms.
829// 5. Insert one more packet.
830// 6. Call GetAudio until that packet is decoded and the PLC ends.
831// 7. Verify that an interruption was logged.
832
833TEST_P(NetEqImplTestSampleRateParameter, AudioInterruptionLogged) {
834 UseNoMocks();
835 CreateInstance();
836
837 const uint8_t kPayloadType = 17; // Just an arbitrary number.
838 const int kPayloadSampleRateHz = 16000;
839 const size_t kPayloadLengthSamples =
840 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
841 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
842 uint8_t payload[kPayloadLengthBytes] = {0};
843 RTPHeader rtp_header;
844 rtp_header.payloadType = kPayloadType;
845 rtp_header.sequenceNumber = 0x1234;
846 rtp_header.timestamp = 0x12345678;
847 rtp_header.ssrc = 0x87654321;
848
849 // Register the payload type.
850 EXPECT_TRUE(neteq_->RegisterPayloadType(
851 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
852
853 // Lambda for inserting packets.
854 auto insert_packet = [&]() {
855 rtp_header.sequenceNumber++;
856 rtp_header.timestamp += kPayloadLengthSamples;
857 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
858 };
859 // Insert 10 packets.
860 for (size_t i = 0; i < 10; ++i) {
861 insert_packet();
862 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
863 }
864
865 AudioFrame output;
866 bool muted;
867 // Keep pulling audio data until a new PLC period is started.
868 size_t count_loops = 0;
869 do {
870 // Make sure we don't hang the test if we never go to PLC.
871 ASSERT_LT(++count_loops, 100u);
872 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
873 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
874
875 // Pull audio 15 times, which produces 150 ms of output audio. This should
876 // all be produced as PLC. The total length of the gap will then be 150 ms
877 // plus an initial fraction of 10 ms at the start and the end of the PLC
878 // period. In total, less than 170 ms.
879 for (size_t i = 0; i < 15; ++i) {
880 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
881 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
882 }
883
884 // Insert one more packet.
885 insert_packet();
886
887 // Pull audio until the newly inserted packet is decoded and the PLC ends.
888 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
889 // Make sure we don't hang the test if we never go to PLC.
890 ASSERT_LT(++count_loops, 100u);
891 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
892 }
893
894 // Verify that the interruption was logged.
895 auto lifetime_stats = neteq_->GetLifetimeStatistics();
896 EXPECT_EQ(1, lifetime_stats.interruption_count);
897 EXPECT_GT(lifetime_stats.total_interruption_duration_ms, 150);
898 EXPECT_LT(lifetime_stats.total_interruption_duration_ms, 170);
899}
900
901INSTANTIATE_TEST_SUITE_P(SampleRates,
902 NetEqImplTestSampleRateParameter,
903 testing::Values(8000, 16000, 32000, 48000));
904
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000905// This test verifies that NetEq can handle comfort noise and enters/quits codec
906// internal CNG mode properly.
907TEST_F(NetEqImplTest, CodecInternalCng) {
908 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +0100909 // Create a mock decoder object.
910 MockAudioDecoder mock_decoder;
911 CreateInstance(
912 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000913
914 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000915 const int kSampleRateKhz = 48;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700916 const size_t kPayloadLengthSamples =
917 static_cast<size_t>(20 * kSampleRateKhz); // 20 ms.
918 const size_t kPayloadLengthBytes = 10;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000919 uint8_t payload[kPayloadLengthBytes] = {0};
920 int16_t dummy_output[kPayloadLengthSamples] = {0};
921
henrik.lundin246ef3e2017-04-24 09:14:32 -0700922 RTPHeader rtp_header;
923 rtp_header.payloadType = kPayloadType;
924 rtp_header.sequenceNumber = 0x1234;
925 rtp_header.timestamp = 0x12345678;
926 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000927
Karl Wiberg43766482015-08-27 15:22:11 +0200928 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700929 EXPECT_CALL(mock_decoder, SampleRateHz())
930 .WillRepeatedly(Return(kSampleRateKhz * 1000));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000931 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin0d96ab72016-04-06 12:28:26 -0700932 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200933 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin0d96ab72016-04-06 12:28:26 -0700934 // Packed duration when asking the decoder for more CNG data (without a new
935 // packet).
936 EXPECT_CALL(mock_decoder, PacketDuration(nullptr, 0))
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200937 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000938
939 // Pointee(x) verifies that first byte of the payload equals x, this makes it
940 // possible to verify that the correct payload is fed to Decode().
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100941 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
942 kSampleRateKhz * 1000, _, _))
943 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000944 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100945 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200946 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000947
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100948 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes,
949 kSampleRateKhz * 1000, _, _))
950 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000951 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100952 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200953 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000954
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100955 EXPECT_CALL(mock_decoder,
956 DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
957 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000958 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100959 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200960 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000961
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100962 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
963 kSampleRateKhz * 1000, _, _))
964 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000965 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100966 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200967 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000968
Niels Möller50b66d52018-12-11 14:43:21 +0100969 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
970 SdpAudioFormat("opus", 48000, 2)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000971
972 // Insert one packet (decoder will return speech).
Karl Wiberg45eb1352019-10-10 14:23:00 +0200973 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000974
975 // Insert second packet (decoder will return CNG).
976 payload[0] = 1;
henrik.lundin246ef3e2017-04-24 09:14:32 -0700977 rtp_header.sequenceNumber++;
978 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200979 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000980
Peter Kastingdce40cf2015-08-24 14:52:23 -0700981 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800982 AudioFrame output;
henrik.lundin55480f52016-03-08 02:37:57 -0800983 AudioFrame::SpeechType expected_type[8] = {
Jonas Olssona4d87372019-07-05 19:08:33 +0200984 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech, AudioFrame::kCNG,
985 AudioFrame::kCNG, AudioFrame::kCNG, AudioFrame::kCNG,
986 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000987 int expected_timestamp_increment[8] = {
988 -1, // will not be used.
989 10 * kSampleRateKhz,
Jonas Olssona4d87372019-07-05 19:08:33 +0200990 -1,
991 -1, // timestamp will be empty during CNG mode; indicated by -1 here.
992 -1,
993 -1,
994 50 * kSampleRateKhz,
995 10 * kSampleRateKhz};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000996
henrik.lundin7a926812016-05-12 13:51:28 -0700997 bool muted;
998 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200999 absl::optional<uint32_t> last_timestamp = neteq_->GetPlayoutTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -07001000 ASSERT_TRUE(last_timestamp);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001001
henrik.lundin0d96ab72016-04-06 12:28:26 -07001002 // Lambda for verifying the timestamps.
1003 auto verify_timestamp = [&last_timestamp, &expected_timestamp_increment](
Danil Chapovalovb6021232018-06-19 13:26:36 +02001004 absl::optional<uint32_t> ts, size_t i) {
henrik.lundin0d96ab72016-04-06 12:28:26 -07001005 if (expected_timestamp_increment[i] == -1) {
1006 // Expect to get an empty timestamp value during CNG and PLC.
1007 EXPECT_FALSE(ts) << "i = " << i;
1008 } else {
1009 ASSERT_TRUE(ts) << "i = " << i;
1010 EXPECT_EQ(*ts, *last_timestamp + expected_timestamp_increment[i])
1011 << "i = " << i;
1012 last_timestamp = ts;
1013 }
1014 };
1015
Peter Kastingdce40cf2015-08-24 14:52:23 -07001016 for (size_t i = 1; i < 6; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001017 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1018 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001019 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001020 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001021 SCOPED_TRACE("");
1022 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001023 }
1024
1025 // Insert third packet, which leaves a gap from last packet.
1026 payload[0] = 2;
henrik.lundin246ef3e2017-04-24 09:14:32 -07001027 rtp_header.sequenceNumber += 2;
1028 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001029 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001030
Peter Kastingdce40cf2015-08-24 14:52:23 -07001031 for (size_t i = 6; i < 8; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001032 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1033 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001034 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001035 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001036 SCOPED_TRACE("");
1037 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001038 }
1039
1040 // Now check the packet buffer, and make sure it is empty.
1041 EXPECT_TRUE(packet_buffer_->Empty());
1042
1043 EXPECT_CALL(mock_decoder, Die());
1044}
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001045
1046TEST_F(NetEqImplTest, UnsupportedDecoder) {
1047 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001048 ::testing::NiceMock<MockAudioDecoder> decoder;
1049
1050 CreateInstance(
1051 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&decoder));
minyue5bd33972016-05-02 04:46:11 -07001052 static const size_t kNetEqMaxFrameSize = 5760; // 120 ms @ 48 kHz.
Peter Kasting69558702016-01-12 16:26:35 -08001053 static const size_t kChannels = 2;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001054
1055 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001056 const int kSampleRateHz = 8000;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001057
Peter Kastingdce40cf2015-08-24 14:52:23 -07001058 const size_t kPayloadLengthSamples =
1059 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001060 const size_t kPayloadLengthBytes = 1;
minyue5bd33972016-05-02 04:46:11 -07001061 uint8_t payload[kPayloadLengthBytes] = {0};
Minyue323b1322015-05-25 13:49:37 +02001062 int16_t dummy_output[kPayloadLengthSamples * kChannels] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001063 RTPHeader rtp_header;
1064 rtp_header.payloadType = kPayloadType;
1065 rtp_header.sequenceNumber = 0x1234;
1066 rtp_header.timestamp = 0x12345678;
1067 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001068
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001069 const uint8_t kFirstPayloadValue = 1;
1070 const uint8_t kSecondPayloadValue = 2;
1071
ossu61a208b2016-09-20 01:38:00 -07001072 EXPECT_CALL(decoder,
1073 PacketDuration(Pointee(kFirstPayloadValue), kPayloadLengthBytes))
1074 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001075 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize + 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001076
ossu61a208b2016-09-20 01:38:00 -07001077 EXPECT_CALL(decoder, DecodeInternal(Pointee(kFirstPayloadValue), _, _, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001078 .Times(0);
1079
ossu61a208b2016-09-20 01:38:00 -07001080 EXPECT_CALL(decoder, DecodeInternal(Pointee(kSecondPayloadValue),
1081 kPayloadLengthBytes, kSampleRateHz, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001082 .Times(1)
ossu61a208b2016-09-20 01:38:00 -07001083 .WillOnce(DoAll(
1084 SetArrayArgument<3>(dummy_output,
1085 dummy_output + kPayloadLengthSamples * kChannels),
1086 SetArgPointee<4>(AudioDecoder::kSpeech),
1087 Return(static_cast<int>(kPayloadLengthSamples * kChannels))));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001088
ossu61a208b2016-09-20 01:38:00 -07001089 EXPECT_CALL(decoder,
1090 PacketDuration(Pointee(kSecondPayloadValue), kPayloadLengthBytes))
1091 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001092 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize)));
ossu61a208b2016-09-20 01:38:00 -07001093
Jonas Olssona4d87372019-07-05 19:08:33 +02001094 EXPECT_CALL(decoder, SampleRateHz()).WillRepeatedly(Return(kSampleRateHz));
ossu61a208b2016-09-20 01:38:00 -07001095
Jonas Olssona4d87372019-07-05 19:08:33 +02001096 EXPECT_CALL(decoder, Channels()).WillRepeatedly(Return(kChannels));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001097
Niels Möllera1eb9c72018-12-07 15:24:42 +01001098 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1099 SdpAudioFormat("L16", 8000, 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001100
1101 // Insert one packet.
1102 payload[0] = kFirstPayloadValue; // This will make Decode() fail.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001103 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001104
1105 // Insert another packet.
1106 payload[0] = kSecondPayloadValue; // This will make Decode() successful.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001107 rtp_header.sequenceNumber++;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001108 // The second timestamp needs to be at least 30 ms after the first to make
1109 // the second packet get decoded.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001110 rtp_header.timestamp += 3 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001111 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001112
henrik.lundin6d8e0112016-03-04 10:34:21 -08001113 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001114 bool muted;
henrik.lundin6d8e0112016-03-04 10:34:21 -08001115 // First call to GetAudio will try to decode the "faulty" packet.
Henrik Lundinc417d9e2017-06-14 12:29:03 +02001116 // Expect kFail return value.
henrik.lundin7a926812016-05-12 13:51:28 -07001117 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001118 // Output size and number of channels should be correct.
1119 const size_t kExpectedOutputSize = 10 * (kSampleRateHz / 1000) * kChannels;
1120 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1121 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001122 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001123
henrik.lundin6d8e0112016-03-04 10:34:21 -08001124 // Second call to GetAudio will decode the packet that is ok. No errors are
1125 // expected.
henrik.lundin7a926812016-05-12 13:51:28 -07001126 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001127 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1128 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001129 EXPECT_THAT(output.packet_infos_, SizeIs(1));
ossu61a208b2016-09-20 01:38:00 -07001130
1131 // Die isn't called through NiceMock (since it's called by the
1132 // MockAudioDecoder constructor), so it needs to be mocked explicitly.
1133 EXPECT_CALL(decoder, Die());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001134}
1135
henrik.lundin116c84e2015-08-27 13:14:48 -07001136// This test inserts packets until the buffer is flushed. After that, it asks
1137// NetEq for the network statistics. The purpose of the test is to make sure
1138// that even though the buffer size increment is negative (which it becomes when
1139// the packet causing a flush is inserted), the packet length stored in the
1140// decision logic remains valid.
1141TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) {
1142 UseNoMocks();
1143 CreateInstance();
1144
1145 const size_t kPayloadLengthSamples = 80;
1146 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1147 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin116c84e2015-08-27 13:14:48 -07001148 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001149 RTPHeader rtp_header;
1150 rtp_header.payloadType = kPayloadType;
1151 rtp_header.sequenceNumber = 0x1234;
1152 rtp_header.timestamp = 0x12345678;
1153 rtp_header.ssrc = 0x87654321;
henrik.lundin116c84e2015-08-27 13:14:48 -07001154
Niels Möller05543682019-01-10 16:55:06 +01001155 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1156 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin116c84e2015-08-27 13:14:48 -07001157
1158 // Insert packets until the buffer flushes.
1159 for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) {
1160 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
Karl Wiberg45eb1352019-10-10 14:23:00 +02001161 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -07001162 rtp_header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples);
1163 ++rtp_header.sequenceNumber;
henrik.lundin116c84e2015-08-27 13:14:48 -07001164 }
1165 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
1166
1167 // Ask for network statistics. This should not crash.
1168 NetEqNetworkStatistics stats;
1169 EXPECT_EQ(NetEq::kOK, neteq_->NetworkStatistics(&stats));
1170}
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001171
1172TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
1173 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001174 // Create a mock decoder object.
1175 MockAudioDecoder mock_decoder;
1176
1177 CreateInstance(
1178 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001179
1180 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001181 const int kSampleRateHz = 8000;
1182 const size_t kPayloadLengthSamples =
1183 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
1184 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples;
1185 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001186 RTPHeader rtp_header;
1187 rtp_header.payloadType = kPayloadType;
1188 rtp_header.sequenceNumber = 0x1234;
1189 rtp_header.timestamp = 0x12345678;
1190 rtp_header.ssrc = 0x87654321;
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001191
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001192 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001193 EXPECT_CALL(mock_decoder, SampleRateHz())
1194 .WillRepeatedly(Return(kSampleRateHz));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001195 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001196 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001197 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001198 int16_t dummy_output[kPayloadLengthSamples] = {0};
1199 // The below expectation will make the mock decoder write
1200 // |kPayloadLengthSamples| - 5 zeros to the output array, and mark it as
1201 // speech. That is, the decoded length is 5 samples shorter than the expected.
1202 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001203 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001204 .WillOnce(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001205 DoAll(SetArrayArgument<3>(dummy_output,
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001206 dummy_output + kPayloadLengthSamples - 5),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001207 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001208 Return(rtc::checked_cast<int>(kPayloadLengthSamples - 5))));
Niels Möllera1eb9c72018-12-07 15:24:42 +01001209 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1210 SdpAudioFormat("L16", 8000, 1)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001211
1212 // Insert one packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001213 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001214
1215 EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength());
1216
1217 // Pull audio once.
1218 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001219 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001220 bool muted;
1221 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001222 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1223 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001224 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001225 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001226
1227 EXPECT_CALL(mock_decoder, Die());
1228}
minyuel6d92bf52015-09-23 15:20:39 +02001229
1230// This test checks the behavior of NetEq when audio decoder fails.
1231TEST_F(NetEqImplTest, DecodingError) {
1232 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001233 // Create a mock decoder object.
1234 MockAudioDecoder mock_decoder;
1235
1236 CreateInstance(
1237 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001238
1239 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001240 const int kSampleRateHz = 8000;
1241 const int kDecoderErrorCode = -97; // Any negative number.
1242
1243 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1244 const size_t kFrameLengthSamples =
1245 static_cast<size_t>(5 * kSampleRateHz / 1000);
1246
1247 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1248
1249 uint8_t payload[kPayloadLengthBytes] = {0};
1250
henrik.lundin246ef3e2017-04-24 09:14:32 -07001251 RTPHeader rtp_header;
1252 rtp_header.payloadType = kPayloadType;
1253 rtp_header.sequenceNumber = 0x1234;
1254 rtp_header.timestamp = 0x12345678;
1255 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001256
minyuel6d92bf52015-09-23 15:20:39 +02001257 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001258 EXPECT_CALL(mock_decoder, SampleRateHz())
1259 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001260 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001261 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001262 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001263 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
1264 EXPECT_CALL(mock_decoder, HasDecodePlc()).WillOnce(Return(false));
minyuel6d92bf52015-09-23 15:20:39 +02001265 int16_t dummy_output[kFrameLengthSamples] = {0};
1266
1267 {
1268 InSequence sequence; // Dummy variable.
1269 // Mock decoder works normally the first time.
1270 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001271 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001272 .Times(3)
1273 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001274 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001275 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001276 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001277 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001278 .RetiresOnSaturation();
1279
1280 // Then mock decoder fails. A common reason for failure can be buffer being
1281 // too short
1282 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001283 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001284 .WillOnce(Return(-1))
1285 .RetiresOnSaturation();
1286
1287 // Mock decoder finally returns to normal.
1288 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001289 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001290 .Times(2)
1291 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001292 DoAll(SetArrayArgument<3>(dummy_output,
1293 dummy_output + kFrameLengthSamples),
1294 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001295 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001296 }
1297
Niels Möllera1eb9c72018-12-07 15:24:42 +01001298 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1299 SdpAudioFormat("L16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001300
1301 // Insert packets.
1302 for (int i = 0; i < 6; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001303 rtp_header.sequenceNumber += 1;
1304 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001305 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001306 }
1307
1308 // Pull audio.
1309 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001310 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001311 bool muted;
1312 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001313 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1314 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001315 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001316 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001317
1318 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001319 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001320 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1321 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001322 // We are not expecting anything for output.speech_type_, since an error was
1323 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001324
1325 // Pull audio again, should continue an expansion.
henrik.lundin7a926812016-05-12 13:51:28 -07001326 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001327 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1328 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001329 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001330 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyuel6d92bf52015-09-23 15:20:39 +02001331
1332 // Pull audio again, should behave normal.
henrik.lundin7a926812016-05-12 13:51:28 -07001333 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001334 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1335 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001336 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001337 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001338
1339 EXPECT_CALL(mock_decoder, Die());
1340}
1341
1342// This test checks the behavior of NetEq when audio decoder fails during CNG.
1343TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
1344 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +01001345
1346 // Create a mock decoder object.
1347 MockAudioDecoder mock_decoder;
1348 CreateInstance(
1349 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001350
1351 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001352 const int kSampleRateHz = 8000;
1353 const int kDecoderErrorCode = -97; // Any negative number.
1354
1355 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1356 const size_t kFrameLengthSamples =
1357 static_cast<size_t>(5 * kSampleRateHz / 1000);
1358
1359 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1360
1361 uint8_t payload[kPayloadLengthBytes] = {0};
1362
henrik.lundin246ef3e2017-04-24 09:14:32 -07001363 RTPHeader rtp_header;
1364 rtp_header.payloadType = kPayloadType;
1365 rtp_header.sequenceNumber = 0x1234;
1366 rtp_header.timestamp = 0x12345678;
1367 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001368
minyuel6d92bf52015-09-23 15:20:39 +02001369 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001370 EXPECT_CALL(mock_decoder, SampleRateHz())
1371 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001372 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001373 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001374 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001375 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
minyuel6d92bf52015-09-23 15:20:39 +02001376 int16_t dummy_output[kFrameLengthSamples] = {0};
1377
1378 {
1379 InSequence sequence; // Dummy variable.
1380 // Mock decoder works normally the first 2 times.
1381 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001382 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001383 .Times(2)
1384 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001385 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001386 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001387 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001388 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001389 .RetiresOnSaturation();
1390
1391 // Then mock decoder fails. A common reason for failure can be buffer being
1392 // too short
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001393 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001394 .WillOnce(Return(-1))
1395 .RetiresOnSaturation();
1396
1397 // Mock decoder finally returns to normal.
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001398 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001399 .Times(2)
1400 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001401 DoAll(SetArrayArgument<3>(dummy_output,
1402 dummy_output + kFrameLengthSamples),
1403 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001404 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001405 }
1406
Niels Möller50b66d52018-12-11 14:43:21 +01001407 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1408 SdpAudioFormat("l16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001409
1410 // Insert 2 packets. This will make netEq into codec internal CNG mode.
1411 for (int i = 0; i < 2; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001412 rtp_header.sequenceNumber += 1;
1413 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001414 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001415 }
1416
1417 // Pull audio.
1418 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001419 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001420 bool muted;
1421 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001422 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1423 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001424 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001425
1426 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001427 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001428 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1429 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001430 // We are not expecting anything for output.speech_type_, since an error was
1431 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001432
1433 // Pull audio again, should resume codec CNG.
henrik.lundin7a926812016-05-12 13:51:28 -07001434 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001435 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1436 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001437 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001438
1439 EXPECT_CALL(mock_decoder, Die());
1440}
1441
henrik.lundind89814b2015-11-23 06:49:25 -08001442// Tests that the return value from last_output_sample_rate_hz() is equal to the
1443// configured inital sample rate.
1444TEST_F(NetEqImplTest, InitialLastOutputSampleRate) {
1445 UseNoMocks();
1446 config_.sample_rate_hz = 48000;
1447 CreateInstance();
1448 EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz());
1449}
1450
henrik.lundined497212016-04-25 10:11:38 -07001451TEST_F(NetEqImplTest, TickTimerIncrement) {
1452 UseNoMocks();
1453 CreateInstance();
1454 ASSERT_TRUE(tick_timer_);
1455 EXPECT_EQ(0u, tick_timer_->ticks());
1456 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001457 bool muted;
1458 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundined497212016-04-25 10:11:38 -07001459 EXPECT_EQ(1u, tick_timer_->ticks());
1460}
1461
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001462TEST_F(NetEqImplTest, SetBaseMinimumDelay) {
1463 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001464 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001465 CreateInstance();
1466
Ivo Creusen53a31f72019-10-24 15:20:39 +02001467 EXPECT_CALL(*mock_neteq_controller_, SetBaseMinimumDelay(_))
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001468 .WillOnce(Return(true))
1469 .WillOnce(Return(false));
1470
1471 const int delay_ms = 200;
1472
1473 EXPECT_EQ(true, neteq_->SetBaseMinimumDelayMs(delay_ms));
1474 EXPECT_EQ(false, neteq_->SetBaseMinimumDelayMs(delay_ms));
1475}
1476
1477TEST_F(NetEqImplTest, GetBaseMinimumDelayMs) {
1478 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001479 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001480 CreateInstance();
1481
1482 const int delay_ms = 200;
1483
Ivo Creusen53a31f72019-10-24 15:20:39 +02001484 EXPECT_CALL(*mock_neteq_controller_, GetBaseMinimumDelay())
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001485 .WillOnce(Return(delay_ms));
1486
1487 EXPECT_EQ(delay_ms, neteq_->GetBaseMinimumDelayMs());
1488}
1489
henrik.lundin114c1b32017-04-26 07:47:32 -07001490TEST_F(NetEqImplTest, TargetDelayMs) {
1491 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001492 use_mock_neteq_controller_ = true;
henrik.lundin114c1b32017-04-26 07:47:32 -07001493 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001494 constexpr int kTargetLevelMs = 510;
1495 EXPECT_CALL(*mock_neteq_controller_, TargetLevelMs())
1496 .WillOnce(Return(kTargetLevelMs));
1497 EXPECT_EQ(510, neteq_->TargetDelayMs());
henrik.lundin114c1b32017-04-26 07:47:32 -07001498}
1499
henrik.lundinb8c55b12017-05-10 07:38:01 -07001500TEST_F(NetEqImplTest, InsertEmptyPacket) {
1501 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001502 use_mock_neteq_controller_ = true;
henrik.lundinb8c55b12017-05-10 07:38:01 -07001503 CreateInstance();
1504
1505 RTPHeader rtp_header;
1506 rtp_header.payloadType = 17;
1507 rtp_header.sequenceNumber = 0x1234;
1508 rtp_header.timestamp = 0x12345678;
1509 rtp_header.ssrc = 0x87654321;
1510
Ivo Creusen53a31f72019-10-24 15:20:39 +02001511 EXPECT_CALL(*mock_neteq_controller_, RegisterEmptyPacket());
henrik.lundinb8c55b12017-05-10 07:38:01 -07001512 neteq_->InsertEmptyPacket(rtp_header);
1513}
1514
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001515TEST_F(NetEqImplTest, EnableRtxHandling) {
1516 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001517 use_mock_neteq_controller_ = true;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001518 config_.enable_rtx_handling = true;
1519 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001520 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001521 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001522 .WillOnce(Return(NetEq::Operation::kNormal));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001523
1524 const int kPayloadLengthSamples = 80;
1525 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1526 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001527 uint8_t payload[kPayloadLengthBytes] = {0};
1528 RTPHeader rtp_header;
1529 rtp_header.payloadType = kPayloadType;
1530 rtp_header.sequenceNumber = 0x1234;
1531 rtp_header.timestamp = 0x12345678;
1532 rtp_header.ssrc = 0x87654321;
1533
Niels Möller05543682019-01-10 16:55:06 +01001534 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1535 SdpAudioFormat("l16", 8000, 1)));
Karl Wiberg45eb1352019-10-10 14:23:00 +02001536 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001537 AudioFrame output;
1538 bool muted;
1539 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
1540
1541 // Insert second packet that was sent before the first packet.
1542 rtp_header.sequenceNumber -= 1;
1543 rtp_header.timestamp -= kPayloadLengthSamples;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001544 EXPECT_CALL(*mock_neteq_controller_,
1545 PacketArrived(
1546 /*last_cng_or_dtmf*/ _,
1547 /*packet_length_samples*/ kPayloadLengthSamples,
1548 /*should_update_stats*/ _,
1549 /*main_sequence_number*/ rtp_header.sequenceNumber,
1550 /*main_timestamp*/ rtp_header.timestamp,
1551 /*fs_hz*/ 8000));
1552
Karl Wiberg45eb1352019-10-10 14:23:00 +02001553 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001554}
1555
minyue5bd33972016-05-02 04:46:11 -07001556class Decoder120ms : public AudioDecoder {
1557 public:
kwiberg347d3512016-06-16 01:59:09 -07001558 Decoder120ms(int sample_rate_hz, SpeechType speech_type)
1559 : sample_rate_hz_(sample_rate_hz),
1560 next_value_(1),
minyue5bd33972016-05-02 04:46:11 -07001561 speech_type_(speech_type) {}
1562
1563 int DecodeInternal(const uint8_t* encoded,
1564 size_t encoded_len,
1565 int sample_rate_hz,
1566 int16_t* decoded,
1567 SpeechType* speech_type) override {
kwiberg347d3512016-06-16 01:59:09 -07001568 EXPECT_EQ(sample_rate_hz_, sample_rate_hz);
minyue5bd33972016-05-02 04:46:11 -07001569 size_t decoded_len =
1570 rtc::CheckedDivExact(sample_rate_hz, 1000) * 120 * Channels();
1571 for (size_t i = 0; i < decoded_len; ++i) {
1572 decoded[i] = next_value_++;
1573 }
1574 *speech_type = speech_type_;
Mirko Bonadei737e0732017-10-19 09:00:17 +02001575 return rtc::checked_cast<int>(decoded_len);
minyue5bd33972016-05-02 04:46:11 -07001576 }
1577
1578 void Reset() override { next_value_ = 1; }
kwiberg347d3512016-06-16 01:59:09 -07001579 int SampleRateHz() const override { return sample_rate_hz_; }
minyue5bd33972016-05-02 04:46:11 -07001580 size_t Channels() const override { return 2; }
1581
1582 private:
kwiberg347d3512016-06-16 01:59:09 -07001583 int sample_rate_hz_;
minyue5bd33972016-05-02 04:46:11 -07001584 int16_t next_value_;
1585 SpeechType speech_type_;
1586};
1587
1588class NetEqImplTest120ms : public NetEqImplTest {
1589 protected:
1590 NetEqImplTest120ms() : NetEqImplTest() {}
1591 virtual ~NetEqImplTest120ms() {}
1592
1593 void CreateInstanceNoMocks() {
1594 UseNoMocks();
Niels Möllera0f44302018-11-30 10:45:12 +01001595 CreateInstance(decoder_factory_);
1596 EXPECT_TRUE(neteq_->RegisterPayloadType(
1597 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001598 }
1599
1600 void CreateInstanceWithDelayManagerMock() {
1601 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001602 use_mock_neteq_controller_ = true;
Niels Möllera0f44302018-11-30 10:45:12 +01001603 CreateInstance(decoder_factory_);
1604 EXPECT_TRUE(neteq_->RegisterPayloadType(
1605 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001606 }
1607
1608 uint32_t timestamp_diff_between_packets() const {
1609 return rtc::CheckedDivExact(kSamplingFreq_, 1000u) * 120;
1610 }
1611
1612 uint32_t first_timestamp() const { return 10u; }
1613
1614 void GetFirstPacket() {
henrik.lundin7a926812016-05-12 13:51:28 -07001615 bool muted;
minyue5bd33972016-05-02 04:46:11 -07001616 for (int i = 0; i < 12; i++) {
henrik.lundin7a926812016-05-12 13:51:28 -07001617 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
1618 EXPECT_FALSE(muted);
minyue5bd33972016-05-02 04:46:11 -07001619 }
1620 }
1621
1622 void InsertPacket(uint32_t timestamp) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001623 RTPHeader rtp_header;
1624 rtp_header.payloadType = kPayloadType;
1625 rtp_header.sequenceNumber = sequence_number_;
1626 rtp_header.timestamp = timestamp;
1627 rtp_header.ssrc = 15;
minyue5bd33972016-05-02 04:46:11 -07001628 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1629 uint8_t payload[kPayloadLengthBytes] = {0};
Karl Wiberg45eb1352019-10-10 14:23:00 +02001630 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue5bd33972016-05-02 04:46:11 -07001631 sequence_number_++;
1632 }
1633
1634 void Register120msCodec(AudioDecoder::SpeechType speech_type) {
Niels Möllera0f44302018-11-30 10:45:12 +01001635 const uint32_t sampling_freq = kSamplingFreq_;
1636 decoder_factory_ =
1637 new rtc::RefCountedObject<test::FunctionAudioDecoderFactory>(
1638 [sampling_freq, speech_type]() {
1639 std::unique_ptr<AudioDecoder> decoder =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001640 std::make_unique<Decoder120ms>(sampling_freq, speech_type);
Niels Möllera0f44302018-11-30 10:45:12 +01001641 RTC_CHECK_EQ(2, decoder->Channels());
1642 return decoder;
1643 });
minyue5bd33972016-05-02 04:46:11 -07001644 }
1645
Niels Möllera0f44302018-11-30 10:45:12 +01001646 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
minyue5bd33972016-05-02 04:46:11 -07001647 AudioFrame output_;
1648 const uint32_t kPayloadType = 17;
1649 const uint32_t kSamplingFreq_ = 48000;
1650 uint16_t sequence_number_ = 1;
1651};
1652
minyue5bd33972016-05-02 04:46:11 -07001653TEST_F(NetEqImplTest120ms, CodecInternalCng) {
minyue5bd33972016-05-02 04:46:11 -07001654 Register120msCodec(AudioDecoder::kComfortNoise);
Niels Möllera0f44302018-11-30 10:45:12 +01001655 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001656
1657 InsertPacket(first_timestamp());
1658 GetFirstPacket();
1659
henrik.lundin7a926812016-05-12 13:51:28 -07001660 bool muted;
1661 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001662 EXPECT_EQ(NetEq::Operation::kCodecInternalCng,
1663 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001664}
1665
1666TEST_F(NetEqImplTest120ms, Normal) {
minyue5bd33972016-05-02 04:46:11 -07001667 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001668 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001669
1670 InsertPacket(first_timestamp());
1671 GetFirstPacket();
1672
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001673 EXPECT_EQ(NetEq::Operation::kNormal, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001674}
1675
1676TEST_F(NetEqImplTest120ms, Merge) {
Niels Möllera0f44302018-11-30 10:45:12 +01001677 Register120msCodec(AudioDecoder::kSpeech);
minyue5bd33972016-05-02 04:46:11 -07001678 CreateInstanceWithDelayManagerMock();
1679
Ivo Creusen53a31f72019-10-24 15:20:39 +02001680 EXPECT_CALL(*mock_neteq_controller_, CngOff()).WillRepeatedly(Return(true));
minyue5bd33972016-05-02 04:46:11 -07001681 InsertPacket(first_timestamp());
1682
1683 GetFirstPacket();
henrik.lundin7a926812016-05-12 13:51:28 -07001684 bool muted;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001685 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001686 .WillOnce(Return(NetEq::Operation::kExpand));
henrik.lundin7a926812016-05-12 13:51:28 -07001687 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
minyue5bd33972016-05-02 04:46:11 -07001688
1689 InsertPacket(first_timestamp() + 2 * timestamp_diff_between_packets());
1690
Ivo Creusen53a31f72019-10-24 15:20:39 +02001691 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001692 .WillOnce(Return(NetEq::Operation::kMerge));
minyue5bd33972016-05-02 04:46:11 -07001693
henrik.lundin7a926812016-05-12 13:51:28 -07001694 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001695 EXPECT_EQ(NetEq::Operation::kMerge, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001696}
1697
1698TEST_F(NetEqImplTest120ms, Expand) {
minyue5bd33972016-05-02 04:46:11 -07001699 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001700 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001701
1702 InsertPacket(first_timestamp());
1703 GetFirstPacket();
1704
henrik.lundin7a926812016-05-12 13:51:28 -07001705 bool muted;
1706 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001707 EXPECT_EQ(NetEq::Operation::kExpand, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001708}
1709
1710TEST_F(NetEqImplTest120ms, FastAccelerate) {
minyue5bd33972016-05-02 04:46:11 -07001711 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001712 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001713
1714 InsertPacket(first_timestamp());
1715 GetFirstPacket();
1716 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1717
Ivo Creusen53a31f72019-10-24 15:20:39 +02001718 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001719 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001720 .WillOnce(Return(NetEq::Operation::kFastAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001721
henrik.lundin7a926812016-05-12 13:51:28 -07001722 bool muted;
1723 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001724 EXPECT_EQ(NetEq::Operation::kFastAccelerate,
1725 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001726}
1727
1728TEST_F(NetEqImplTest120ms, PreemptiveExpand) {
minyue5bd33972016-05-02 04:46:11 -07001729 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001730 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001731
1732 InsertPacket(first_timestamp());
1733 GetFirstPacket();
1734
1735 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1736
Ivo Creusen53a31f72019-10-24 15:20:39 +02001737 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001738 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001739 .WillOnce(Return(NetEq::Operation::kPreemptiveExpand));
minyue5bd33972016-05-02 04:46:11 -07001740
henrik.lundin7a926812016-05-12 13:51:28 -07001741 bool muted;
1742 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001743 EXPECT_EQ(NetEq::Operation::kPreemptiveExpand,
1744 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001745}
1746
1747TEST_F(NetEqImplTest120ms, Accelerate) {
minyue5bd33972016-05-02 04:46:11 -07001748 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001749 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001750
1751 InsertPacket(first_timestamp());
1752 GetFirstPacket();
1753
1754 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1755
Ivo Creusen53a31f72019-10-24 15:20:39 +02001756 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001757 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001758 .WillOnce(Return(NetEq::Operation::kAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001759
henrik.lundin7a926812016-05-12 13:51:28 -07001760 bool muted;
1761 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001762 EXPECT_EQ(NetEq::Operation::kAccelerate, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001763}
1764
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001765} // namespace webrtc