Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / neteq_impl_unittest.cc
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_,
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(&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