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