• 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 <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