OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 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 |
11 #include "webrtc/modules/rtp_rtcp/source/rtp_packet.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtp_packet.h" |
12 | 12 |
13 #include <cstring> | 13 #include <cstring> |
14 #include <utility> | 14 #include <utility> |
15 | 15 |
16 #include "webrtc/common_types.h" | 16 #include "webrtc/common_types.h" |
17 #include "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h" | 17 #include "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h" |
18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
19 #include "webrtc/rtc_base/checks.h" | 19 #include "webrtc/rtc_base/checks.h" |
20 #include "webrtc/rtc_base/logging.h" | 20 #include "webrtc/rtc_base/logging.h" |
21 #include "webrtc/rtc_base/random.h" | 21 #include "webrtc/rtc_base/random.h" |
| 22 #include "webrtc/rtc_base/safe_conversions.h" |
22 | 23 |
23 namespace webrtc { | 24 namespace webrtc { |
24 namespace rtp { | 25 namespace rtp { |
25 namespace { | 26 namespace { |
26 constexpr size_t kFixedHeaderSize = 12; | 27 constexpr size_t kFixedHeaderSize = 12; |
27 constexpr uint8_t kRtpVersion = 2; | 28 constexpr uint8_t kRtpVersion = 2; |
28 constexpr uint16_t kOneByteExtensionId = 0xBEDE; | 29 constexpr uint16_t kOneByteExtensionId = 0xBEDE; |
29 constexpr size_t kOneByteHeaderSize = 1; | 30 constexpr size_t kOneByteHeaderSize = 1; |
30 constexpr size_t kDefaultPacketSize = 1500; | 31 constexpr size_t kDefaultPacketSize = 1500; |
31 } // namespace | 32 } // namespace |
32 | 33 |
33 constexpr size_t Packet::kMaxExtensionHeaders; | 34 constexpr int Packet::kMaxExtensionHeaders; |
34 constexpr int Packet::kMinExtensionId; | 35 constexpr int Packet::kMinExtensionId; |
35 constexpr int Packet::kMaxExtensionId; | 36 constexpr int Packet::kMaxExtensionId; |
36 | 37 |
37 // 0 1 2 3 | 38 // 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 // 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 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
40 // |V=2|P|X| CC |M| PT | sequence number | | 41 // |V=2|P|X| CC |M| PT | sequence number | |
41 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 42 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
42 // | timestamp | | 43 // | timestamp | |
43 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 44 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
(...skipping 27 matching lines...) Expand all Loading... |
71 IdentifyExtensions(*extensions); | 72 IdentifyExtensions(*extensions); |
72 } else { | 73 } else { |
73 for (size_t i = 0; i < kMaxExtensionHeaders; ++i) | 74 for (size_t i = 0; i < kMaxExtensionHeaders; ++i) |
74 extension_entries_[i].type = ExtensionManager::kInvalidType; | 75 extension_entries_[i].type = ExtensionManager::kInvalidType; |
75 } | 76 } |
76 } | 77 } |
77 | 78 |
78 Packet::~Packet() {} | 79 Packet::~Packet() {} |
79 | 80 |
80 void Packet::IdentifyExtensions(const ExtensionManager& extensions) { | 81 void Packet::IdentifyExtensions(const ExtensionManager& extensions) { |
81 for (size_t i = 0; i < kMaxExtensionHeaders; ++i) | 82 for (int i = 0; i < kMaxExtensionHeaders; ++i) |
82 extension_entries_[i].type = extensions.GetType(i + 1); | 83 extension_entries_[i].type = extensions.GetType(i + 1); |
83 } | 84 } |
84 | 85 |
85 bool Packet::Parse(const uint8_t* buffer, size_t buffer_size) { | 86 bool Packet::Parse(const uint8_t* buffer, size_t buffer_size) { |
86 if (!ParseBuffer(buffer, buffer_size)) { | 87 if (!ParseBuffer(buffer, buffer_size)) { |
87 Clear(); | 88 Clear(); |
88 return false; | 89 return false; |
89 } | 90 } |
90 buffer_.SetData(buffer, buffer_size); | 91 buffer_.SetData(buffer, buffer_size); |
91 RTC_DCHECK_EQ(size(), buffer_size); | 92 RTC_DCHECK_EQ(size(), buffer_size); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(8), ssrc); | 236 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(8), ssrc); |
236 } | 237 } |
237 | 238 |
238 void Packet::SetCsrcs(const std::vector<uint32_t>& csrcs) { | 239 void Packet::SetCsrcs(const std::vector<uint32_t>& csrcs) { |
239 RTC_DCHECK_EQ(extensions_size_, 0); | 240 RTC_DCHECK_EQ(extensions_size_, 0); |
240 RTC_DCHECK_EQ(payload_size_, 0); | 241 RTC_DCHECK_EQ(payload_size_, 0); |
241 RTC_DCHECK_EQ(padding_size_, 0); | 242 RTC_DCHECK_EQ(padding_size_, 0); |
242 RTC_DCHECK_LE(csrcs.size(), 0x0fu); | 243 RTC_DCHECK_LE(csrcs.size(), 0x0fu); |
243 RTC_DCHECK_LE(kFixedHeaderSize + 4 * csrcs.size(), capacity()); | 244 RTC_DCHECK_LE(kFixedHeaderSize + 4 * csrcs.size(), capacity()); |
244 payload_offset_ = kFixedHeaderSize + 4 * csrcs.size(); | 245 payload_offset_ = kFixedHeaderSize + 4 * csrcs.size(); |
245 WriteAt(0, (data()[0] & 0xF0) | csrcs.size()); | 246 WriteAt(0, (data()[0] & 0xF0) | rtc::dchecked_cast<uint8_t>(csrcs.size())); |
246 size_t offset = kFixedHeaderSize; | 247 size_t offset = kFixedHeaderSize; |
247 for (uint32_t csrc : csrcs) { | 248 for (uint32_t csrc : csrcs) { |
248 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(offset), csrc); | 249 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(offset), csrc); |
249 offset += 4; | 250 offset += 4; |
250 } | 251 } |
251 buffer_.SetSize(payload_offset_); | 252 buffer_.SetSize(payload_offset_); |
252 } | 253 } |
253 | 254 |
254 bool Packet::HasRawExtension(int id) const { | 255 bool Packet::HasRawExtension(int id) const { |
255 if (id == ExtensionManager::kInvalidId) | 256 if (id == ExtensionManager::kInvalidId) |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 | 322 |
322 // All checks passed, write down the extension headers. | 323 // All checks passed, write down the extension headers. |
323 if (extensions_size_ == 0) { | 324 if (extensions_size_ == 0) { |
324 RTC_DCHECK_EQ(payload_offset_, kFixedHeaderSize + (num_csrc * 4)); | 325 RTC_DCHECK_EQ(payload_offset_, kFixedHeaderSize + (num_csrc * 4)); |
325 WriteAt(0, data()[0] | 0x10); // Set extension bit. | 326 WriteAt(0, data()[0] | 0x10); // Set extension bit. |
326 // Profile specific ID always set to OneByteExtensionHeader. | 327 // Profile specific ID always set to OneByteExtensionHeader. |
327 ByteWriter<uint16_t>::WriteBigEndian(WriteAt(extensions_offset - 4), | 328 ByteWriter<uint16_t>::WriteBigEndian(WriteAt(extensions_offset - 4), |
328 kOneByteExtensionId); | 329 kOneByteExtensionId); |
329 } | 330 } |
330 | 331 |
331 WriteAt(extensions_offset + extensions_size_, (id << 4) | (length - 1)); | 332 uint8_t one_byte_header = rtc::dchecked_cast<uint8_t>(id) << 4; |
| 333 one_byte_header |= rtc::dchecked_cast<uint8_t>(length - 1); |
| 334 WriteAt(extensions_offset + extensions_size_, one_byte_header); |
332 | 335 |
333 extension_entry->offset = | 336 extension_entry->offset = rtc::dchecked_cast<uint16_t>( |
334 extensions_offset + extensions_size_ + kOneByteHeaderSize; | 337 extensions_offset + extensions_size_ + kOneByteHeaderSize); |
335 extension_entry->length = length; | 338 extension_entry->length = rtc::dchecked_cast<uint8_t>(length); |
336 extensions_size_ = new_extensions_size; | 339 extensions_size_ = rtc::dchecked_cast<uint16_t>(new_extensions_size); |
337 | 340 |
338 // Update header length field. | 341 // Update header length field. |
339 uint16_t extensions_words = (extensions_size_ + 3) / 4; // Wrap up to 32bit. | 342 uint16_t extensions_words = (extensions_size_ + 3) / 4; // Wrap up to 32bit. |
340 ByteWriter<uint16_t>::WriteBigEndian(WriteAt(extensions_offset - 2), | 343 ByteWriter<uint16_t>::WriteBigEndian(WriteAt(extensions_offset - 2), |
341 extensions_words); | 344 extensions_words); |
342 // Fill extension padding place with zeroes. | 345 // Fill extension padding place with zeroes. |
343 size_t extension_padding_size = 4 * extensions_words - extensions_size_; | 346 size_t extension_padding_size = 4 * extensions_words - extensions_size_; |
344 memset(WriteAt(extensions_offset + extensions_size_), 0, | 347 memset(WriteAt(extensions_offset + extensions_size_), 0, |
345 extension_padding_size); | 348 extension_padding_size); |
346 payload_offset_ = extensions_offset + 4 * extensions_words; | 349 payload_offset_ = extensions_offset + 4 * extensions_words; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 break; | 493 break; |
491 } | 494 } |
492 | 495 |
493 size_t idx = id - 1; | 496 size_t idx = id - 1; |
494 if (extension_entries_[idx].length != 0) { | 497 if (extension_entries_[idx].length != 0) { |
495 LOG(LS_VERBOSE) << "Duplicate rtp header extension id " << id | 498 LOG(LS_VERBOSE) << "Duplicate rtp header extension id " << id |
496 << ". Overwriting."; | 499 << ". Overwriting."; |
497 } | 500 } |
498 | 501 |
499 extensions_size_ += kOneByteHeaderSize; | 502 extensions_size_ += kOneByteHeaderSize; |
500 extension_entries_[idx].offset = extension_offset + extensions_size_; | 503 extension_entries_[idx].offset = |
501 extension_entries_[idx].length = length; | 504 rtc::dchecked_cast<uint16_t>(extension_offset + extensions_size_); |
| 505 extension_entries_[idx].length = rtc::dchecked_cast<uint16_t>(length); |
502 extensions_size_ += length; | 506 extensions_size_ += length; |
503 } | 507 } |
504 } | 508 } |
505 payload_offset_ = extension_offset + extensions_capacity; | 509 payload_offset_ = extension_offset + extensions_capacity; |
506 } | 510 } |
507 | 511 |
508 if (payload_offset_ + padding_size_ > size) { | 512 if (payload_offset_ + padding_size_ > size) { |
509 return false; | 513 return false; |
510 } | 514 } |
511 payload_size_ = size - payload_offset_ - padding_size_; | 515 payload_size_ = size - payload_offset_ - padding_size_; |
512 return true; | 516 return true; |
513 } | 517 } |
514 | 518 |
515 rtc::ArrayView<const uint8_t> Packet::FindExtension(ExtensionType type) const { | 519 rtc::ArrayView<const uint8_t> Packet::FindExtension(ExtensionType type) const { |
516 for (const ExtensionInfo& extension : extension_entries_) { | 520 for (const ExtensionInfo& extension : extension_entries_) { |
517 if (extension.type == type) { | 521 if (extension.type == type) { |
518 if (extension.length == 0) { | 522 if (extension.length == 0) { |
519 // Extension is registered but not set. | 523 // Extension is registered but not set. |
520 return nullptr; | 524 return nullptr; |
521 } | 525 } |
522 return rtc::MakeArrayView(data() + extension.offset, extension.length); | 526 return rtc::MakeArrayView(data() + extension.offset, extension.length); |
523 } | 527 } |
524 } | 528 } |
525 return nullptr; | 529 return nullptr; |
526 } | 530 } |
527 | 531 |
528 rtc::ArrayView<uint8_t> Packet::AllocateExtension(ExtensionType type, | 532 rtc::ArrayView<uint8_t> Packet::AllocateExtension(ExtensionType type, |
529 size_t length) { | 533 size_t length) { |
530 for (size_t i = 0; i < kMaxExtensionHeaders; ++i) { | 534 for (int i = 0; i < kMaxExtensionHeaders; ++i) { |
531 if (extension_entries_[i].type == type) { | 535 if (extension_entries_[i].type == type) { |
532 int extension_id = i + 1; | 536 int extension_id = i + 1; |
533 return AllocateRawExtension(extension_id, length); | 537 return AllocateRawExtension(extension_id, length); |
534 } | 538 } |
535 } | 539 } |
536 // Extension not registered. | 540 // Extension not registered. |
537 return nullptr; | 541 return nullptr; |
538 } | 542 } |
539 | 543 |
540 uint8_t* Packet::WriteAt(size_t offset) { | 544 uint8_t* Packet::WriteAt(size_t offset) { |
541 return buffer_.data() + offset; | 545 return buffer_.data() + offset; |
542 } | 546 } |
543 | 547 |
544 void Packet::WriteAt(size_t offset, uint8_t byte) { | 548 void Packet::WriteAt(size_t offset, uint8_t byte) { |
545 buffer_.data()[offset] = byte; | 549 buffer_.data()[offset] = byte; |
546 } | 550 } |
547 | 551 |
548 } // namespace rtp | 552 } // namespace rtp |
549 } // namespace webrtc | 553 } // namespace webrtc |
OLD | NEW |