blob: c1feedbf53d327dffd623fc270529efee0b646bc [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 Anton64b626b2019-01-28 17:25:26 -080013#include "absl/algorithm/container.h"
Harald Alvestrand4d7160e2019-04-12 07:01:29 +020014#include "absl/memory/memory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010015#include "rtc_base/checks.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000016#include "rtc_base/strings/string_builder.h"
Yves Gerey3e707812018-11-28 16:47:49 +010017
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000018namespace cricket {
Steve Anton4ab68ee2017-12-19 14:26:11 -080019namespace {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000020
Steve Anton4ab68ee2017-12-19 14:26:11 -080021ContentInfo* 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;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000027 }
28 }
Steve Anton4ab68ee2017-12-19 14:26:11 -080029 return nullptr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000030}
31
Steve Anton4ab68ee2017-12-19 14:26:11 -080032} // namespace
33
34const ContentInfo* FindContentInfoByName(const ContentInfos& contents,
35 const std::string& name) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000036 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
Steve Anton4ab68ee2017-12-19 14:26:11 -080045const ContentInfo* FindContentInfoByType(const ContentInfos& contents,
Steve Anton5adfafd2017-12-20 16:34:00 -080046 MediaProtocolType type) {
47 for (const auto& content : contents) {
48 if (content.type == type) {
49 return &content;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000050 }
51 }
Steve Anton5adfafd2017-12-20 16:34:00 -080052 return nullptr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053}
54
Steve Antond3ea9992017-10-31 12:38:23 -070055ContentGroup::ContentGroup(const std::string& semantics)
56 : semantics_(semantics) {}
57
58ContentGroup::ContentGroup(const ContentGroup&) = default;
59ContentGroup::ContentGroup(ContentGroup&&) = default;
60ContentGroup& ContentGroup::operator=(const ContentGroup&) = default;
61ContentGroup& ContentGroup::operator=(ContentGroup&&) = default;
62ContentGroup::~ContentGroup() = default;
63
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000064const std::string* ContentGroup::FirstContentName() const {
65 return (!content_names_.empty()) ? &(*content_names_.begin()) : NULL;
66}
67
68bool ContentGroup::HasContentName(const std::string& content_name) const {
Steve Anton64b626b2019-01-28 17:25:26 -080069 return absl::c_linear_search(content_names_, content_name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000070}
71
72void ContentGroup::AddContentName(const std::string& content_name) {
73 if (!HasContentName(content_name)) {
74 content_names_.push_back(content_name);
75 }
76}
77
78bool ContentGroup::RemoveContentName(const std::string& content_name) {
Steve Anton64b626b2019-01-28 17:25:26 -080079 ContentNames::iterator iter = absl::c_find(content_names_, content_name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000080 if (iter == content_names_.end()) {
81 return false;
82 }
83 content_names_.erase(iter);
84 return true;
85}
86
Harald Alvestrand7a2db8a2021-06-14 15:41:30 +000087std::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
Steve Antond3ea9992017-10-31 12:38:23 -070099SessionDescription::SessionDescription() = default;
Steve Antond3ea9992017-10-31 12:38:23 -0700100SessionDescription::SessionDescription(const SessionDescription&) = default;
101
Jonas Olssona4d87372019-07-05 19:08:33 +0200102SessionDescription::~SessionDescription() {}
Steve Antond3ea9992017-10-31 12:38:23 -0700103
Harald Alvestrand4d7160e2019-04-12 07:01:29 +0200104std::unique_ptr<SessionDescription> SessionDescription::Clone() const {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200105 // Copy using the private copy constructor.
106 // This will clone the descriptions using ContentInfo's copy constructor.
107 return absl::WrapUnique(new SessionDescription(*this));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000108}
109
110const ContentInfo* SessionDescription::GetContentByName(
111 const std::string& name) const {
112 return FindContentInfoByName(contents_, name);
113}
114
Steve Anton4ab68ee2017-12-19 14:26:11 -0800115ContentInfo* SessionDescription::GetContentByName(const std::string& name) {
116 return FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000117}
118
Steve Antonb1c1de12017-12-21 15:14:30 -0800119const MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000120 const std::string& name) const {
121 const ContentInfo* cinfo = FindContentInfoByName(contents_, name);
122 if (cinfo == NULL) {
123 return NULL;
124 }
125
Steve Antonb1c1de12017-12-21 15:14:30 -0800126 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000127}
128
Steve Antonb1c1de12017-12-21 15:14:30 -0800129MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000130 const std::string& name) {
Steve Anton4ab68ee2017-12-19 14:26:11 -0800131 ContentInfo* cinfo = FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000132 if (cinfo == NULL) {
133 return NULL;
134 }
135
Steve Antonb1c1de12017-12-21 15:14:30 -0800136 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000137}
138
139const ContentInfo* SessionDescription::FirstContentByType(
Steve Anton5adfafd2017-12-20 16:34:00 -0800140 MediaProtocolType type) const {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000141 return FindContentInfoByType(contents_, type);
142}
143
144const ContentInfo* SessionDescription::FirstContent() const {
145 return (contents_.empty()) ? NULL : &(*contents_.begin());
146}
147
Harald Alvestrand1716d392019-06-03 20:35:45 +0200148void SessionDescription::AddContent(
149 const std::string& name,
150 MediaProtocolType type,
151 std::unique_ptr<MediaContentDescription> description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800152 ContentInfo content(type);
153 content.name = name;
Harald Alvestrand1716d392019-06-03 20:35:45 +0200154 content.set_media_description(std::move(description));
155 AddContent(std::move(content));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000156}
157
Harald Alvestrand1716d392019-06-03 20:35:45 +0200158void SessionDescription::AddContent(
159 const std::string& name,
160 MediaProtocolType type,
161 bool rejected,
162 std::unique_ptr<MediaContentDescription> description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800163 ContentInfo content(type);
164 content.name = name;
165 content.rejected = rejected;
Harald Alvestrand1716d392019-06-03 20:35:45 +0200166 content.set_media_description(std::move(description));
167 AddContent(std::move(content));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000168}
169
Harald Alvestrand1716d392019-06-03 20:35:45 +0200170void SessionDescription::AddContent(
171 const std::string& name,
172 MediaProtocolType type,
173 bool rejected,
174 bool bundle_only,
175 std::unique_ptr<MediaContentDescription> description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800176 ContentInfo content(type);
177 content.name = name;
178 content.rejected = rejected;
179 content.bundle_only = bundle_only;
Harald Alvestrand1716d392019-06-03 20:35:45 +0200180 content.set_media_description(std::move(description));
181 AddContent(std::move(content));
Johannes Kron9ac3c912018-10-12 10:54:26 +0200182}
183
Harald Alvestrand1716d392019-06-03 20:35:45 +0200184void SessionDescription::AddContent(ContentInfo&& content) {
Johannes Kron9581bc42018-10-23 10:17:39 +0200185 if (extmap_allow_mixed()) {
Johannes Kron9ac3c912018-10-12 10:54:26 +0200186 // Mixed support on session level overrides setting on media level.
Harald Alvestrand1716d392019-06-03 20:35:45 +0200187 content.media_description()->set_extmap_allow_mixed_enum(
Johannes Kron9ac3c912018-10-12 10:54:26 +0200188 MediaContentDescription::kSession);
189 }
Harald Alvestrand1716d392019-06-03 20:35:45 +0200190 contents_.push_back(std::move(content));
deadbeef25ed4352016-12-12 18:37:36 -0800191}
192
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000193bool SessionDescription::RemoveContentByName(const std::string& name) {
194 for (ContentInfos::iterator content = contents_.begin();
195 content != contents_.end(); ++content) {
196 if (content->name == name) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000197 contents_.erase(content);
198 return true;
199 }
200 }
201
202 return false;
203}
204
Steve Anton06817cd2018-12-18 15:55:30 -0800205void SessionDescription::AddTransportInfo(const TransportInfo& transport_info) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000206 transport_infos_.push_back(transport_info);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000207}
208
209bool 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
220const 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
231TransportInfo* 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
242void 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
252bool 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
262const 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
Henrik Boströmf8187e02021-04-26 21:04:26 +0200273std::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
Harald Alvestrand1716d392019-06-03 20:35:45 +0200284ContentInfo::~ContentInfo() {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200285}
286
287// Copy operator.
288ContentInfo::ContentInfo(const ContentInfo& o)
289 : name(o.name),
290 type(o.type),
291 rejected(o.rejected),
292 bundle_only(o.bundle_only),
Harald Alvestrand8e7d4bf2020-02-26 09:32:30 +0100293 description_(o.description_->Clone()) {}
Harald Alvestrand1716d392019-06-03 20:35:45 +0200294
295ContentInfo& 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();
Harald Alvestrand1716d392019-06-03 20:35:45 +0200301 return *this;
302}
303
304const MediaContentDescription* ContentInfo::media_description() const {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200305 return description_.get();
306}
307
308MediaContentDescription* ContentInfo::media_description() {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200309 return description_.get();
310}
311
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000312} // namespace cricket