1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <assert.h>
12
13 #include "webrtc/common_types.h"
14 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
15
16 namespace webrtc {
17
RtpHeaderExtensionMap()18 RtpHeaderExtensionMap::RtpHeaderExtensionMap() {
19 }
20
~RtpHeaderExtensionMap()21 RtpHeaderExtensionMap::~RtpHeaderExtensionMap() {
22 Erase();
23 }
24
Erase()25 void RtpHeaderExtensionMap::Erase() {
26 while (!extensionMap_.empty()) {
27 std::map<uint8_t, HeaderExtension*>::iterator it =
28 extensionMap_.begin();
29 delete it->second;
30 extensionMap_.erase(it);
31 }
32 }
33
Register(const RTPExtensionType type,const uint8_t id)34 int32_t RtpHeaderExtensionMap::Register(const RTPExtensionType type,
35 const uint8_t id) {
36 if (id < 1 || id > 14) {
37 return -1;
38 }
39 std::map<uint8_t, HeaderExtension*>::iterator it =
40 extensionMap_.find(id);
41 if (it != extensionMap_.end()) {
42 if (it->second->type != type) {
43 // An extension is already registered with the same id
44 // but a different type, so return failure.
45 return -1;
46 }
47 // This extension type is already registered with this id,
48 // so return success.
49 return 0;
50 }
51 extensionMap_[id] = new HeaderExtension(type);
52 return 0;
53 }
54
Deregister(const RTPExtensionType type)55 int32_t RtpHeaderExtensionMap::Deregister(const RTPExtensionType type) {
56 uint8_t id;
57 if (GetId(type, &id) != 0) {
58 return 0;
59 }
60 std::map<uint8_t, HeaderExtension*>::iterator it =
61 extensionMap_.find(id);
62 assert(it != extensionMap_.end());
63 delete it->second;
64 extensionMap_.erase(it);
65 return 0;
66 }
67
IsRegistered(RTPExtensionType type) const68 bool RtpHeaderExtensionMap::IsRegistered(RTPExtensionType type) const {
69 std::map<uint8_t, HeaderExtension*>::const_iterator it =
70 extensionMap_.begin();
71 for (; it != extensionMap_.end(); ++it) {
72 if (it->second->type == type)
73 return true;
74 }
75 return false;
76 }
77
GetType(const uint8_t id,RTPExtensionType * type) const78 int32_t RtpHeaderExtensionMap::GetType(const uint8_t id,
79 RTPExtensionType* type) const {
80 assert(type);
81 std::map<uint8_t, HeaderExtension*>::const_iterator it =
82 extensionMap_.find(id);
83 if (it == extensionMap_.end()) {
84 return -1;
85 }
86 HeaderExtension* extension = it->second;
87 *type = extension->type;
88 return 0;
89 }
90
GetId(const RTPExtensionType type,uint8_t * id) const91 int32_t RtpHeaderExtensionMap::GetId(const RTPExtensionType type,
92 uint8_t* id) const {
93 assert(id);
94 std::map<uint8_t, HeaderExtension*>::const_iterator it =
95 extensionMap_.begin();
96
97 while (it != extensionMap_.end()) {
98 HeaderExtension* extension = it->second;
99 if (extension->type == type) {
100 *id = it->first;
101 return 0;
102 }
103 it++;
104 }
105 return -1;
106 }
107
GetTotalLengthInBytes() const108 uint16_t RtpHeaderExtensionMap::GetTotalLengthInBytes() const {
109 // Get length for each extension block.
110 uint16_t length = 0;
111 std::map<uint8_t, HeaderExtension*>::const_iterator it =
112 extensionMap_.begin();
113 while (it != extensionMap_.end()) {
114 HeaderExtension* extension = it->second;
115 length += extension->length;
116 it++;
117 }
118 // Add RTP extension header length.
119 if (length > 0) {
120 length += kRtpOneByteHeaderLength;
121 }
122 return length;
123 }
124
GetLengthUntilBlockStartInBytes(const RTPExtensionType type) const125 int32_t RtpHeaderExtensionMap::GetLengthUntilBlockStartInBytes(
126 const RTPExtensionType type) const {
127 uint8_t id;
128 if (GetId(type, &id) != 0) {
129 // Not registered.
130 return -1;
131 }
132 // Get length until start of extension block type.
133 uint16_t length = kRtpOneByteHeaderLength;
134
135 std::map<uint8_t, HeaderExtension*>::const_iterator it =
136 extensionMap_.begin();
137 while (it != extensionMap_.end()) {
138 HeaderExtension* extension = it->second;
139 if (extension->type == type) {
140 break;
141 } else {
142 length += extension->length;
143 }
144 it++;
145 }
146 return length;
147 }
148
Size() const149 int32_t RtpHeaderExtensionMap::Size() const {
150 return extensionMap_.size();
151 }
152
First() const153 RTPExtensionType RtpHeaderExtensionMap::First() const {
154 std::map<uint8_t, HeaderExtension*>::const_iterator it =
155 extensionMap_.begin();
156 if (it == extensionMap_.end()) {
157 return kRtpExtensionNone;
158 }
159 HeaderExtension* extension = it->second;
160 return extension->type;
161 }
162
Next(RTPExtensionType type) const163 RTPExtensionType RtpHeaderExtensionMap::Next(RTPExtensionType type) const {
164 uint8_t id;
165 if (GetId(type, &id) != 0) {
166 return kRtpExtensionNone;
167 }
168 std::map<uint8_t, HeaderExtension*>::const_iterator it =
169 extensionMap_.find(id);
170 if (it == extensionMap_.end()) {
171 return kRtpExtensionNone;
172 }
173 it++;
174 if (it == extensionMap_.end()) {
175 return kRtpExtensionNone;
176 }
177 HeaderExtension* extension = it->second;
178 return extension->type;
179 }
180
GetCopy(RtpHeaderExtensionMap * map) const181 void RtpHeaderExtensionMap::GetCopy(RtpHeaderExtensionMap* map) const {
182 assert(map);
183 std::map<uint8_t, HeaderExtension*>::const_iterator it =
184 extensionMap_.begin();
185 while (it != extensionMap_.end()) {
186 HeaderExtension* extension = it->second;
187 map->Register(extension->type, it->first);
188 it++;
189 }
190 }
191 } // namespace webrtc
192