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