blob: 476bf1af6a34116bbecffd04eabcc4113aa2f629 [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"
Harald Alvestrand5fc28b12019-05-13 13:36:16 +020018#include "pc/media_protocol_names.h"
Yves Gerey3e707812018-11-28 16:47:49 +010019#include "rtc_base/checks.h"
20
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000021namespace cricket {
Steve Anton4ab68ee2017-12-19 14:26:11 -080022namespace {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000023
Steve Anton4ab68ee2017-12-19 14:26:11 -080024ContentInfo* 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;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000030 }
31 }
Steve Anton4ab68ee2017-12-19 14:26:11 -080032 return nullptr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000033}
34
Steve Anton4ab68ee2017-12-19 14:26:11 -080035} // namespace
36
37const ContentInfo* FindContentInfoByName(const ContentInfos& contents,
38 const std::string& name) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000039 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
Steve Anton4ab68ee2017-12-19 14:26:11 -080048const ContentInfo* FindContentInfoByType(const ContentInfos& contents,
Steve Anton5adfafd2017-12-20 16:34:00 -080049 MediaProtocolType type) {
50 for (const auto& content : contents) {
51 if (content.type == type) {
52 return &content;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053 }
54 }
Steve Anton5adfafd2017-12-20 16:34:00 -080055 return nullptr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000056}
57
Steve Antond3ea9992017-10-31 12:38:23 -070058ContentGroup::ContentGroup(const std::string& semantics)
59 : semantics_(semantics) {}
60
61ContentGroup::ContentGroup(const ContentGroup&) = default;
62ContentGroup::ContentGroup(ContentGroup&&) = default;
63ContentGroup& ContentGroup::operator=(const ContentGroup&) = default;
64ContentGroup& ContentGroup::operator=(ContentGroup&&) = default;
65ContentGroup::~ContentGroup() = default;
66
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000067const std::string* ContentGroup::FirstContentName() const {
68 return (!content_names_.empty()) ? &(*content_names_.begin()) : NULL;
69}
70
71bool ContentGroup::HasContentName(const std::string& content_name) const {
Steve Anton64b626b2019-01-28 17:25:26 -080072 return absl::c_linear_search(content_names_, content_name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000073}
74
75void ContentGroup::AddContentName(const std::string& content_name) {
76 if (!HasContentName(content_name)) {
77 content_names_.push_back(content_name);
78 }
79}
80
81bool ContentGroup::RemoveContentName(const std::string& content_name) {
Steve Anton64b626b2019-01-28 17:25:26 -080082 ContentNames::iterator iter = absl::c_find(content_names_, content_name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000083 if (iter == content_names_.end()) {
84 return false;
85 }
86 content_names_.erase(iter);
87 return true;
88}
89
Steve Antond3ea9992017-10-31 12:38:23 -070090SessionDescription::SessionDescription() = default;
Steve Antond3ea9992017-10-31 12:38:23 -070091SessionDescription::SessionDescription(const SessionDescription&) = default;
92
93SessionDescription::~SessionDescription() {
Steve Antond3ea9992017-10-31 12:38:23 -070094}
95
Harald Alvestrand4d7160e2019-04-12 07:01:29 +020096std::unique_ptr<SessionDescription> SessionDescription::Clone() const {
Harald Alvestrand1716d392019-06-03 20:35:45 +020097 // Copy using the private copy constructor.
98 // This will clone the descriptions using ContentInfo's copy constructor.
99 return absl::WrapUnique(new SessionDescription(*this));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000100}
101
Harald Alvestrand4d7160e2019-04-12 07:01:29 +0200102SessionDescription* SessionDescription::Copy() const {
103 return Clone().release();
104}
105
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000106const ContentInfo* SessionDescription::GetContentByName(
107 const std::string& name) const {
108 return FindContentInfoByName(contents_, name);
109}
110
Steve Anton4ab68ee2017-12-19 14:26:11 -0800111ContentInfo* SessionDescription::GetContentByName(const std::string& name) {
112 return FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000113}
114
Steve Antonb1c1de12017-12-21 15:14:30 -0800115const MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000116 const std::string& name) const {
117 const ContentInfo* cinfo = FindContentInfoByName(contents_, name);
118 if (cinfo == NULL) {
119 return NULL;
120 }
121
Steve Antonb1c1de12017-12-21 15:14:30 -0800122 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000123}
124
Steve Antonb1c1de12017-12-21 15:14:30 -0800125MediaContentDescription* SessionDescription::GetContentDescriptionByName(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000126 const std::string& name) {
Steve Anton4ab68ee2017-12-19 14:26:11 -0800127 ContentInfo* cinfo = FindContentInfoByName(&contents_, name);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128 if (cinfo == NULL) {
129 return NULL;
130 }
131
Steve Antonb1c1de12017-12-21 15:14:30 -0800132 return cinfo->media_description();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000133}
134
135const ContentInfo* SessionDescription::FirstContentByType(
Steve Anton5adfafd2017-12-20 16:34:00 -0800136 MediaProtocolType type) const {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000137 return FindContentInfoByType(contents_, type);
138}
139
140const ContentInfo* SessionDescription::FirstContent() const {
141 return (contents_.empty()) ? NULL : &(*contents_.begin());
142}
143
Harald Alvestrand1716d392019-06-03 20:35:45 +0200144void SessionDescription::AddContent(
145 const std::string& name,
146 MediaProtocolType type,
147 std::unique_ptr<MediaContentDescription> description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800148 ContentInfo content(type);
149 content.name = name;
Harald Alvestrand1716d392019-06-03 20:35:45 +0200150 content.set_media_description(std::move(description));
151 AddContent(std::move(content));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000152}
153
Harald Alvestrand1716d392019-06-03 20:35:45 +0200154void SessionDescription::AddContent(
155 const std::string& name,
156 MediaProtocolType type,
157 bool rejected,
158 std::unique_ptr<MediaContentDescription> description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800159 ContentInfo content(type);
160 content.name = name;
161 content.rejected = rejected;
Harald Alvestrand1716d392019-06-03 20:35:45 +0200162 content.set_media_description(std::move(description));
163 AddContent(std::move(content));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000164}
165
Harald Alvestrand1716d392019-06-03 20:35:45 +0200166void SessionDescription::AddContent(
167 const std::string& name,
168 MediaProtocolType type,
169 bool rejected,
170 bool bundle_only,
171 std::unique_ptr<MediaContentDescription> description) {
Steve Anton5adfafd2017-12-20 16:34:00 -0800172 ContentInfo content(type);
173 content.name = name;
174 content.rejected = rejected;
175 content.bundle_only = bundle_only;
Harald Alvestrand1716d392019-06-03 20:35:45 +0200176 content.set_media_description(std::move(description));
177 AddContent(std::move(content));
Johannes Kron9ac3c912018-10-12 10:54:26 +0200178}
179
Harald Alvestrand1716d392019-06-03 20:35:45 +0200180void SessionDescription::AddContent(ContentInfo&& content) {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200181 // Unwrap the as_data shim layer before using.
Harald Alvestrand1716d392019-06-03 20:35:45 +0200182 auto* description = content.media_description();
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200183 bool should_delete = false;
184 if (description->as_rtp_data()) {
185 if (description->as_rtp_data() != description) {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200186 auto* media_description =
187 description->deprecated_as_data()->Unshim(&should_delete);
188 // If should_delete was false, the media description passed to
189 // AddContent is referenced from elsewhere, and double deletion
190 // is going to result. Don't allow this.
191 RTC_CHECK(should_delete)
192 << "Non-owned shim description passed to AddContent";
193 // Setting the media description will delete the old description.
194 content.set_media_description(absl::WrapUnique(media_description));
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200195 }
Harald Alvestrand1716d392019-06-03 20:35:45 +0200196 } else if (description->as_sctp()) {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200197 if (description->as_sctp() != description) {
Harald Alvestrand1716d392019-06-03 20:35:45 +0200198 auto* media_description =
199 description->deprecated_as_data()->Unshim(&should_delete);
200 RTC_CHECK(should_delete)
201 << "Non-owned shim description passed to AddContent";
202 content.set_media_description(absl::WrapUnique(media_description));
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200203 }
204 }
Johannes Kron9581bc42018-10-23 10:17:39 +0200205 if (extmap_allow_mixed()) {
Johannes Kron9ac3c912018-10-12 10:54:26 +0200206 // Mixed support on session level overrides setting on media level.
Harald Alvestrand1716d392019-06-03 20:35:45 +0200207 content.media_description()->set_extmap_allow_mixed_enum(
Johannes Kron9ac3c912018-10-12 10:54:26 +0200208 MediaContentDescription::kSession);
209 }
Harald Alvestrand1716d392019-06-03 20:35:45 +0200210 contents_.push_back(std::move(content));
deadbeef25ed4352016-12-12 18:37:36 -0800211}
212
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000213bool SessionDescription::RemoveContentByName(const std::string& name) {
214 for (ContentInfos::iterator content = contents_.begin();
215 content != contents_.end(); ++content) {
216 if (content->name == name) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000217 contents_.erase(content);
218 return true;
219 }
220 }
221
222 return false;
223}
224
Steve Anton06817cd2018-12-18 15:55:30 -0800225void SessionDescription::AddTransportInfo(const TransportInfo& transport_info) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000226 transport_infos_.push_back(transport_info);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000227}
228
229bool SessionDescription::RemoveTransportInfoByName(const std::string& name) {
230 for (TransportInfos::iterator transport_info = transport_infos_.begin();
231 transport_info != transport_infos_.end(); ++transport_info) {
232 if (transport_info->content_name == name) {
233 transport_infos_.erase(transport_info);
234 return true;
235 }
236 }
237 return false;
238}
239
240const TransportInfo* SessionDescription::GetTransportInfoByName(
241 const std::string& name) const {
242 for (TransportInfos::const_iterator iter = transport_infos_.begin();
243 iter != transport_infos_.end(); ++iter) {
244 if (iter->content_name == name) {
245 return &(*iter);
246 }
247 }
248 return NULL;
249}
250
251TransportInfo* SessionDescription::GetTransportInfoByName(
252 const std::string& name) {
253 for (TransportInfos::iterator iter = transport_infos_.begin();
254 iter != transport_infos_.end(); ++iter) {
255 if (iter->content_name == name) {
256 return &(*iter);
257 }
258 }
259 return NULL;
260}
261
262void SessionDescription::RemoveGroupByName(const std::string& name) {
263 for (ContentGroups::iterator iter = content_groups_.begin();
264 iter != content_groups_.end(); ++iter) {
265 if (iter->semantics() == name) {
266 content_groups_.erase(iter);
267 break;
268 }
269 }
270}
271
272bool SessionDescription::HasGroup(const std::string& name) const {
273 for (ContentGroups::const_iterator iter = content_groups_.begin();
274 iter != content_groups_.end(); ++iter) {
275 if (iter->semantics() == name) {
276 return true;
277 }
278 }
279 return false;
280}
281
282const ContentGroup* SessionDescription::GetGroupByName(
283 const std::string& name) const {
284 for (ContentGroups::const_iterator iter = content_groups_.begin();
285 iter != content_groups_.end(); ++iter) {
286 if (iter->semantics() == name) {
287 return &(*iter);
288 }
289 }
290 return NULL;
291}
292
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200293// DataContentDescription shim creation
Harald Alvestranda33a8602019-05-28 11:33:50 +0200294DataContentDescription* RtpDataContentDescription::deprecated_as_data() {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200295 if (!shim_) {
296 shim_.reset(new DataContentDescription(this));
297 }
298 return shim_.get();
299}
300
Harald Alvestranda33a8602019-05-28 11:33:50 +0200301DataContentDescription* RtpDataContentDescription::as_data() {
302 return deprecated_as_data();
303}
304
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200305const DataContentDescription* RtpDataContentDescription::as_data() const {
306 return const_cast<RtpDataContentDescription*>(this)->as_data();
307}
308
Harald Alvestranda33a8602019-05-28 11:33:50 +0200309DataContentDescription* SctpDataContentDescription::deprecated_as_data() {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200310 if (!shim_) {
311 shim_.reset(new DataContentDescription(this));
312 }
313 return shim_.get();
314}
315
Harald Alvestranda33a8602019-05-28 11:33:50 +0200316DataContentDescription* SctpDataContentDescription::as_data() {
317 return deprecated_as_data();
318}
319
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200320const DataContentDescription* SctpDataContentDescription::as_data() const {
Harald Alvestranda33a8602019-05-28 11:33:50 +0200321 return const_cast<SctpDataContentDescription*>(this)->deprecated_as_data();
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200322}
323
324DataContentDescription::DataContentDescription() {
325 // In this case, we will initialize |owned_description_| as soon as
326 // we are told what protocol to use via set_protocol or another function
327 // calling CreateShimTarget.
328}
329
330DataContentDescription::DataContentDescription(
331 SctpDataContentDescription* wrapped)
332 : real_description_(wrapped) {
333 // SctpDataContentDescription doesn't contain codecs, but code
334 // using DataContentDescription expects to see one.
335 Super::AddCodec(
336 cricket::DataCodec(kGoogleSctpDataCodecPlType, kGoogleSctpDataCodecName));
337}
338
339DataContentDescription::DataContentDescription(
340 RtpDataContentDescription* wrapped)
341 : real_description_(wrapped) {}
342
343DataContentDescription::DataContentDescription(
344 const DataContentDescription* o) {
345 if (o->real_description_) {
346 owned_description_ = absl::WrapUnique(o->real_description_->Copy());
347 real_description_ = owned_description_.get();
348 } else {
349 // Copy all information collected so far, including codecs.
350 Super::operator=(*o);
351 }
352}
353
354void DataContentDescription::CreateShimTarget(bool is_sctp) {
355 RTC_LOG(LS_INFO) << "Creating shim target, is_sctp is " << is_sctp;
356 RTC_CHECK(!owned_description_.get());
357 if (is_sctp) {
358 owned_description_ = absl::make_unique<SctpDataContentDescription>();
359 // Copy all information collected so far, except codecs.
360 owned_description_->MediaContentDescription::operator=(*this);
361 } else {
362 owned_description_ = absl::make_unique<RtpDataContentDescription>();
363 // Copy all information collected so far, including codecs.
364 owned_description_->as_rtp_data()
365 ->MediaContentDescriptionImpl<RtpDataCodec>::operator=(*this);
366 }
367 real_description_ = owned_description_.get();
368}
369
370MediaContentDescription* DataContentDescription::Unshim(bool* should_delete) {
371 // If protocol isn't decided at this point, we have a problem.
372 RTC_CHECK(real_description_);
373 if (owned_description_) {
374 // Pass ownership to caller, and remove myself.
375 // Since caller can't know if I was owner or owned, tell them.
376 MediaContentDescription* to_return = owned_description_.release();
377 *should_delete = true;
378 return to_return;
379 }
380 // Real object is owner, and presumably referenced from elsewhere.
381 *should_delete = false;
382 return real_description_;
383}
384
385void DataContentDescription::set_protocol(const std::string& protocol) {
386 if (!real_description_) {
387 CreateShimTarget(IsSctpProtocol(protocol));
388 }
389 real_description_->set_protocol(protocol);
390}
391
392bool DataContentDescription::IsSctp() const {
393 return (real_description_ && real_description_->as_sctp());
394}
395
396void DataContentDescription::EnsureIsRtp() {
397 RTC_CHECK(real_description_);
398 RTC_CHECK(real_description_->as_rtp_data());
399}
400
401RtpDataContentDescription* DataContentDescription::as_rtp_data() {
402 if (real_description_) {
403 return real_description_->as_rtp_data();
404 }
405 return nullptr;
406}
407
408SctpDataContentDescription* DataContentDescription::as_sctp() {
409 if (real_description_) {
410 return real_description_->as_sctp();
411 }
412 return nullptr;
413}
414
415// Override all methods defined in MediaContentDescription.
416bool DataContentDescription::has_codecs() const {
417 if (!real_description_) {
418 return Super::has_codecs();
419 }
420 return real_description_->has_codecs();
421}
422std::string DataContentDescription::protocol() const {
423 if (!real_description_) {
424 return Super::protocol();
425 }
426 return real_description_->protocol();
427}
428
429webrtc::RtpTransceiverDirection DataContentDescription::direction() const {
430 if (!real_description_) {
431 return Super::direction();
432 }
433 return real_description_->direction();
434}
435void DataContentDescription::set_direction(
436 webrtc::RtpTransceiverDirection direction) {
437 if (!real_description_) {
438 return Super::set_direction(direction);
439 }
440 return real_description_->set_direction(direction);
441}
442bool DataContentDescription::rtcp_mux() const {
443 if (!real_description_) {
444 return Super::rtcp_mux();
445 }
446 return real_description_->rtcp_mux();
447}
448void DataContentDescription::set_rtcp_mux(bool mux) {
449 if (!real_description_) {
450 Super::set_rtcp_mux(mux);
451 return;
452 }
453 real_description_->set_rtcp_mux(mux);
454}
455bool DataContentDescription::rtcp_reduced_size() const {
456 if (!real_description_) {
457 return Super::rtcp_reduced_size();
458 }
459 return real_description_->rtcp_reduced_size();
460}
461void DataContentDescription::set_rtcp_reduced_size(bool reduced_size) {
462 if (!real_description_) {
463 return Super::set_rtcp_reduced_size(reduced_size);
464 }
465
466 return real_description_->set_rtcp_reduced_size(reduced_size);
467}
468int DataContentDescription::bandwidth() const {
469 if (!real_description_) {
470 return Super::bandwidth();
471 }
472
473 return real_description_->bandwidth();
474}
475void DataContentDescription::set_bandwidth(int bandwidth) {
476 if (!real_description_) {
477 return Super::set_bandwidth(bandwidth);
478 }
479
480 return real_description_->set_bandwidth(bandwidth);
481}
482const std::vector<CryptoParams>& DataContentDescription::cryptos() const {
483 if (!real_description_) {
484 return Super::cryptos();
485 }
486
487 return real_description_->cryptos();
488}
489void DataContentDescription::AddCrypto(const CryptoParams& params) {
490 if (!real_description_) {
491 return Super::AddCrypto(params);
492 }
493
494 return real_description_->AddCrypto(params);
495}
496void DataContentDescription::set_cryptos(
497 const std::vector<CryptoParams>& cryptos) {
498 if (!real_description_) {
499 return Super::set_cryptos(cryptos);
500 }
501
502 return real_description_->set_cryptos(cryptos);
503}
504const RtpHeaderExtensions& DataContentDescription::rtp_header_extensions()
505 const {
506 if (!real_description_) {
507 return Super::rtp_header_extensions();
508 }
509
510 return real_description_->rtp_header_extensions();
511}
512void DataContentDescription::set_rtp_header_extensions(
513 const RtpHeaderExtensions& extensions) {
514 if (!real_description_) {
515 return Super::set_rtp_header_extensions(extensions);
516 }
517
518 return real_description_->set_rtp_header_extensions(extensions);
519}
520void DataContentDescription::AddRtpHeaderExtension(
521 const webrtc::RtpExtension& ext) {
522 if (!real_description_) {
523 return Super::AddRtpHeaderExtension(ext);
524 }
525 return real_description_->AddRtpHeaderExtension(ext);
526}
527void DataContentDescription::AddRtpHeaderExtension(
528 const cricket::RtpHeaderExtension& ext) {
529 if (!real_description_) {
530 return Super::AddRtpHeaderExtension(ext);
531 }
532 return real_description_->AddRtpHeaderExtension(ext);
533}
534void DataContentDescription::ClearRtpHeaderExtensions() {
535 if (!real_description_) {
536 return Super::ClearRtpHeaderExtensions();
537 }
538 return real_description_->ClearRtpHeaderExtensions();
539}
540bool DataContentDescription::rtp_header_extensions_set() const {
541 if (!real_description_) {
542 return Super::rtp_header_extensions_set();
543 }
544 return real_description_->rtp_header_extensions_set();
545}
546const StreamParamsVec& DataContentDescription::streams() const {
547 if (!real_description_) {
548 return Super::streams();
549 }
550 return real_description_->streams();
551}
552StreamParamsVec& DataContentDescription::mutable_streams() {
553 if (!real_description_) {
554 return Super::mutable_streams();
555 }
556 return real_description_->mutable_streams();
557}
558void DataContentDescription::AddStream(const StreamParams& stream) {
559 if (!real_description_) {
560 return Super::AddStream(stream);
561 }
562 return real_description_->AddStream(stream);
563}
564void DataContentDescription::SetCnameIfEmpty(const std::string& cname) {
565 if (!real_description_) {
566 return Super::SetCnameIfEmpty(cname);
567 }
568 return real_description_->SetCnameIfEmpty(cname);
569}
570uint32_t DataContentDescription::first_ssrc() const {
571 if (!real_description_) {
572 return Super::first_ssrc();
573 }
574 return real_description_->first_ssrc();
575}
576bool DataContentDescription::has_ssrcs() const {
577 if (!real_description_) {
578 return Super::has_ssrcs();
579 }
580 return real_description_->has_ssrcs();
581}
582void DataContentDescription::set_conference_mode(bool enable) {
583 if (!real_description_) {
584 return Super::set_conference_mode(enable);
585 }
586 return real_description_->set_conference_mode(enable);
587}
588bool DataContentDescription::conference_mode() const {
589 if (!real_description_) {
590 return Super::conference_mode();
591 }
592 return real_description_->conference_mode();
593}
594void DataContentDescription::set_connection_address(
595 const rtc::SocketAddress& address) {
596 if (!real_description_) {
597 return Super::set_connection_address(address);
598 }
599 return real_description_->set_connection_address(address);
600}
601const rtc::SocketAddress& DataContentDescription::connection_address() const {
602 if (!real_description_) {
603 return Super::connection_address();
604 }
605 return real_description_->connection_address();
606}
607void DataContentDescription::set_extmap_allow_mixed_enum(
608 ExtmapAllowMixed mixed) {
609 if (!real_description_) {
610 return Super::set_extmap_allow_mixed_enum(mixed);
611 }
612 return real_description_->set_extmap_allow_mixed_enum(mixed);
613}
614MediaContentDescription::ExtmapAllowMixed
615DataContentDescription::extmap_allow_mixed_enum() const {
616 if (!real_description_) {
617 return Super::extmap_allow_mixed_enum();
618 }
619 return real_description_->extmap_allow_mixed_enum();
620}
621bool DataContentDescription::HasSimulcast() const {
622 if (!real_description_) {
623 return Super::HasSimulcast();
624 }
625 return real_description_->HasSimulcast();
626}
627SimulcastDescription& DataContentDescription::simulcast_description() {
628 if (!real_description_) {
629 return Super::simulcast_description();
630 }
631 return real_description_->simulcast_description();
632}
633const SimulcastDescription& DataContentDescription::simulcast_description()
634 const {
635 if (!real_description_) {
636 return Super::simulcast_description();
637 }
638 return real_description_->simulcast_description();
639}
640void DataContentDescription::set_simulcast_description(
641 const SimulcastDescription& simulcast) {
642 if (!real_description_) {
643 return Super::set_simulcast_description(simulcast);
644 }
645 return real_description_->set_simulcast_description(simulcast);
646}
647
648// Methods defined in MediaContentDescriptionImpl.
649// For SCTP, we implement codec handling.
650// For RTP, we pass the codecs.
651// In the cases where type hasn't been decided yet, we return dummies.
652
653const std::vector<DataCodec>& DataContentDescription::codecs() const {
654 if (IsSctp() || !real_description_) {
655 return Super::codecs();
656 }
657 return real_description_->as_rtp_data()->codecs();
658}
659
660void DataContentDescription::set_codecs(const std::vector<DataCodec>& codecs) {
661 if (IsSctp() || !real_description_) {
662 Super::set_codecs(codecs);
663 } else {
664 EnsureIsRtp();
665 real_description_->as_rtp_data()->set_codecs(codecs);
666 }
667}
668
669bool DataContentDescription::HasCodec(int id) {
670 if (IsSctp() || !real_description_) {
671 return Super::HasCodec(id);
672 }
673 return real_description_->as_rtp_data()->HasCodec(id);
674}
675
676void DataContentDescription::AddCodec(const DataCodec& codec) {
677 if (IsSctp() || !real_description_) {
678 Super::AddCodec(codec);
679 } else {
680 EnsureIsRtp();
681 real_description_->as_rtp_data()->AddCodec(codec);
682 }
683}
684
685void DataContentDescription::AddOrReplaceCodec(const DataCodec& codec) {
686 if (IsSctp() || real_description_) {
687 Super::AddOrReplaceCodec(codec);
688 } else {
689 EnsureIsRtp();
690 real_description_->as_rtp_data()->AddOrReplaceCodec(codec);
691 }
692}
693
694void DataContentDescription::AddCodecs(const std::vector<DataCodec>& codecs) {
695 if (IsSctp() || !real_description_) {
696 Super::AddCodecs(codecs);
697 } else {
698 EnsureIsRtp();
699 real_description_->as_rtp_data()->AddCodecs(codecs);
700 }
701}
702
Harald Alvestrand1716d392019-06-03 20:35:45 +0200703ContentInfo::~ContentInfo() {
704 if (description_ && description_.get() != description) {
705 // If description_ is null, we assume that a move operator
706 // has been applied.
707 RTC_LOG(LS_ERROR) << "ContentInfo::description has been updated by "
708 << "assignment. This usage is deprecated.";
709 description_.reset(description); // ensure that it is destroyed.
710 }
711}
712
713// Copy operator.
714ContentInfo::ContentInfo(const ContentInfo& o)
715 : name(o.name),
716 type(o.type),
717 rejected(o.rejected),
718 bundle_only(o.bundle_only),
719 description_(o.description_->Clone()),
720 description(description_.get()) {}
721
722ContentInfo& ContentInfo::operator=(const ContentInfo& o) {
723 name = o.name;
724 type = o.type;
725 rejected = o.rejected;
726 bundle_only = o.bundle_only;
727 description_ = o.description_->Clone();
728 description = description_.get();
729 return *this;
730}
731
732const MediaContentDescription* ContentInfo::media_description() const {
733 if (description_.get() != description) {
734 // Someone's updated |description|, or used a move operator
735 // on the record.
736 RTC_LOG(LS_ERROR) << "ContentInfo::description has been updated by "
737 << "assignment. This usage is deprecated.";
738 const_cast<ContentInfo*>(this)->description_.reset(description);
739 }
740 return description_.get();
741}
742
743MediaContentDescription* ContentInfo::media_description() {
744 if (description_.get() != description) {
745 // Someone's updated |description|, or used a move operator
746 // on the record.
747 RTC_LOG(LS_ERROR) << "ContentInfo::description has been updated by "
748 << "assignment. This usage is deprecated.";
749 description_.reset(description);
750 }
751 return description_.get();
752}
753
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000754} // namespace cricket