1 /* 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 11 #include "webrtc/modules/audio_coding/neteq/interface/neteq.h" 12 #include "webrtc/modules/audio_coding/neteq/neteq_impl.h" 13 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" 30 31 using ::testing::Return; 32 using ::testing::ReturnNull; 33 using ::testing::_; 34 using ::testing::SetArgPointee; 35 using ::testing::InSequence; 36 using ::testing::Invoke; 37 using ::testing::WithArg; 38 39 namespace webrtc { 40 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; 47 } 48 49 class NetEqImplTest : public ::testing::Test { 50 protected: 51 NetEqImplTest() 52 : neteq_(NULL), 53 config_(), 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), 64 delay_manager_(NULL), 65 use_mock_delay_manager_(true), 66 mock_dtmf_buffer_(NULL), 67 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), 73 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; 80 } 81 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_; 86 } else { 87 buffer_level_filter_ = new BufferLevelFilter; 88 } 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_; 94 } else { 95 decoder_database_ = new DecoderDatabase; 96 } 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_; 101 } else { 102 delay_peak_detector_ = new DelayPeakDetector; 103 } 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_; 109 } else { 110 delay_manager_ = 111 new DelayManager(config_.max_packets_in_buffer, delay_peak_detector_); 112 } 113 if (use_mock_dtmf_buffer_) { 114 mock_dtmf_buffer_ = new MockDtmfBuffer(config_.sample_rate_hz); 115 dtmf_buffer_ = mock_dtmf_buffer_; 116 } else { 117 dtmf_buffer_ = new DtmfBuffer(config_.sample_rate_hz); 118 } 119 if (use_mock_dtmf_tone_generator_) { 120 mock_dtmf_tone_generator_ = new MockDtmfToneGenerator; 121 dtmf_tone_generator_ = mock_dtmf_tone_generator_; 122 } else { 123 dtmf_tone_generator_ = new DtmfToneGenerator; 124 } 125 if (use_mock_packet_buffer_) { 126 mock_packet_buffer_ = new MockPacketBuffer(config_.max_packets_in_buffer); 127 packet_buffer_ = mock_packet_buffer_; 128 } else { 129 packet_buffer_ = new PacketBuffer(config_.max_packets_in_buffer); 130 } 131 if (use_mock_payload_splitter_) { 132 mock_payload_splitter_ = new MockPayloadSplitter; 133 payload_splitter_ = mock_payload_splitter_; 134 } else { 135 payload_splitter_ = new PayloadSplitter; 136 } 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; 142 143 neteq_ = new NetEqImpl(config_.sample_rate_hz, 144 buffer_level_filter_, 145 decoder_database_, 146 delay_manager_, 147 delay_peak_detector_, 148 dtmf_buffer_, 149 dtmf_tone_generator_, 150 packet_buffer_, 151 payload_splitter_, 152 timestamp_scaler_, 153 accelerate_factory, 154 expand_factory, 155 preemptive_expand_factory); 156 ASSERT_TRUE(neteq_ != NULL); 157 } 158 159 void UseNoMocks() { 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; 169 } 170 171 virtual ~NetEqImplTest() { 172 if (use_mock_buffer_level_filter_) { 173 EXPECT_CALL(*mock_buffer_level_filter_, Die()).Times(1); 174 } 175 if (use_mock_decoder_database_) { 176 EXPECT_CALL(*mock_decoder_database_, Die()).Times(1); 177 } 178 if (use_mock_delay_manager_) { 179 EXPECT_CALL(*mock_delay_manager_, Die()).Times(1); 180 } 181 if (use_mock_delay_peak_detector_) { 182 EXPECT_CALL(*mock_delay_peak_detector_, Die()).Times(1); 183 } 184 if (use_mock_dtmf_buffer_) { 185 EXPECT_CALL(*mock_dtmf_buffer_, Die()).Times(1); 186 } 187 if (use_mock_dtmf_tone_generator_) { 188 EXPECT_CALL(*mock_dtmf_tone_generator_, Die()).Times(1); 189 } 190 if (use_mock_packet_buffer_) { 191 EXPECT_CALL(*mock_packet_buffer_, Die()).Times(1); 192 } 193 delete neteq_; 194 } 195 196 NetEqImpl* neteq_; 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_; 223 }; 224 225 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); 231 delete neteq; 232 } 233 234 TEST_F(NetEqImplTest, RegisterPayloadType) { 235 CreateInstance(); 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); 241 } 242 243 TEST_F(NetEqImplTest, RemovePayloadType) { 244 CreateInstance(); 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)); 250 } 251 252 TEST_F(NetEqImplTest, InsertPacket) { 253 CreateInstance(); 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; 266 267 // Create a mock decoder object. 268 MockAudioDecoder mock_decoder; 269 // BWE update function called with first packet. 270 EXPECT_CALL(mock_decoder, IncomingPacket(_, 271 kPayloadLength, 272 kFirstSequenceNumber, 273 kFirstTimestamp, 274 kFirstReceiveTime)); 275 // BWE update function called with second packet. 276 EXPECT_CALL(mock_decoder, IncomingPacket(_, 277 kPayloadLength, 278 kFirstSequenceNumber + 1, 279 kFirstTimestamp + 160, 280 kFirstReceiveTime + 155)); 281 EXPECT_CALL(mock_decoder, Die()).Times(1); // Called when deleted. 282 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(_)) 287 .Times(2) 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)) 292 .Times(3) 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)); 300 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()) 309 .Times(1); 310 EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _)) 311 .Times(2) 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()) 319 .Times(1) 320 .WillOnce(Return(&rtp_header.header)); 321 322 // Expectations for DTMF buffer. 323 EXPECT_CALL(*mock_dtmf_buffer_, Flush()) 324 .Times(1); 325 326 // Expectations for delay manager. 327 { 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)) 332 .Times(1); 333 EXPECT_CALL(*mock_delay_manager_, last_pack_cng_or_dtmf()) 334 .Times(2) 335 .WillRepeatedly(Return(-1)); 336 EXPECT_CALL(*mock_delay_manager_, set_last_pack_cng_or_dtmf(0)) 337 .Times(1); 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)) 341 .Times(1); 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)); 346 } 347 348 // Expectations for payload splitter. 349 EXPECT_CALL(*mock_payload_splitter_, SplitAudio(_, _)) 350 .Times(2) 351 .WillRepeatedly(Return(PayloadSplitter::kOK)); 352 353 // Insert first packet. 354 neteq_->InsertPacket(rtp_header, payload, kPayloadLength, kFirstReceiveTime); 355 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); 361 } 362 363 TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) { 364 UseNoMocks(); 365 CreateInstance(); 366 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; 377 378 EXPECT_EQ(NetEq::kOK, 379 neteq_->RegisterPayloadType(kDecoderPCM16B, kPayloadType)); 380 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()); 389 } 390 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); 400 } 401 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) { 405 UseNoMocks(); 406 CreateInstance(); 407 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; 419 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 { 424 public: 425 explicit CountingSamplesDecoder(enum NetEqDecoder type) 426 : AudioDecoder(type), next_value_(1) {} 427 428 // Produce as many samples as input bytes (|encoded_len|). 429 virtual int Decode(const uint8_t* encoded, 430 size_t encoded_len, 431 int16_t* decoded, 432 SpeechType* speech_type) { 433 for (size_t i = 0; i < encoded_len; ++i) { 434 decoded[i] = next_value_++; 435 } 436 *speech_type = kSpeech; 437 return encoded_len; 438 } 439 440 virtual int Init() { 441 next_value_ = 1; 442 return 0; 443 } 444 445 uint16_t next_value() const { return next_value_; } 446 447 private: 448 int16_t next_value_; 449 } decoder_(kDecoderPCM16B); 450 451 EXPECT_EQ(NetEq::kOK, 452 neteq_->RegisterExternalDecoder( 453 &decoder_, kDecoderPCM16B, kPayloadType)); 454 455 // Insert one packet. 456 EXPECT_EQ(NetEq::kOK, 457 neteq_->InsertPacket( 458 rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); 459 460 // Pull audio once. 461 const int kMaxOutputSize = 10 * kSampleRateHz / 1000; 462 int16_t output[kMaxOutputSize]; 463 int samples_per_channel; 464 int num_channels; 465 NetEqOutputType type; 466 EXPECT_EQ( 467 NetEq::kOK, 468 neteq_->GetAudio( 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); 473 474 // Start with a simple check that the fake decoder is behaving as expected. 475 EXPECT_EQ(kPayloadLengthSamples, decoder_.next_value() - 1); 476 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], 483 timestamp); 484 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()); 491 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())); 496 } 497 498 } // namespace webrtc 499