| 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 |