1 /*
2 * Copyright 2010 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 "pc/session_description.h"
12
13 #include <algorithm>
14 #include <utility>
15
16 #include "absl/algorithm/container.h"
17 #include "absl/memory/memory.h"
18 #include "pc/media_protocol_names.h"
19 #include "rtc_base/checks.h"
20
21 namespace cricket {
22 namespace {
23
FindContentInfoByName(ContentInfos * contents,const std::string & name)24 ContentInfo* FindContentInfoByName(ContentInfos* contents,
25 const std::string& name) {
26 RTC_DCHECK(contents);
27 for (ContentInfo& content : *contents) {
28 if (content.name == name) {
29 return &content;
30 }
31 }
32 return nullptr;
33 }
34
35 } // namespace
36
FindContentInfoByName(const ContentInfos & contents,const std::string & name)37 const ContentInfo* FindContentInfoByName(const ContentInfos& contents,
38 const std::string& name) {
39 for (ContentInfos::const_iterator content = contents.begin();
40 content != contents.end(); ++content) {
41 if (content->name == name) {
42 return &(*content);
43 }
44 }
45 return NULL;
46 }
47
FindContentInfoByType(const ContentInfos & contents,MediaProtocolType type)48 const ContentInfo* FindContentInfoByType(const ContentInfos& contents,
49 MediaProtocolType type) {
50 for (const auto& content : contents) {
51 if (content.type == type) {
52 return &content;
53 }
54 }
55 return nullptr;
56 }
57
ContentGroup(const std::string & semantics)58 ContentGroup::ContentGroup(const std::string& semantics)
59 : semantics_(semantics) {}
60
61 ContentGroup::ContentGroup(const ContentGroup&) = default;
62 ContentGroup::ContentGroup(ContentGroup&&) = default;
63 ContentGroup& ContentGroup::operator=(const ContentGroup&) = default;
64 ContentGroup& ContentGroup::operator=(ContentGroup&&) = default;
65 ContentGroup::~ContentGroup() = default;
66
FirstContentName() const67 const std::string* ContentGroup::FirstContentName() const {
68 return (!content_names_.empty()) ? &(*content_names_.begin()) : NULL;
69 }
70
HasContentName(const std::string & content_name) const71 bool ContentGroup::HasContentName(const std::string& content_name) const {
72 return absl::c_linear_search(content_names_, content_name);
73 }
74
AddContentName(const std::string & content_name)75 void ContentGroup::AddContentName(const std::string& content_name) {
76 if (!HasContentName(content_name)) {
77 content_names_.push_back(content_name);
78 }
79 }
80
RemoveContentName(const std::string & content_name)81 bool ContentGroup::RemoveContentName(const std::string& content_name) {
82 ContentNames::iterator iter = absl::c_find(content_names_, content_name);
83 if (iter == content_names_.end()) {
84 return false;
85 }
86 content_names_.erase(iter);
87 return true;
88 }
89
90 SessionDescription::SessionDescription() = default;
91 SessionDescription::SessionDescription(const SessionDescription&) = default;
92
~SessionDescription()93 SessionDescription::~SessionDescription() {}
94
Clone() const95 std::unique_ptr<SessionDescription> SessionDescription::Clone() const {
96 // Copy using the private copy constructor.
97 // This will clone the descriptions using ContentInfo's copy constructor.
98 return absl::WrapUnique(new SessionDescription(*this));
99 }
100
GetContentByName(const std::string & name) const101 const ContentInfo* SessionDescription::GetContentByName(
102 const std::string& name) const {
103 return FindContentInfoByName(contents_, name);
104 }
105
GetContentByName(const std::string & name)106 ContentInfo* SessionDescription::GetContentByName(const std::string& name) {
107 return FindContentInfoByName(&contents_, name);
108 }
109
GetContentDescriptionByName(const std::string & name) const110 const MediaContentDescription* SessionDescription::GetContentDescriptionByName(
111 const std::string& name) const {
112 const ContentInfo* cinfo = FindContentInfoByName(contents_, name);
113 if (cinfo == NULL) {
114 return NULL;
115 }
116
117 return cinfo->media_description();
118 }
119
GetContentDescriptionByName(const std::string & name)120 MediaContentDescription* SessionDescription::GetContentDescriptionByName(
121 const std::string& name) {
122 ContentInfo* cinfo = FindContentInfoByName(&contents_, name);
123 if (cinfo == NULL) {
124 return NULL;
125 }
126
127 return cinfo->media_description();
128 }
129
FirstContentByType(MediaProtocolType type) const130 const ContentInfo* SessionDescription::FirstContentByType(
131 MediaProtocolType type) const {
132 return FindContentInfoByType(contents_, type);
133 }
134
FirstContent() const135 const ContentInfo* SessionDescription::FirstContent() const {
136 return (contents_.empty()) ? NULL : &(*contents_.begin());
137 }
138
AddContent(const std::string & name,MediaProtocolType type,std::unique_ptr<MediaContentDescription> description)139 void SessionDescription::AddContent(
140 const std::string& name,
141 MediaProtocolType type,
142 std::unique_ptr<MediaContentDescription> description) {
143 ContentInfo content(type);
144 content.name = name;
145 content.set_media_description(std::move(description));
146 AddContent(std::move(content));
147 }
148
AddContent(const std::string & name,MediaProtocolType type,bool rejected,std::unique_ptr<MediaContentDescription> description)149 void SessionDescription::AddContent(
150 const std::string& name,
151 MediaProtocolType type,
152 bool rejected,
153 std::unique_ptr<MediaContentDescription> description) {
154 ContentInfo content(type);
155 content.name = name;
156 content.rejected = rejected;
157 content.set_media_description(std::move(description));
158 AddContent(std::move(content));
159 }
160
AddContent(const std::string & name,MediaProtocolType type,bool rejected,bool bundle_only,std::unique_ptr<MediaContentDescription> description)161 void SessionDescription::AddContent(
162 const std::string& name,
163 MediaProtocolType type,
164 bool rejected,
165 bool bundle_only,
166 std::unique_ptr<MediaContentDescription> description) {
167 ContentInfo content(type);
168 content.name = name;
169 content.rejected = rejected;
170 content.bundle_only = bundle_only;
171 content.set_media_description(std::move(description));
172 AddContent(std::move(content));
173 }
174
AddContent(ContentInfo && content)175 void SessionDescription::AddContent(ContentInfo&& content) {
176 if (extmap_allow_mixed()) {
177 // Mixed support on session level overrides setting on media level.
178 content.media_description()->set_extmap_allow_mixed_enum(
179 MediaContentDescription::kSession);
180 }
181 contents_.push_back(std::move(content));
182 }
183
RemoveContentByName(const std::string & name)184 bool SessionDescription::RemoveContentByName(const std::string& name) {
185 for (ContentInfos::iterator content = contents_.begin();
186 content != contents_.end(); ++content) {
187 if (content->name == name) {
188 contents_.erase(content);
189 return true;
190 }
191 }
192
193 return false;
194 }
195
AddTransportInfo(const TransportInfo & transport_info)196 void SessionDescription::AddTransportInfo(const TransportInfo& transport_info) {
197 transport_infos_.push_back(transport_info);
198 }
199
RemoveTransportInfoByName(const std::string & name)200 bool SessionDescription::RemoveTransportInfoByName(const std::string& name) {
201 for (TransportInfos::iterator transport_info = transport_infos_.begin();
202 transport_info != transport_infos_.end(); ++transport_info) {
203 if (transport_info->content_name == name) {
204 transport_infos_.erase(transport_info);
205 return true;
206 }
207 }
208 return false;
209 }
210
GetTransportInfoByName(const std::string & name) const211 const TransportInfo* SessionDescription::GetTransportInfoByName(
212 const std::string& name) const {
213 for (TransportInfos::const_iterator iter = transport_infos_.begin();
214 iter != transport_infos_.end(); ++iter) {
215 if (iter->content_name == name) {
216 return &(*iter);
217 }
218 }
219 return NULL;
220 }
221
GetTransportInfoByName(const std::string & name)222 TransportInfo* SessionDescription::GetTransportInfoByName(
223 const std::string& name) {
224 for (TransportInfos::iterator iter = transport_infos_.begin();
225 iter != transport_infos_.end(); ++iter) {
226 if (iter->content_name == name) {
227 return &(*iter);
228 }
229 }
230 return NULL;
231 }
232
RemoveGroupByName(const std::string & name)233 void SessionDescription::RemoveGroupByName(const std::string& name) {
234 for (ContentGroups::iterator iter = content_groups_.begin();
235 iter != content_groups_.end(); ++iter) {
236 if (iter->semantics() == name) {
237 content_groups_.erase(iter);
238 break;
239 }
240 }
241 }
242
HasGroup(const std::string & name) const243 bool SessionDescription::HasGroup(const std::string& name) const {
244 for (ContentGroups::const_iterator iter = content_groups_.begin();
245 iter != content_groups_.end(); ++iter) {
246 if (iter->semantics() == name) {
247 return true;
248 }
249 }
250 return false;
251 }
252
GetGroupByName(const std::string & name) const253 const ContentGroup* SessionDescription::GetGroupByName(
254 const std::string& name) const {
255 for (ContentGroups::const_iterator iter = content_groups_.begin();
256 iter != content_groups_.end(); ++iter) {
257 if (iter->semantics() == name) {
258 return &(*iter);
259 }
260 }
261 return NULL;
262 }
263
~ContentInfo()264 ContentInfo::~ContentInfo() {
265 }
266
267 // Copy operator.
ContentInfo(const ContentInfo & o)268 ContentInfo::ContentInfo(const ContentInfo& o)
269 : name(o.name),
270 type(o.type),
271 rejected(o.rejected),
272 bundle_only(o.bundle_only),
273 description_(o.description_->Clone()) {}
274
operator =(const ContentInfo & o)275 ContentInfo& ContentInfo::operator=(const ContentInfo& o) {
276 name = o.name;
277 type = o.type;
278 rejected = o.rejected;
279 bundle_only = o.bundle_only;
280 description_ = o.description_->Clone();
281 return *this;
282 }
283
media_description() const284 const MediaContentDescription* ContentInfo::media_description() const {
285 return description_.get();
286 }
287
media_description()288 MediaContentDescription* ContentInfo::media_description() {
289 return description_.get();
290 }
291
292 } // namespace cricket
293