Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(614)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc

Issue 2452293004: Simplify and extend RtpHeaderExtensionMap (Closed)
Patch Set: Add DCHECKs to GetId/GetType Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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 <assert.h> 11 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
12 12
13 #include "webrtc/base/arraysize.h"
13 #include "webrtc/base/checks.h" 14 #include "webrtc/base/checks.h"
14 #include "webrtc/common_types.h" 15 #include "webrtc/base/logging.h"
15 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h" 16 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
16 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 17 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
17 18
18 namespace webrtc { 19 namespace webrtc {
20 namespace {
19 21
20 constexpr uint8_t RtpHeaderExtensionMap::kInvalidId; 22 using RtpUtility::Word32Align;
21 23
22 RtpHeaderExtensionMap::RtpHeaderExtensionMap() { 24 struct ExtensionInfo {
25 RTPExtensionType type;
26 size_t value_size;
27 const char* uri;
28 };
29
30 template <typename Extension>
31 constexpr ExtensionInfo CreateExtensionInfo() {
32 return {Extension::kId, Extension::kValueSizeBytes, Extension::kUri};
23 } 33 }
24 34
25 RtpHeaderExtensionMap::~RtpHeaderExtensionMap() { 35 constexpr ExtensionInfo kExtensions[] = {
26 Erase(); 36 CreateExtensionInfo<TransmissionOffset>(),
27 } 37 CreateExtensionInfo<AudioLevel>(),
38 CreateExtensionInfo<AbsoluteSendTime>(),
39 CreateExtensionInfo<VideoOrientation>(),
40 CreateExtensionInfo<TransportSequenceNumber>(),
41 CreateExtensionInfo<PlayoutDelayLimits>(),
42 };
28 43
29 void RtpHeaderExtensionMap::Erase() { 44 // Because of kRtpExtensionNone, NumberOfExtension is 1 bigger than the actual
30 while (!extensionMap_.empty()) { 45 // number of known extensions.
31 std::map<uint8_t, HeaderExtension*>::iterator it = 46 static_assert(arraysize(kExtensions) ==
32 extensionMap_.begin(); 47 static_cast<int>(kRtpExtensionNumberOfExtensions) - 1,
33 delete it->second; 48 "kExtensions expect to list all known extensions");
34 extensionMap_.erase(it);
35 }
36 }
37 49
38 int32_t RtpHeaderExtensionMap::Register(RTPExtensionType type, uint8_t id) { 50 size_t ValueSize(RTPExtensionType type) {
39 if (id < 1 || id > 14) { 51 for (const ExtensionInfo& extension : kExtensions)
40 return -1; 52 if (type == extension.type)
41 } 53 return extension.value_size;
42 std::map<uint8_t, HeaderExtension*>::iterator it = 54
43 extensionMap_.find(id); 55 RTC_NOTREACHED();
44 if (it != extensionMap_.end()) {
45 if (it->second->type != type) {
46 // An extension is already registered with the same id
47 // but a different type, so return failure.
48 return -1;
49 }
50 // This extension type is already registered with this id,
51 // so return success.
52 return 0;
53 }
54 RTC_DCHECK_EQ(kInvalidId, GetId(type));
55 extensionMap_[id] = new HeaderExtension(type);
56 return 0; 56 return 0;
57 } 57 }
58 58
59 int32_t RtpHeaderExtensionMap::Deregister(const RTPExtensionType type) { 59 } // namespace
60 uint8_t id; 60
61 if (GetId(type, &id) != 0) { 61 constexpr RTPExtensionType RtpHeaderExtensionMap::kInvalidType;
62 constexpr uint8_t RtpHeaderExtensionMap::kInvalidId;
63 constexpr uint8_t RtpHeaderExtensionMap::kMinId;
64 constexpr uint8_t RtpHeaderExtensionMap::kMaxId;
65
66 RtpHeaderExtensionMap::RtpHeaderExtensionMap() {
67 total_values_size_bytes_ = 0;
68 for (auto& type : types_)
69 type = kInvalidType;
70 for (auto& id : ids_)
71 id = kInvalidId;
72 }
73
74 RtpHeaderExtensionMap::RtpHeaderExtensionMap(
75 std::initializer_list<RtpExtension> extensions)
76 : RtpHeaderExtensionMap() {
77 for (const RtpExtension& extension : extensions)
78 RegisterByUri(extension.id, extension.uri);
79 }
80
81 bool RtpHeaderExtensionMap::RegisterByType(uint8_t id, RTPExtensionType type) {
82 for (const ExtensionInfo& extension : kExtensions)
83 if (type == extension.type)
84 return Register(id, extension.type, extension.value_size, extension.uri);
85 RTC_NOTREACHED();
86 return false;
87 }
88
89 bool RtpHeaderExtensionMap::RegisterByUri(uint8_t id, const std::string& uri) {
90 for (const ExtensionInfo& extension : kExtensions)
91 if (uri == extension.uri)
92 return Register(id, extension.type, extension.value_size, extension.uri);
93 LOG(LS_WARNING) << "Unknown extension uri:'" << uri
94 << "', id: " << static_cast<int>(id) << '.';
95 return false;
96 }
97
98 size_t RtpHeaderExtensionMap::GetTotalLengthInBytes() const {
99 if (total_values_size_bytes_ == 0)
62 return 0; 100 return 0;
101 return Word32Align(kRtpOneByteHeaderLength + total_values_size_bytes_);
102 }
103
104 int32_t RtpHeaderExtensionMap::Deregister(RTPExtensionType type) {
105 if (IsRegistered(type)) {
106 uint8_t id = GetId(type);
107 total_values_size_bytes_ -= (ValueSize(type) + 1);
108 types_[id] = kInvalidType;
109 ids_[type] = kInvalidId;
63 } 110 }
64 std::map<uint8_t, HeaderExtension*>::iterator it =
65 extensionMap_.find(id);
66 assert(it != extensionMap_.end());
67 delete it->second;
68 extensionMap_.erase(it);
69 return 0; 111 return 0;
70 } 112 }
71 113
72 bool RtpHeaderExtensionMap::IsRegistered(RTPExtensionType type) const { 114 bool RtpHeaderExtensionMap::Register(uint8_t id,
73 std::map<uint8_t, HeaderExtension*>::const_iterator it = 115 RTPExtensionType type,
74 extensionMap_.begin(); 116 size_t value_size,
75 for (; it != extensionMap_.end(); ++it) { 117 const char* uri) {
76 if (it->second->type == type) 118 RTC_DCHECK_GT(type, kRtpExtensionNone);
77 return true; 119 RTC_DCHECK_LT(type, kRtpExtensionNumberOfExtensions);
120 RTC_DCHECK_GE(value_size, 1U);
121 RTC_DCHECK_LE(value_size, 16U);
122
123 if (id < kMinId || id > kMaxId) {
124 LOG(LS_WARNING) << "Failed to register extension uri:'" << uri
125 << "' with invalid id:" << static_cast<int>(id) << ".";
126 return false;
78 } 127 }
79 return false; 128
129 if (GetType(id) == type) { // Same type/id pair already registered.
130 LOG(LS_VERBOSE) << "Reregistering extension uri:'" << uri
131 << "', id:" << static_cast<int>(id);
132 return true;
133 }
134
135 if (GetType(id) != kInvalidType) { // |id| used by another extension type.
136 LOG(LS_WARNING) << "Failed to register extension uri:'" << uri
137 << "', id:" << static_cast<int>(id)
138 << ". Id already in use by extension type "
139 << static_cast<int>(GetType(id));
140 return false;
141 }
142 RTC_DCHECK(!IsRegistered(type));
143
144 types_[id] = type;
145 ids_[type] = id;
146 total_values_size_bytes_ += (value_size + 1);
147 return true;
80 } 148 }
81 149
82 int32_t RtpHeaderExtensionMap::GetType(const uint8_t id,
83 RTPExtensionType* type) const {
84 assert(type);
85 std::map<uint8_t, HeaderExtension*>::const_iterator it =
86 extensionMap_.find(id);
87 if (it == extensionMap_.end()) {
88 return -1;
89 }
90 HeaderExtension* extension = it->second;
91 *type = extension->type;
92 return 0;
93 }
94
95 RTPExtensionType RtpHeaderExtensionMap::GetType(uint8_t id) const {
96 auto it = extensionMap_.find(id);
97 if (it == extensionMap_.end()) {
98 return kInvalidType;
99 }
100 return it->second->type;
101 }
102
103 int32_t RtpHeaderExtensionMap::GetId(const RTPExtensionType type,
104 uint8_t* id) const {
105 assert(id);
106 std::map<uint8_t, HeaderExtension*>::const_iterator it =
107 extensionMap_.begin();
108
109 while (it != extensionMap_.end()) {
110 HeaderExtension* extension = it->second;
111 if (extension->type == type) {
112 *id = it->first;
113 return 0;
114 }
115 it++;
116 }
117 return -1;
118 }
119
120 uint8_t RtpHeaderExtensionMap::GetId(RTPExtensionType type) const {
121 for (auto kv : extensionMap_) {
122 if (kv.second->type == type)
123 return kv.first;
124 }
125 return kInvalidId;
126 }
127
128 size_t RtpHeaderExtensionMap::GetTotalLengthInBytes() const {
129 // Get length for each extension block.
130 size_t length = 0;
131 for (const auto& kv : extensionMap_)
132 length += kv.second->length;
133 // Add RTP extension header length.
134 if (length > 0)
135 length += kRtpOneByteHeaderLength;
136 // Pad up to nearest 32bit word.
137 length = RtpUtility::Word32Align(length);
138 return length;
139 }
140
141 int32_t RtpHeaderExtensionMap::Size() const {
142 return extensionMap_.size();
143 }
144
145 void RtpHeaderExtensionMap::GetCopy(RtpHeaderExtensionMap* map) const {
146 assert(map);
147 std::map<uint8_t, HeaderExtension*>::const_iterator it =
148 extensionMap_.begin();
149 while (it != extensionMap_.end()) {
150 HeaderExtension* extension = it->second;
151 map->Register(extension->type, it->first);
152 it++;
153 }
154 }
155 } // namespace webrtc 150 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_header_extension.h ('k') | webrtc/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698