Refactor to remove direct memory dependency on kMaxId

When two-byte header extensions are enabled, kMaxId will change from 15
to 255. This CL is a refactor to remove the direct dependency between
memory allocation and kMaxId.

Bug: webrtc:7990
Change-Id: I38974a9c705eb6a0fdba9038a7d909861587d98d
Reviewed-on: https://webrtc-review.googlesource.com/101580
Commit-Queue: Johannes Kron <kron@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24801}
This commit is contained in:
Johannes Kron
2018-09-24 14:50:48 +02:00
committed by Commit Bot
parent 3a9731ff2f
commit c5744b8b21
5 changed files with 89 additions and 58 deletions

View File

@ -68,18 +68,14 @@ RtpPacket::RtpPacket(const ExtensionManager* extensions, size_t capacity)
RTC_DCHECK_GE(capacity, kFixedHeaderSize);
Clear();
if (extensions) {
IdentifyExtensions(*extensions);
} else {
for (size_t i = 0; i < kMaxExtensionHeaders; ++i)
extension_entries_[i].type = ExtensionManager::kInvalidType;
extensions_ = *extensions;
}
}
RtpPacket::~RtpPacket() {}
void RtpPacket::IdentifyExtensions(const ExtensionManager& extensions) {
for (int i = 0; i < kMaxExtensionHeaders; ++i)
extension_entries_[i].type = extensions.GetType(i + 1);
extensions_ = extensions;
}
bool RtpPacket::Parse(const uint8_t* buffer, size_t buffer_size) {
@ -127,9 +123,8 @@ void RtpPacket::CopyHeaderFrom(const RtpPacket& packet) {
timestamp_ = packet.timestamp_;
ssrc_ = packet.ssrc_;
payload_offset_ = packet.payload_offset_;
for (size_t i = 0; i < kMaxExtensionHeaders; ++i) {
extension_entries_[i] = packet.extension_entries_[i];
}
extensions_ = packet.extensions_;
extension_entries_ = packet.extension_entries_;
extensions_size_ = packet.extensions_size_;
buffer_.SetData(packet.data(), packet.headers_size());
// Reset payload and padding.
@ -189,14 +184,13 @@ rtc::ArrayView<uint8_t> RtpPacket::AllocateRawExtension(int id, size_t length) {
RTC_DCHECK_GE(length, 1);
RTC_DCHECK_LE(length, 16);
ExtensionInfo* extension_entry = &extension_entries_[id - 1];
if (extension_entry->offset != 0) {
const ExtensionInfo* extension_entry = FindExtensionInfo(id);
if (extension_entry != nullptr) {
// Extension already reserved. Check if same length is used.
if (extension_entry->length == length)
return rtc::MakeArrayView(WriteAt(extension_entry->offset), length);
RTC_LOG(LS_ERROR) << "Length mismatch for extension id " << id << " type "
<< static_cast<int>(extension_entry->type)
RTC_LOG(LS_ERROR) << "Length mismatch for extension id " << id
<< ": expected "
<< static_cast<int>(extension_entry->length)
<< ". received " << length;
@ -235,9 +229,11 @@ rtc::ArrayView<uint8_t> RtpPacket::AllocateRawExtension(int id, size_t length) {
one_byte_header |= rtc::dchecked_cast<uint8_t>(length - 1);
WriteAt(extensions_offset + extensions_size_, one_byte_header);
extension_entry->offset = rtc::dchecked_cast<uint16_t>(
const uint16_t extension_info_offset = rtc::dchecked_cast<uint16_t>(
extensions_offset + extensions_size_ + kOneByteHeaderSize);
extension_entry->length = rtc::dchecked_cast<uint8_t>(length);
const uint8_t extension_info_length = rtc::dchecked_cast<uint8_t>(length);
extension_entries_.emplace_back(id, extension_info_length,
extension_info_offset);
extensions_size_ = new_extensions_size;
// Update header length field.
@ -251,7 +247,8 @@ rtc::ArrayView<uint8_t> RtpPacket::AllocateRawExtension(int id, size_t length) {
extension_padding_size);
payload_offset_ = extensions_offset + 4 * extensions_words;
buffer_.SetSize(payload_offset_);
return rtc::MakeArrayView(WriteAt(extension_entry->offset), length);
return rtc::MakeArrayView(WriteAt(extension_info_offset),
extension_info_length);
}
uint8_t* RtpPacket::AllocatePayload(size_t size_bytes) {
@ -306,10 +303,7 @@ void RtpPacket::Clear() {
payload_size_ = 0;
padding_size_ = 0;
extensions_size_ = 0;
for (ExtensionInfo& location : extension_entries_) {
location.offset = 0;
location.length = 0;
}
extension_entries_.clear();
memset(WriteAt(0), 0, kFixedHeaderSize);
buffer_.SetSize(kFixedHeaderSize);
@ -396,8 +390,8 @@ bool RtpPacket::ParseBuffer(const uint8_t* buffer, size_t size) {
break;
}
size_t idx = id - 1;
if (extension_entries_[idx].length != 0) {
ExtensionInfo& extension_info = FindOrCreateExtensionInfo(id);
if (extension_info.length != 0) {
RTC_LOG(LS_VERBOSE)
<< "Duplicate rtp header extension id " << id << ". Overwriting.";
}
@ -408,8 +402,8 @@ bool RtpPacket::ParseBuffer(const uint8_t* buffer, size_t size) {
RTC_DLOG(LS_WARNING) << "Oversized rtp header extension.";
break;
}
extension_entries_[idx].offset = static_cast<uint16_t>(offset);
extension_entries_[idx].length = length;
extension_info.offset = static_cast<uint16_t>(offset);
extension_info.length = length;
extensions_size_ += kOneByteHeaderSize + length;
}
}
@ -423,30 +417,48 @@ bool RtpPacket::ParseBuffer(const uint8_t* buffer, size_t size) {
return true;
}
rtc::ArrayView<const uint8_t> RtpPacket::FindExtension(
ExtensionType type) const {
const RtpPacket::ExtensionInfo* RtpPacket::FindExtensionInfo(int id) const {
for (const ExtensionInfo& extension : extension_entries_) {
if (extension.type == type) {
if (extension.length == 0) {
// Extension is registered but not set.
return nullptr;
}
return rtc::MakeArrayView(data() + extension.offset, extension.length);
if (extension.id == id) {
return &extension;
}
}
return nullptr;
}
RtpPacket::ExtensionInfo& RtpPacket::FindOrCreateExtensionInfo(int id) {
for (ExtensionInfo& extension : extension_entries_) {
if (extension.id == id) {
return extension;
}
}
extension_entries_.emplace_back(id);
return extension_entries_.back();
}
rtc::ArrayView<const uint8_t> RtpPacket::FindExtension(
ExtensionType type) const {
uint8_t id = extensions_.GetId(type);
if (id == ExtensionManager::kInvalidId) {
// Extension not registered.
return nullptr;
}
ExtensionInfo const* extension_info = FindExtensionInfo(id);
if (extension_info == nullptr) {
return nullptr;
}
return rtc::MakeArrayView(data() + extension_info->offset,
extension_info->length);
}
rtc::ArrayView<uint8_t> RtpPacket::AllocateExtension(ExtensionType type,
size_t length) {
for (int i = 0; i < kMaxExtensionHeaders; ++i) {
if (extension_entries_[i].type == type) {
int extension_id = i + 1;
return AllocateRawExtension(extension_id, length);
}
uint8_t id = extensions_.GetId(type);
if (id == ExtensionManager::kInvalidId) {
// Extension not registered.
return nullptr;
}
// Extension not registered.
return nullptr;
return AllocateRawExtension(id, length);
}
} // namespace webrtc