blob: a081f8a3ed0f937fe3bdd1a37f394383371bba55 [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"
Yves Gerey3e707812018-11-28 16:47:49 +010016#include "rtc_base/checks.h"
17
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
Steve Antond3ea9992017-10-31 12:38:23 -070087SessionDescription::SessionDescription() = default;
Steve Antond3ea9992017-10-31 12:38:23 -070088SessionDescription::SessionDescription(const SessionDescription&) = default;
89
90SessionDescription::~SessionDescription() {
91 for (ContentInfos::iterator content = contents_.begin();
92 content != contents_.end(); ++content) {
93 delete content->description;
94 }
95}
96
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000097SessionDescription* SessionDescription::Copy() const {
98 SessionDescription* copy = new SessionDescription(*this);
99 // Copy all ContentDescriptions.
100 for (ContentInfos::iterator content = copy->contents_.begin();
Steve Anton4ab68ee2017-12-19 14:26:11 -0800101 content != copy->contents().end(); ++content) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000102 content->description = content->description->Copy();
103 }
104 return copy;
105}
106
107const ContentInfo* SessionDescription::GetContentByName(
108 const std::string& name) const {
109 return FindContentInfoByName(contents_, name);
110}
111
Steve Anton4ab68ee2017-12-19 14:26:11 -0800112ContentInfo* SessionDescription::GetContentByName(const std::string& name) {
113 return FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000114}
115
Steve Antonb1c1de12017-12-21 15:14:30 -0800116const MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000117 const std::string& name) const {
118 const ContentInfo* cinfo = FindContentInfoByName(contents_, name);
119 if (cinfo == NULL) {
120 return NULL;
121 }
122
Steve Antonb1c1de12017-12-21 15:14:30 -0800123 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000124}
125
Steve Antonb1c1de12017-12-21 15:14:30 -0800126MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000127 const std::string& name) {
Steve Anton4ab68ee2017-12-19 14:26:11 -0800128 ContentInfo* cinfo = FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000129 if (cinfo == NULL) {
130 return NULL;
131 }
132
Steve Antonb1c1de12017-12-21 15:14:30 -0800133 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000134}
135
136const ContentInfo* SessionDescription::FirstContentByType(
Steve Anton5adfafd2017-12-20 16:34:00 -0800137 MediaProtocolType type) const {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000138 return FindContentInfoByType(contents_, type);
139}
140
141const ContentInfo* SessionDescription::FirstContent() const {
142 return (contents_.empty()) ? NULL : &(*contents_.begin());
143}
144
145void SessionDescription::AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800146 MediaProtocolType type,
Steve Antonb1c1de12017-12-21 15:14:30 -0800147 MediaContentDescription* description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800148 ContentInfo content(type);
149 content.name = name;
150 content.description = description;
Johannes Kron9ac3c912018-10-12 10:54:26 +0200151 AddContent(&content);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000152}
153
154void SessionDescription::AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800155 MediaProtocolType type,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000156 bool rejected,
Steve Antonb1c1de12017-12-21 15:14:30 -0800157 MediaContentDescription* description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800158 ContentInfo content(type);
159 content.name = name;
160 content.rejected = rejected;
161 content.description = description;
Johannes Kron9ac3c912018-10-12 10:54:26 +0200162 AddContent(&content);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000163}
164
deadbeef25ed4352016-12-12 18:37:36 -0800165void SessionDescription::AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800166 MediaProtocolType type,
deadbeef25ed4352016-12-12 18:37:36 -0800167 bool rejected,
168 bool bundle_only,
Steve Antonb1c1de12017-12-21 15:14:30 -0800169 MediaContentDescription* description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800170 ContentInfo content(type);
171 content.name = name;
172 content.rejected = rejected;
173 content.bundle_only = bundle_only;
174 content.description = description;
Johannes Kron9ac3c912018-10-12 10:54:26 +0200175 AddContent(&content);
176}
177
178void SessionDescription::AddContent(ContentInfo* content) {
Johannes Kron9581bc42018-10-23 10:17:39 +0200179 if (extmap_allow_mixed()) {
Johannes Kron9ac3c912018-10-12 10:54:26 +0200180 // Mixed support on session level overrides setting on media level.
Johannes Kron9581bc42018-10-23 10:17:39 +0200181 content->description->set_extmap_allow_mixed_enum(
Johannes Kron9ac3c912018-10-12 10:54:26 +0200182 MediaContentDescription::kSession);
183 }
184 contents_.push_back(std::move(*content));
deadbeef25ed4352016-12-12 18:37:36 -0800185}
186
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000187bool SessionDescription::RemoveContentByName(const std::string& name) {
188 for (ContentInfos::iterator content = contents_.begin();
189 content != contents_.end(); ++content) {
190 if (content->name == name) {
191 delete content->description;
192 contents_.erase(content);
193 return true;
194 }
195 }
196
197 return false;
198}
199
Steve Anton06817cd2018-12-18 15:55:30 -0800200void SessionDescription::AddTransportInfo(const TransportInfo& transport_info) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000201 transport_infos_.push_back(transport_info);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000202}
203
204bool SessionDescription::RemoveTransportInfoByName(const std::string& name) {
205 for (TransportInfos::iterator transport_info = transport_infos_.begin();
206 transport_info != transport_infos_.end(); ++transport_info) {
207 if (transport_info->content_name == name) {
208 transport_infos_.erase(transport_info);
209 return true;
210 }
211 }
212 return false;
213}
214
215const TransportInfo* SessionDescription::GetTransportInfoByName(
216 const std::string& name) const {
217 for (TransportInfos::const_iterator iter = transport_infos_.begin();
218 iter != transport_infos_.end(); ++iter) {
219 if (iter->content_name == name) {
220 return &(*iter);
221 }
222 }
223 return NULL;
224}
225
226TransportInfo* SessionDescription::GetTransportInfoByName(
227 const std::string& name) {
228 for (TransportInfos::iterator iter = transport_infos_.begin();
229 iter != transport_infos_.end(); ++iter) {
230 if (iter->content_name == name) {
231 return &(*iter);
232 }
233 }
234 return NULL;
235}
236
237void SessionDescription::RemoveGroupByName(const std::string& name) {
238 for (ContentGroups::iterator iter = content_groups_.begin();
239 iter != content_groups_.end(); ++iter) {
240 if (iter->semantics() == name) {
241 content_groups_.erase(iter);
242 break;
243 }
244 }
245}
246
247bool SessionDescription::HasGroup(const std::string& name) const {
248 for (ContentGroups::const_iterator iter = content_groups_.begin();
249 iter != content_groups_.end(); ++iter) {
250 if (iter->semantics() == name) {
251 return true;
252 }
253 }
254 return false;
255}
256
257const ContentGroup* SessionDescription::GetGroupByName(
258 const std::string& name) const {
259 for (ContentGroups::const_iterator iter = content_groups_.begin();
260 iter != content_groups_.end(); ++iter) {
261 if (iter->semantics() == name) {
262 return &(*iter);
263 }
264 }
265 return NULL;
266}
267
268} // namespace cricket