OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 } | 66 } |
67 last_time = time; | 67 last_time = time; |
68 } | 68 } |
69 expected_seq_.insert(expected_seq_.begin(), &received_seq[0], | 69 expected_seq_.insert(expected_seq_.begin(), &received_seq[0], |
70 &received_seq[length]); | 70 &received_seq[length]); |
71 } | 71 } |
72 | 72 |
73 void VerifyPacket() { | 73 void VerifyPacket() { |
74 serialized_ = feedback_->Build(); | 74 serialized_ = feedback_->Build(); |
75 VerifyInternal(); | 75 VerifyInternal(); |
76 feedback_ = TransportFeedback::ParseFrom(serialized_->Buffer(), | 76 feedback_ = TransportFeedback::ParseFrom(serialized_.data(), |
77 serialized_->Length()); | 77 serialized_.size()); |
78 ASSERT_NE(nullptr, feedback_.get()); | 78 ASSERT_NE(nullptr, feedback_.get()); |
79 VerifyInternal(); | 79 VerifyInternal(); |
80 } | 80 } |
81 | 81 |
82 static const size_t kAnySize = static_cast<size_t>(0) - 1; | 82 static const size_t kAnySize = static_cast<size_t>(0) - 1; |
83 | 83 |
84 private: | 84 private: |
85 void VerifyInternal() { | 85 void VerifyInternal() { |
86 if (expected_size_ != kAnySize) { | 86 if (expected_size_ != kAnySize) { |
87 // Round up to whole 32-bit words. | 87 // Round up to whole 32-bit words. |
88 size_t expected_size_words = (expected_size_ + 3) / 4; | 88 size_t expected_size_words = (expected_size_ + 3) / 4; |
89 size_t expected_size_bytes = expected_size_words * 4; | 89 size_t expected_size_bytes = expected_size_words * 4; |
90 EXPECT_EQ(expected_size_bytes, serialized_->Length()); | 90 EXPECT_EQ(expected_size_bytes, serialized_.size()); |
91 } | 91 } |
92 | 92 |
93 std::vector<TransportFeedback::StatusSymbol> symbols = | 93 std::vector<TransportFeedback::StatusSymbol> symbols = |
94 feedback_->GetStatusVector(); | 94 feedback_->GetStatusVector(); |
95 uint16_t seq = feedback_->GetBaseSequence(); | 95 uint16_t seq = feedback_->GetBaseSequence(); |
96 auto seq_it = expected_seq_.begin(); | 96 auto seq_it = expected_seq_.begin(); |
97 for (TransportFeedback::StatusSymbol symbol : symbols) { | 97 for (TransportFeedback::StatusSymbol symbol : symbols) { |
98 bool received = | 98 bool received = |
99 (symbol == TransportFeedback::StatusSymbol::kReceivedSmallDelta || | 99 (symbol == TransportFeedback::StatusSymbol::kReceivedSmallDelta || |
100 symbol == TransportFeedback::StatusSymbol::kReceivedLargeDelta); | 100 symbol == TransportFeedback::StatusSymbol::kReceivedLargeDelta); |
(...skipping 29 matching lines...) Expand all Loading... |
130 | 130 |
131 deltas[i] = offset + (last_seq * default_delta_); | 131 deltas[i] = offset + (last_seq * default_delta_); |
132 } | 132 } |
133 } | 133 } |
134 | 134 |
135 std::vector<uint16_t> expected_seq_; | 135 std::vector<uint16_t> expected_seq_; |
136 std::vector<int64_t> expected_deltas_; | 136 std::vector<int64_t> expected_deltas_; |
137 size_t expected_size_; | 137 size_t expected_size_; |
138 int64_t default_delta_; | 138 int64_t default_delta_; |
139 rtc::scoped_ptr<TransportFeedback> feedback_; | 139 rtc::scoped_ptr<TransportFeedback> feedback_; |
140 rtc::scoped_ptr<rtcp::RawPacket> serialized_; | 140 rtc::Buffer serialized_; |
141 }; | 141 }; |
142 | 142 |
143 TEST(RtcpPacketTest, TransportFeedback_OneBitVector) { | 143 TEST(RtcpPacketTest, TransportFeedback_OneBitVector) { |
144 const uint16_t kReceived[] = {1, 2, 7, 8, 9, 10, 13}; | 144 const uint16_t kReceived[] = {1, 2, 7, 8, 9, 10, 13}; |
145 const size_t kLength = sizeof(kReceived) / sizeof(uint16_t); | 145 const size_t kLength = sizeof(kReceived) / sizeof(uint16_t); |
146 const size_t kExpectedSizeBytes = | 146 const size_t kExpectedSizeBytes = |
147 kHeaderSize + kStatusChunkSize + (kLength * kSmallDeltaSize); | 147 kHeaderSize + kStatusChunkSize + (kLength * kSmallDeltaSize); |
148 | 148 |
149 FeedbackTester test; | 149 FeedbackTester test; |
150 test.WithExpectedSize(kExpectedSizeBytes); | 150 test.WithExpectedSize(kExpectedSizeBytes); |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 EXPECT_TRUE(packet->WithReceivedPacket(1, kMaxNegativeTimeDelta)); | 390 EXPECT_TRUE(packet->WithReceivedPacket(1, kMaxNegativeTimeDelta)); |
391 | 391 |
392 // Base time at maximum value. | 392 // Base time at maximum value. |
393 int64_t kMaxBaseTime = | 393 int64_t kMaxBaseTime = |
394 static_cast<int64_t>(TransportFeedback::kDeltaScaleFactor) * (1L << 8) * | 394 static_cast<int64_t>(TransportFeedback::kDeltaScaleFactor) * (1L << 8) * |
395 ((1L << 23) - 1); | 395 ((1L << 23) - 1); |
396 packet.reset(new TransportFeedback()); | 396 packet.reset(new TransportFeedback()); |
397 packet->WithBase(0, kMaxBaseTime); | 397 packet->WithBase(0, kMaxBaseTime); |
398 packet->WithReceivedPacket(0, kMaxBaseTime); | 398 packet->WithReceivedPacket(0, kMaxBaseTime); |
399 // Serialize and de-serialize (verify 24bit parsing). | 399 // Serialize and de-serialize (verify 24bit parsing). |
400 rtc::scoped_ptr<rtcp::RawPacket> raw_packet = packet->Build(); | 400 rtc::Buffer raw_packet = packet->Build(); |
401 packet = | 401 packet = TransportFeedback::ParseFrom(raw_packet.data(), raw_packet.size()); |
402 TransportFeedback::ParseFrom(raw_packet->Buffer(), raw_packet->Length()); | |
403 EXPECT_EQ(kMaxBaseTime, packet->GetBaseTimeUs()); | 402 EXPECT_EQ(kMaxBaseTime, packet->GetBaseTimeUs()); |
404 | 403 |
405 // Base time above maximum value. | 404 // Base time above maximum value. |
406 int64_t kTooLargeBaseTime = | 405 int64_t kTooLargeBaseTime = |
407 kMaxBaseTime + (TransportFeedback::kDeltaScaleFactor * (1L << 8)); | 406 kMaxBaseTime + (TransportFeedback::kDeltaScaleFactor * (1L << 8)); |
408 packet.reset(new TransportFeedback()); | 407 packet.reset(new TransportFeedback()); |
409 packet->WithBase(0, kTooLargeBaseTime); | 408 packet->WithBase(0, kTooLargeBaseTime); |
410 packet->WithReceivedPacket(0, kTooLargeBaseTime); | 409 packet->WithReceivedPacket(0, kTooLargeBaseTime); |
411 raw_packet = packet->Build(); | 410 raw_packet = packet->Build(); |
412 packet = | 411 packet = TransportFeedback::ParseFrom(raw_packet.data(), raw_packet.size()); |
413 TransportFeedback::ParseFrom(raw_packet->Buffer(), raw_packet->Length()); | |
414 EXPECT_NE(kTooLargeBaseTime, packet->GetBaseTimeUs()); | 412 EXPECT_NE(kTooLargeBaseTime, packet->GetBaseTimeUs()); |
415 | 413 |
416 // TODO(sprang): Once we support max length lower than RTCP length limit, | 414 // TODO(sprang): Once we support max length lower than RTCP length limit, |
417 // add back test for max size in bytes. | 415 // add back test for max size in bytes. |
418 } | 416 } |
419 | 417 |
420 TEST(RtcpPacketTest, TransportFeedback_Padding) { | 418 TEST(RtcpPacketTest, TransportFeedback_Padding) { |
421 const size_t kExpectedSizeBytes = | 419 const size_t kExpectedSizeBytes = |
422 kHeaderSize + kStatusChunkSize + kSmallDeltaSize; | 420 kHeaderSize + kStatusChunkSize + kSmallDeltaSize; |
423 const size_t kExpectedSizeWords = (kExpectedSizeBytes + 3) / 4; | 421 const size_t kExpectedSizeWords = (kExpectedSizeBytes + 3) / 4; |
424 | 422 |
425 TransportFeedback feedback; | 423 TransportFeedback feedback; |
426 feedback.WithBase(0, 0); | 424 feedback.WithBase(0, 0); |
427 EXPECT_TRUE(feedback.WithReceivedPacket(0, 0)); | 425 EXPECT_TRUE(feedback.WithReceivedPacket(0, 0)); |
428 | 426 |
429 rtc::scoped_ptr<rtcp::RawPacket> packet(feedback.Build()); | 427 rtc::Buffer packet = feedback.Build(); |
430 EXPECT_EQ(kExpectedSizeWords * 4, packet->Length()); | 428 EXPECT_EQ(kExpectedSizeWords * 4, packet.size()); |
431 ASSERT_GT(kExpectedSizeWords * 4, kExpectedSizeBytes); | 429 ASSERT_GT(kExpectedSizeWords * 4, kExpectedSizeBytes); |
432 for (size_t i = kExpectedSizeBytes; i < kExpectedSizeWords * 4; ++i) | 430 for (size_t i = kExpectedSizeBytes; i < kExpectedSizeWords * 4; ++i) |
433 EXPECT_EQ(0u, packet->Buffer()[i]); | 431 EXPECT_EQ(0u, packet.data()[i]); |
434 | 432 |
435 // Modify packet by adding 4 bytes of padding at the end. Not currently used | 433 // Modify packet by adding 4 bytes of padding at the end. Not currently used |
436 // when we're sending, but need to be able to handle it when receiving. | 434 // when we're sending, but need to be able to handle it when receiving. |
437 | 435 |
438 const int kPaddingBytes = 4; | 436 const int kPaddingBytes = 4; |
439 const size_t kExpectedSizeWithPadding = | 437 const size_t kExpectedSizeWithPadding = |
440 (kExpectedSizeWords * 4) + kPaddingBytes; | 438 (kExpectedSizeWords * 4) + kPaddingBytes; |
441 uint8_t mod_buffer[kExpectedSizeWithPadding]; | 439 uint8_t mod_buffer[kExpectedSizeWithPadding]; |
442 memcpy(mod_buffer, packet->Buffer(), kExpectedSizeWords * 4); | 440 memcpy(mod_buffer, packet.data(), kExpectedSizeWords * 4); |
443 memset(&mod_buffer[kExpectedSizeWords * 4], 0, kPaddingBytes - 1); | 441 memset(&mod_buffer[kExpectedSizeWords * 4], 0, kPaddingBytes - 1); |
444 mod_buffer[kExpectedSizeWithPadding - 1] = kPaddingBytes; | 442 mod_buffer[kExpectedSizeWithPadding - 1] = kPaddingBytes; |
445 const uint8_t padding_flag = 1 << 5; | 443 const uint8_t padding_flag = 1 << 5; |
446 mod_buffer[0] |= padding_flag; | 444 mod_buffer[0] |= padding_flag; |
447 ByteWriter<uint16_t>::WriteBigEndian( | 445 ByteWriter<uint16_t>::WriteBigEndian( |
448 &mod_buffer[2], ByteReader<uint16_t>::ReadBigEndian(&mod_buffer[2]) + | 446 &mod_buffer[2], ByteReader<uint16_t>::ReadBigEndian(&mod_buffer[2]) + |
449 ((kPaddingBytes + 3) / 4)); | 447 ((kPaddingBytes + 3) / 4)); |
450 | 448 |
451 rtc::scoped_ptr<TransportFeedback> parsed_packet( | 449 rtc::scoped_ptr<TransportFeedback> parsed_packet( |
452 TransportFeedback::ParseFrom(mod_buffer, kExpectedSizeWithPadding)); | 450 TransportFeedback::ParseFrom(mod_buffer, kExpectedSizeWithPadding)); |
453 ASSERT_TRUE(parsed_packet.get() != nullptr); | 451 ASSERT_TRUE(parsed_packet.get() != nullptr); |
454 EXPECT_EQ(kExpectedSizeWords * 4, packet->Length()); // Padding not included. | 452 EXPECT_EQ(kExpectedSizeWords * 4, packet.size()); // Padding not included. |
455 } | 453 } |
456 | 454 |
457 TEST(RtcpPacketTest, TransportFeedback_CorrectlySplitsVectorChunks) { | 455 TEST(RtcpPacketTest, TransportFeedback_CorrectlySplitsVectorChunks) { |
458 const int kOneBitVectorCapacity = 14; | 456 const int kOneBitVectorCapacity = 14; |
459 const int64_t kLargeTimeDelta = | 457 const int64_t kLargeTimeDelta = |
460 TransportFeedback::kDeltaScaleFactor * (1 << 8); | 458 TransportFeedback::kDeltaScaleFactor * (1 << 8); |
461 | 459 |
462 // Test that a number of small deltas followed by a large delta results in a | 460 // Test that a number of small deltas followed by a large delta results in a |
463 // correct split into multiple chunks, as needed. | 461 // correct split into multiple chunks, as needed. |
464 | 462 |
465 for (int deltas = 0; deltas <= kOneBitVectorCapacity + 1; ++deltas) { | 463 for (int deltas = 0; deltas <= kOneBitVectorCapacity + 1; ++deltas) { |
466 TransportFeedback feedback; | 464 TransportFeedback feedback; |
467 feedback.WithBase(0, 0); | 465 feedback.WithBase(0, 0); |
468 for (int i = 0; i < deltas; ++i) | 466 for (int i = 0; i < deltas; ++i) |
469 feedback.WithReceivedPacket(i, i * 1000); | 467 feedback.WithReceivedPacket(i, i * 1000); |
470 feedback.WithReceivedPacket(deltas, deltas * 1000 + kLargeTimeDelta); | 468 feedback.WithReceivedPacket(deltas, deltas * 1000 + kLargeTimeDelta); |
471 | 469 |
472 rtc::scoped_ptr<rtcp::RawPacket> serialized_packet = feedback.Build(); | 470 rtc::Buffer serialized_packet = feedback.Build(); |
473 EXPECT_TRUE(serialized_packet.get() != nullptr); | |
474 rtc::scoped_ptr<TransportFeedback> deserialized_packet = | 471 rtc::scoped_ptr<TransportFeedback> deserialized_packet = |
475 TransportFeedback::ParseFrom(serialized_packet->Buffer(), | 472 TransportFeedback::ParseFrom(serialized_packet.data(), |
476 serialized_packet->Length()); | 473 serialized_packet.size()); |
477 EXPECT_TRUE(deserialized_packet.get() != nullptr); | 474 EXPECT_TRUE(deserialized_packet.get() != nullptr); |
478 } | 475 } |
479 } | 476 } |
480 | 477 |
481 } // namespace | 478 } // namespace |
482 } // namespace webrtc | 479 } // namespace webrtc |
OLD | NEW |