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/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
24using ::testing::Return;
25using ::testing::ReturnNull;
26
27namespace webrtc {
28
29static const int kRedPayloadType = 100;
30static const int kPayloadLength = 10;
31static const int kRedHeaderLength = 4;  // 4 bytes RED header.
32static const uint16_t kSequenceNumber = 0;
33static 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.
53Packet* 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// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
107Packet* 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|.
123Packet* 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.
137void 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
157TEST(PayloadSplitter, CreateAndDestroy) {
158  PayloadSplitter* splitter = new PayloadSplitter;
159  delete splitter;
160}
161
162// Packet A is split into A1 and A2.
163TEST(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.
189TEST(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.
229TEST(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).
296TEST(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.
331TEST(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.
356TEST(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.
415TEST(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
445class 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.
511TEST_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
566INSTANTIATE_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
576class 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.
590TEST_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).
645INSTANTIATE_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.
661TEST(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.
692TEST(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
722TEST(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
778