Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / payload_splitter_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 // Unit tests for PayloadSplitter class.
12
13 #include "webrtc/modules/audio_coding/neteq/payload_splitter.h"
14
15 #include <assert.h>
16
17 #include <utility>  // pair
18
19 #include "gtest/gtest.h"
20 #include "webrtc/modules/audio_coding/neteq/mock/mock_decoder_database.h"
21 #include "webrtc/modules/audio_coding/neteq/packet.h"
22 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
23
24 using ::testing::Return;
25 using ::testing::ReturnNull;
26
27 namespace webrtc {
28
29 static const int kRedPayloadType = 100;
30 static const int kPayloadLength = 10;
31 static const int kRedHeaderLength = 4;  // 4 bytes RED header.
32 static const uint16_t kSequenceNumber = 0;
33 static const uint32_t kBaseTimestamp = 0x12345678;
34
35 // RED headers (according to RFC 2198):
36 //
37 //    0                   1                   2                   3
38 //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
39 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 //   |F|   block PT  |  timestamp offset         |   block length    |
41 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 //
43 // Last RED header:
44 //    0 1 2 3 4 5 6 7
45 //   +-+-+-+-+-+-+-+-+
46 //   |0|   Block PT  |
47 //   +-+-+-+-+-+-+-+-+
48
49 // Creates a RED packet, with |num_payloads| payloads, with payload types given
50 // by the values in array |payload_types| (which must be of length
51 // |num_payloads|). Each redundant payload is |timestamp_offset| samples
52 // "behind" the the previous payload.
53 Packet* CreateRedPayload(int num_payloads,
54                          uint8_t* payload_types,
55                          int timestamp_offset) {
56   Packet* packet = new Packet;
57   packet->header.payloadType = kRedPayloadType;
58   packet->header.timestamp = kBaseTimestamp;
59   packet->header.sequenceNumber = kSequenceNumber;
60   packet->payload_length = (kPayloadLength + 1) +
61       (num_payloads - 1) * (kPayloadLength + kRedHeaderLength);
62   uint8_t* payload = new uint8_t[packet->payload_length];
63   uint8_t* payload_ptr = payload;
64   for (int i = 0; i < num_payloads; ++i) {
65     // Write the RED headers.
66     if (i == num_payloads - 1) {
67       // Special case for last payload.
68       *payload_ptr = payload_types[i] & 0x7F;  // F = 0;
69       ++payload_ptr;
70       break;
71     }
72     *payload_ptr = payload_types[i] & 0x7F;
73     // Not the last block; set F = 1.
74     *payload_ptr |= 0x80;
75     ++payload_ptr;
76     int this_offset = (num_payloads - i - 1) * timestamp_offset;
77     *payload_ptr = this_offset >> 6;
78     ++payload_ptr;
79     assert(kPayloadLength <= 1023);  // Max length described by 10 bits.
80     *payload_ptr = ((this_offset & 0x3F) << 2) | (kPayloadLength >> 8);
81     ++payload_ptr;
82     *payload_ptr = kPayloadLength & 0xFF;
83     ++payload_ptr;
84   }
85   for (int i = 0; i < num_payloads; ++i) {
86     // Write |i| to all bytes in each payload.
87     memset(payload_ptr, i, kPayloadLength);
88     payload_ptr += kPayloadLength;
89   }
90   packet->payload = payload;
91   return packet;
92 }
93
94
95 // A possible Opus packet that contains FEC is the following.
96 // The frame is 20 ms in duration.
97 //
98 // 0                   1                   2                   3
99 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
100 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101 // |0|0|0|0|1|0|0|0|x|1|x|x|x|x|x|x|x|                             |
102 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                             |
103 // |                    Compressed frame 1 (N-2 bytes)...          :
104 // :                                                               |
105 // |                                                               |
106 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
107 Packet* CreateOpusFecPacket(uint8_t payload_type, int payload_length,
108                             uint8_t payload_value) {
109   Packet* packet = new Packet;
110   packet->header.payloadType = payload_type;
111   packet->header.timestamp = kBaseTimestamp;
112   packet->header.sequenceNumber = kSequenceNumber;
113   packet->payload_length = payload_length;
114   uint8_t* payload = new uint8_t[packet->payload_length];
115   payload[0] = 0x08;
116   payload[1] = 0x40;
117   memset(&payload[2], payload_value, payload_length - 2);
118   packet->payload = payload;
119   return packet;
120 }
121
122 // Create a packet with all payload bytes set to |payload_value|.
123 Packet* CreatePacket(uint8_t payload_type, int payload_length,
124                      uint8_t payload_value) {
125   Packet* packet = new Packet;
126   packet->header.payloadType = payload_type;
127   packet->header.timestamp = kBaseTimestamp;
128   packet->header.sequenceNumber = kSequenceNumber;
129   packet->payload_length = payload_length;
130   uint8_t* payload = new uint8_t[packet->payload_length];
131   memset(payload, payload_value, payload_length);
132   packet->payload = payload;
133   return packet;
134 }
135
136 // Checks that |packet| has the attributes given in the remaining parameters.
137 void VerifyPacket(const Packet* packet,
138                   int payload_length,
139                   uint8_t payload_type,
140                   uint16_t sequence_number,
141                   uint32_t timestamp,
142                   uint8_t payload_value,
143                   bool primary = true) {
144   EXPECT_EQ(payload_length, packet->payload_length);
145   EXPECT_EQ(payload_type, packet->header.payloadType);
146   EXPECT_EQ(sequence_number, packet->header.sequenceNumber);
147   EXPECT_EQ(timestamp, packet->header.timestamp);
148   EXPECT_EQ(primary, packet->primary);
149   ASSERT_FALSE(packet->payload == NULL);
150   for (int i = 0; i < packet->payload_length; ++i) {
151     EXPECT_EQ(payload_value, packet->payload[i]);
152   }
153 }
154
155 // Start of test definitions.
156
157 TEST(PayloadSplitter, CreateAndDestroy) {
158   PayloadSplitter* splitter = new PayloadSplitter;
159   delete splitter;
160 }
161
162 // Packet A is split into A1 and A2.
163 TEST(RedPayloadSplitter, OnePacketTwoPayloads) {
164   uint8_t payload_types[] = {0, 0};
165   const int kTimestampOffset = 160;
166   Packet* packet = CreateRedPayload(2, payload_types, kTimestampOffset);
167   PacketList packet_list;
168   packet_list.push_back(packet);
169   PayloadSplitter splitter;
170   EXPECT_EQ(PayloadSplitter::kOK, splitter.SplitRed(&packet_list));
171   ASSERT_EQ(2u, packet_list.size());
172   // Check first packet. The first in list should always be the primary payload.
173   packet = packet_list.front();
174   VerifyPacket(packet, kPayloadLength, payload_types[1], kSequenceNumber,
175                kBaseTimestamp, 1, true);
176   delete [] packet->payload;
177   delete packet;
178   packet_list.pop_front();
179   // Check second packet.
180   packet = packet_list.front();
181   VerifyPacket(packet, kPayloadLength, payload_types[0], kSequenceNumber,
182                kBaseTimestamp - kTimestampOffset, 0, false);
183   delete [] packet->payload;
184   delete packet;
185 }
186
187 // Packets A and B are not split at all. Only the RED header in each packet is
188 // removed.
189 TEST(RedPayloadSplitter, TwoPacketsOnePayload) {
190   uint8_t payload_types[] = {0};
191   const int kTimestampOffset = 160;
192   // Create first packet, with a single RED payload.
193   Packet* packet = CreateRedPayload(1, payload_types, kTimestampOffset);
194   PacketList packet_list;
195   packet_list.push_back(packet);
196   // Create second packet, with a single RED payload.
197   packet = CreateRedPayload(1, payload_types, kTimestampOffset);
198   // Manually change timestamp and sequence number of second packet.
199   packet->header.timestamp += kTimestampOffset;
200   packet->header.sequenceNumber++;
201   packet_list.push_back(packet);
202   PayloadSplitter splitter;
203   EXPECT_EQ(PayloadSplitter::kOK, splitter.SplitRed(&packet_list));
204   ASSERT_EQ(2u, packet_list.size());
205   // Check first packet.
206   packet = packet_list.front();
207   VerifyPacket(packet, kPayloadLength, payload_types[0], kSequenceNumber,
208                kBaseTimestamp, 0, true);
209   delete [] packet->payload;
210   delete packet;
211   packet_list.pop_front();
212   // Check second packet.
213   packet = packet_list.front();
214   VerifyPacket(packet, kPayloadLength, payload_types[0], kSequenceNumber + 1,
215                kBaseTimestamp + kTimestampOffset, 0, true);
216   delete [] packet->payload;
217   delete packet;
218 }
219
220 // Packets A and B are split into packets A1, A2, A3, B1, B2, B3, with
221 // attributes as follows:
222 //
223 //                  A1*   A2    A3    B1*   B2    B3
224 // Payload type     0     1     2     0     1     2
225 // Timestamp        b     b-o   b-2o  b+o   b     b-o
226 // Sequence number  0     0     0     1     1     1
227 //
228 // b = kBaseTimestamp, o = kTimestampOffset, * = primary.
229 TEST(RedPayloadSplitter, TwoPacketsThreePayloads) {
230   uint8_t payload_types[] = {2, 1, 0};  // Primary is the last one.
231   const int kTimestampOffset = 160;
232   // Create first packet, with 3 RED payloads.
233   Packet* packet = CreateRedPayload(3, payload_types, kTimestampOffset);
234   PacketList packet_list;
235   packet_list.push_back(packet);
236   // Create first packet, with 3 RED payloads.
237   packet = CreateRedPayload(3, payload_types, kTimestampOffset);
238   // Manually change timestamp and sequence number of second packet.
239   packet->header.timestamp += kTimestampOffset;
240   packet->header.sequenceNumber++;
241   packet_list.push_back(packet);
242   PayloadSplitter splitter;
243   EXPECT_EQ(PayloadSplitter::kOK, splitter.SplitRed(&packet_list));
244   ASSERT_EQ(6u, packet_list.size());
245   // Check first packet, A1.
246   packet = packet_list.front();
247   VerifyPacket(packet, kPayloadLength, payload_types[2], kSequenceNumber,
248                kBaseTimestamp, 2, true);
249   delete [] packet->payload;
250   delete packet;
251   packet_list.pop_front();
252   // Check second packet, A2.
253   packet = packet_list.front();
254   VerifyPacket(packet, kPayloadLength, payload_types[1], kSequenceNumber,
255                kBaseTimestamp - kTimestampOffset, 1, false);
256   delete [] packet->payload;
257   delete packet;
258   packet_list.pop_front();
259   // Check third packet, A3.
260   packet = packet_list.front();
261   VerifyPacket(packet, kPayloadLength, payload_types[0], kSequenceNumber,
262                kBaseTimestamp - 2 * kTimestampOffset, 0, false);
263   delete [] packet->payload;
264   delete packet;
265   packet_list.pop_front();
266   // Check fourth packet, B1.
267   packet = packet_list.front();
268   VerifyPacket(packet, kPayloadLength, payload_types[2], kSequenceNumber + 1,
269                kBaseTimestamp + kTimestampOffset, 2, true);
270   delete [] packet->payload;
271   delete packet;
272   packet_list.pop_front();
273   // Check fifth packet, B2.
274   packet = packet_list.front();
275   VerifyPacket(packet, kPayloadLength, payload_types[1], kSequenceNumber + 1,
276                kBaseTimestamp, 1, false);
277   delete [] packet->payload;
278   delete packet;
279   packet_list.pop_front();
280   // Check sixth packet, B3.
281   packet = packet_list.front();
282   VerifyPacket(packet, kPayloadLength, payload_types[0], kSequenceNumber + 1,
283                kBaseTimestamp - kTimestampOffset, 0, false);
284   delete [] packet->payload;
285   delete packet;
286 }
287
288 // Creates a list with 4 packets with these payload types:
289 // 0 = CNGnb
290 // 1 = PCMu
291 // 2 = DTMF (AVT)
292 // 3 = iLBC
293 // We expect the method CheckRedPayloads to discard the iLBC packet, since it
294 // is a non-CNG, non-DTMF payload of another type than the first speech payload
295 // found in the list (which is PCMu).
296 TEST(RedPayloadSplitter, CheckRedPayloads) {
297   PacketList packet_list;
298   for (int i = 0; i <= 3; ++i) {
299     // Create packet with payload type |i|, payload length 10 bytes, all 0.
300     Packet* packet = CreatePacket(i, 10, 0);
301     packet_list.push_back(packet);
302   }
303
304   // Use a real DecoderDatabase object here instead of a mock, since it is
305   // easier to just register the payload types and let the actual implementation
306   // do its job.
307   DecoderDatabase decoder_database;
308   decoder_database.RegisterPayload(0, kDecoderCNGnb);
309   decoder_database.RegisterPayload(1, kDecoderPCMu);
310   decoder_database.RegisterPayload(2, kDecoderAVT);
311   decoder_database.RegisterPayload(3, kDecoderILBC);
312
313   PayloadSplitter splitter;
314   splitter.CheckRedPayloads(&packet_list, decoder_database);
315
316   ASSERT_EQ(3u, packet_list.size());  // Should have dropped the last packet.
317   // Verify packets. The loop verifies that payload types 0, 1, and 2 are in the
318   // list.
319   for (int i = 0; i <= 2; ++i) {
320     Packet* packet = packet_list.front();
321     VerifyPacket(packet, 10, i, kSequenceNumber, kBaseTimestamp, 0, true);
322     delete [] packet->payload;
323     delete packet;
324     packet_list.pop_front();
325   }
326   EXPECT_TRUE(packet_list.empty());
327 }
328
329 // Packet A is split into A1, A2 and A3. But the length parameter is off, so
330 // the last payloads should be discarded.
331 TEST(RedPayloadSplitter, WrongPayloadLength) {
332   uint8_t payload_types[] = {0, 0, 0};
333   const int kTimestampOffset = 160;
334   Packet* packet = CreateRedPayload(3, payload_types, kTimestampOffset);
335   // Manually tamper with the payload length of the packet.
336   // This is one byte too short for the second payload (out of three).
337   // We expect only the first payload to be returned.
338   packet->payload_length -= kPayloadLength + 1;
339   PacketList packet_list;
340   packet_list.push_back(packet);
341   PayloadSplitter splitter;
342   EXPECT_EQ(PayloadSplitter::kRedLengthMismatch,
343             splitter.SplitRed(&packet_list));
344   ASSERT_EQ(1u, packet_list.size());
345   // Check first packet.
346   packet = packet_list.front();
347   VerifyPacket(packet, kPayloadLength, payload_types[0], kSequenceNumber,
348                kBaseTimestamp - 2 * kTimestampOffset, 0, false);
349   delete [] packet->payload;
350   delete packet;
351   packet_list.pop_front();
352 }
353
354 // Test that iSAC, iSAC-swb, RED, DTMF, CNG, and "Arbitrary" payloads do not
355 // get split.
356 TEST(AudioPayloadSplitter, NonSplittable) {
357   // Set up packets with different RTP payload types. The actual values do not
358   // matter, since we are mocking the decoder database anyway.
359   PacketList packet_list;
360   for (int i = 0; i < 6; ++i) {
361     // Let the payload type be |i|, and the payload value 10 * |i|.
362     packet_list.push_back(CreatePacket(i, kPayloadLength, 10 * i));
363   }
364
365   MockDecoderDatabase decoder_database;
366   // Tell the mock decoder database to return DecoderInfo structs with different
367   // codec types.
368   // Use scoped pointers to avoid having to delete them later.
369   scoped_ptr<DecoderDatabase::DecoderInfo> info0(
370       new DecoderDatabase::DecoderInfo(kDecoderISAC, 16000, NULL, false));
371   EXPECT_CALL(decoder_database, GetDecoderInfo(0))
372       .WillRepeatedly(Return(info0.get()));
373   scoped_ptr<DecoderDatabase::DecoderInfo> info1(
374       new DecoderDatabase::DecoderInfo(kDecoderISACswb, 32000, NULL, false));
375   EXPECT_CALL(decoder_database, GetDecoderInfo(1))
376       .WillRepeatedly(Return(info1.get()));
377   scoped_ptr<DecoderDatabase::DecoderInfo> info2(
378       new DecoderDatabase::DecoderInfo(kDecoderRED, 8000, NULL, false));
379   EXPECT_CALL(decoder_database, GetDecoderInfo(2))
380       .WillRepeatedly(Return(info2.get()));
381   scoped_ptr<DecoderDatabase::DecoderInfo> info3(
382       new DecoderDatabase::DecoderInfo(kDecoderAVT, 8000, NULL, false));
383   EXPECT_CALL(decoder_database, GetDecoderInfo(3))
384       .WillRepeatedly(Return(info3.get()));
385   scoped_ptr<DecoderDatabase::DecoderInfo> info4(
386       new DecoderDatabase::DecoderInfo(kDecoderCNGnb, 8000, NULL, false));
387   EXPECT_CALL(decoder_database, GetDecoderInfo(4))
388       .WillRepeatedly(Return(info4.get()));
389   scoped_ptr<DecoderDatabase::DecoderInfo> info5(
390       new DecoderDatabase::DecoderInfo(kDecoderArbitrary, 8000, NULL, false));
391   EXPECT_CALL(decoder_database, GetDecoderInfo(5))
392       .WillRepeatedly(Return(info5.get()));
393
394   PayloadSplitter splitter;
395   EXPECT_EQ(0, splitter.SplitAudio(&packet_list, decoder_database));
396   EXPECT_EQ(6u, packet_list.size());
397
398   // Check that all payloads are intact.
399   uint8_t payload_type = 0;
400   PacketList::iterator it = packet_list.begin();
401   while (it != packet_list.end()) {
402     VerifyPacket((*it), kPayloadLength, payload_type, kSequenceNumber,
403                  kBaseTimestamp, 10 * payload_type);
404     ++payload_type;
405     delete [] (*it)->payload;
406     delete (*it);
407     it = packet_list.erase(it);
408   }
409
410   // The destructor is called when decoder_database goes out of scope.
411   EXPECT_CALL(decoder_database, Die());
412 }
413
414 // Test unknown payload type.
415 TEST(AudioPayloadSplitter, UnknownPayloadType) {
416   PacketList packet_list;
417   static const uint8_t kPayloadType = 17;  // Just a random number.
418   int kPayloadLengthBytes = 4711;  // Random number.
419   packet_list.push_back(CreatePacket(kPayloadType, kPayloadLengthBytes, 0));
420
421   MockDecoderDatabase decoder_database;
422   // Tell the mock decoder database to return NULL when asked for decoder info.
423   // This signals that the decoder database does not recognize the payload type.
424   EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
425       .WillRepeatedly(ReturnNull());
426
427   PayloadSplitter splitter;
428   EXPECT_EQ(PayloadSplitter::kUnknownPayloadType,
429             splitter.SplitAudio(&packet_list, decoder_database));
430   EXPECT_EQ(1u, packet_list.size());
431
432
433   // Delete the packets and payloads to avoid having the test leak memory.
434   PacketList::iterator it = packet_list.begin();
435   while (it != packet_list.end()) {
436     delete [] (*it)->payload;
437     delete (*it);
438     it = packet_list.erase(it);
439   }
440
441   // The destructor is called when decoder_database goes out of scope.
442   EXPECT_CALL(decoder_database, Die());
443 }
444
445 class SplitBySamplesTest : public ::testing::TestWithParam<NetEqDecoder> {
446  protected:
447   virtual void SetUp() {
448     decoder_type_ = GetParam();
449     switch (decoder_type_) {
450       case kDecoderPCMu:
451       case kDecoderPCMa:
452         bytes_per_ms_ = 8;
453         samples_per_ms_ = 8;
454         break;
455       case kDecoderPCMu_2ch:
456       case kDecoderPCMa_2ch:
457         bytes_per_ms_ = 2 * 8;
458         samples_per_ms_ = 8;
459         break;
460       case kDecoderG722:
461         bytes_per_ms_ = 8;
462         samples_per_ms_ = 16;
463         break;
464       case kDecoderPCM16B:
465         bytes_per_ms_ = 16;
466         samples_per_ms_ = 8;
467         break;
468       case kDecoderPCM16Bwb:
469         bytes_per_ms_ = 32;
470         samples_per_ms_ = 16;
471         break;
472       case kDecoderPCM16Bswb32kHz:
473         bytes_per_ms_ = 64;
474         samples_per_ms_ = 32;
475         break;
476       case kDecoderPCM16Bswb48kHz:
477         bytes_per_ms_ = 96;
478         samples_per_ms_ = 48;
479         break;
480       case kDecoderPCM16B_2ch:
481         bytes_per_ms_ = 2 * 16;
482         samples_per_ms_ = 8;
483         break;
484       case kDecoderPCM16Bwb_2ch:
485         bytes_per_ms_ = 2 * 32;
486         samples_per_ms_ = 16;
487         break;
488       case kDecoderPCM16Bswb32kHz_2ch:
489         bytes_per_ms_ = 2 * 64;
490         samples_per_ms_ = 32;
491         break;
492       case kDecoderPCM16Bswb48kHz_2ch:
493         bytes_per_ms_ = 2 * 96;
494         samples_per_ms_ = 48;
495         break;
496       case kDecoderPCM16B_5ch:
497         bytes_per_ms_ = 5 * 16;
498         samples_per_ms_ = 8;
499         break;
500       default:
501         assert(false);
502         break;
503     }
504   }
505   int bytes_per_ms_;
506   int samples_per_ms_;
507   NetEqDecoder decoder_type_;
508 };
509
510 // Test splitting sample-based payloads.
511 TEST_P(SplitBySamplesTest, PayloadSizes) {
512   PacketList packet_list;
513   static const uint8_t kPayloadType = 17;  // Just a random number.
514   for (int payload_size_ms = 10; payload_size_ms <= 60; payload_size_ms += 10) {
515     // The payload values are set to be the same as the payload_size, so that
516     // one can distinguish from which packet the split payloads come from.
517     int payload_size_bytes = payload_size_ms * bytes_per_ms_;
518     packet_list.push_back(CreatePacket(kPayloadType, payload_size_bytes,
519                                        payload_size_ms));
520   }
521
522   MockDecoderDatabase decoder_database;
523   // Tell the mock decoder database to return DecoderInfo structs with different
524   // codec types.
525   // Use scoped pointers to avoid having to delete them later.
526   // (Sample rate is set to 8000 Hz, but does not matter.)
527   scoped_ptr<DecoderDatabase::DecoderInfo> info(
528       new DecoderDatabase::DecoderInfo(decoder_type_, 8000, NULL, false));
529   EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
530       .WillRepeatedly(Return(info.get()));
531
532   PayloadSplitter splitter;
533   EXPECT_EQ(0, splitter.SplitAudio(&packet_list, decoder_database));
534   // The payloads are expected to be split as follows:
535   // 10 ms -> 10 ms
536   // 20 ms -> 20 ms
537   // 30 ms -> 30 ms
538   // 40 ms -> 20 + 20 ms
539   // 50 ms -> 25 + 25 ms
540   // 60 ms -> 30 + 30 ms
541   int expected_size_ms[] = {10, 20, 30, 20, 20, 25, 25, 30, 30};
542   int expected_payload_value[] = {10, 20, 30, 40, 40, 50, 50, 60, 60};
543   int expected_timestamp_offset_ms[] = {0, 0, 0, 0, 20, 0, 25, 0, 30};
544   size_t expected_num_packets =
545       sizeof(expected_size_ms) / sizeof(expected_size_ms[0]);
546   EXPECT_EQ(expected_num_packets, packet_list.size());
547
548   PacketList::iterator it = packet_list.begin();
549   int i = 0;
550   while (it != packet_list.end()) {
551     int length_bytes = expected_size_ms[i] * bytes_per_ms_;
552     uint32_t expected_timestamp = kBaseTimestamp +
553         expected_timestamp_offset_ms[i] * samples_per_ms_;
554     VerifyPacket((*it), length_bytes, kPayloadType, kSequenceNumber,
555                  expected_timestamp, expected_payload_value[i]);
556     delete [] (*it)->payload;
557     delete (*it);
558     it = packet_list.erase(it);
559     ++i;
560   }
561
562   // The destructor is called when decoder_database goes out of scope.
563   EXPECT_CALL(decoder_database, Die());
564 }
565
566 INSTANTIATE_TEST_CASE_P(
567     PayloadSplitter, SplitBySamplesTest,
568     ::testing::Values(kDecoderPCMu, kDecoderPCMa, kDecoderPCMu_2ch,
569                       kDecoderPCMa_2ch, kDecoderG722, kDecoderPCM16B,
570                       kDecoderPCM16Bwb, kDecoderPCM16Bswb32kHz,
571                       kDecoderPCM16Bswb48kHz, kDecoderPCM16B_2ch,
572                       kDecoderPCM16Bwb_2ch, kDecoderPCM16Bswb32kHz_2ch,
573                       kDecoderPCM16Bswb48kHz_2ch, kDecoderPCM16B_5ch));
574
575
576 class SplitIlbcTest : public ::testing::TestWithParam<std::pair<int, int> > {
577  protected:
578   virtual void SetUp() {
579     const std::pair<int, int> parameters = GetParam();
580     num_frames_ = parameters.first;
581     frame_length_ms_ = parameters.second;
582     frame_length_bytes_ = (frame_length_ms_ == 20) ? 38 : 50;
583   }
584   size_t num_frames_;
585   int frame_length_ms_;
586   int frame_length_bytes_;
587 };
588
589 // Test splitting sample-based payloads.
590 TEST_P(SplitIlbcTest, NumFrames) {
591   PacketList packet_list;
592   static const uint8_t kPayloadType = 17;  // Just a random number.
593   const int frame_length_samples = frame_length_ms_ * 8;
594   int payload_length_bytes = frame_length_bytes_ * num_frames_;
595   Packet* packet = CreatePacket(kPayloadType, payload_length_bytes, 0);
596   // Fill payload with increasing integers {0, 1, 2, ...}.
597   for (int i = 0; i < packet->payload_length; ++i) {
598     packet->payload[i] = static_cast<uint8_t>(i);
599   }
600   packet_list.push_back(packet);
601
602   MockDecoderDatabase decoder_database;
603   // Tell the mock decoder database to return DecoderInfo structs with different
604   // codec types.
605   // Use scoped pointers to avoid having to delete them later.
606   scoped_ptr<DecoderDatabase::DecoderInfo> info(
607       new DecoderDatabase::DecoderInfo(kDecoderILBC, 8000, NULL, false));
608   EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
609       .WillRepeatedly(Return(info.get()));
610
611   PayloadSplitter splitter;
612   EXPECT_EQ(0, splitter.SplitAudio(&packet_list, decoder_database));
613   EXPECT_EQ(num_frames_, packet_list.size());
614
615   PacketList::iterator it = packet_list.begin();
616   int frame_num = 0;
617   uint8_t payload_value = 0;
618   while (it != packet_list.end()) {
619     Packet* packet = (*it);
620     EXPECT_EQ(kBaseTimestamp + frame_length_samples * frame_num,
621               packet->header.timestamp);
622     EXPECT_EQ(frame_length_bytes_, packet->payload_length);
623     EXPECT_EQ(kPayloadType, packet->header.payloadType);
624     EXPECT_EQ(kSequenceNumber, packet->header.sequenceNumber);
625     EXPECT_EQ(true, packet->primary);
626     ASSERT_FALSE(packet->payload == NULL);
627     for (int i = 0; i < packet->payload_length; ++i) {
628       EXPECT_EQ(payload_value, packet->payload[i]);
629       ++payload_value;
630     }
631     delete [] (*it)->payload;
632     delete (*it);
633     it = packet_list.erase(it);
634     ++frame_num;
635   }
636
637   // The destructor is called when decoder_database goes out of scope.
638   EXPECT_CALL(decoder_database, Die());
639 }
640
641 // Test 1 through 5 frames of 20 and 30 ms size.
642 // Also test the maximum number of frames in one packet for 20 and 30 ms.
643 // The maximum is defined by the largest payload length that can be uniquely
644 // resolved to a frame size of either 38 bytes (20 ms) or 50 bytes (30 ms).
645 INSTANTIATE_TEST_CASE_P(
646     PayloadSplitter, SplitIlbcTest,
647     ::testing::Values(std::pair<int, int>(1, 20),  // 1 frame, 20 ms.
648                       std::pair<int, int>(2, 20),  // 2 frames, 20 ms.
649                       std::pair<int, int>(3, 20),  // And so on.
650                       std::pair<int, int>(4, 20),
651                       std::pair<int, int>(5, 20),
652                       std::pair<int, int>(24, 20),
653                       std::pair<int, int>(1, 30),
654                       std::pair<int, int>(2, 30),
655                       std::pair<int, int>(3, 30),
656                       std::pair<int, int>(4, 30),
657                       std::pair<int, int>(5, 30),
658                       std::pair<int, int>(18, 30)));
659
660 // Test too large payload size.
661 TEST(IlbcPayloadSplitter, TooLargePayload) {
662   PacketList packet_list;
663   static const uint8_t kPayloadType = 17;  // Just a random number.
664   int kPayloadLengthBytes = 950;
665   Packet* packet = CreatePacket(kPayloadType, kPayloadLengthBytes, 0);
666   packet_list.push_back(packet);
667
668   MockDecoderDatabase decoder_database;
669   scoped_ptr<DecoderDatabase::DecoderInfo> info(
670       new DecoderDatabase::DecoderInfo(kDecoderILBC, 8000, NULL, false));
671   EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
672       .WillRepeatedly(Return(info.get()));
673
674   PayloadSplitter splitter;
675   EXPECT_EQ(PayloadSplitter::kTooLargePayload,
676             splitter.SplitAudio(&packet_list, decoder_database));
677   EXPECT_EQ(1u, packet_list.size());
678
679   // Delete the packets and payloads to avoid having the test leak memory.
680   PacketList::iterator it = packet_list.begin();
681   while (it != packet_list.end()) {
682     delete [] (*it)->payload;
683     delete (*it);
684     it = packet_list.erase(it);
685   }
686
687   // The destructor is called when decoder_database goes out of scope.
688   EXPECT_CALL(decoder_database, Die());
689 }
690
691 // Payload not an integer number of frames.
692 TEST(IlbcPayloadSplitter, UnevenPayload) {
693   PacketList packet_list;
694   static const uint8_t kPayloadType = 17;  // Just a random number.
695   int kPayloadLengthBytes = 39;  // Not an even number of frames.
696   Packet* packet = CreatePacket(kPayloadType, kPayloadLengthBytes, 0);
697   packet_list.push_back(packet);
698
699   MockDecoderDatabase decoder_database;
700   scoped_ptr<DecoderDatabase::DecoderInfo> info(
701       new DecoderDatabase::DecoderInfo(kDecoderILBC, 8000, NULL, false));
702   EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
703       .WillRepeatedly(Return(info.get()));
704
705   PayloadSplitter splitter;
706   EXPECT_EQ(PayloadSplitter::kFrameSplitError,
707             splitter.SplitAudio(&packet_list, decoder_database));
708   EXPECT_EQ(1u, packet_list.size());
709
710   // Delete the packets and payloads to avoid having the test leak memory.
711   PacketList::iterator it = packet_list.begin();
712   while (it != packet_list.end()) {
713     delete [] (*it)->payload;
714     delete (*it);
715     it = packet_list.erase(it);
716   }
717
718   // The destructor is called when decoder_database goes out of scope.
719   EXPECT_CALL(decoder_database, Die());
720 }
721
722 TEST(FecPayloadSplitter, MixedPayload) {
723   PacketList packet_list;
724   DecoderDatabase decoder_database;
725
726   decoder_database.RegisterPayload(0, kDecoderOpus);
727   decoder_database.RegisterPayload(1, kDecoderPCMu);
728
729   Packet* packet = CreateOpusFecPacket(0, 10, 0xFF);
730   packet_list.push_back(packet);
731
732   packet = CreatePacket(0, 10, 0); // Non-FEC Opus payload.
733   packet_list.push_back(packet);
734
735   packet = CreatePacket(1, 10, 0); // Non-Opus payload.
736   packet_list.push_back(packet);
737
738   PayloadSplitter splitter;
739   EXPECT_EQ(PayloadSplitter::kOK,
740             splitter.SplitFec(&packet_list, &decoder_database));
741   EXPECT_EQ(4u, packet_list.size());
742
743   // Check first packet.
744   packet = packet_list.front();
745   EXPECT_EQ(0, packet->header.payloadType);
746   EXPECT_EQ(kBaseTimestamp - 20 * 48, packet->header.timestamp);
747   EXPECT_EQ(10, packet->payload_length);
748   EXPECT_FALSE(packet->primary);
749   delete [] packet->payload;
750   delete packet;
751   packet_list.pop_front();
752
753   // Check second packet.
754   packet = packet_list.front();
755   EXPECT_EQ(0, packet->header.payloadType);
756   EXPECT_EQ(kBaseTimestamp, packet->header.timestamp);
757   EXPECT_EQ(10, packet->payload_length);
758   EXPECT_TRUE(packet->primary);
759   delete [] packet->payload;
760   delete packet;
761   packet_list.pop_front();
762
763   // Check third packet.
764   packet = packet_list.front();
765   VerifyPacket(packet, 10, 0, kSequenceNumber, kBaseTimestamp, 0, true);
766   delete [] packet->payload;
767   delete packet;
768   packet_list.pop_front();
769
770   // Check fourth packet.
771   packet = packet_list.front();
772   VerifyPacket(packet, 10, 1, kSequenceNumber, kBaseTimestamp, 0, true);
773   delete [] packet->payload;
774   delete packet;
775 }
776
777 }  // namespace webrtc