blob: c66a0e25f90d2ea40e821e67d8e82fe1fe870dfb [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) {
Ivo Creusena2b31c32020-10-14 17:54:22 +0200287 using ::testing::AllOf;
288 using ::testing::Field;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000289 CreateInstance();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000290 const size_t kPayloadLength = 100;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000291 const uint8_t kPayloadType = 0;
292 const uint16_t kFirstSequenceNumber = 0x1234;
293 const uint32_t kFirstTimestamp = 0x12345678;
294 const uint32_t kSsrc = 0x87654321;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000295 uint8_t payload[kPayloadLength] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700296 RTPHeader rtp_header;
297 rtp_header.payloadType = kPayloadType;
298 rtp_header.sequenceNumber = kFirstSequenceNumber;
299 rtp_header.timestamp = kFirstTimestamp;
300 rtp_header.ssrc = kSsrc;
ossu7a377612016-10-18 04:06:13 -0700301 Packet fake_packet;
302 fake_packet.payload_type = kPayloadType;
303 fake_packet.sequence_number = kFirstSequenceNumber;
304 fake_packet.timestamp = kFirstTimestamp;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000305
kwibergc0f2dcf2016-05-31 06:28:03 -0700306 rtc::scoped_refptr<MockAudioDecoderFactory> mock_decoder_factory(
307 new rtc::RefCountedObject<MockAudioDecoderFactory>);
Karl Wibergd6fbf2a2018-02-27 13:37:31 +0100308 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _, _))
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800309 .WillOnce(Invoke([&](const SdpAudioFormat& format,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200310 absl::optional<AudioCodecPairId> codec_pair_id,
ehmaldonadob55bd5f2017-02-02 11:51:21 -0800311 std::unique_ptr<AudioDecoder>* dec) {
kwibergc0f2dcf2016-05-31 06:28:03 -0700312 EXPECT_EQ("pcmu", format.name);
313
314 std::unique_ptr<MockAudioDecoder> mock_decoder(new MockAudioDecoder);
315 EXPECT_CALL(*mock_decoder, Channels()).WillRepeatedly(Return(1));
316 EXPECT_CALL(*mock_decoder, SampleRateHz()).WillRepeatedly(Return(8000));
kwibergc0f2dcf2016-05-31 06:28:03 -0700317 EXPECT_CALL(*mock_decoder, Die()).Times(1); // Called when deleted.
318
319 *dec = std::move(mock_decoder);
320 }));
Niels Möller72899062019-01-11 09:36:13 +0100321 DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
322 absl::nullopt, mock_decoder_factory);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000323
324 // Expectations for decoder database.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000325 EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000326 .WillRepeatedly(Return(&info));
327
328 // Expectations for packet buffer.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000329 EXPECT_CALL(*mock_packet_buffer_, Empty())
330 .WillOnce(Return(false)); // Called once after first packet is inserted.
Ivo Creusen7b463c52020-11-25 11:32:40 +0100331 EXPECT_CALL(*mock_packet_buffer_, Flush(_)).Times(1);
332 EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _, _, _, _, _))
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000333 .Times(2)
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100334 .WillRepeatedly(DoAll(SetArgPointee<2>(kPayloadType),
335 WithArg<0>(Invoke(DeletePacketsAndReturnOk))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000336 // SetArgPointee<2>(kPayloadType) means that the third argument (zero-based
337 // index) is a pointer, and the variable pointed to is set to kPayloadType.
338 // Also invoke the function DeletePacketsAndReturnOk to properly delete all
339 // packets in the list (to avoid memory leaks in the test).
ossu7a377612016-10-18 04:06:13 -0700340 EXPECT_CALL(*mock_packet_buffer_, PeekNextPacket())
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000341 .Times(1)
ossu7a377612016-10-18 04:06:13 -0700342 .WillOnce(Return(&fake_packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000343
344 // Expectations for DTMF buffer.
Jonas Olssona4d87372019-07-05 19:08:33 +0200345 EXPECT_CALL(*mock_dtmf_buffer_, Flush()).Times(1);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000346
347 // Expectations for delay manager.
348 {
349 // All expectations within this block must be called in this specific order.
350 InSequence sequence; // Dummy variable.
351 // Expectations when the first packet is inserted.
Ivo Creusena2b31c32020-10-14 17:54:22 +0200352 EXPECT_CALL(
353 *mock_neteq_controller_,
354 PacketArrived(
355 /*fs_hz*/ 8000,
356 /*should_update_stats*/ _,
357 /*info*/
358 AllOf(
359 Field(&NetEqController::PacketArrivedInfo::is_cng_or_dtmf,
360 false),
361 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
362 kFirstSequenceNumber),
363 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
364 kFirstTimestamp))));
365 EXPECT_CALL(
366 *mock_neteq_controller_,
367 PacketArrived(
368 /*fs_hz*/ 8000,
369 /*should_update_stats*/ _,
370 /*info*/
371 AllOf(
372 Field(&NetEqController::PacketArrivedInfo::is_cng_or_dtmf,
373 false),
374 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
375 kFirstSequenceNumber + 1),
376 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
377 kFirstTimestamp + 160))));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000378 }
379
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000380 // Insert first packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200381 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000382
383 // Insert second packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700384 rtp_header.timestamp += 160;
385 rtp_header.sequenceNumber += 1;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200386 neteq_->InsertPacket(rtp_header, payload);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000387}
388
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000389TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
390 UseNoMocks();
391 CreateInstance();
392
393 const int kPayloadLengthSamples = 80;
394 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
Jonas Olssona4d87372019-07-05 19:08:33 +0200395 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000396 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700397 RTPHeader rtp_header;
398 rtp_header.payloadType = kPayloadType;
399 rtp_header.sequenceNumber = 0x1234;
400 rtp_header.timestamp = 0x12345678;
401 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000402
Niels Möller05543682019-01-10 16:55:06 +0100403 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
404 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000405
406 // Insert packets. The buffer should not flush.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700407 for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) {
Karl Wiberg45eb1352019-10-10 14:23:00 +0200408 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700409 rtp_header.timestamp += kPayloadLengthSamples;
410 rtp_header.sequenceNumber += 1;
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000411 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
412 }
413
414 // Insert one more packet and make sure the buffer got flushed. That is, it
415 // should only hold one single packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200416 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700417 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700418 const Packet* test_packet = packet_buffer_->PeekNextPacket();
henrik.lundin246ef3e2017-04-24 09:14:32 -0700419 EXPECT_EQ(rtp_header.timestamp, test_packet->timestamp);
420 EXPECT_EQ(rtp_header.sequenceNumber, test_packet->sequence_number);
henrik.lundin@webrtc.org04ea2322014-03-12 05:55:10 +0000421}
422
solenberg2779bab2016-11-17 04:45:19 -0800423TEST_F(NetEqImplTest, TestDtmfPacketAVT) {
Niels Möller05543682019-01-10 16:55:06 +0100424 TestDtmfPacket(8000);
solenberg2779bab2016-11-17 04:45:19 -0800425}
solenberg99df6c02016-10-11 04:35:34 -0700426
solenberg2779bab2016-11-17 04:45:19 -0800427TEST_F(NetEqImplTest, TestDtmfPacketAVT16kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100428 TestDtmfPacket(16000);
solenberg2779bab2016-11-17 04:45:19 -0800429}
solenberg99df6c02016-10-11 04:35:34 -0700430
solenberg2779bab2016-11-17 04:45:19 -0800431TEST_F(NetEqImplTest, TestDtmfPacketAVT32kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100432 TestDtmfPacket(32000);
solenberg2779bab2016-11-17 04:45:19 -0800433}
solenberg99df6c02016-10-11 04:35:34 -0700434
solenberg2779bab2016-11-17 04:45:19 -0800435TEST_F(NetEqImplTest, TestDtmfPacketAVT48kHz) {
Niels Möller05543682019-01-10 16:55:06 +0100436 TestDtmfPacket(48000);
solenberg99df6c02016-10-11 04:35:34 -0700437}
438
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000439// This test verifies that timestamps propagate from the incoming packets
440// through to the sync buffer and to the playout timestamp.
441TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000442 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000443 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700444 const size_t kPayloadLengthSamples =
445 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000446 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
447 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700448 RTPHeader rtp_header;
449 rtp_header.payloadType = kPayloadType;
450 rtp_header.sequenceNumber = 0x1234;
451 rtp_header.timestamp = 0x12345678;
452 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000453 rtp_header.numCSRCs = 3;
454 rtp_header.arrOfCSRCs[0] = 43;
455 rtp_header.arrOfCSRCs[1] = 65;
456 rtp_header.arrOfCSRCs[2] = 17;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000457
458 // This is a dummy decoder that produces as many output samples as the input
459 // has bytes. The output is an increasing series, starting at 1 for the first
460 // sample, and then increasing by 1 for each sample.
461 class CountingSamplesDecoder : public AudioDecoder {
462 public:
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000463 CountingSamplesDecoder() : next_value_(1) {}
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000464
465 // Produce as many samples as input bytes (|encoded_len|).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100466 int DecodeInternal(const uint8_t* encoded,
467 size_t encoded_len,
468 int /* sample_rate_hz */,
469 int16_t* decoded,
470 SpeechType* speech_type) override {
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000471 for (size_t i = 0; i < encoded_len; ++i) {
472 decoded[i] = next_value_++;
473 }
474 *speech_type = kSpeech;
Mirko Bonadei737e0732017-10-19 09:00:17 +0200475 return rtc::checked_cast<int>(encoded_len);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000476 }
477
Karl Wiberg43766482015-08-27 15:22:11 +0200478 void Reset() override { next_value_ = 1; }
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000479
kwiberg347d3512016-06-16 01:59:09 -0700480 int SampleRateHz() const override { return kSampleRateHz; }
481
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000482 size_t Channels() const override { return 1; }
483
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000484 uint16_t next_value() const { return next_value_; }
485
486 private:
487 int16_t next_value_;
kwiberg@webrtc.org721ef632014-11-04 11:51:46 +0000488 } decoder_;
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000489
Niels Möllerb7180c02018-12-06 13:07:11 +0100490 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory =
491 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&decoder_);
492
493 UseNoMocks();
494 CreateInstance(decoder_factory);
495
496 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
Niels Möllera1eb9c72018-12-07 15:24:42 +0100497 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000498
499 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000500 clock_.AdvanceTimeMilliseconds(123456);
501 int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200502 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000503
504 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700505 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800506 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700507 bool muted;
508 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
509 ASSERT_FALSE(muted);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800510 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
511 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800512 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000513
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000514 // Verify |output.packet_infos_|.
515 ASSERT_THAT(output.packet_infos_, SizeIs(1));
516 {
517 const auto& packet_info = output.packet_infos_[0];
518 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
519 EXPECT_THAT(packet_info.csrcs(), ElementsAre(43, 65, 17));
520 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
521 EXPECT_FALSE(packet_info.audio_level().has_value());
522 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
523 }
524
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000525 // Start with a simple check that the fake decoder is behaving as expected.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700526 EXPECT_EQ(kPayloadLengthSamples,
527 static_cast<size_t>(decoder_.next_value() - 1));
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000528
529 // The value of the last of the output samples is the same as the number of
530 // samples played from the decoded packet. Thus, this number + the RTP
531 // timestamp should match the playout timestamp.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200532 // Wrap the expected value in an absl::optional to compare them as such.
henrik.lundin9a410dd2016-04-06 01:39:22 -0700533 EXPECT_EQ(
Danil Chapovalovb6021232018-06-19 13:26:36 +0200534 absl::optional<uint32_t>(rtp_header.timestamp +
535 output.data()[output.samples_per_channel_ - 1]),
henrik.lundin9a410dd2016-04-06 01:39:22 -0700536 neteq_->GetPlayoutTimestamp());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000537
538 // Check the timestamp for the last value in the sync buffer. This should
539 // be one full frame length ahead of the RTP timestamp.
540 const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
541 ASSERT_TRUE(sync_buffer != NULL);
henrik.lundin246ef3e2017-04-24 09:14:32 -0700542 EXPECT_EQ(rtp_header.timestamp + kPayloadLengthSamples,
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000543 sync_buffer->end_timestamp());
544
545 // Check that the number of samples still to play from the sync buffer add
546 // up with what was already played out.
henrik.lundin6d8e0112016-03-04 10:34:21 -0800547 EXPECT_EQ(
yujo36b1a5f2017-06-12 12:45:32 -0700548 kPayloadLengthSamples - output.data()[output.samples_per_channel_ - 1],
henrik.lundin6d8e0112016-03-04 10:34:21 -0800549 sync_buffer->FutureLength());
henrik.lundin@webrtc.orgb287d962014-04-07 21:21:45 +0000550}
551
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000552TEST_F(NetEqImplTest, ReorderedPacket) {
553 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +0100554 // Create a mock decoder object.
555 MockAudioDecoder mock_decoder;
556
557 CreateInstance(
558 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000559
560 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000561 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700562 const size_t kPayloadLengthSamples =
563 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000564 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
565 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700566 RTPHeader rtp_header;
567 rtp_header.payloadType = kPayloadType;
568 rtp_header.sequenceNumber = 0x1234;
569 rtp_header.timestamp = 0x12345678;
570 rtp_header.ssrc = 0x87654321;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000571 rtp_header.extension.hasAudioLevel = true;
572 rtp_header.extension.audioLevel = 42;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000573
Karl Wiberg43766482015-08-27 15:22:11 +0200574 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700575 EXPECT_CALL(mock_decoder, SampleRateHz())
576 .WillRepeatedly(Return(kSampleRateHz));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000577 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin034154b2016-04-27 06:11:50 -0700578 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeiea7a3f82017-10-19 11:40:55 +0200579 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000580 int16_t dummy_output[kPayloadLengthSamples] = {0};
581 // The below expectation will make the mock decoder write
582 // |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100583 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
584 kSampleRateHz, _, _))
585 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000586 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100587 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200588 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
Niels Möllera1eb9c72018-12-07 15:24:42 +0100589 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
590 SdpAudioFormat("L16", 8000, 1)));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000591
592 // Insert one packet.
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000593 clock_.AdvanceTimeMilliseconds(123456);
594 int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200595 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000596
597 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700598 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800599 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700600 bool muted;
601 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800602 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
603 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800604 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000605
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000606 // Verify |output.packet_infos_|.
607 ASSERT_THAT(output.packet_infos_, SizeIs(1));
608 {
609 const auto& packet_info = output.packet_infos_[0];
610 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
611 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
612 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
613 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
614 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
615 }
616
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000617 // Insert two more packets. The first one is out of order, and is already too
618 // old, the second one is the expected next packet.
henrik.lundin246ef3e2017-04-24 09:14:32 -0700619 rtp_header.sequenceNumber -= 1;
620 rtp_header.timestamp -= kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000621 rtp_header.extension.audioLevel = 1;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000622 payload[0] = 1;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000623 clock_.AdvanceTimeMilliseconds(1000);
Karl Wiberg45eb1352019-10-10 14:23:00 +0200624 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -0700625 rtp_header.sequenceNumber += 2;
626 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000627 rtp_header.extension.audioLevel = 2;
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000628 payload[0] = 2;
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000629 clock_.AdvanceTimeMilliseconds(2000);
630 expected_receive_time_ms = clock_.TimeInMilliseconds();
Karl Wiberg45eb1352019-10-10 14:23:00 +0200631 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000632
633 // Expect only the second packet to be decoded (the one with "2" as the first
634 // payload byte).
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100635 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
636 kSampleRateHz, _, _))
637 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000638 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100639 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200640 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000641
642 // Pull audio once.
henrik.lundin7a926812016-05-12 13:51:28 -0700643 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800644 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
645 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800646 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000647
648 // Now check the packet buffer, and make sure it is empty, since the
649 // out-of-order packet should have been discarded.
650 EXPECT_TRUE(packet_buffer_->Empty());
651
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000652 // Verify |output.packet_infos_|. Expect to only see the second packet.
653 ASSERT_THAT(output.packet_infos_, SizeIs(1));
654 {
655 const auto& packet_info = output.packet_infos_[0];
656 EXPECT_EQ(packet_info.ssrc(), rtp_header.ssrc);
657 EXPECT_THAT(packet_info.csrcs(), IsEmpty());
658 EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
659 EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
660 EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
661 }
662
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000663 EXPECT_CALL(mock_decoder, Die());
664}
665
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000666// This test verifies that NetEq can handle the situation where the first
667// incoming packet is rejected.
henrik.lundin@webrtc.org6ff3ac12014-11-20 14:14:49 +0000668TEST_F(NetEqImplTest, FirstPacketUnknown) {
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000669 UseNoMocks();
670 CreateInstance();
671
672 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000673 const int kSampleRateHz = 8000;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700674 const size_t kPayloadLengthSamples =
675 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
henrik.lundinc9ec8752016-10-13 02:43:34 -0700676 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000677 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -0700678 RTPHeader rtp_header;
679 rtp_header.payloadType = kPayloadType;
680 rtp_header.sequenceNumber = 0x1234;
681 rtp_header.timestamp = 0x12345678;
682 rtp_header.ssrc = 0x87654321;
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000683
684 // Insert one packet. Note that we have not registered any payload type, so
685 // this packet will be rejected.
Karl Wiberg45eb1352019-10-10 14:23:00 +0200686 EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000687
688 // Pull audio once.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700689 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -0800690 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -0700691 bool muted;
692 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800693 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
694 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
695 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800696 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000697 EXPECT_THAT(output.packet_infos_, IsEmpty());
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000698
699 // Register the payload type.
Niels Möller05543682019-01-10 16:55:06 +0100700 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
701 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000702
703 // Insert 10 packets.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700704 for (size_t i = 0; i < 10; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -0700705 rtp_header.sequenceNumber++;
706 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200707 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000708 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
709 }
710
711 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700712 for (size_t i = 0; i < 3; ++i) {
henrik.lundin7a926812016-05-12 13:51:28 -0700713 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -0800714 ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
715 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
716 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -0800717 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000718 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000719 EXPECT_THAT(output.packet_infos_, SizeIs(1));
henrik.lundin@webrtc.orged910682014-11-20 11:01:02 +0000720 }
721}
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000722
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200723// This test verifies that audio interruption is not logged for the initial
724// PLC period before the first packet is deocoded.
725// TODO(henrik.lundin) Maybe move this test to neteq_network_stats_unittest.cc.
Henrik Lundinfe047752019-11-19 12:58:11 +0100726// Make the test parametrized, so that we can test with different initial
727// sample rates in NetEq.
728class NetEqImplTestSampleRateParameter
729 : public NetEqImplTest,
730 public testing::WithParamInterface<int> {
731 protected:
732 NetEqImplTestSampleRateParameter()
733 : NetEqImplTest(), initial_sample_rate_hz_(GetParam()) {
734 config_.sample_rate_hz = initial_sample_rate_hz_;
735 }
736
737 const int initial_sample_rate_hz_;
738};
739
740// This test does the following:
741// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
742// sample rate of 16000.
743// 1. Start calling GetAudio before inserting any encoded audio. The audio
744// produced will be PLC.
745// 2. Insert a number of encoded audio packets.
746// 3. Keep calling GetAudio and verify that no audio interruption was logged.
747// Call GetAudio until NetEq runs out of data again; PLC starts.
748// 4. Insert one more packet.
749// 5. Call GetAudio until that packet is decoded and the PLC ends.
750
751TEST_P(NetEqImplTestSampleRateParameter,
752 NoAudioInterruptionLoggedBeforeFirstDecode) {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200753 UseNoMocks();
754 CreateInstance();
755
756 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundinfe047752019-11-19 12:58:11 +0100757 const int kPayloadSampleRateHz = 16000;
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200758 const size_t kPayloadLengthSamples =
Henrik Lundinfe047752019-11-19 12:58:11 +0100759 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200760 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
761 uint8_t payload[kPayloadLengthBytes] = {0};
762 RTPHeader rtp_header;
763 rtp_header.payloadType = kPayloadType;
764 rtp_header.sequenceNumber = 0x1234;
765 rtp_header.timestamp = 0x12345678;
766 rtp_header.ssrc = 0x87654321;
767
768 // Register the payload type.
Henrik Lundinfe047752019-11-19 12:58:11 +0100769 EXPECT_TRUE(neteq_->RegisterPayloadType(
770 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200771
772 // Pull audio several times. No packets have been inserted yet.
Henrik Lundinfe047752019-11-19 12:58:11 +0100773 const size_t initial_output_size =
774 static_cast<size_t>(10 * initial_sample_rate_hz_ / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200775 AudioFrame output;
776 bool muted;
777 for (int i = 0; i < 100; ++i) {
778 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100779 EXPECT_EQ(initial_output_size, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200780 EXPECT_EQ(1u, output.num_channels_);
781 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000782 EXPECT_THAT(output.packet_infos_, IsEmpty());
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200783 }
784
Henrik Lundinfe047752019-11-19 12:58:11 +0100785 // Lambda for inserting packets.
786 auto insert_packet = [&]() {
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200787 rtp_header.sequenceNumber++;
788 rtp_header.timestamp += kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +0200789 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundinfe047752019-11-19 12:58:11 +0100790 };
791 // Insert 10 packets.
792 for (size_t i = 0; i < 10; ++i) {
793 insert_packet();
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200794 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
795 }
796
797 // Pull audio repeatedly and make sure we get normal output, that is not PLC.
Henrik Lundinfe047752019-11-19 12:58:11 +0100798 constexpr size_t kOutputSize =
799 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200800 for (size_t i = 0; i < 3; ++i) {
801 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Henrik Lundinfe047752019-11-19 12:58:11 +0100802 EXPECT_EQ(kOutputSize, output.samples_per_channel_);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200803 EXPECT_EQ(1u, output.num_channels_);
804 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
805 << "NetEq did not decode the packets as expected.";
Alessio Bazzica8f319a32019-07-24 16:47:02 +0000806 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200807 }
808
Henrik Lundinfe047752019-11-19 12:58:11 +0100809 // Verify that no interruption was logged.
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200810 auto lifetime_stats = neteq_->GetLifetimeStatistics();
Henrik Lundin44125fa2019-04-29 17:00:46 +0200811 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundinfe047752019-11-19 12:58:11 +0100812
813 // Keep pulling audio data until a new PLC period is started.
814 size_t count_loops = 0;
815 while (output.speech_type_ == AudioFrame::kNormalSpeech) {
816 // Make sure we don't hang the test if we never go to PLC.
817 ASSERT_LT(++count_loops, 100u);
818 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
819 }
820
Jakob Ivarsson80fb9782020-10-09 13:41:06 +0200821 // Insert a few packets to avoid postpone decoding after expand.
822 for (size_t i = 0; i < 5; ++i) {
823 insert_packet();
824 }
Henrik Lundinfe047752019-11-19 12:58:11 +0100825
826 // Pull audio until the newly inserted packet is decoded and the PLC ends.
827 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
828 // Make sure we don't hang the test if we never go to PLC.
829 ASSERT_LT(++count_loops, 100u);
830 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
831 }
832
833 // Verify that no interruption was logged.
834 lifetime_stats = neteq_->GetLifetimeStatistics();
835 EXPECT_EQ(0, lifetime_stats.interruption_count);
Henrik Lundin2a8bd092019-04-26 09:47:07 +0200836}
837
Henrik Lundinfe047752019-11-19 12:58:11 +0100838// This test does the following:
839// 0. Set up NetEq with initial sample rate given by test parameter, and a codec
840// sample rate of 16000.
841// 1. Insert a number of encoded audio packets.
842// 2. Call GetAudio and verify that decoded audio is produced.
843// 3. Keep calling GetAudio until NetEq runs out of data; PLC starts.
844// 4. Keep calling GetAudio until PLC has been produced for at least 150 ms.
845// 5. Insert one more packet.
846// 6. Call GetAudio until that packet is decoded and the PLC ends.
847// 7. Verify that an interruption was logged.
848
849TEST_P(NetEqImplTestSampleRateParameter, AudioInterruptionLogged) {
850 UseNoMocks();
851 CreateInstance();
852
853 const uint8_t kPayloadType = 17; // Just an arbitrary number.
854 const int kPayloadSampleRateHz = 16000;
855 const size_t kPayloadLengthSamples =
856 static_cast<size_t>(10 * kPayloadSampleRateHz / 1000); // 10 ms.
857 const size_t kPayloadLengthBytes = kPayloadLengthSamples * 2;
858 uint8_t payload[kPayloadLengthBytes] = {0};
859 RTPHeader rtp_header;
860 rtp_header.payloadType = kPayloadType;
861 rtp_header.sequenceNumber = 0x1234;
862 rtp_header.timestamp = 0x12345678;
863 rtp_header.ssrc = 0x87654321;
864
865 // Register the payload type.
866 EXPECT_TRUE(neteq_->RegisterPayloadType(
867 kPayloadType, SdpAudioFormat("l16", kPayloadSampleRateHz, 1)));
868
869 // Lambda for inserting packets.
870 auto insert_packet = [&]() {
871 rtp_header.sequenceNumber++;
872 rtp_header.timestamp += kPayloadLengthSamples;
873 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
874 };
875 // Insert 10 packets.
876 for (size_t i = 0; i < 10; ++i) {
877 insert_packet();
878 EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
879 }
880
881 AudioFrame output;
882 bool muted;
883 // Keep pulling audio data until a new PLC period is started.
884 size_t count_loops = 0;
885 do {
886 // Make sure we don't hang the test if we never go to PLC.
887 ASSERT_LT(++count_loops, 100u);
888 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
889 } while (output.speech_type_ == AudioFrame::kNormalSpeech);
890
891 // Pull audio 15 times, which produces 150 ms of output audio. This should
892 // all be produced as PLC. The total length of the gap will then be 150 ms
893 // plus an initial fraction of 10 ms at the start and the end of the PLC
894 // period. In total, less than 170 ms.
895 for (size_t i = 0; i < 15; ++i) {
896 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
897 EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
898 }
899
Jakob Ivarsson80fb9782020-10-09 13:41:06 +0200900 // Insert a few packets to avoid postpone decoding after expand.
901 for (size_t i = 0; i < 5; ++i) {
902 insert_packet();
903 }
Henrik Lundinfe047752019-11-19 12:58:11 +0100904
905 // Pull audio until the newly inserted packet is decoded and the PLC ends.
906 while (output.speech_type_ != AudioFrame::kNormalSpeech) {
907 // Make sure we don't hang the test if we never go to PLC.
908 ASSERT_LT(++count_loops, 100u);
909 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
910 }
911
912 // Verify that the interruption was logged.
913 auto lifetime_stats = neteq_->GetLifetimeStatistics();
914 EXPECT_EQ(1, lifetime_stats.interruption_count);
915 EXPECT_GT(lifetime_stats.total_interruption_duration_ms, 150);
916 EXPECT_LT(lifetime_stats.total_interruption_duration_ms, 170);
917}
918
919INSTANTIATE_TEST_SUITE_P(SampleRates,
920 NetEqImplTestSampleRateParameter,
921 testing::Values(8000, 16000, 32000, 48000));
922
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000923// This test verifies that NetEq can handle comfort noise and enters/quits codec
924// internal CNG mode properly.
925TEST_F(NetEqImplTest, CodecInternalCng) {
926 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +0100927 // Create a mock decoder object.
928 MockAudioDecoder mock_decoder;
929 CreateInstance(
930 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000931
932 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000933 const int kSampleRateKhz = 48;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700934 const size_t kPayloadLengthSamples =
935 static_cast<size_t>(20 * kSampleRateKhz); // 20 ms.
936 const size_t kPayloadLengthBytes = 10;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000937 uint8_t payload[kPayloadLengthBytes] = {0};
938 int16_t dummy_output[kPayloadLengthSamples] = {0};
939
henrik.lundin246ef3e2017-04-24 09:14:32 -0700940 RTPHeader rtp_header;
941 rtp_header.payloadType = kPayloadType;
942 rtp_header.sequenceNumber = 0x1234;
943 rtp_header.timestamp = 0x12345678;
944 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000945
Karl Wiberg43766482015-08-27 15:22:11 +0200946 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -0700947 EXPECT_CALL(mock_decoder, SampleRateHz())
948 .WillRepeatedly(Return(kSampleRateKhz * 1000));
henrik.lundin@webrtc.org6dba1eb2015-03-18 09:47:08 +0000949 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
henrik.lundin0d96ab72016-04-06 12:28:26 -0700950 EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200951 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
henrik.lundin0d96ab72016-04-06 12:28:26 -0700952 // Packed duration when asking the decoder for more CNG data (without a new
953 // packet).
954 EXPECT_CALL(mock_decoder, PacketDuration(nullptr, 0))
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200955 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000956
957 // Pointee(x) verifies that first byte of the payload equals x, this makes it
958 // possible to verify that the correct payload is fed to Decode().
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100959 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
960 kSampleRateKhz * 1000, _, _))
961 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000962 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100963 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200964 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000965
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100966 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes,
967 kSampleRateKhz * 1000, _, _))
968 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000969 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100970 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200971 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000972
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100973 EXPECT_CALL(mock_decoder,
974 DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
975 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000976 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100977 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200978 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000979
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100980 EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
981 kSampleRateKhz * 1000, _, _))
982 .WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000983 dummy_output + kPayloadLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +0100984 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +0200985 Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000986
Niels Möller50b66d52018-12-11 14:43:21 +0100987 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
988 SdpAudioFormat("opus", 48000, 2)));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +0000989
Jakob Ivarsson79d9c372021-01-15 15:57:58 +0000990 // Insert one packet (decoder will return speech).
991 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
992
993 // Insert second packet (decoder will return CNG).
994 payload[0] = 1;
995 rtp_header.sequenceNumber++;
996 rtp_header.timestamp += kPayloadLengthSamples;
997 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
998
Peter Kastingdce40cf2015-08-24 14:52:23 -0700999 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001000 AudioFrame output;
henrik.lundin55480f52016-03-08 02:37:57 -08001001 AudioFrame::SpeechType expected_type[8] = {
Jonas Olssona4d87372019-07-05 19:08:33 +02001002 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech, AudioFrame::kCNG,
1003 AudioFrame::kCNG, AudioFrame::kCNG, AudioFrame::kCNG,
1004 AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001005 int expected_timestamp_increment[8] = {
1006 -1, // will not be used.
1007 10 * kSampleRateKhz,
Jonas Olssona4d87372019-07-05 19:08:33 +02001008 -1,
1009 -1, // timestamp will be empty during CNG mode; indicated by -1 here.
1010 -1,
1011 -1,
1012 50 * kSampleRateKhz,
1013 10 * kSampleRateKhz};
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001014
henrik.lundin7a926812016-05-12 13:51:28 -07001015 bool muted;
1016 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
Danil Chapovalovb6021232018-06-19 13:26:36 +02001017 absl::optional<uint32_t> last_timestamp = neteq_->GetPlayoutTimestamp();
henrik.lundin9a410dd2016-04-06 01:39:22 -07001018 ASSERT_TRUE(last_timestamp);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001019
henrik.lundin0d96ab72016-04-06 12:28:26 -07001020 // Lambda for verifying the timestamps.
1021 auto verify_timestamp = [&last_timestamp, &expected_timestamp_increment](
Danil Chapovalovb6021232018-06-19 13:26:36 +02001022 absl::optional<uint32_t> ts, size_t i) {
henrik.lundin0d96ab72016-04-06 12:28:26 -07001023 if (expected_timestamp_increment[i] == -1) {
1024 // Expect to get an empty timestamp value during CNG and PLC.
1025 EXPECT_FALSE(ts) << "i = " << i;
1026 } else {
1027 ASSERT_TRUE(ts) << "i = " << i;
1028 EXPECT_EQ(*ts, *last_timestamp + expected_timestamp_increment[i])
1029 << "i = " << i;
1030 last_timestamp = ts;
1031 }
1032 };
1033
Peter Kastingdce40cf2015-08-24 14:52:23 -07001034 for (size_t i = 1; i < 6; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001035 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1036 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001037 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001038 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001039 SCOPED_TRACE("");
1040 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001041 }
1042
1043 // Insert third packet, which leaves a gap from last packet.
1044 payload[0] = 2;
henrik.lundin246ef3e2017-04-24 09:14:32 -07001045 rtp_header.sequenceNumber += 2;
1046 rtp_header.timestamp += 2 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001047 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001048
Peter Kastingdce40cf2015-08-24 14:52:23 -07001049 for (size_t i = 6; i < 8; ++i) {
henrik.lundin6d8e0112016-03-04 10:34:21 -08001050 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1051 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001052 EXPECT_EQ(expected_type[i - 1], output.speech_type_);
henrik.lundin7a926812016-05-12 13:51:28 -07001053 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin0d96ab72016-04-06 12:28:26 -07001054 SCOPED_TRACE("");
1055 verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
minyue@webrtc.org1784d7c2014-12-09 10:46:39 +00001056 }
1057
1058 // Now check the packet buffer, and make sure it is empty.
1059 EXPECT_TRUE(packet_buffer_->Empty());
1060
1061 EXPECT_CALL(mock_decoder, Die());
1062}
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001063
1064TEST_F(NetEqImplTest, UnsupportedDecoder) {
1065 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001066 ::testing::NiceMock<MockAudioDecoder> decoder;
1067
1068 CreateInstance(
1069 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&decoder));
minyue5bd33972016-05-02 04:46:11 -07001070 static const size_t kNetEqMaxFrameSize = 5760; // 120 ms @ 48 kHz.
Peter Kasting69558702016-01-12 16:26:35 -08001071 static const size_t kChannels = 2;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001072
1073 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001074 const int kSampleRateHz = 8000;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001075
Peter Kastingdce40cf2015-08-24 14:52:23 -07001076 const size_t kPayloadLengthSamples =
1077 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001078 const size_t kPayloadLengthBytes = 1;
minyue5bd33972016-05-02 04:46:11 -07001079 uint8_t payload[kPayloadLengthBytes] = {0};
Minyue323b1322015-05-25 13:49:37 +02001080 int16_t dummy_output[kPayloadLengthSamples * kChannels] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001081 RTPHeader rtp_header;
1082 rtp_header.payloadType = kPayloadType;
1083 rtp_header.sequenceNumber = 0x1234;
1084 rtp_header.timestamp = 0x12345678;
1085 rtp_header.ssrc = 0x87654321;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001086
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001087 const uint8_t kFirstPayloadValue = 1;
1088 const uint8_t kSecondPayloadValue = 2;
1089
ossu61a208b2016-09-20 01:38:00 -07001090 EXPECT_CALL(decoder,
1091 PacketDuration(Pointee(kFirstPayloadValue), kPayloadLengthBytes))
1092 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001093 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize + 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001094
ossu61a208b2016-09-20 01:38:00 -07001095 EXPECT_CALL(decoder, DecodeInternal(Pointee(kFirstPayloadValue), _, _, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001096 .Times(0);
1097
ossu61a208b2016-09-20 01:38:00 -07001098 EXPECT_CALL(decoder, DecodeInternal(Pointee(kSecondPayloadValue),
1099 kPayloadLengthBytes, kSampleRateHz, _, _))
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001100 .Times(1)
ossu61a208b2016-09-20 01:38:00 -07001101 .WillOnce(DoAll(
1102 SetArrayArgument<3>(dummy_output,
1103 dummy_output + kPayloadLengthSamples * kChannels),
1104 SetArgPointee<4>(AudioDecoder::kSpeech),
1105 Return(static_cast<int>(kPayloadLengthSamples * kChannels))));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001106
ossu61a208b2016-09-20 01:38:00 -07001107 EXPECT_CALL(decoder,
1108 PacketDuration(Pointee(kSecondPayloadValue), kPayloadLengthBytes))
1109 .Times(AtLeast(1))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001110 .WillRepeatedly(Return(rtc::checked_cast<int>(kNetEqMaxFrameSize)));
ossu61a208b2016-09-20 01:38:00 -07001111
Jonas Olssona4d87372019-07-05 19:08:33 +02001112 EXPECT_CALL(decoder, SampleRateHz()).WillRepeatedly(Return(kSampleRateHz));
ossu61a208b2016-09-20 01:38:00 -07001113
Jonas Olssona4d87372019-07-05 19:08:33 +02001114 EXPECT_CALL(decoder, Channels()).WillRepeatedly(Return(kChannels));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001115
Niels Möllera1eb9c72018-12-07 15:24:42 +01001116 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1117 SdpAudioFormat("L16", 8000, 1)));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001118
1119 // Insert one packet.
1120 payload[0] = kFirstPayloadValue; // This will make Decode() fail.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001121 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001122
1123 // Insert another packet.
1124 payload[0] = kSecondPayloadValue; // This will make Decode() successful.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001125 rtp_header.sequenceNumber++;
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001126 // The second timestamp needs to be at least 30 ms after the first to make
1127 // the second packet get decoded.
henrik.lundin246ef3e2017-04-24 09:14:32 -07001128 rtp_header.timestamp += 3 * kPayloadLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001129 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001130
henrik.lundin6d8e0112016-03-04 10:34:21 -08001131 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001132 bool muted;
henrik.lundin6d8e0112016-03-04 10:34:21 -08001133 // First call to GetAudio will try to decode the "faulty" packet.
Henrik Lundinc417d9e2017-06-14 12:29:03 +02001134 // Expect kFail return value.
henrik.lundin7a926812016-05-12 13:51:28 -07001135 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001136 // Output size and number of channels should be correct.
1137 const size_t kExpectedOutputSize = 10 * (kSampleRateHz / 1000) * kChannels;
1138 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1139 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001140 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001141
henrik.lundin6d8e0112016-03-04 10:34:21 -08001142 // Second call to GetAudio will decode the packet that is ok. No errors are
1143 // expected.
henrik.lundin7a926812016-05-12 13:51:28 -07001144 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001145 EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
1146 EXPECT_EQ(kChannels, output.num_channels_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001147 EXPECT_THAT(output.packet_infos_, SizeIs(1));
ossu61a208b2016-09-20 01:38:00 -07001148
1149 // Die isn't called through NiceMock (since it's called by the
1150 // MockAudioDecoder constructor), so it needs to be mocked explicitly.
1151 EXPECT_CALL(decoder, Die());
minyue@webrtc.org7f7d7e32015-03-16 12:30:37 +00001152}
1153
henrik.lundin116c84e2015-08-27 13:14:48 -07001154// This test inserts packets until the buffer is flushed. After that, it asks
1155// NetEq for the network statistics. The purpose of the test is to make sure
1156// that even though the buffer size increment is negative (which it becomes when
1157// the packet causing a flush is inserted), the packet length stored in the
1158// decision logic remains valid.
1159TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) {
1160 UseNoMocks();
1161 CreateInstance();
1162
1163 const size_t kPayloadLengthSamples = 80;
1164 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1165 const uint8_t kPayloadType = 17; // Just an arbitrary number.
henrik.lundin116c84e2015-08-27 13:14:48 -07001166 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001167 RTPHeader rtp_header;
1168 rtp_header.payloadType = kPayloadType;
1169 rtp_header.sequenceNumber = 0x1234;
1170 rtp_header.timestamp = 0x12345678;
1171 rtp_header.ssrc = 0x87654321;
henrik.lundin116c84e2015-08-27 13:14:48 -07001172
Niels Möller05543682019-01-10 16:55:06 +01001173 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1174 SdpAudioFormat("l16", 8000, 1)));
henrik.lundin116c84e2015-08-27 13:14:48 -07001175
1176 // Insert packets until the buffer flushes.
1177 for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) {
1178 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
Karl Wiberg45eb1352019-10-10 14:23:00 +02001179 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
henrik.lundin246ef3e2017-04-24 09:14:32 -07001180 rtp_header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples);
1181 ++rtp_header.sequenceNumber;
henrik.lundin116c84e2015-08-27 13:14:48 -07001182 }
1183 EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
1184
1185 // Ask for network statistics. This should not crash.
1186 NetEqNetworkStatistics stats;
1187 EXPECT_EQ(NetEq::kOK, neteq_->NetworkStatistics(&stats));
1188}
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001189
1190TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
1191 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001192 // Create a mock decoder object.
1193 MockAudioDecoder mock_decoder;
1194
1195 CreateInstance(
1196 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001197
1198 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001199 const int kSampleRateHz = 8000;
1200 const size_t kPayloadLengthSamples =
1201 static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
1202 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples;
1203 uint8_t payload[kPayloadLengthBytes] = {0};
henrik.lundin246ef3e2017-04-24 09:14:32 -07001204 RTPHeader rtp_header;
1205 rtp_header.payloadType = kPayloadType;
1206 rtp_header.sequenceNumber = 0x1234;
1207 rtp_header.timestamp = 0x12345678;
1208 rtp_header.ssrc = 0x87654321;
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001209
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001210 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001211 EXPECT_CALL(mock_decoder, SampleRateHz())
1212 .WillRepeatedly(Return(kSampleRateHz));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001213 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001214 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001215 .WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001216 int16_t dummy_output[kPayloadLengthSamples] = {0};
1217 // The below expectation will make the mock decoder write
1218 // |kPayloadLengthSamples| - 5 zeros to the output array, and mark it as
1219 // speech. That is, the decoded length is 5 samples shorter than the expected.
1220 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001221 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001222 .WillOnce(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001223 DoAll(SetArrayArgument<3>(dummy_output,
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001224 dummy_output + kPayloadLengthSamples - 5),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001225 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001226 Return(rtc::checked_cast<int>(kPayloadLengthSamples - 5))));
Niels Möllera1eb9c72018-12-07 15:24:42 +01001227 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1228 SdpAudioFormat("L16", 8000, 1)));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001229
1230 // Insert one packet.
Karl Wiberg45eb1352019-10-10 14:23:00 +02001231 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001232
1233 EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength());
1234
1235 // Pull audio once.
1236 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001237 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001238 bool muted;
1239 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001240 ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
1241 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001242 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001243 EXPECT_THAT(output.packet_infos_, SizeIs(1));
Henrik Lundin05f71fc2015-09-01 11:51:58 +02001244
1245 EXPECT_CALL(mock_decoder, Die());
1246}
minyuel6d92bf52015-09-23 15:20:39 +02001247
1248// This test checks the behavior of NetEq when audio decoder fails.
1249TEST_F(NetEqImplTest, DecodingError) {
1250 UseNoMocks();
Niels Möllera1eb9c72018-12-07 15:24:42 +01001251 // Create a mock decoder object.
1252 MockAudioDecoder mock_decoder;
1253
1254 CreateInstance(
1255 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001256
1257 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001258 const int kSampleRateHz = 8000;
1259 const int kDecoderErrorCode = -97; // Any negative number.
1260
1261 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1262 const size_t kFrameLengthSamples =
1263 static_cast<size_t>(5 * kSampleRateHz / 1000);
1264
1265 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1266
1267 uint8_t payload[kPayloadLengthBytes] = {0};
1268
henrik.lundin246ef3e2017-04-24 09:14:32 -07001269 RTPHeader rtp_header;
1270 rtp_header.payloadType = kPayloadType;
1271 rtp_header.sequenceNumber = 0x1234;
1272 rtp_header.timestamp = 0x12345678;
1273 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001274
minyuel6d92bf52015-09-23 15:20:39 +02001275 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001276 EXPECT_CALL(mock_decoder, SampleRateHz())
1277 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001278 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001279 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001280 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001281 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
1282 EXPECT_CALL(mock_decoder, HasDecodePlc()).WillOnce(Return(false));
minyuel6d92bf52015-09-23 15:20:39 +02001283 int16_t dummy_output[kFrameLengthSamples] = {0};
1284
1285 {
1286 InSequence sequence; // Dummy variable.
1287 // Mock decoder works normally the first time.
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(3)
1291 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001292 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001293 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001294 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001295 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001296 .RetiresOnSaturation();
1297
1298 // Then mock decoder fails. A common reason for failure can be buffer being
1299 // too short
1300 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001301 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001302 .WillOnce(Return(-1))
1303 .RetiresOnSaturation();
1304
1305 // Mock decoder finally returns to normal.
1306 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001307 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001308 .Times(2)
1309 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001310 DoAll(SetArrayArgument<3>(dummy_output,
1311 dummy_output + kFrameLengthSamples),
1312 SetArgPointee<4>(AudioDecoder::kSpeech),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001313 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001314 }
1315
Niels Möllera1eb9c72018-12-07 15:24:42 +01001316 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1317 SdpAudioFormat("L16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001318
1319 // Insert packets.
Jakob Ivarsson80fb9782020-10-09 13:41:06 +02001320 for (int i = 0; i < 20; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001321 rtp_header.sequenceNumber += 1;
1322 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001323 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001324 }
1325
1326 // Pull audio.
1327 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001328 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001329 bool muted;
1330 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001331 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1332 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001333 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001334 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001335
1336 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001337 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001338 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1339 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001340 // We are not expecting anything for output.speech_type_, since an error was
1341 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001342
1343 // Pull audio again, should continue an expansion.
henrik.lundin7a926812016-05-12 13:51:28 -07001344 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001345 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1346 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001347 EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001348 EXPECT_THAT(output.packet_infos_, IsEmpty());
minyuel6d92bf52015-09-23 15:20:39 +02001349
1350 // Pull audio again, should behave normal.
henrik.lundin7a926812016-05-12 13:51:28 -07001351 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001352 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1353 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001354 EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001355 EXPECT_THAT(output.packet_infos_, SizeIs(2)); // 5 ms packets vs 10 ms output
minyuel6d92bf52015-09-23 15:20:39 +02001356
1357 EXPECT_CALL(mock_decoder, Die());
1358}
1359
1360// This test checks the behavior of NetEq when audio decoder fails during CNG.
1361TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
1362 UseNoMocks();
Niels Möller50b66d52018-12-11 14:43:21 +01001363
1364 // Create a mock decoder object.
1365 MockAudioDecoder mock_decoder;
1366 CreateInstance(
1367 new rtc::RefCountedObject<test::AudioDecoderProxyFactory>(&mock_decoder));
minyuel6d92bf52015-09-23 15:20:39 +02001368
1369 const uint8_t kPayloadType = 17; // Just an arbitrary number.
minyuel6d92bf52015-09-23 15:20:39 +02001370 const int kSampleRateHz = 8000;
1371 const int kDecoderErrorCode = -97; // Any negative number.
1372
1373 // We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
1374 const size_t kFrameLengthSamples =
1375 static_cast<size_t>(5 * kSampleRateHz / 1000);
1376
1377 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1378
1379 uint8_t payload[kPayloadLengthBytes] = {0};
1380
henrik.lundin246ef3e2017-04-24 09:14:32 -07001381 RTPHeader rtp_header;
1382 rtp_header.payloadType = kPayloadType;
1383 rtp_header.sequenceNumber = 0x1234;
1384 rtp_header.timestamp = 0x12345678;
1385 rtp_header.ssrc = 0x87654321;
minyuel6d92bf52015-09-23 15:20:39 +02001386
minyuel6d92bf52015-09-23 15:20:39 +02001387 EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
kwiberg342f7402016-06-16 03:18:00 -07001388 EXPECT_CALL(mock_decoder, SampleRateHz())
1389 .WillRepeatedly(Return(kSampleRateHz));
minyuel6d92bf52015-09-23 15:20:39 +02001390 EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
minyuel6d92bf52015-09-23 15:20:39 +02001391 EXPECT_CALL(mock_decoder, PacketDuration(_, _))
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001392 .WillRepeatedly(Return(rtc::checked_cast<int>(kFrameLengthSamples)));
Jonas Olssona4d87372019-07-05 19:08:33 +02001393 EXPECT_CALL(mock_decoder, ErrorCode()).WillOnce(Return(kDecoderErrorCode));
minyuel6d92bf52015-09-23 15:20:39 +02001394 int16_t dummy_output[kFrameLengthSamples] = {0};
1395
1396 {
1397 InSequence sequence; // Dummy variable.
1398 // Mock decoder works normally the first 2 times.
1399 EXPECT_CALL(mock_decoder,
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001400 DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001401 .Times(2)
1402 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001403 DoAll(SetArrayArgument<3>(dummy_output,
minyuel6d92bf52015-09-23 15:20:39 +02001404 dummy_output + kFrameLengthSamples),
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001405 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001406 Return(rtc::checked_cast<int>(kFrameLengthSamples))))
minyuel6d92bf52015-09-23 15:20:39 +02001407 .RetiresOnSaturation();
1408
1409 // Then mock decoder fails. A common reason for failure can be buffer being
1410 // too short
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001411 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001412 .WillOnce(Return(-1))
1413 .RetiresOnSaturation();
1414
1415 // Mock decoder finally returns to normal.
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001416 EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
minyuel6d92bf52015-09-23 15:20:39 +02001417 .Times(2)
1418 .WillRepeatedly(
Peter Boströmd7b7ae82015-12-08 13:41:35 +01001419 DoAll(SetArrayArgument<3>(dummy_output,
1420 dummy_output + kFrameLengthSamples),
1421 SetArgPointee<4>(AudioDecoder::kComfortNoise),
Mirko Bonadeib7e17882017-10-20 11:18:47 +02001422 Return(rtc::checked_cast<int>(kFrameLengthSamples))));
minyuel6d92bf52015-09-23 15:20:39 +02001423 }
1424
Niels Möller50b66d52018-12-11 14:43:21 +01001425 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1426 SdpAudioFormat("l16", 8000, 1)));
minyuel6d92bf52015-09-23 15:20:39 +02001427
1428 // Insert 2 packets. This will make netEq into codec internal CNG mode.
1429 for (int i = 0; i < 2; ++i) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001430 rtp_header.sequenceNumber += 1;
1431 rtp_header.timestamp += kFrameLengthSamples;
Karl Wiberg45eb1352019-10-10 14:23:00 +02001432 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyuel6d92bf52015-09-23 15:20:39 +02001433 }
1434
1435 // Pull audio.
1436 const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
henrik.lundin6d8e0112016-03-04 10:34:21 -08001437 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001438 bool muted;
1439 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001440 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1441 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001442 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001443
1444 // Pull audio again. Decoder fails.
henrik.lundin7a926812016-05-12 13:51:28 -07001445 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001446 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1447 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001448 // We are not expecting anything for output.speech_type_, since an error was
1449 // returned.
minyuel6d92bf52015-09-23 15:20:39 +02001450
1451 // Pull audio again, should resume codec CNG.
henrik.lundin7a926812016-05-12 13:51:28 -07001452 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundin6d8e0112016-03-04 10:34:21 -08001453 EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
1454 EXPECT_EQ(1u, output.num_channels_);
henrik.lundin55480f52016-03-08 02:37:57 -08001455 EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
minyuel6d92bf52015-09-23 15:20:39 +02001456
1457 EXPECT_CALL(mock_decoder, Die());
1458}
1459
henrik.lundind89814b2015-11-23 06:49:25 -08001460// Tests that the return value from last_output_sample_rate_hz() is equal to the
1461// configured inital sample rate.
1462TEST_F(NetEqImplTest, InitialLastOutputSampleRate) {
1463 UseNoMocks();
1464 config_.sample_rate_hz = 48000;
1465 CreateInstance();
1466 EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz());
1467}
1468
henrik.lundined497212016-04-25 10:11:38 -07001469TEST_F(NetEqImplTest, TickTimerIncrement) {
1470 UseNoMocks();
1471 CreateInstance();
1472 ASSERT_TRUE(tick_timer_);
1473 EXPECT_EQ(0u, tick_timer_->ticks());
1474 AudioFrame output;
henrik.lundin7a926812016-05-12 13:51:28 -07001475 bool muted;
1476 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
henrik.lundined497212016-04-25 10:11:38 -07001477 EXPECT_EQ(1u, tick_timer_->ticks());
1478}
1479
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001480TEST_F(NetEqImplTest, SetBaseMinimumDelay) {
1481 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001482 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001483 CreateInstance();
1484
Ivo Creusen53a31f72019-10-24 15:20:39 +02001485 EXPECT_CALL(*mock_neteq_controller_, SetBaseMinimumDelay(_))
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001486 .WillOnce(Return(true))
1487 .WillOnce(Return(false));
1488
1489 const int delay_ms = 200;
1490
1491 EXPECT_EQ(true, neteq_->SetBaseMinimumDelayMs(delay_ms));
1492 EXPECT_EQ(false, neteq_->SetBaseMinimumDelayMs(delay_ms));
1493}
1494
1495TEST_F(NetEqImplTest, GetBaseMinimumDelayMs) {
1496 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001497 use_mock_neteq_controller_ = true;
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001498 CreateInstance();
1499
1500 const int delay_ms = 200;
1501
Ivo Creusen53a31f72019-10-24 15:20:39 +02001502 EXPECT_CALL(*mock_neteq_controller_, GetBaseMinimumDelay())
Ruslan Burakov9bee67c2019-02-05 13:49:26 +01001503 .WillOnce(Return(delay_ms));
1504
1505 EXPECT_EQ(delay_ms, neteq_->GetBaseMinimumDelayMs());
1506}
1507
henrik.lundin114c1b32017-04-26 07:47:32 -07001508TEST_F(NetEqImplTest, TargetDelayMs) {
1509 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001510 use_mock_neteq_controller_ = true;
henrik.lundin114c1b32017-04-26 07:47:32 -07001511 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001512 constexpr int kTargetLevelMs = 510;
1513 EXPECT_CALL(*mock_neteq_controller_, TargetLevelMs())
1514 .WillOnce(Return(kTargetLevelMs));
1515 EXPECT_EQ(510, neteq_->TargetDelayMs());
henrik.lundin114c1b32017-04-26 07:47:32 -07001516}
1517
henrik.lundinb8c55b12017-05-10 07:38:01 -07001518TEST_F(NetEqImplTest, InsertEmptyPacket) {
1519 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001520 use_mock_neteq_controller_ = true;
henrik.lundinb8c55b12017-05-10 07:38:01 -07001521 CreateInstance();
1522
1523 RTPHeader rtp_header;
1524 rtp_header.payloadType = 17;
1525 rtp_header.sequenceNumber = 0x1234;
1526 rtp_header.timestamp = 0x12345678;
1527 rtp_header.ssrc = 0x87654321;
1528
Ivo Creusen53a31f72019-10-24 15:20:39 +02001529 EXPECT_CALL(*mock_neteq_controller_, RegisterEmptyPacket());
henrik.lundinb8c55b12017-05-10 07:38:01 -07001530 neteq_->InsertEmptyPacket(rtp_header);
1531}
1532
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001533TEST_F(NetEqImplTest, EnableRtxHandling) {
Ivo Creusena2b31c32020-10-14 17:54:22 +02001534 using ::testing::AllOf;
1535 using ::testing::Field;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001536 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001537 use_mock_neteq_controller_ = true;
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001538 config_.enable_rtx_handling = true;
1539 CreateInstance();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001540 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001541 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001542 .WillOnce(Return(NetEq::Operation::kNormal));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001543
1544 const int kPayloadLengthSamples = 80;
1545 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
1546 const uint8_t kPayloadType = 17; // Just an arbitrary number.
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001547 uint8_t payload[kPayloadLengthBytes] = {0};
1548 RTPHeader rtp_header;
1549 rtp_header.payloadType = kPayloadType;
1550 rtp_header.sequenceNumber = 0x1234;
1551 rtp_header.timestamp = 0x12345678;
1552 rtp_header.ssrc = 0x87654321;
1553
Niels Möller05543682019-01-10 16:55:06 +01001554 EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
1555 SdpAudioFormat("l16", 8000, 1)));
Karl Wiberg45eb1352019-10-10 14:23:00 +02001556 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001557 AudioFrame output;
1558 bool muted;
1559 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
1560
1561 // Insert second packet that was sent before the first packet.
1562 rtp_header.sequenceNumber -= 1;
1563 rtp_header.timestamp -= kPayloadLengthSamples;
Ivo Creusena2b31c32020-10-14 17:54:22 +02001564 EXPECT_CALL(
1565 *mock_neteq_controller_,
1566 PacketArrived(
1567 /*fs_hz*/ 8000,
1568 /*should_update_stats*/ _,
1569 /*info*/
1570 AllOf(
1571 Field(&NetEqController::PacketArrivedInfo::packet_length_samples,
1572 kPayloadLengthSamples),
1573 Field(&NetEqController::PacketArrivedInfo::main_sequence_number,
1574 rtp_header.sequenceNumber),
1575 Field(&NetEqController::PacketArrivedInfo::main_timestamp,
1576 rtp_header.timestamp))));
Ivo Creusen53a31f72019-10-24 15:20:39 +02001577
Karl Wiberg45eb1352019-10-10 14:23:00 +02001578 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
Jakob Ivarsson39b934b2019-01-10 10:28:23 +01001579}
1580
minyue5bd33972016-05-02 04:46:11 -07001581class Decoder120ms : public AudioDecoder {
1582 public:
kwiberg347d3512016-06-16 01:59:09 -07001583 Decoder120ms(int sample_rate_hz, SpeechType speech_type)
1584 : sample_rate_hz_(sample_rate_hz),
1585 next_value_(1),
minyue5bd33972016-05-02 04:46:11 -07001586 speech_type_(speech_type) {}
1587
1588 int DecodeInternal(const uint8_t* encoded,
1589 size_t encoded_len,
1590 int sample_rate_hz,
1591 int16_t* decoded,
1592 SpeechType* speech_type) override {
kwiberg347d3512016-06-16 01:59:09 -07001593 EXPECT_EQ(sample_rate_hz_, sample_rate_hz);
minyue5bd33972016-05-02 04:46:11 -07001594 size_t decoded_len =
1595 rtc::CheckedDivExact(sample_rate_hz, 1000) * 120 * Channels();
1596 for (size_t i = 0; i < decoded_len; ++i) {
1597 decoded[i] = next_value_++;
1598 }
1599 *speech_type = speech_type_;
Mirko Bonadei737e0732017-10-19 09:00:17 +02001600 return rtc::checked_cast<int>(decoded_len);
minyue5bd33972016-05-02 04:46:11 -07001601 }
1602
1603 void Reset() override { next_value_ = 1; }
kwiberg347d3512016-06-16 01:59:09 -07001604 int SampleRateHz() const override { return sample_rate_hz_; }
minyue5bd33972016-05-02 04:46:11 -07001605 size_t Channels() const override { return 2; }
1606
1607 private:
kwiberg347d3512016-06-16 01:59:09 -07001608 int sample_rate_hz_;
minyue5bd33972016-05-02 04:46:11 -07001609 int16_t next_value_;
1610 SpeechType speech_type_;
1611};
1612
1613class NetEqImplTest120ms : public NetEqImplTest {
1614 protected:
1615 NetEqImplTest120ms() : NetEqImplTest() {}
1616 virtual ~NetEqImplTest120ms() {}
1617
1618 void CreateInstanceNoMocks() {
1619 UseNoMocks();
Niels Möllera0f44302018-11-30 10:45:12 +01001620 CreateInstance(decoder_factory_);
1621 EXPECT_TRUE(neteq_->RegisterPayloadType(
1622 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001623 }
1624
1625 void CreateInstanceWithDelayManagerMock() {
1626 UseNoMocks();
Ivo Creusen53a31f72019-10-24 15:20:39 +02001627 use_mock_neteq_controller_ = true;
Niels Möllera0f44302018-11-30 10:45:12 +01001628 CreateInstance(decoder_factory_);
1629 EXPECT_TRUE(neteq_->RegisterPayloadType(
1630 kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}})));
minyue5bd33972016-05-02 04:46:11 -07001631 }
1632
1633 uint32_t timestamp_diff_between_packets() const {
1634 return rtc::CheckedDivExact(kSamplingFreq_, 1000u) * 120;
1635 }
1636
1637 uint32_t first_timestamp() const { return 10u; }
1638
1639 void GetFirstPacket() {
henrik.lundin7a926812016-05-12 13:51:28 -07001640 bool muted;
minyue5bd33972016-05-02 04:46:11 -07001641 for (int i = 0; i < 12; i++) {
henrik.lundin7a926812016-05-12 13:51:28 -07001642 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
1643 EXPECT_FALSE(muted);
minyue5bd33972016-05-02 04:46:11 -07001644 }
1645 }
1646
1647 void InsertPacket(uint32_t timestamp) {
henrik.lundin246ef3e2017-04-24 09:14:32 -07001648 RTPHeader rtp_header;
1649 rtp_header.payloadType = kPayloadType;
1650 rtp_header.sequenceNumber = sequence_number_;
1651 rtp_header.timestamp = timestamp;
1652 rtp_header.ssrc = 15;
minyue5bd33972016-05-02 04:46:11 -07001653 const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
1654 uint8_t payload[kPayloadLengthBytes] = {0};
Karl Wiberg45eb1352019-10-10 14:23:00 +02001655 EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
minyue5bd33972016-05-02 04:46:11 -07001656 sequence_number_++;
1657 }
1658
1659 void Register120msCodec(AudioDecoder::SpeechType speech_type) {
Niels Möllera0f44302018-11-30 10:45:12 +01001660 const uint32_t sampling_freq = kSamplingFreq_;
1661 decoder_factory_ =
1662 new rtc::RefCountedObject<test::FunctionAudioDecoderFactory>(
1663 [sampling_freq, speech_type]() {
1664 std::unique_ptr<AudioDecoder> decoder =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001665 std::make_unique<Decoder120ms>(sampling_freq, speech_type);
Niels Möllera0f44302018-11-30 10:45:12 +01001666 RTC_CHECK_EQ(2, decoder->Channels());
1667 return decoder;
1668 });
minyue5bd33972016-05-02 04:46:11 -07001669 }
1670
Niels Möllera0f44302018-11-30 10:45:12 +01001671 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
minyue5bd33972016-05-02 04:46:11 -07001672 AudioFrame output_;
1673 const uint32_t kPayloadType = 17;
1674 const uint32_t kSamplingFreq_ = 48000;
1675 uint16_t sequence_number_ = 1;
1676};
1677
minyue5bd33972016-05-02 04:46:11 -07001678TEST_F(NetEqImplTest120ms, CodecInternalCng) {
minyue5bd33972016-05-02 04:46:11 -07001679 Register120msCodec(AudioDecoder::kComfortNoise);
Niels Möllera0f44302018-11-30 10:45:12 +01001680 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001681
1682 InsertPacket(first_timestamp());
1683 GetFirstPacket();
1684
henrik.lundin7a926812016-05-12 13:51:28 -07001685 bool muted;
1686 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001687 EXPECT_EQ(NetEq::Operation::kCodecInternalCng,
1688 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001689}
1690
1691TEST_F(NetEqImplTest120ms, Normal) {
minyue5bd33972016-05-02 04:46:11 -07001692 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001693 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001694
1695 InsertPacket(first_timestamp());
1696 GetFirstPacket();
1697
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001698 EXPECT_EQ(NetEq::Operation::kNormal, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001699}
1700
1701TEST_F(NetEqImplTest120ms, Merge) {
Niels Möllera0f44302018-11-30 10:45:12 +01001702 Register120msCodec(AudioDecoder::kSpeech);
minyue5bd33972016-05-02 04:46:11 -07001703 CreateInstanceWithDelayManagerMock();
1704
Ivo Creusen53a31f72019-10-24 15:20:39 +02001705 EXPECT_CALL(*mock_neteq_controller_, CngOff()).WillRepeatedly(Return(true));
minyue5bd33972016-05-02 04:46:11 -07001706 InsertPacket(first_timestamp());
1707
1708 GetFirstPacket();
henrik.lundin7a926812016-05-12 13:51:28 -07001709 bool muted;
Ivo Creusen53a31f72019-10-24 15:20:39 +02001710 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001711 .WillOnce(Return(NetEq::Operation::kExpand));
henrik.lundin7a926812016-05-12 13:51:28 -07001712 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
minyue5bd33972016-05-02 04:46:11 -07001713
1714 InsertPacket(first_timestamp() + 2 * timestamp_diff_between_packets());
1715
Ivo Creusen53a31f72019-10-24 15:20:39 +02001716 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001717 .WillOnce(Return(NetEq::Operation::kMerge));
minyue5bd33972016-05-02 04:46:11 -07001718
henrik.lundin7a926812016-05-12 13:51:28 -07001719 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001720 EXPECT_EQ(NetEq::Operation::kMerge, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001721}
1722
1723TEST_F(NetEqImplTest120ms, Expand) {
minyue5bd33972016-05-02 04:46:11 -07001724 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001725 CreateInstanceNoMocks();
minyue5bd33972016-05-02 04:46:11 -07001726
1727 InsertPacket(first_timestamp());
1728 GetFirstPacket();
1729
henrik.lundin7a926812016-05-12 13:51:28 -07001730 bool muted;
1731 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001732 EXPECT_EQ(NetEq::Operation::kExpand, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001733}
1734
1735TEST_F(NetEqImplTest120ms, FastAccelerate) {
minyue5bd33972016-05-02 04:46:11 -07001736 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001737 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001738
1739 InsertPacket(first_timestamp());
1740 GetFirstPacket();
1741 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1742
Ivo Creusen53a31f72019-10-24 15:20:39 +02001743 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001744 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001745 .WillOnce(Return(NetEq::Operation::kFastAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001746
henrik.lundin7a926812016-05-12 13:51:28 -07001747 bool muted;
1748 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001749 EXPECT_EQ(NetEq::Operation::kFastAccelerate,
1750 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001751}
1752
1753TEST_F(NetEqImplTest120ms, PreemptiveExpand) {
minyue5bd33972016-05-02 04:46:11 -07001754 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001755 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001756
1757 InsertPacket(first_timestamp());
1758 GetFirstPacket();
1759
1760 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1761
Ivo Creusen53a31f72019-10-24 15:20:39 +02001762 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001763 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001764 .WillOnce(Return(NetEq::Operation::kPreemptiveExpand));
minyue5bd33972016-05-02 04:46:11 -07001765
henrik.lundin7a926812016-05-12 13:51:28 -07001766 bool muted;
1767 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001768 EXPECT_EQ(NetEq::Operation::kPreemptiveExpand,
1769 neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001770}
1771
1772TEST_F(NetEqImplTest120ms, Accelerate) {
minyue5bd33972016-05-02 04:46:11 -07001773 Register120msCodec(AudioDecoder::kSpeech);
Niels Möllera0f44302018-11-30 10:45:12 +01001774 CreateInstanceWithDelayManagerMock();
minyue5bd33972016-05-02 04:46:11 -07001775
1776 InsertPacket(first_timestamp());
1777 GetFirstPacket();
1778
1779 InsertPacket(first_timestamp() + timestamp_diff_between_packets());
1780
Ivo Creusen53a31f72019-10-24 15:20:39 +02001781 EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
minyue5bd33972016-05-02 04:46:11 -07001782 .Times(1)
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001783 .WillOnce(Return(NetEq::Operation::kAccelerate));
minyue5bd33972016-05-02 04:46:11 -07001784
henrik.lundin7a926812016-05-12 13:51:28 -07001785 bool muted;
1786 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
Ivo Creusen3ce44a32019-10-31 14:38:11 +01001787 EXPECT_EQ(NetEq::Operation::kAccelerate, neteq_->last_operation_for_test());
minyue5bd33972016-05-02 04:46:11 -07001788}
1789
Alessio Bazzica8f319a32019-07-24 16:47:02 +00001790} // namespace webrtc