Index: webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc b/webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc |
index b7c73062759df159f35ecbfc2b01646307db1331..7fdff3498532ad43aef92592cafc94f463371b6d 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc |
@@ -8,143 +8,148 @@ |
* be found in the AUTHORS file in the root of the source tree. |
*/ |
+#include <assert.h> |
+ |
+#include "webrtc/base/checks.h" |
+#include "webrtc/common_types.h" |
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h" |
- |
-#include "webrtc/base/arraysize.h" |
-#include "webrtc/base/checks.h" |
-#include "webrtc/base/logging.h" |
-#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" |
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
namespace webrtc { |
-namespace { |
-using RtpUtility::Word32Align; |
+constexpr uint8_t RtpHeaderExtensionMap::kInvalidId; |
-struct ExtensionInfo { |
- RTPExtensionType type; |
- size_t value_size; |
- const char* uri; |
-}; |
- |
-template <typename Extension> |
-constexpr ExtensionInfo CreateExtensionInfo() { |
- return {Extension::kId, Extension::kValueSizeBytes, Extension::kUri}; |
+RtpHeaderExtensionMap::RtpHeaderExtensionMap() { |
} |
-constexpr ExtensionInfo kExtensions[] = { |
- CreateExtensionInfo<TransmissionOffset>(), |
- CreateExtensionInfo<AudioLevel>(), |
- CreateExtensionInfo<AbsoluteSendTime>(), |
- CreateExtensionInfo<VideoOrientation>(), |
- CreateExtensionInfo<TransportSequenceNumber>(), |
- CreateExtensionInfo<PlayoutDelayLimits>(), |
-}; |
+RtpHeaderExtensionMap::~RtpHeaderExtensionMap() { |
+ Erase(); |
+} |
-// Because of kRtpExtensionNone, NumberOfExtension is 1 bigger than the actual |
-// number of known extensions. |
-static_assert(arraysize(kExtensions) == |
- static_cast<int>(kRtpExtensionNumberOfExtensions) - 1, |
- "kExtensions expect to list all known extensions"); |
+void RtpHeaderExtensionMap::Erase() { |
+ while (!extensionMap_.empty()) { |
+ std::map<uint8_t, HeaderExtension*>::iterator it = |
+ extensionMap_.begin(); |
+ delete it->second; |
+ extensionMap_.erase(it); |
+ } |
+} |
-size_t ValueSize(RTPExtensionType type) { |
- for (const ExtensionInfo& extension : kExtensions) |
- if (type == extension.type) |
- return extension.value_size; |
- |
- RTC_NOTREACHED(); |
+int32_t RtpHeaderExtensionMap::Register(RTPExtensionType type, uint8_t id) { |
+ if (id < 1 || id > 14) { |
+ return -1; |
+ } |
+ std::map<uint8_t, HeaderExtension*>::iterator it = |
+ extensionMap_.find(id); |
+ if (it != extensionMap_.end()) { |
+ if (it->second->type != type) { |
+ // An extension is already registered with the same id |
+ // but a different type, so return failure. |
+ return -1; |
+ } |
+ // This extension type is already registered with this id, |
+ // so return success. |
+ return 0; |
+ } |
+ RTC_DCHECK_EQ(kInvalidId, GetId(type)); |
+ extensionMap_[id] = new HeaderExtension(type); |
return 0; |
} |
-} // namespace |
- |
-constexpr RTPExtensionType RtpHeaderExtensionMap::kInvalidType; |
-constexpr uint8_t RtpHeaderExtensionMap::kInvalidId; |
-constexpr uint8_t RtpHeaderExtensionMap::kMinId; |
-constexpr uint8_t RtpHeaderExtensionMap::kMaxId; |
- |
-RtpHeaderExtensionMap::RtpHeaderExtensionMap() { |
- total_values_size_bytes_ = 0; |
- for (auto& type : types_) |
- type = kInvalidType; |
- for (auto& id : ids_) |
- id = kInvalidId; |
+int32_t RtpHeaderExtensionMap::Deregister(const RTPExtensionType type) { |
+ uint8_t id; |
+ if (GetId(type, &id) != 0) { |
+ return 0; |
+ } |
+ std::map<uint8_t, HeaderExtension*>::iterator it = |
+ extensionMap_.find(id); |
+ assert(it != extensionMap_.end()); |
+ delete it->second; |
+ extensionMap_.erase(it); |
+ return 0; |
} |
-RtpHeaderExtensionMap::RtpHeaderExtensionMap( |
- std::initializer_list<RtpExtension> extensions) |
- : RtpHeaderExtensionMap() { |
- for (const RtpExtension& extension : extensions) |
- RegisterByUri(extension.id, extension.uri); |
-} |
- |
-bool RtpHeaderExtensionMap::RegisterByType(uint8_t id, RTPExtensionType type) { |
- for (const ExtensionInfo& extension : kExtensions) |
- if (type == extension.type) |
- return Register(id, extension.type, extension.value_size, extension.uri); |
- RTC_NOTREACHED(); |
+bool RtpHeaderExtensionMap::IsRegistered(RTPExtensionType type) const { |
+ std::map<uint8_t, HeaderExtension*>::const_iterator it = |
+ extensionMap_.begin(); |
+ for (; it != extensionMap_.end(); ++it) { |
+ if (it->second->type == type) |
+ return true; |
+ } |
return false; |
} |
-bool RtpHeaderExtensionMap::RegisterByUri(uint8_t id, const std::string& uri) { |
- for (const ExtensionInfo& extension : kExtensions) |
- if (uri == extension.uri) |
- return Register(id, extension.type, extension.value_size, extension.uri); |
- LOG(LS_WARNING) << "Unknown extension uri:'" << uri |
- << "', id: " << static_cast<int>(id) << '.'; |
- return false; |
+int32_t RtpHeaderExtensionMap::GetType(const uint8_t id, |
+ RTPExtensionType* type) const { |
+ assert(type); |
+ std::map<uint8_t, HeaderExtension*>::const_iterator it = |
+ extensionMap_.find(id); |
+ if (it == extensionMap_.end()) { |
+ return -1; |
+ } |
+ HeaderExtension* extension = it->second; |
+ *type = extension->type; |
+ return 0; |
+} |
+ |
+RTPExtensionType RtpHeaderExtensionMap::GetType(uint8_t id) const { |
+ auto it = extensionMap_.find(id); |
+ if (it == extensionMap_.end()) { |
+ return kInvalidType; |
+ } |
+ return it->second->type; |
+} |
+ |
+int32_t RtpHeaderExtensionMap::GetId(const RTPExtensionType type, |
+ uint8_t* id) const { |
+ assert(id); |
+ std::map<uint8_t, HeaderExtension*>::const_iterator it = |
+ extensionMap_.begin(); |
+ |
+ while (it != extensionMap_.end()) { |
+ HeaderExtension* extension = it->second; |
+ if (extension->type == type) { |
+ *id = it->first; |
+ return 0; |
+ } |
+ it++; |
+ } |
+ return -1; |
+} |
+ |
+uint8_t RtpHeaderExtensionMap::GetId(RTPExtensionType type) const { |
+ for (auto kv : extensionMap_) { |
+ if (kv.second->type == type) |
+ return kv.first; |
+ } |
+ return kInvalidId; |
} |
size_t RtpHeaderExtensionMap::GetTotalLengthInBytes() const { |
- if (total_values_size_bytes_ == 0) |
- return 0; |
- return Word32Align(kRtpOneByteHeaderLength + total_values_size_bytes_); |
+ // Get length for each extension block. |
+ size_t length = 0; |
+ for (const auto& kv : extensionMap_) |
+ length += kv.second->length; |
+ // Add RTP extension header length. |
+ if (length > 0) |
+ length += kRtpOneByteHeaderLength; |
+ // Pad up to nearest 32bit word. |
+ length = RtpUtility::Word32Align(length); |
+ return length; |
} |
-int32_t RtpHeaderExtensionMap::Deregister(RTPExtensionType type) { |
- if (IsRegistered(type)) { |
- uint8_t id = GetId(type); |
- total_values_size_bytes_ -= (ValueSize(type) + 1); |
- types_[id] = kInvalidType; |
- ids_[type] = kInvalidId; |
- } |
- return 0; |
+int32_t RtpHeaderExtensionMap::Size() const { |
+ return extensionMap_.size(); |
} |
-bool RtpHeaderExtensionMap::Register(uint8_t id, |
- RTPExtensionType type, |
- size_t value_size, |
- const char* uri) { |
- RTC_DCHECK_GT(type, kRtpExtensionNone); |
- RTC_DCHECK_LT(type, kRtpExtensionNumberOfExtensions); |
- RTC_DCHECK_GE(value_size, 1U); |
- RTC_DCHECK_LE(value_size, 16U); |
- |
- if (id < kMinId || id > kMaxId) { |
- LOG(LS_WARNING) << "Failed to register extension uri:'" << uri |
- << "' with invalid id:" << static_cast<int>(id) << "."; |
- return false; |
+void RtpHeaderExtensionMap::GetCopy(RtpHeaderExtensionMap* map) const { |
+ assert(map); |
+ std::map<uint8_t, HeaderExtension*>::const_iterator it = |
+ extensionMap_.begin(); |
+ while (it != extensionMap_.end()) { |
+ HeaderExtension* extension = it->second; |
+ map->Register(extension->type, it->first); |
+ it++; |
} |
- |
- if (GetType(id) == type) { // Same type/id pair already registered. |
- LOG(LS_VERBOSE) << "Reregistering extension uri:'" << uri |
- << "', id:" << static_cast<int>(id); |
- return true; |
- } |
- |
- if (GetType(id) != kInvalidType) { // |id| used by another extension type. |
- LOG(LS_WARNING) << "Failed to register extension uri:'" << uri |
- << "', id:" << static_cast<int>(id) |
- << ". Id already in use by extension type " |
- << static_cast<int>(GetType(id)); |
- return false; |
- } |
- RTC_DCHECK(!IsRegistered(type)); |
- |
- types_[id] = type; |
- ids_[type] = id; |
- total_values_size_bytes_ += (value_size + 1); |
- return true; |
} |
- |
} // namespace webrtc |