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