2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
12 #include "webrtc/modules/audio_coding/neteq/neteq_impl.h"
14 #include "gmock/gmock.h"
15 #include "gtest/gtest.h"
16 #include "webrtc/modules/audio_coding/neteq/accelerate.h"
17 #include "webrtc/modules/audio_coding/neteq/expand.h"
18 #include "webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h"
19 #include "webrtc/modules/audio_coding/neteq/mock/mock_buffer_level_filter.h"
20 #include "webrtc/modules/audio_coding/neteq/mock/mock_decoder_database.h"
21 #include "webrtc/modules/audio_coding/neteq/mock/mock_delay_manager.h"
22 #include "webrtc/modules/audio_coding/neteq/mock/mock_delay_peak_detector.h"
23 #include "webrtc/modules/audio_coding/neteq/mock/mock_dtmf_buffer.h"
24 #include "webrtc/modules/audio_coding/neteq/mock/mock_dtmf_tone_generator.h"
25 #include "webrtc/modules/audio_coding/neteq/mock/mock_packet_buffer.h"
26 #include "webrtc/modules/audio_coding/neteq/mock/mock_payload_splitter.h"
27 #include "webrtc/modules/audio_coding/neteq/preemptive_expand.h"
28 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h"
29 #include "webrtc/modules/audio_coding/neteq/timestamp_scaler.h"
31 using ::testing::Return;
32 using ::testing::ReturnNull;
34 using ::testing::SetArgPointee;
35 using ::testing::InSequence;
36 using ::testing::Invoke;
37 using ::testing::WithArg;
41 // This function is called when inserting a packet list into the mock packet
42 // buffer. The purpose is to delete all inserted packets properly, to avoid
43 // memory leaks in the test.
44 int DeletePacketsAndReturnOk(PacketList* packet_list) {
45 PacketBuffer::DeleteAllPackets(packet_list);
46 return PacketBuffer::kOK;
49 class NetEqImplTest : public ::testing::Test {
54 mock_buffer_level_filter_(NULL),
55 buffer_level_filter_(NULL),
56 use_mock_buffer_level_filter_(true),
57 mock_decoder_database_(NULL),
58 decoder_database_(NULL),
59 use_mock_decoder_database_(true),
60 mock_delay_peak_detector_(NULL),
61 delay_peak_detector_(NULL),
62 use_mock_delay_peak_detector_(true),
63 mock_delay_manager_(NULL),
65 use_mock_delay_manager_(true),
66 mock_dtmf_buffer_(NULL),
68 use_mock_dtmf_buffer_(true),
69 mock_dtmf_tone_generator_(NULL),
70 dtmf_tone_generator_(NULL),
71 use_mock_dtmf_tone_generator_(true),
72 mock_packet_buffer_(NULL),
74 use_mock_packet_buffer_(true),
75 mock_payload_splitter_(NULL),
76 payload_splitter_(NULL),
77 use_mock_payload_splitter_(true),
78 timestamp_scaler_(NULL) {
79 config_.sample_rate_hz = 8000;
82 void CreateInstance() {
83 if (use_mock_buffer_level_filter_) {
84 mock_buffer_level_filter_ = new MockBufferLevelFilter;
85 buffer_level_filter_ = mock_buffer_level_filter_;
87 buffer_level_filter_ = new BufferLevelFilter;
89 if (use_mock_decoder_database_) {
90 mock_decoder_database_ = new MockDecoderDatabase;
91 EXPECT_CALL(*mock_decoder_database_, GetActiveCngDecoder())
92 .WillOnce(ReturnNull());
93 decoder_database_ = mock_decoder_database_;
95 decoder_database_ = new DecoderDatabase;
97 if (use_mock_delay_peak_detector_) {
98 mock_delay_peak_detector_ = new MockDelayPeakDetector;
99 EXPECT_CALL(*mock_delay_peak_detector_, Reset()).Times(1);
100 delay_peak_detector_ = mock_delay_peak_detector_;
102 delay_peak_detector_ = new DelayPeakDetector;
104 if (use_mock_delay_manager_) {
105 mock_delay_manager_ = new MockDelayManager(config_.max_packets_in_buffer,
106 delay_peak_detector_);
107 EXPECT_CALL(*mock_delay_manager_, set_streaming_mode(false)).Times(1);
108 delay_manager_ = mock_delay_manager_;
111 new DelayManager(config_.max_packets_in_buffer, delay_peak_detector_);
113 if (use_mock_dtmf_buffer_) {
114 mock_dtmf_buffer_ = new MockDtmfBuffer(config_.sample_rate_hz);
115 dtmf_buffer_ = mock_dtmf_buffer_;
117 dtmf_buffer_ = new DtmfBuffer(config_.sample_rate_hz);
119 if (use_mock_dtmf_tone_generator_) {
120 mock_dtmf_tone_generator_ = new MockDtmfToneGenerator;
121 dtmf_tone_generator_ = mock_dtmf_tone_generator_;
123 dtmf_tone_generator_ = new DtmfToneGenerator;
125 if (use_mock_packet_buffer_) {
126 mock_packet_buffer_ = new MockPacketBuffer(config_.max_packets_in_buffer);
127 packet_buffer_ = mock_packet_buffer_;
129 packet_buffer_ = new PacketBuffer(config_.max_packets_in_buffer);
131 if (use_mock_payload_splitter_) {
132 mock_payload_splitter_ = new MockPayloadSplitter;
133 payload_splitter_ = mock_payload_splitter_;
135 payload_splitter_ = new PayloadSplitter;
137 timestamp_scaler_ = new TimestampScaler(*decoder_database_);
138 AccelerateFactory* accelerate_factory = new AccelerateFactory;
139 ExpandFactory* expand_factory = new ExpandFactory;
140 PreemptiveExpandFactory* preemptive_expand_factory =
141 new PreemptiveExpandFactory;
143 neteq_ = new NetEqImpl(config_,
144 buffer_level_filter_,
147 delay_peak_detector_,
149 dtmf_tone_generator_,
155 preemptive_expand_factory);
156 ASSERT_TRUE(neteq_ != NULL);
160 ASSERT_TRUE(neteq_ == NULL) << "Must call UseNoMocks before CreateInstance";
161 use_mock_buffer_level_filter_ = false;
162 use_mock_decoder_database_ = false;
163 use_mock_delay_peak_detector_ = false;
164 use_mock_delay_manager_ = false;
165 use_mock_dtmf_buffer_ = false;
166 use_mock_dtmf_tone_generator_ = false;
167 use_mock_packet_buffer_ = false;
168 use_mock_payload_splitter_ = false;
171 virtual ~NetEqImplTest() {
172 if (use_mock_buffer_level_filter_) {
173 EXPECT_CALL(*mock_buffer_level_filter_, Die()).Times(1);
175 if (use_mock_decoder_database_) {
176 EXPECT_CALL(*mock_decoder_database_, Die()).Times(1);
178 if (use_mock_delay_manager_) {
179 EXPECT_CALL(*mock_delay_manager_, Die()).Times(1);
181 if (use_mock_delay_peak_detector_) {
182 EXPECT_CALL(*mock_delay_peak_detector_, Die()).Times(1);
184 if (use_mock_dtmf_buffer_) {
185 EXPECT_CALL(*mock_dtmf_buffer_, Die()).Times(1);
187 if (use_mock_dtmf_tone_generator_) {
188 EXPECT_CALL(*mock_dtmf_tone_generator_, Die()).Times(1);
190 if (use_mock_packet_buffer_) {
191 EXPECT_CALL(*mock_packet_buffer_, Die()).Times(1);
197 NetEq::Config config_;
198 MockBufferLevelFilter* mock_buffer_level_filter_;
199 BufferLevelFilter* buffer_level_filter_;
200 bool use_mock_buffer_level_filter_;
201 MockDecoderDatabase* mock_decoder_database_;
202 DecoderDatabase* decoder_database_;
203 bool use_mock_decoder_database_;
204 MockDelayPeakDetector* mock_delay_peak_detector_;
205 DelayPeakDetector* delay_peak_detector_;
206 bool use_mock_delay_peak_detector_;
207 MockDelayManager* mock_delay_manager_;
208 DelayManager* delay_manager_;
209 bool use_mock_delay_manager_;
210 MockDtmfBuffer* mock_dtmf_buffer_;
211 DtmfBuffer* dtmf_buffer_;
212 bool use_mock_dtmf_buffer_;
213 MockDtmfToneGenerator* mock_dtmf_tone_generator_;
214 DtmfToneGenerator* dtmf_tone_generator_;
215 bool use_mock_dtmf_tone_generator_;
216 MockPacketBuffer* mock_packet_buffer_;
217 PacketBuffer* packet_buffer_;
218 bool use_mock_packet_buffer_;
219 MockPayloadSplitter* mock_payload_splitter_;
220 PayloadSplitter* payload_splitter_;
221 bool use_mock_payload_splitter_;
222 TimestampScaler* timestamp_scaler_;
226 // This tests the interface class NetEq.
227 // TODO(hlundin): Move to separate file?
228 TEST(NetEq, CreateAndDestroy) {
229 NetEq::Config config;
230 NetEq* neteq = NetEq::Create(config);
234 TEST_F(NetEqImplTest, RegisterPayloadType) {
236 uint8_t rtp_payload_type = 0;
237 NetEqDecoder codec_type = kDecoderPCMu;
238 EXPECT_CALL(*mock_decoder_database_,
239 RegisterPayload(rtp_payload_type, codec_type));
240 neteq_->RegisterPayloadType(codec_type, rtp_payload_type);
243 TEST_F(NetEqImplTest, RemovePayloadType) {
245 uint8_t rtp_payload_type = 0;
246 EXPECT_CALL(*mock_decoder_database_, Remove(rtp_payload_type))
247 .WillOnce(Return(DecoderDatabase::kDecoderNotFound));
248 // Check that kFail is returned when database returns kDecoderNotFound.
249 EXPECT_EQ(NetEq::kFail, neteq_->RemovePayloadType(rtp_payload_type));
252 TEST_F(NetEqImplTest, InsertPacket) {
254 const int kPayloadLength = 100;
255 const uint8_t kPayloadType = 0;
256 const uint16_t kFirstSequenceNumber = 0x1234;
257 const uint32_t kFirstTimestamp = 0x12345678;
258 const uint32_t kSsrc = 0x87654321;
259 const uint32_t kFirstReceiveTime = 17;
260 uint8_t payload[kPayloadLength] = {0};
261 WebRtcRTPHeader rtp_header;
262 rtp_header.header.payloadType = kPayloadType;
263 rtp_header.header.sequenceNumber = kFirstSequenceNumber;
264 rtp_header.header.timestamp = kFirstTimestamp;
265 rtp_header.header.ssrc = kSsrc;
267 // Create a mock decoder object.
268 MockAudioDecoder mock_decoder;
269 // BWE update function called with first packet.
270 EXPECT_CALL(mock_decoder, IncomingPacket(_,
272 kFirstSequenceNumber,
275 // BWE update function called with second packet.
276 EXPECT_CALL(mock_decoder, IncomingPacket(_,
278 kFirstSequenceNumber + 1,
279 kFirstTimestamp + 160,
280 kFirstReceiveTime + 155));
281 EXPECT_CALL(mock_decoder, Die()).Times(1); // Called when deleted.
283 // Expectations for decoder database.
284 EXPECT_CALL(*mock_decoder_database_, IsRed(kPayloadType))
285 .WillRepeatedly(Return(false)); // This is not RED.
286 EXPECT_CALL(*mock_decoder_database_, CheckPayloadTypes(_))
288 .WillRepeatedly(Return(DecoderDatabase::kOK)); // Payload type is valid.
289 EXPECT_CALL(*mock_decoder_database_, IsDtmf(kPayloadType))
290 .WillRepeatedly(Return(false)); // This is not DTMF.
291 EXPECT_CALL(*mock_decoder_database_, GetDecoder(kPayloadType))
293 .WillRepeatedly(Return(&mock_decoder));
294 EXPECT_CALL(*mock_decoder_database_, IsComfortNoise(kPayloadType))
295 .WillRepeatedly(Return(false)); // This is not CNG.
296 DecoderDatabase::DecoderInfo info;
297 info.codec_type = kDecoderPCMu;
298 EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
299 .WillRepeatedly(Return(&info));
301 // Expectations for packet buffer.
302 EXPECT_CALL(*mock_packet_buffer_, NumPacketsInBuffer())
303 .WillOnce(Return(0)) // First packet.
304 .WillOnce(Return(1)) // Second packet.
305 .WillOnce(Return(2)); // Second packet, checking after it was inserted.
306 EXPECT_CALL(*mock_packet_buffer_, Empty())
307 .WillOnce(Return(false)); // Called once after first packet is inserted.
308 EXPECT_CALL(*mock_packet_buffer_, Flush())
310 EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _))
312 .WillRepeatedly(DoAll(SetArgPointee<2>(kPayloadType),
313 WithArg<0>(Invoke(DeletePacketsAndReturnOk))));
314 // SetArgPointee<2>(kPayloadType) means that the third argument (zero-based
315 // index) is a pointer, and the variable pointed to is set to kPayloadType.
316 // Also invoke the function DeletePacketsAndReturnOk to properly delete all
317 // packets in the list (to avoid memory leaks in the test).
318 EXPECT_CALL(*mock_packet_buffer_, NextRtpHeader())
320 .WillOnce(Return(&rtp_header.header));
322 // Expectations for DTMF buffer.
323 EXPECT_CALL(*mock_dtmf_buffer_, Flush())
326 // Expectations for delay manager.
328 // All expectations within this block must be called in this specific order.
329 InSequence sequence; // Dummy variable.
330 // Expectations when the first packet is inserted.
331 EXPECT_CALL(*mock_delay_manager_, LastDecoderType(kDecoderPCMu))
333 EXPECT_CALL(*mock_delay_manager_, last_pack_cng_or_dtmf())
335 .WillRepeatedly(Return(-1));
336 EXPECT_CALL(*mock_delay_manager_, set_last_pack_cng_or_dtmf(0))
338 EXPECT_CALL(*mock_delay_manager_, ResetPacketIatCount()).Times(1);
339 // Expectations when the second packet is inserted. Slightly different.
340 EXPECT_CALL(*mock_delay_manager_, LastDecoderType(kDecoderPCMu))
342 EXPECT_CALL(*mock_delay_manager_, last_pack_cng_or_dtmf())
343 .WillOnce(Return(0));
344 EXPECT_CALL(*mock_delay_manager_, SetPacketAudioLength(30))
345 .WillOnce(Return(0));
348 // Expectations for payload splitter.
349 EXPECT_CALL(*mock_payload_splitter_, SplitAudio(_, _))
351 .WillRepeatedly(Return(PayloadSplitter::kOK));
353 // Insert first packet.
354 neteq_->InsertPacket(rtp_header, payload, kPayloadLength, kFirstReceiveTime);
356 // Insert second packet.
357 rtp_header.header.timestamp += 160;
358 rtp_header.header.sequenceNumber += 1;
359 neteq_->InsertPacket(rtp_header, payload, kPayloadLength,
360 kFirstReceiveTime + 155);
363 TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
367 const int kPayloadLengthSamples = 80;
368 const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
369 const uint8_t kPayloadType = 17; // Just an arbitrary number.
370 const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
371 uint8_t payload[kPayloadLengthBytes] = {0};
372 WebRtcRTPHeader rtp_header;
373 rtp_header.header.payloadType = kPayloadType;
374 rtp_header.header.sequenceNumber = 0x1234;
375 rtp_header.header.timestamp = 0x12345678;
376 rtp_header.header.ssrc = 0x87654321;
378 EXPECT_EQ(NetEq::kOK,
379 neteq_->RegisterPayloadType(kDecoderPCM16B, kPayloadType));
381 // Insert packets. The buffer should not flush.
382 for (int i = 1; i <= config_.max_packets_in_buffer; ++i) {
383 EXPECT_EQ(NetEq::kOK,
384 neteq_->InsertPacket(
385 rtp_header, payload, kPayloadLengthBytes, kReceiveTime));
386 rtp_header.header.timestamp += kPayloadLengthSamples;
387 rtp_header.header.sequenceNumber += 1;
388 EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
391 // Insert one more packet and make sure the buffer got flushed. That is, it
392 // should only hold one single packet.
393 EXPECT_EQ(NetEq::kOK,
394 neteq_->InsertPacket(
395 rtp_header, payload, kPayloadLengthBytes, kReceiveTime));
396 EXPECT_EQ(1, packet_buffer_->NumPacketsInBuffer());
397 const RTPHeader* test_header = packet_buffer_->NextRtpHeader();
398 EXPECT_EQ(rtp_header.header.timestamp, test_header->timestamp);
399 EXPECT_EQ(rtp_header.header.sequenceNumber, test_header->sequenceNumber);
402 // This test verifies that timestamps propagate from the incoming packets
403 // through to the sync buffer and to the playout timestamp.
404 TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
408 const uint8_t kPayloadType = 17; // Just an arbitrary number.
409 const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
410 const int kSampleRateHz = 8000;
411 const int kPayloadLengthSamples = 10 * kSampleRateHz / 1000; // 10 ms.
412 const size_t kPayloadLengthBytes = kPayloadLengthSamples;
413 uint8_t payload[kPayloadLengthBytes] = {0};
414 WebRtcRTPHeader rtp_header;
415 rtp_header.header.payloadType = kPayloadType;
416 rtp_header.header.sequenceNumber = 0x1234;
417 rtp_header.header.timestamp = 0x12345678;
418 rtp_header.header.ssrc = 0x87654321;
420 // This is a dummy decoder that produces as many output samples as the input
421 // has bytes. The output is an increasing series, starting at 1 for the first
422 // sample, and then increasing by 1 for each sample.
423 class CountingSamplesDecoder : public AudioDecoder {
425 explicit CountingSamplesDecoder(enum NetEqDecoder type)
426 : AudioDecoder(type), next_value_(1) {}
428 // Produce as many samples as input bytes (|encoded_len|).
429 virtual int Decode(const uint8_t* encoded,
432 SpeechType* speech_type) {
433 for (size_t i = 0; i < encoded_len; ++i) {
434 decoded[i] = next_value_++;
436 *speech_type = kSpeech;
445 uint16_t next_value() const { return next_value_; }
449 } decoder_(kDecoderPCM16B);
451 EXPECT_EQ(NetEq::kOK,
452 neteq_->RegisterExternalDecoder(
453 &decoder_, kDecoderPCM16B, kPayloadType));
455 // Insert one packet.
456 EXPECT_EQ(NetEq::kOK,
457 neteq_->InsertPacket(
458 rtp_header, payload, kPayloadLengthBytes, kReceiveTime));
461 const int kMaxOutputSize = 10 * kSampleRateHz / 1000;
462 int16_t output[kMaxOutputSize];
463 int samples_per_channel;
465 NetEqOutputType type;
469 kMaxOutputSize, output, &samples_per_channel, &num_channels, &type));
470 ASSERT_EQ(kMaxOutputSize, samples_per_channel);
471 EXPECT_EQ(1, num_channels);
472 EXPECT_EQ(kOutputNormal, type);
474 // Start with a simple check that the fake decoder is behaving as expected.
475 EXPECT_EQ(kPayloadLengthSamples, decoder_.next_value() - 1);
477 // The value of the last of the output samples is the same as the number of
478 // samples played from the decoded packet. Thus, this number + the RTP
479 // timestamp should match the playout timestamp.
480 uint32_t timestamp = 0;
481 EXPECT_TRUE(neteq_->GetPlayoutTimestamp(×tamp));
482 EXPECT_EQ(rtp_header.header.timestamp + output[samples_per_channel - 1],
485 // Check the timestamp for the last value in the sync buffer. This should
486 // be one full frame length ahead of the RTP timestamp.
487 const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
488 ASSERT_TRUE(sync_buffer != NULL);
489 EXPECT_EQ(rtp_header.header.timestamp + kPayloadLengthSamples,
490 sync_buffer->end_timestamp());
492 // Check that the number of samples still to play from the sync buffer add
493 // up with what was already played out.
494 EXPECT_EQ(kPayloadLengthSamples - output[samples_per_channel - 1],
495 static_cast<int>(sync_buffer->FutureLength()));
498 } // namespace webrtc