blob: 7b878cbf7be1948de53964a70c8c1d02934e0f81 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "pc/session_description.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000012
Steve Anton5adfafd2017-12-20 16:34:00 -080013#include <utility>
14
Steve Anton64b626b2019-01-28 17:25:26 -080015#include "absl/algorithm/container.h"
Harald Alvestrand4d7160e2019-04-12 07:01:29 +020016#include "absl/memory/memory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010017#include "rtc_base/checks.h"
18
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000019namespace cricket {
Steve Anton4ab68ee2017-12-19 14:26:11 -080020namespace {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000021
Steve Anton4ab68ee2017-12-19 14:26:11 -080022ContentInfo* FindContentInfoByName(ContentInfos* contents,
23 const std::string& name) {
24 RTC_DCHECK(contents);
25 for (ContentInfo& content : *contents) {
26 if (content.name == name) {
27 return &content;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000028 }
29 }
Steve Anton4ab68ee2017-12-19 14:26:11 -080030 return nullptr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000031}
32
Steve Anton4ab68ee2017-12-19 14:26:11 -080033} // namespace
34
35const ContentInfo* FindContentInfoByName(const ContentInfos& contents,
36 const std::string& name) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000037 for (ContentInfos::const_iterator content = contents.begin();
38 content != contents.end(); ++content) {
39 if (content->name == name) {
40 return &(*content);
41 }
42 }
43 return NULL;
44}
45
Steve Anton4ab68ee2017-12-19 14:26:11 -080046const ContentInfo* FindContentInfoByType(const ContentInfos& contents,
Steve Anton5adfafd2017-12-20 16:34:00 -080047 MediaProtocolType type) {
48 for (const auto& content : contents) {
49 if (content.type == type) {
50 return &content;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000051 }
52 }
Steve Anton5adfafd2017-12-20 16:34:00 -080053 return nullptr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000054}
55
Steve Antond3ea9992017-10-31 12:38:23 -070056ContentGroup::ContentGroup(const std::string& semantics)
57 : semantics_(semantics) {}
58
59ContentGroup::ContentGroup(const ContentGroup&) = default;
60ContentGroup::ContentGroup(ContentGroup&&) = default;
61ContentGroup& ContentGroup::operator=(const ContentGroup&) = default;
62ContentGroup& ContentGroup::operator=(ContentGroup&&) = default;
63ContentGroup::~ContentGroup() = default;
64
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000065const std::string* ContentGroup::FirstContentName() const {
66 return (!content_names_.empty()) ? &(*content_names_.begin()) : NULL;
67}
68
69bool ContentGroup::HasContentName(const std::string& content_name) const {
Steve Anton64b626b2019-01-28 17:25:26 -080070 return absl::c_linear_search(content_names_, content_name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000071}
72
73void ContentGroup::AddContentName(const std::string& content_name) {
74 if (!HasContentName(content_name)) {
75 content_names_.push_back(content_name);
76 }
77}
78
79bool ContentGroup::RemoveContentName(const std::string& content_name) {
Steve Anton64b626b2019-01-28 17:25:26 -080080 ContentNames::iterator iter = absl::c_find(content_names_, content_name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000081 if (iter == content_names_.end()) {
82 return false;
83 }
84 content_names_.erase(iter);
85 return true;
86}
87
Harald Alvestrand7a2db8a2021-06-14 15:41:30 +000088std::string ContentGroup::ToString() const {
89 rtc::StringBuilder acc;
90 acc << semantics_ << "(";
91 if (!content_names_.empty()) {
92 for (const auto& name : content_names_) {
93 acc << name << " ";
94 }
95 }
96 acc << ")";
97 return acc.Release();
98}
99
Steve Antond3ea9992017-10-31 12:38:23 -0700100SessionDescription::SessionDescription() = default;
Steve Antond3ea9992017-10-31 12:38:23 -0700101SessionDescription::SessionDescription(const SessionDescription&) = default;
102
Jonas Olssona4d87372019-07-05 19:08:33 +0200103SessionDescription::~SessionDescription() {}
Steve Antond3ea9992017-10-31 12:38:23 -0700104
Harald Alvestrand4d7160e2019-04-12 07:01:29 +0200105std::unique_ptr<SessionDescription> SessionDescription::Clone() const {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200106 // Copy using the private copy constructor.
107 // This will clone the descriptions using ContentInfo's copy constructor.
108 return absl::WrapUnique(new SessionDescription(*this));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000109}
110
111const ContentInfo* SessionDescription::GetContentByName(
112 const std::string& name) const {
113 return FindContentInfoByName(contents_, name);
114}
115
Steve Anton4ab68ee2017-12-19 14:26:11 -0800116ContentInfo* SessionDescription::GetContentByName(const std::string& name) {
117 return FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000118}
119
Steve Antonb1c1de12017-12-21 15:14:30 -0800120const MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000121 const std::string& name) const {
122 const ContentInfo* cinfo = FindContentInfoByName(contents_, name);
123 if (cinfo == NULL) {
124 return NULL;
125 }
126
Steve Antonb1c1de12017-12-21 15:14:30 -0800127 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128}
129
Steve Antonb1c1de12017-12-21 15:14:30 -0800130MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000131 const std::string& name) {
Steve Anton4ab68ee2017-12-19 14:26:11 -0800132 ContentInfo* cinfo = FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000133 if (cinfo == NULL) {
134 return NULL;
135 }
136
Steve Antonb1c1de12017-12-21 15:14:30 -0800137 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000138}
139
140const ContentInfo* SessionDescription::FirstContentByType(
Steve Anton5adfafd2017-12-20 16:34:00 -0800141 MediaProtocolType type) const {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000142 return FindContentInfoByType(contents_, type);
143}
144
145const ContentInfo* SessionDescription::FirstContent() const {
146 return (contents_.empty()) ? NULL : &(*contents_.begin());
147}
148
Harald Alvestrand1716d392019-06-03 20:35:45 +0200149void SessionDescription::AddContent(
150 const std::string& name,
151 MediaProtocolType type,
152 std::unique_ptr<MediaContentDescription> description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800153 ContentInfo content(type);
154 content.name = name;
Harald Alvestrand1716d392019-06-03 20:35:45 +0200155 content.set_media_description(std::move(description));
156 AddContent(std::move(content));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000157}
158
Harald Alvestrand1716d392019-06-03 20:35:45 +0200159void SessionDescription::AddContent(
160 const std::string& name,
161 MediaProtocolType type,
162 bool rejected,
163 std::unique_ptr<MediaContentDescription> description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800164 ContentInfo content(type);
165 content.name = name;
166 content.rejected = rejected;
Harald Alvestrand1716d392019-06-03 20:35:45 +0200167 content.set_media_description(std::move(description));
168 AddContent(std::move(content));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000169}
170
Harald Alvestrand1716d392019-06-03 20:35:45 +0200171void SessionDescription::AddContent(
172 const std::string& name,
173 MediaProtocolType type,
174 bool rejected,
175 bool bundle_only,
176 std::unique_ptr<MediaContentDescription> description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800177 ContentInfo content(type);
178 content.name = name;
179 content.rejected = rejected;
180 content.bundle_only = bundle_only;
Harald Alvestrand1716d392019-06-03 20:35:45 +0200181 content.set_media_description(std::move(description));
182 AddContent(std::move(content));
Johannes Kron9ac3c912018-10-12 10:54:26 +0200183}
184
Harald Alvestrand1716d392019-06-03 20:35:45 +0200185void SessionDescription::AddContent(ContentInfo&& content) {
Johannes Kron9581bc42018-10-23 10:17:39 +0200186 if (extmap_allow_mixed()) {
Johannes Kron9ac3c912018-10-12 10:54:26 +0200187 // Mixed support on session level overrides setting on media level.
Harald Alvestrand1716d392019-06-03 20:35:45 +0200188 content.media_description()->set_extmap_allow_mixed_enum(
Johannes Kron9ac3c912018-10-12 10:54:26 +0200189 MediaContentDescription::kSession);
190 }
Harald Alvestrand1716d392019-06-03 20:35:45 +0200191 contents_.push_back(std::move(content));
deadbeef25ed4352016-12-12 18:37:36 -0800192}
193
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000194bool SessionDescription::RemoveContentByName(const std::string& name) {
195 for (ContentInfos::iterator content = contents_.begin();
196 content != contents_.end(); ++content) {
197 if (content->name == name) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000198 contents_.erase(content);
199 return true;
200 }
201 }
202
203 return false;
204}
205
Steve Anton06817cd2018-12-18 15:55:30 -0800206void SessionDescription::AddTransportInfo(const TransportInfo& transport_info) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000207 transport_infos_.push_back(transport_info);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000208}
209
210bool SessionDescription::RemoveTransportInfoByName(const std::string& name) {
211 for (TransportInfos::iterator transport_info = transport_infos_.begin();
212 transport_info != transport_infos_.end(); ++transport_info) {
213 if (transport_info->content_name == name) {
214 transport_infos_.erase(transport_info);
215 return true;
216 }
217 }
218 return false;
219}
220
221const TransportInfo* SessionDescription::GetTransportInfoByName(
222 const std::string& name) const {
223 for (TransportInfos::const_iterator iter = transport_infos_.begin();
224 iter != transport_infos_.end(); ++iter) {
225 if (iter->content_name == name) {
226 return &(*iter);
227 }
228 }
229 return NULL;
230}
231
232TransportInfo* SessionDescription::GetTransportInfoByName(
233 const std::string& name) {
234 for (TransportInfos::iterator iter = transport_infos_.begin();
235 iter != transport_infos_.end(); ++iter) {
236 if (iter->content_name == name) {
237 return &(*iter);
238 }
239 }
240 return NULL;
241}
242
243void SessionDescription::RemoveGroupByName(const std::string& name) {
244 for (ContentGroups::iterator iter = content_groups_.begin();
245 iter != content_groups_.end(); ++iter) {
246 if (iter->semantics() == name) {
247 content_groups_.erase(iter);
248 break;
249 }
250 }
251}
252
253bool SessionDescription::HasGroup(const std::string& name) const {
254 for (ContentGroups::const_iterator iter = content_groups_.begin();
255 iter != content_groups_.end(); ++iter) {
256 if (iter->semantics() == name) {
257 return true;
258 }
259 }
260 return false;
261}
262
263const ContentGroup* SessionDescription::GetGroupByName(
264 const std::string& name) const {
265 for (ContentGroups::const_iterator iter = content_groups_.begin();
266 iter != content_groups_.end(); ++iter) {
267 if (iter->semantics() == name) {
268 return &(*iter);
269 }
270 }
271 return NULL;
272}
273
Henrik Boströmf8187e02021-04-26 21:04:26 +0200274std::vector<const ContentGroup*> SessionDescription::GetGroupsByName(
275 const std::string& name) const {
276 std::vector<const ContentGroup*> content_groups;
277 for (const ContentGroup& content_group : content_groups_) {
278 if (content_group.semantics() == name) {
279 content_groups.push_back(&content_group);
280 }
281 }
282 return content_groups;
283}
284
Harald Alvestrand1716d392019-06-03 20:35:45 +0200285ContentInfo::~ContentInfo() {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200286}
287
288// Copy operator.
289ContentInfo::ContentInfo(const ContentInfo& o)
290 : name(o.name),
291 type(o.type),
292 rejected(o.rejected),
293 bundle_only(o.bundle_only),
Harald Alvestrand8e7d4bf2020-02-26 09:32:30 +0100294 description_(o.description_->Clone()) {}
Harald Alvestrand1716d392019-06-03 20:35:45 +0200295
296ContentInfo& ContentInfo::operator=(const ContentInfo& o) {
297 name = o.name;
298 type = o.type;
299 rejected = o.rejected;
300 bundle_only = o.bundle_only;
301 description_ = o.description_->Clone();
Harald Alvestrand1716d392019-06-03 20:35:45 +0200302 return *this;
303}
304
305const MediaContentDescription* ContentInfo::media_description() const {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200306 return description_.get();
307}
308
309MediaContentDescription* ContentInfo::media_description() {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200310 return description_.get();
311}
312
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000313} // namespace cricket