| 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 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 // |One-byte eXtensions id = 0xbede| length in 32bits | | 45 // |One-byte eXtensions id = 0xbede| length in 32bits | |
| 46 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 46 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 47 // | Extensions | | 47 // | Extensions | |
| 48 // | .... | | 48 // | .... | |
| 49 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 49 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 50 // | Payload | | 50 // | Payload | |
| 51 // | .... : padding... | | 51 // | .... : padding... | |
| 52 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 52 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 53 // | padding | Padding size | | 53 // | padding | Padding size | |
| 54 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 54 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 55 Packet::Packet() : Packet(nullptr, kDefaultPacketSize) {} |
| 56 |
| 55 Packet::Packet(const ExtensionManager* extensions) | 57 Packet::Packet(const ExtensionManager* extensions) |
| 56 : extensions_(extensions), buffer_(kDefaultPacketSize) { | 58 : Packet(extensions, kDefaultPacketSize) {} |
| 57 Clear(); | |
| 58 } | |
| 59 | 59 |
| 60 Packet::Packet(const ExtensionManager* extensions, size_t capacity) | 60 Packet::Packet(const ExtensionManager* extensions, size_t capacity) |
| 61 : extensions_(extensions), buffer_(capacity) { | 61 : buffer_(capacity) { |
| 62 RTC_DCHECK_GE(capacity, kFixedHeaderSize); | 62 RTC_DCHECK_GE(capacity, kFixedHeaderSize); |
| 63 Clear(); | 63 Clear(); |
| 64 if (extensions) { |
| 65 IdentifyExtensions(*extensions); |
| 66 } else { |
| 67 for (size_t i = 0; i < kMaxExtensionHeaders; ++i) |
| 68 extension_entries_[i].type = ExtensionManager::kInvalidType; |
| 69 } |
| 64 } | 70 } |
| 65 | 71 |
| 66 Packet::~Packet() {} | 72 Packet::~Packet() {} |
| 67 | 73 |
| 68 void Packet::IdentifyExtensions(const ExtensionManager* extensions) { | 74 void Packet::IdentifyExtensions(const ExtensionManager& extensions) { |
| 69 RTC_DCHECK(extensions); | 75 for (size_t i = 0; i < kMaxExtensionHeaders; ++i) |
| 70 extensions_ = extensions; | 76 extension_entries_[i].type = extensions.GetType(i + 1); |
| 71 for (size_t i = 0; i < num_extensions_; ++i) { | |
| 72 uint8_t id = data()[extension_entries_[i].offset - 1] >> 4; | |
| 73 extension_entries_[i].type = extensions_->GetType(id); | |
| 74 } | |
| 75 } | 77 } |
| 76 | 78 |
| 77 bool Packet::Parse(const uint8_t* buffer, size_t buffer_size) { | 79 bool Packet::Parse(const uint8_t* buffer, size_t buffer_size) { |
| 78 if (!ParseBuffer(buffer, buffer_size)) { | 80 if (!ParseBuffer(buffer, buffer_size)) { |
| 79 Clear(); | 81 Clear(); |
| 80 return false; | 82 return false; |
| 81 } | 83 } |
| 82 buffer_.SetData(buffer, buffer_size); | 84 buffer_.SetData(buffer, buffer_size); |
| 83 RTC_DCHECK_EQ(size(), buffer_size); | 85 RTC_DCHECK_EQ(size(), buffer_size); |
| 84 return true; | 86 return true; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 | 206 |
| 205 void Packet::CopyHeaderFrom(const Packet& packet) { | 207 void Packet::CopyHeaderFrom(const Packet& packet) { |
| 206 RTC_DCHECK_GE(capacity(), packet.headers_size()); | 208 RTC_DCHECK_GE(capacity(), packet.headers_size()); |
| 207 | 209 |
| 208 marker_ = packet.marker_; | 210 marker_ = packet.marker_; |
| 209 payload_type_ = packet.payload_type_; | 211 payload_type_ = packet.payload_type_; |
| 210 sequence_number_ = packet.sequence_number_; | 212 sequence_number_ = packet.sequence_number_; |
| 211 timestamp_ = packet.timestamp_; | 213 timestamp_ = packet.timestamp_; |
| 212 ssrc_ = packet.ssrc_; | 214 ssrc_ = packet.ssrc_; |
| 213 payload_offset_ = packet.payload_offset_; | 215 payload_offset_ = packet.payload_offset_; |
| 214 num_extensions_ = packet.num_extensions_; | 216 for (size_t i = 0; i < kMaxExtensionHeaders; ++i) { |
| 215 for (size_t i = 0; i < num_extensions_; ++i) { | |
| 216 extension_entries_[i] = packet.extension_entries_[i]; | 217 extension_entries_[i] = packet.extension_entries_[i]; |
| 217 } | 218 } |
| 218 extensions_size_ = packet.extensions_size_; | 219 extensions_size_ = packet.extensions_size_; |
| 219 buffer_.SetData(packet.data(), packet.headers_size()); | 220 buffer_.SetData(packet.data(), packet.headers_size()); |
| 220 // Reset payload and padding. | 221 // Reset payload and padding. |
| 221 payload_size_ = 0; | 222 payload_size_ = 0; |
| 222 padding_size_ = 0; | 223 padding_size_ = 0; |
| 223 } | 224 } |
| 224 | 225 |
| 225 void Packet::SetMarker(bool marker_bit) { | 226 void Packet::SetMarker(bool marker_bit) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 246 timestamp_ = timestamp; | 247 timestamp_ = timestamp; |
| 247 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(4), timestamp); | 248 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(4), timestamp); |
| 248 } | 249 } |
| 249 | 250 |
| 250 void Packet::SetSsrc(uint32_t ssrc) { | 251 void Packet::SetSsrc(uint32_t ssrc) { |
| 251 ssrc_ = ssrc; | 252 ssrc_ = ssrc; |
| 252 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(8), ssrc); | 253 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(8), ssrc); |
| 253 } | 254 } |
| 254 | 255 |
| 255 void Packet::SetCsrcs(const std::vector<uint32_t>& csrcs) { | 256 void Packet::SetCsrcs(const std::vector<uint32_t>& csrcs) { |
| 256 RTC_DCHECK_EQ(num_extensions_, 0); | 257 RTC_DCHECK_EQ(extensions_size_, 0); |
| 257 RTC_DCHECK_EQ(payload_size_, 0); | 258 RTC_DCHECK_EQ(payload_size_, 0); |
| 258 RTC_DCHECK_EQ(padding_size_, 0); | 259 RTC_DCHECK_EQ(padding_size_, 0); |
| 259 RTC_DCHECK_LE(csrcs.size(), 0x0fu); | 260 RTC_DCHECK_LE(csrcs.size(), 0x0fu); |
| 260 RTC_DCHECK_LE(kFixedHeaderSize + 4 * csrcs.size(), capacity()); | 261 RTC_DCHECK_LE(kFixedHeaderSize + 4 * csrcs.size(), capacity()); |
| 261 payload_offset_ = kFixedHeaderSize + 4 * csrcs.size(); | 262 payload_offset_ = kFixedHeaderSize + 4 * csrcs.size(); |
| 262 WriteAt(0, (data()[0] & 0xF0) | csrcs.size()); | 263 WriteAt(0, (data()[0] & 0xF0) | csrcs.size()); |
| 263 size_t offset = kFixedHeaderSize; | 264 size_t offset = kFixedHeaderSize; |
| 264 for (uint32_t csrc : csrcs) { | 265 for (uint32_t csrc : csrcs) { |
| 265 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(offset), csrc); | 266 ByteWriter<uint32_t>::WriteBigEndian(WriteAt(offset), csrc); |
| 266 offset += 4; | 267 offset += 4; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 | 316 |
| 316 void Packet::Clear() { | 317 void Packet::Clear() { |
| 317 marker_ = false; | 318 marker_ = false; |
| 318 payload_type_ = 0; | 319 payload_type_ = 0; |
| 319 sequence_number_ = 0; | 320 sequence_number_ = 0; |
| 320 timestamp_ = 0; | 321 timestamp_ = 0; |
| 321 ssrc_ = 0; | 322 ssrc_ = 0; |
| 322 payload_offset_ = kFixedHeaderSize; | 323 payload_offset_ = kFixedHeaderSize; |
| 323 payload_size_ = 0; | 324 payload_size_ = 0; |
| 324 padding_size_ = 0; | 325 padding_size_ = 0; |
| 325 num_extensions_ = 0; | |
| 326 extensions_size_ = 0; | 326 extensions_size_ = 0; |
| 327 for (ExtensionInfo& location : extension_entries_) { |
| 328 location.offset = 0; |
| 329 location.length = 0; |
| 330 } |
| 327 | 331 |
| 328 memset(WriteAt(0), 0, kFixedHeaderSize); | 332 memset(WriteAt(0), 0, kFixedHeaderSize); |
| 329 buffer_.SetSize(kFixedHeaderSize); | 333 buffer_.SetSize(kFixedHeaderSize); |
| 330 WriteAt(0, kRtpVersion << 6); | 334 WriteAt(0, kRtpVersion << 6); |
| 331 } | 335 } |
| 332 | 336 |
| 333 bool Packet::ParseBuffer(const uint8_t* buffer, size_t size) { | 337 bool Packet::ParseBuffer(const uint8_t* buffer, size_t size) { |
| 334 if (size < kFixedHeaderSize) { | 338 if (size < kFixedHeaderSize) { |
| 335 return false; | 339 return false; |
| 336 } | 340 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 355 if (has_padding) { | 359 if (has_padding) { |
| 356 padding_size_ = buffer[size - 1]; | 360 padding_size_ = buffer[size - 1]; |
| 357 if (padding_size_ == 0) { | 361 if (padding_size_ == 0) { |
| 358 LOG(LS_WARNING) << "Padding was set, but padding size is zero"; | 362 LOG(LS_WARNING) << "Padding was set, but padding size is zero"; |
| 359 return false; | 363 return false; |
| 360 } | 364 } |
| 361 } else { | 365 } else { |
| 362 padding_size_ = 0; | 366 padding_size_ = 0; |
| 363 } | 367 } |
| 364 | 368 |
| 365 num_extensions_ = 0; | |
| 366 extensions_size_ = 0; | 369 extensions_size_ = 0; |
| 370 for (ExtensionInfo& location : extension_entries_) { |
| 371 location.offset = 0; |
| 372 location.length = 0; |
| 373 } |
| 367 if (has_extension) { | 374 if (has_extension) { |
| 368 /* RTP header extension, RFC 3550. | 375 /* RTP header extension, RFC 3550. |
| 369 0 1 2 3 | 376 0 1 2 3 |
| 370 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 | 377 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 |
| 371 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 378 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 372 | defined by profile | length | | 379 | defined by profile | length | |
| 373 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 380 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 374 | header extension | | 381 | header extension | |
| 375 | .... | | 382 | .... | |
| 376 */ | 383 */ |
| 377 size_t extension_offset = payload_offset_ + 4; | 384 size_t extension_offset = payload_offset_ + 4; |
| 378 if (extension_offset > size) { | 385 if (extension_offset > size) { |
| 379 return false; | 386 return false; |
| 380 } | 387 } |
| 381 uint16_t profile = | 388 uint16_t profile = |
| 382 ByteReader<uint16_t>::ReadBigEndian(&buffer[payload_offset_]); | 389 ByteReader<uint16_t>::ReadBigEndian(&buffer[payload_offset_]); |
| 383 size_t extensions_capacity = | 390 size_t extensions_capacity = |
| 384 ByteReader<uint16_t>::ReadBigEndian(&buffer[payload_offset_ + 2]); | 391 ByteReader<uint16_t>::ReadBigEndian(&buffer[payload_offset_ + 2]); |
| 385 extensions_capacity *= 4; | 392 extensions_capacity *= 4; |
| 386 if (extension_offset + extensions_capacity > size) { | 393 if (extension_offset + extensions_capacity > size) { |
| 387 return false; | 394 return false; |
| 388 } | 395 } |
| 389 if (profile != kOneByteExtensionId) { | 396 if (profile != kOneByteExtensionId) { |
| 390 LOG(LS_WARNING) << "Unsupported rtp extension " << profile; | 397 LOG(LS_WARNING) << "Unsupported rtp extension " << profile; |
| 391 } else { | 398 } else { |
| 392 constexpr uint8_t kPaddingId = 0; | 399 constexpr uint8_t kPaddingId = 0; |
| 393 constexpr uint8_t kReservedId = 15; | 400 constexpr uint8_t kReservedId = 15; |
| 394 while (extensions_size_ + kOneByteHeaderSize < extensions_capacity) { | 401 while (extensions_size_ + kOneByteHeaderSize < extensions_capacity) { |
| 395 uint8_t id = buffer[extension_offset + extensions_size_] >> 4; | 402 int id = buffer[extension_offset + extensions_size_] >> 4; |
| 396 if (id == kReservedId) { | 403 if (id == kReservedId) { |
| 397 break; | 404 break; |
| 398 } else if (id == kPaddingId) { | 405 } else if (id == kPaddingId) { |
| 399 extensions_size_++; | 406 extensions_size_++; |
| 400 continue; | 407 continue; |
| 401 } | 408 } |
| 402 uint8_t length = | 409 uint8_t length = |
| 403 1 + (buffer[extension_offset + extensions_size_] & 0xf); | 410 1 + (buffer[extension_offset + extensions_size_] & 0xf); |
| 404 if (extensions_size_ + kOneByteHeaderSize + length > | 411 if (extensions_size_ + kOneByteHeaderSize + length > |
| 405 extensions_capacity) { | 412 extensions_capacity) { |
| 406 LOG(LS_WARNING) << "Oversized rtp header extension."; | 413 LOG(LS_WARNING) << "Oversized rtp header extension."; |
| 407 break; | 414 break; |
| 408 } | 415 } |
| 409 if (num_extensions_ >= kMaxExtensionHeaders) { | 416 |
| 410 LOG(LS_WARNING) << "Too many rtp header extensions."; | 417 size_t idx = id - 1; |
| 411 break; | 418 if (extension_entries_[idx].length != 0) { |
| 419 LOG(LS_VERBOSE) << "Duplicate rtp header extension id " << id |
| 420 << ". Overwriting."; |
| 412 } | 421 } |
| 422 |
| 413 extensions_size_ += kOneByteHeaderSize; | 423 extensions_size_ += kOneByteHeaderSize; |
| 414 extension_entries_[num_extensions_].type = | 424 extension_entries_[idx].offset = extension_offset + extensions_size_; |
| 415 extensions_ ? extensions_->GetType(id) | 425 extension_entries_[idx].length = length; |
| 416 : ExtensionManager::kInvalidType; | |
| 417 extension_entries_[num_extensions_].length = length; | |
| 418 extension_entries_[num_extensions_].offset = | |
| 419 extension_offset + extensions_size_; | |
| 420 num_extensions_++; | |
| 421 extensions_size_ += length; | 426 extensions_size_ += length; |
| 422 } | 427 } |
| 423 } | 428 } |
| 424 payload_offset_ = extension_offset + extensions_capacity; | 429 payload_offset_ = extension_offset + extensions_capacity; |
| 425 } | 430 } |
| 426 | 431 |
| 427 if (payload_offset_ + padding_size_ > size) { | 432 if (payload_offset_ + padding_size_ > size) { |
| 428 return false; | 433 return false; |
| 429 } | 434 } |
| 430 payload_size_ = size - payload_offset_ - padding_size_; | 435 payload_size_ = size - payload_offset_ - padding_size_; |
| 431 return true; | 436 return true; |
| 432 } | 437 } |
| 433 | 438 |
| 434 bool Packet::FindExtension(ExtensionType type, | 439 bool Packet::FindExtension(ExtensionType type, |
| 435 uint8_t length, | 440 uint8_t length, |
| 436 uint16_t* offset) const { | 441 uint16_t* offset) const { |
| 437 RTC_DCHECK(offset); | 442 RTC_DCHECK(offset); |
| 438 for (size_t i = 0; i < num_extensions_; ++i) { | 443 for (const ExtensionInfo& extension : extension_entries_) { |
| 439 if (extension_entries_[i].type == type) { | 444 if (extension.type == type) { |
| 440 if (length != extension_entries_[i].length) { | 445 if (extension.length == 0) { |
| 446 // Extension is registered but not set. |
| 447 return false; |
| 448 } |
| 449 if (length != extension.length) { |
| 441 LOG(LS_WARNING) << "Length mismatch for extension '" << type | 450 LOG(LS_WARNING) << "Length mismatch for extension '" << type |
| 442 << "': expected " << static_cast<int>(length) | 451 << "': expected " << static_cast<int>(length) |
| 443 << ", received " | 452 << ", received " << static_cast<int>(extension.length); |
| 444 << static_cast<int>(extension_entries_[i].length); | |
| 445 return false; | 453 return false; |
| 446 } | 454 } |
| 447 *offset = extension_entries_[i].offset; | 455 *offset = extension.offset; |
| 448 return true; | 456 return true; |
| 449 } | 457 } |
| 450 } | 458 } |
| 451 return false; | 459 return false; |
| 452 } | 460 } |
| 453 | 461 |
| 454 bool Packet::AllocateExtension(ExtensionType type, | 462 bool Packet::AllocateExtension(ExtensionType type, |
| 455 uint8_t length, | 463 uint8_t length, |
| 456 uint16_t* offset) { | 464 uint16_t* offset) { |
| 457 if (!extensions_) { | 465 uint8_t extension_id = ExtensionManager::kInvalidId; |
| 466 ExtensionInfo* extension_entry = nullptr; |
| 467 for (size_t i = 0; i < kMaxExtensionHeaders; ++i) { |
| 468 if (extension_entries_[i].type == type) { |
| 469 extension_id = i + 1; |
| 470 extension_entry = &extension_entries_[i]; |
| 471 break; |
| 472 } |
| 473 } |
| 474 |
| 475 if (!extension_entry) // Extension not registered. |
| 458 return false; | 476 return false; |
| 459 } | 477 |
| 460 if (FindExtension(type, length, offset)) { | 478 if (extension_entry->length != 0) { // Already allocated. |
| 479 if (length != extension_entry->length) { |
| 480 LOG(LS_WARNING) << "Length mismatch for extension '" << type |
| 481 << "': expected " << static_cast<int>(length) |
| 482 << ", received " |
| 483 << static_cast<int>(extension_entry->length); |
| 484 return false; |
| 485 } |
| 486 *offset = extension_entry->offset; |
| 461 return true; | 487 return true; |
| 462 } | 488 } |
| 463 | 489 |
| 464 // Can't add new extension after payload/padding was set. | 490 // Can't add new extension after payload/padding was set. |
| 465 if (payload_size_ > 0) { | 491 if (payload_size_ > 0) { |
| 466 return false; | 492 return false; |
| 467 } | 493 } |
| 468 if (padding_size_ > 0) { | 494 if (padding_size_ > 0) { |
| 469 return false; | 495 return false; |
| 470 } | 496 } |
| 471 | 497 |
| 472 uint8_t extension_id = extensions_->GetId(type); | |
| 473 if (extension_id == ExtensionManager::kInvalidId) { | |
| 474 return false; | |
| 475 } | |
| 476 RTC_DCHECK_GT(length, 0); | 498 RTC_DCHECK_GT(length, 0); |
| 477 RTC_DCHECK_LE(length, 16); | 499 RTC_DCHECK_LE(length, 16); |
| 478 | 500 |
| 479 size_t num_csrc = data()[0] & 0x0F; | 501 size_t num_csrc = data()[0] & 0x0F; |
| 480 size_t extensions_offset = kFixedHeaderSize + (num_csrc * 4) + 4; | 502 size_t extensions_offset = kFixedHeaderSize + (num_csrc * 4) + 4; |
| 481 if (extensions_offset + extensions_size_ + kOneByteHeaderSize + length > | 503 if (extensions_offset + extensions_size_ + kOneByteHeaderSize + length > |
| 482 capacity()) { | 504 capacity()) { |
| 483 LOG(LS_WARNING) << "Extension cannot be registered: " | 505 LOG(LS_WARNING) << "Extension cannot be registered: " |
| 484 "Not enough space left in buffer."; | 506 "Not enough space left in buffer."; |
| 485 return false; | 507 return false; |
| 486 } | 508 } |
| 487 | 509 |
| 488 uint16_t new_extensions_size = | 510 uint16_t new_extensions_size = |
| 489 extensions_size_ + kOneByteHeaderSize + length; | 511 extensions_size_ + kOneByteHeaderSize + length; |
| 490 uint16_t extensions_words = | 512 uint16_t extensions_words = |
| 491 (new_extensions_size + 3) / 4; // Wrap up to 32bit. | 513 (new_extensions_size + 3) / 4; // Wrap up to 32bit. |
| 492 | 514 |
| 493 // All checks passed, write down the extension. | 515 // All checks passed, write down the extension. |
| 494 if (num_extensions_ == 0) { | 516 if (extensions_size_ == 0) { |
| 495 RTC_DCHECK_EQ(payload_offset_, kFixedHeaderSize + (num_csrc * 4)); | 517 RTC_DCHECK_EQ(payload_offset_, kFixedHeaderSize + (num_csrc * 4)); |
| 496 RTC_DCHECK_EQ(extensions_size_, 0); | |
| 497 WriteAt(0, data()[0] | 0x10); // Set extension bit. | 518 WriteAt(0, data()[0] | 0x10); // Set extension bit. |
| 498 // Profile specific ID always set to OneByteExtensionHeader. | 519 // Profile specific ID always set to OneByteExtensionHeader. |
| 499 ByteWriter<uint16_t>::WriteBigEndian(WriteAt(extensions_offset - 4), | 520 ByteWriter<uint16_t>::WriteBigEndian(WriteAt(extensions_offset - 4), |
| 500 kOneByteExtensionId); | 521 kOneByteExtensionId); |
| 501 } | 522 } |
| 502 | 523 |
| 503 WriteAt(extensions_offset + extensions_size_, | 524 WriteAt(extensions_offset + extensions_size_, |
| 504 (extension_id << 4) | (length - 1)); | 525 (extension_id << 4) | (length - 1)); |
| 505 RTC_DCHECK(num_extensions_ < kMaxExtensionHeaders); | 526 |
| 506 extension_entries_[num_extensions_].type = type; | 527 extension_entry->length = length; |
| 507 extension_entries_[num_extensions_].length = length; | |
| 508 *offset = extensions_offset + kOneByteHeaderSize + extensions_size_; | 528 *offset = extensions_offset + kOneByteHeaderSize + extensions_size_; |
| 509 extension_entries_[num_extensions_].offset = *offset; | 529 extension_entry->offset = *offset; |
| 510 ++num_extensions_; | |
| 511 extensions_size_ = new_extensions_size; | 530 extensions_size_ = new_extensions_size; |
| 512 | 531 |
| 513 // Update header length field. | 532 // Update header length field. |
| 514 ByteWriter<uint16_t>::WriteBigEndian(WriteAt(extensions_offset - 2), | 533 ByteWriter<uint16_t>::WriteBigEndian(WriteAt(extensions_offset - 2), |
| 515 extensions_words); | 534 extensions_words); |
| 516 // Fill extension padding place with zeroes. | 535 // Fill extension padding place with zeroes. |
| 517 size_t extension_padding_size = 4 * extensions_words - extensions_size_; | 536 size_t extension_padding_size = 4 * extensions_words - extensions_size_; |
| 518 memset(WriteAt(extensions_offset + extensions_size_), 0, | 537 memset(WriteAt(extensions_offset + extensions_size_), 0, |
| 519 extension_padding_size); | 538 extension_padding_size); |
| 520 payload_offset_ = extensions_offset + 4 * extensions_words; | 539 payload_offset_ = extensions_offset + 4 * extensions_words; |
| 521 buffer_.SetSize(payload_offset_); | 540 buffer_.SetSize(payload_offset_); |
| 522 return true; | 541 return true; |
| 523 } | 542 } |
| 524 | 543 |
| 525 uint8_t* Packet::WriteAt(size_t offset) { | 544 uint8_t* Packet::WriteAt(size_t offset) { |
| 526 return buffer_.data() + offset; | 545 return buffer_.data() + offset; |
| 527 } | 546 } |
| 528 | 547 |
| 529 void Packet::WriteAt(size_t offset, uint8_t byte) { | 548 void Packet::WriteAt(size_t offset, uint8_t byte) { |
| 530 buffer_.data()[offset] = byte; | 549 buffer_.data()[offset] = byte; |
| 531 } | 550 } |
| 532 | 551 |
| 533 } // namespace rtp | 552 } // namespace rtp |
| 534 } // namespace webrtc | 553 } // namespace webrtc |
| OLD | NEW |