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