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 "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/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
31using ::testing::Return;
32using ::testing::ReturnNull;
33using ::testing::_;
34using ::testing::SetArgPointee;
35using ::testing::InSequence;
36using ::testing::Invoke;
37using ::testing::WithArg;
38
39namespace 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.
44int DeletePacketsAndReturnOk(PacketList* packet_list) {
45  PacketBuffer::DeleteAllPackets(packet_list);
46  return PacketBuffer::kOK;
47}
48
49class 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_,
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?
228TEST(NetEq, CreateAndDestroy) {
229  NetEq::Config config;
230  NetEq* neteq = NetEq::Create(config);
231  delete neteq;
232}
233
234TEST_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
243TEST_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
252TEST_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
363TEST_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.
404TEST_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(&timestamp));
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