blob: d4ccb5082ead686d83c44d87f16348b92af683a6 [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
Harald Alvestrand4d7160e2019-04-12 07:01:29 +020013#include <algorithm>
Steve Anton5adfafd2017-12-20 16:34:00 -080014#include <utility>
15
Steve Anton64b626b2019-01-28 17:25:26 -080016#include "absl/algorithm/container.h"
Harald Alvestrand4d7160e2019-04-12 07:01:29 +020017#include "absl/memory/memory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "rtc_base/checks.h"
19
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000020namespace cricket {
Steve Anton4ab68ee2017-12-19 14:26:11 -080021namespace {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000022
Steve Anton4ab68ee2017-12-19 14:26:11 -080023ContentInfo* FindContentInfoByName(ContentInfos* contents,
24 const std::string& name) {
25 RTC_DCHECK(contents);
26 for (ContentInfo& content : *contents) {
27 if (content.name == name) {
28 return &content;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000029 }
30 }
Steve Anton4ab68ee2017-12-19 14:26:11 -080031 return nullptr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000032}
33
Steve Anton4ab68ee2017-12-19 14:26:11 -080034} // namespace
35
36const ContentInfo* FindContentInfoByName(const ContentInfos& contents,
37 const std::string& name) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000038 for (ContentInfos::const_iterator content = contents.begin();
39 content != contents.end(); ++content) {
40 if (content->name == name) {
41 return &(*content);
42 }
43 }
44 return NULL;
45}
46
Steve Anton4ab68ee2017-12-19 14:26:11 -080047const ContentInfo* FindContentInfoByType(const ContentInfos& contents,
Steve Anton5adfafd2017-12-20 16:34:00 -080048 MediaProtocolType type) {
49 for (const auto& content : contents) {
50 if (content.type == type) {
51 return &content;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000052 }
53 }
Steve Anton5adfafd2017-12-20 16:34:00 -080054 return nullptr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000055}
56
Steve Antond3ea9992017-10-31 12:38:23 -070057ContentGroup::ContentGroup(const std::string& semantics)
58 : semantics_(semantics) {}
59
60ContentGroup::ContentGroup(const ContentGroup&) = default;
61ContentGroup::ContentGroup(ContentGroup&&) = default;
62ContentGroup& ContentGroup::operator=(const ContentGroup&) = default;
63ContentGroup& ContentGroup::operator=(ContentGroup&&) = default;
64ContentGroup::~ContentGroup() = default;
65
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000066const std::string* ContentGroup::FirstContentName() const {
67 return (!content_names_.empty()) ? &(*content_names_.begin()) : NULL;
68}
69
70bool ContentGroup::HasContentName(const std::string& content_name) const {
Steve Anton64b626b2019-01-28 17:25:26 -080071 return absl::c_linear_search(content_names_, content_name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072}
73
74void ContentGroup::AddContentName(const std::string& content_name) {
75 if (!HasContentName(content_name)) {
76 content_names_.push_back(content_name);
77 }
78}
79
80bool ContentGroup::RemoveContentName(const std::string& content_name) {
Steve Anton64b626b2019-01-28 17:25:26 -080081 ContentNames::iterator iter = absl::c_find(content_names_, content_name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000082 if (iter == content_names_.end()) {
83 return false;
84 }
85 content_names_.erase(iter);
86 return true;
87}
88
Steve Antond3ea9992017-10-31 12:38:23 -070089SessionDescription::SessionDescription() = default;
Steve Antond3ea9992017-10-31 12:38:23 -070090SessionDescription::SessionDescription(const SessionDescription&) = default;
91
92SessionDescription::~SessionDescription() {
93 for (ContentInfos::iterator content = contents_.begin();
94 content != contents_.end(); ++content) {
95 delete content->description;
96 }
97}
98
Harald Alvestrand4d7160e2019-04-12 07:01:29 +020099std::unique_ptr<SessionDescription> SessionDescription::Clone() const {
100 // Copy the non-special portions using the private copy constructor.
101 auto copy = absl::WrapUnique(new SessionDescription(*this));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000102 // Copy all ContentDescriptions.
103 for (ContentInfos::iterator content = copy->contents_.begin();
Steve Anton4ab68ee2017-12-19 14:26:11 -0800104 content != copy->contents().end(); ++content) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000105 content->description = content->description->Copy();
106 }
107 return copy;
108}
109
Harald Alvestrand4d7160e2019-04-12 07:01:29 +0200110SessionDescription* SessionDescription::Copy() const {
111 return Clone().release();
112}
113
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000114const ContentInfo* SessionDescription::GetContentByName(
115 const std::string& name) const {
116 return FindContentInfoByName(contents_, name);
117}
118
Steve Anton4ab68ee2017-12-19 14:26:11 -0800119ContentInfo* SessionDescription::GetContentByName(const std::string& name) {
120 return FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000121}
122
Steve Antonb1c1de12017-12-21 15:14:30 -0800123const MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000124 const std::string& name) const {
125 const ContentInfo* cinfo = FindContentInfoByName(contents_, name);
126 if (cinfo == NULL) {
127 return NULL;
128 }
129
Steve Antonb1c1de12017-12-21 15:14:30 -0800130 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000131}
132
Steve Antonb1c1de12017-12-21 15:14:30 -0800133MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000134 const std::string& name) {
Steve Anton4ab68ee2017-12-19 14:26:11 -0800135 ContentInfo* cinfo = FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000136 if (cinfo == NULL) {
137 return NULL;
138 }
139
Steve Antonb1c1de12017-12-21 15:14:30 -0800140 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000141}
142
143const ContentInfo* SessionDescription::FirstContentByType(
Steve Anton5adfafd2017-12-20 16:34:00 -0800144 MediaProtocolType type) const {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000145 return FindContentInfoByType(contents_, type);
146}
147
148const ContentInfo* SessionDescription::FirstContent() const {
149 return (contents_.empty()) ? NULL : &(*contents_.begin());
150}
151
152void SessionDescription::AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800153 MediaProtocolType type,
Steve Antonb1c1de12017-12-21 15:14:30 -0800154 MediaContentDescription* description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800155 ContentInfo content(type);
156 content.name = name;
157 content.description = description;
Johannes Kron9ac3c912018-10-12 10:54:26 +0200158 AddContent(&content);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000159}
160
161void SessionDescription::AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800162 MediaProtocolType type,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000163 bool rejected,
Steve Antonb1c1de12017-12-21 15:14:30 -0800164 MediaContentDescription* description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800165 ContentInfo content(type);
166 content.name = name;
167 content.rejected = rejected;
168 content.description = description;
Johannes Kron9ac3c912018-10-12 10:54:26 +0200169 AddContent(&content);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000170}
171
deadbeef25ed4352016-12-12 18:37:36 -0800172void SessionDescription::AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800173 MediaProtocolType type,
deadbeef25ed4352016-12-12 18:37:36 -0800174 bool rejected,
175 bool bundle_only,
Steve Antonb1c1de12017-12-21 15:14:30 -0800176 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;
181 content.description = description;
Johannes Kron9ac3c912018-10-12 10:54:26 +0200182 AddContent(&content);
183}
184
185void 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.
Johannes Kron9581bc42018-10-23 10:17:39 +0200188 content->description->set_extmap_allow_mixed_enum(
Johannes Kron9ac3c912018-10-12 10:54:26 +0200189 MediaContentDescription::kSession);
190 }
191 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) {
198 delete content->description;
199 contents_.erase(content);
200 return true;
201 }
202 }
203
204 return false;
205}
206
Steve Anton06817cd2018-12-18 15:55:30 -0800207void SessionDescription::AddTransportInfo(const TransportInfo& transport_info) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000208 transport_infos_.push_back(transport_info);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000209}
210
211bool SessionDescription::RemoveTransportInfoByName(const std::string& name) {
212 for (TransportInfos::iterator transport_info = transport_infos_.begin();
213 transport_info != transport_infos_.end(); ++transport_info) {
214 if (transport_info->content_name == name) {
215 transport_infos_.erase(transport_info);
216 return true;
217 }
218 }
219 return false;
220}
221
222const TransportInfo* SessionDescription::GetTransportInfoByName(
223 const std::string& name) const {
224 for (TransportInfos::const_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
233TransportInfo* SessionDescription::GetTransportInfoByName(
234 const std::string& name) {
235 for (TransportInfos::iterator iter = transport_infos_.begin();
236 iter != transport_infos_.end(); ++iter) {
237 if (iter->content_name == name) {
238 return &(*iter);
239 }
240 }
241 return NULL;
242}
243
244void SessionDescription::RemoveGroupByName(const std::string& name) {
245 for (ContentGroups::iterator iter = content_groups_.begin();
246 iter != content_groups_.end(); ++iter) {
247 if (iter->semantics() == name) {
248 content_groups_.erase(iter);
249 break;
250 }
251 }
252}
253
254bool SessionDescription::HasGroup(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 true;
259 }
260 }
261 return false;
262}
263
264const ContentGroup* SessionDescription::GetGroupByName(
265 const std::string& name) const {
266 for (ContentGroups::const_iterator iter = content_groups_.begin();
267 iter != content_groups_.end(); ++iter) {
268 if (iter->semantics() == name) {
269 return &(*iter);
270 }
271 }
272 return NULL;
273}
274
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000275} // namespace cricket