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
24using ::testing::Return;
25using ::testing::ReturnNull;
26
27namespace webrtc {
28
29static const int kRedPayloadType = 100;
30static const size_t kPayloadLength = 10;
31static const size_t kRedHeaderLength = 4;  // 4 bytes RED header.
32static const uint16_t kSequenceNumber = 0;
33static 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// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47void 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.
75Packet* 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|.
123Packet* 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.
142void 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
162TEST(PayloadSplitter, CreateAndDestroy) {
163  PayloadSplitter* splitter = new PayloadSplitter;
164  delete splitter;
165}
166
167// Packet A is split into A1 and A2.
168TEST(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.
194TEST(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.
234TEST(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).
301TEST(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.
336TEST(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.
361TEST(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.
426TEST(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
456class SplitBySamplesTest : public ::testing::TestWithParam<NetEqDecoder> {
457 protected:
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.
522TEST_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
577INSTANTIATE_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
595class SplitIlbcTest : public ::testing::TestWithParam<std::pair<int, int> > {
596 protected:
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.
609TEST_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).
665INSTANTIATE_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.
681TEST(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.
713TEST(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
744TEST(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
799TEST(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