1 /* 2 * Copyright 2004 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 11 #ifndef PC_SESSION_DESCRIPTION_H_ 12 #define PC_SESSION_DESCRIPTION_H_ 13 14 #include <stddef.h> 15 #include <stdint.h> 16 17 #include <iosfwd> 18 #include <memory> 19 #include <string> 20 #include <utility> 21 #include <vector> 22 23 #include "absl/memory/memory.h" 24 #include "api/crypto_params.h" 25 #include "api/media_types.h" 26 #include "api/rtp_parameters.h" 27 #include "api/rtp_transceiver_interface.h" 28 #include "media/base/media_channel.h" 29 #include "media/base/stream_params.h" 30 #include "p2p/base/transport_description.h" 31 #include "p2p/base/transport_info.h" 32 #include "pc/media_protocol_names.h" 33 #include "pc/simulcast_description.h" 34 #include "rtc_base/deprecation.h" 35 #include "rtc_base/socket_address.h" 36 #include "rtc_base/system/rtc_export.h" 37 38 namespace cricket { 39 40 typedef std::vector<AudioCodec> AudioCodecs; 41 typedef std::vector<VideoCodec> VideoCodecs; 42 typedef std::vector<RtpDataCodec> RtpDataCodecs; 43 typedef std::vector<CryptoParams> CryptoParamsVec; 44 typedef std::vector<webrtc::RtpExtension> RtpHeaderExtensions; 45 46 // RTC4585 RTP/AVPF 47 extern const char kMediaProtocolAvpf[]; 48 // RFC5124 RTP/SAVPF 49 extern const char kMediaProtocolSavpf[]; 50 51 extern const char kMediaProtocolDtlsSavpf[]; 52 53 // Options to control how session descriptions are generated. 54 const int kAutoBandwidth = -1; 55 56 class AudioContentDescription; 57 class VideoContentDescription; 58 class RtpDataContentDescription; 59 class SctpDataContentDescription; 60 61 // Describes a session description media section. There are subclasses for each 62 // media type (audio, video, data) that will have additional information. 63 class MediaContentDescription { 64 public: 65 MediaContentDescription() = default; 66 virtual ~MediaContentDescription() = default; 67 68 virtual MediaType type() const = 0; 69 70 // Try to cast this media description to an AudioContentDescription. Returns 71 // nullptr if the cast fails. as_audio()72 virtual AudioContentDescription* as_audio() { return nullptr; } as_audio()73 virtual const AudioContentDescription* as_audio() const { return nullptr; } 74 75 // Try to cast this media description to a VideoContentDescription. Returns 76 // nullptr if the cast fails. as_video()77 virtual VideoContentDescription* as_video() { return nullptr; } as_video()78 virtual const VideoContentDescription* as_video() const { return nullptr; } 79 as_rtp_data()80 virtual RtpDataContentDescription* as_rtp_data() { return nullptr; } as_rtp_data()81 virtual const RtpDataContentDescription* as_rtp_data() const { 82 return nullptr; 83 } 84 as_sctp()85 virtual SctpDataContentDescription* as_sctp() { return nullptr; } as_sctp()86 virtual const SctpDataContentDescription* as_sctp() const { return nullptr; } 87 88 virtual bool has_codecs() const = 0; 89 90 // Copy operator that returns an unique_ptr. 91 // Not a virtual function. 92 // If a type-specific variant of Clone() is desired, override it, or 93 // simply use std::make_unique<typename>(*this) instead of Clone(). Clone()94 std::unique_ptr<MediaContentDescription> Clone() const { 95 return absl::WrapUnique(CloneInternal()); 96 } 97 98 // |protocol| is the expected media transport protocol, such as RTP/AVPF, 99 // RTP/SAVPF or SCTP/DTLS. protocol()100 virtual std::string protocol() const { return protocol_; } set_protocol(const std::string & protocol)101 virtual void set_protocol(const std::string& protocol) { 102 protocol_ = protocol; 103 } 104 direction()105 virtual webrtc::RtpTransceiverDirection direction() const { 106 return direction_; 107 } set_direction(webrtc::RtpTransceiverDirection direction)108 virtual void set_direction(webrtc::RtpTransceiverDirection direction) { 109 direction_ = direction; 110 } 111 rtcp_mux()112 virtual bool rtcp_mux() const { return rtcp_mux_; } set_rtcp_mux(bool mux)113 virtual void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; } 114 rtcp_reduced_size()115 virtual bool rtcp_reduced_size() const { return rtcp_reduced_size_; } set_rtcp_reduced_size(bool reduced_size)116 virtual void set_rtcp_reduced_size(bool reduced_size) { 117 rtcp_reduced_size_ = reduced_size; 118 } 119 120 // Indicates support for the remote network estimate packet type. This 121 // functionality is experimental and subject to change without notice. remote_estimate()122 virtual bool remote_estimate() const { return remote_estimate_; } set_remote_estimate(bool remote_estimate)123 virtual void set_remote_estimate(bool remote_estimate) { 124 remote_estimate_ = remote_estimate; 125 } 126 bandwidth()127 virtual int bandwidth() const { return bandwidth_; } set_bandwidth(int bandwidth)128 virtual void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; } 129 cryptos()130 virtual const std::vector<CryptoParams>& cryptos() const { return cryptos_; } AddCrypto(const CryptoParams & params)131 virtual void AddCrypto(const CryptoParams& params) { 132 cryptos_.push_back(params); 133 } set_cryptos(const std::vector<CryptoParams> & cryptos)134 virtual void set_cryptos(const std::vector<CryptoParams>& cryptos) { 135 cryptos_ = cryptos; 136 } 137 rtp_header_extensions()138 virtual const RtpHeaderExtensions& rtp_header_extensions() const { 139 return rtp_header_extensions_; 140 } set_rtp_header_extensions(const RtpHeaderExtensions & extensions)141 virtual void set_rtp_header_extensions( 142 const RtpHeaderExtensions& extensions) { 143 rtp_header_extensions_ = extensions; 144 rtp_header_extensions_set_ = true; 145 } AddRtpHeaderExtension(const webrtc::RtpExtension & ext)146 virtual void AddRtpHeaderExtension(const webrtc::RtpExtension& ext) { 147 rtp_header_extensions_.push_back(ext); 148 rtp_header_extensions_set_ = true; 149 } ClearRtpHeaderExtensions()150 virtual void ClearRtpHeaderExtensions() { 151 rtp_header_extensions_.clear(); 152 rtp_header_extensions_set_ = true; 153 } 154 // We can't always tell if an empty list of header extensions is 155 // because the other side doesn't support them, or just isn't hooked up to 156 // signal them. For now we assume an empty list means no signaling, but 157 // provide the ClearRtpHeaderExtensions method to allow "no support" to be 158 // clearly indicated (i.e. when derived from other information). rtp_header_extensions_set()159 virtual bool rtp_header_extensions_set() const { 160 return rtp_header_extensions_set_; 161 } streams()162 virtual const StreamParamsVec& streams() const { return send_streams_; } 163 // TODO(pthatcher): Remove this by giving mediamessage.cc access 164 // to MediaContentDescription mutable_streams()165 virtual StreamParamsVec& mutable_streams() { return send_streams_; } AddStream(const StreamParams & stream)166 virtual void AddStream(const StreamParams& stream) { 167 send_streams_.push_back(stream); 168 } 169 // Legacy streams have an ssrc, but nothing else. AddLegacyStream(uint32_t ssrc)170 void AddLegacyStream(uint32_t ssrc) { 171 AddStream(StreamParams::CreateLegacy(ssrc)); 172 } AddLegacyStream(uint32_t ssrc,uint32_t fid_ssrc)173 void AddLegacyStream(uint32_t ssrc, uint32_t fid_ssrc) { 174 StreamParams sp = StreamParams::CreateLegacy(ssrc); 175 sp.AddFidSsrc(ssrc, fid_ssrc); 176 AddStream(sp); 177 } 178 179 // Sets the CNAME of all StreamParams if it have not been set. SetCnameIfEmpty(const std::string & cname)180 virtual void SetCnameIfEmpty(const std::string& cname) { 181 for (cricket::StreamParamsVec::iterator it = send_streams_.begin(); 182 it != send_streams_.end(); ++it) { 183 if (it->cname.empty()) 184 it->cname = cname; 185 } 186 } first_ssrc()187 virtual uint32_t first_ssrc() const { 188 if (send_streams_.empty()) { 189 return 0; 190 } 191 return send_streams_[0].first_ssrc(); 192 } has_ssrcs()193 virtual bool has_ssrcs() const { 194 if (send_streams_.empty()) { 195 return false; 196 } 197 return send_streams_[0].has_ssrcs(); 198 } 199 set_conference_mode(bool enable)200 virtual void set_conference_mode(bool enable) { conference_mode_ = enable; } conference_mode()201 virtual bool conference_mode() const { return conference_mode_; } 202 203 // https://tools.ietf.org/html/rfc4566#section-5.7 204 // May be present at the media or session level of SDP. If present at both 205 // levels, the media-level attribute overwrites the session-level one. set_connection_address(const rtc::SocketAddress & address)206 virtual void set_connection_address(const rtc::SocketAddress& address) { 207 connection_address_ = address; 208 } connection_address()209 virtual const rtc::SocketAddress& connection_address() const { 210 return connection_address_; 211 } 212 213 // Determines if it's allowed to mix one- and two-byte rtp header extensions 214 // within the same rtp stream. 215 enum ExtmapAllowMixed { kNo, kSession, kMedia }; set_extmap_allow_mixed_enum(ExtmapAllowMixed new_extmap_allow_mixed)216 virtual void set_extmap_allow_mixed_enum( 217 ExtmapAllowMixed new_extmap_allow_mixed) { 218 if (new_extmap_allow_mixed == kMedia && 219 extmap_allow_mixed_enum_ == kSession) { 220 // Do not downgrade from session level to media level. 221 return; 222 } 223 extmap_allow_mixed_enum_ = new_extmap_allow_mixed; 224 } extmap_allow_mixed_enum()225 virtual ExtmapAllowMixed extmap_allow_mixed_enum() const { 226 return extmap_allow_mixed_enum_; 227 } extmap_allow_mixed()228 virtual bool extmap_allow_mixed() const { 229 return extmap_allow_mixed_enum_ != kNo; 230 } 231 232 // Simulcast functionality. HasSimulcast()233 virtual bool HasSimulcast() const { return !simulcast_.empty(); } simulcast_description()234 virtual SimulcastDescription& simulcast_description() { return simulcast_; } simulcast_description()235 virtual const SimulcastDescription& simulcast_description() const { 236 return simulcast_; 237 } set_simulcast_description(const SimulcastDescription & simulcast)238 virtual void set_simulcast_description( 239 const SimulcastDescription& simulcast) { 240 simulcast_ = simulcast; 241 } receive_rids()242 virtual const std::vector<RidDescription>& receive_rids() const { 243 return receive_rids_; 244 } set_receive_rids(const std::vector<RidDescription> & rids)245 virtual void set_receive_rids(const std::vector<RidDescription>& rids) { 246 receive_rids_ = rids; 247 } 248 249 protected: 250 bool rtcp_mux_ = false; 251 bool rtcp_reduced_size_ = false; 252 bool remote_estimate_ = false; 253 int bandwidth_ = kAutoBandwidth; 254 std::string protocol_; 255 std::vector<CryptoParams> cryptos_; 256 std::vector<webrtc::RtpExtension> rtp_header_extensions_; 257 bool rtp_header_extensions_set_ = false; 258 StreamParamsVec send_streams_; 259 bool conference_mode_ = false; 260 webrtc::RtpTransceiverDirection direction_ = 261 webrtc::RtpTransceiverDirection::kSendRecv; 262 rtc::SocketAddress connection_address_; 263 // Mixed one- and two-byte header not included in offer on media level or 264 // session level, but we will respond that we support it. The plan is to add 265 // it to our offer on session level. See todo in SessionDescription. 266 ExtmapAllowMixed extmap_allow_mixed_enum_ = kNo; 267 268 SimulcastDescription simulcast_; 269 std::vector<RidDescription> receive_rids_; 270 271 private: 272 // Copy function that returns a raw pointer. Caller will assert ownership. 273 // Should only be called by the Clone() function. Must be implemented 274 // by each final subclass. 275 virtual MediaContentDescription* CloneInternal() const = 0; 276 }; 277 278 template <class C> 279 class MediaContentDescriptionImpl : public MediaContentDescription { 280 public: set_protocol(const std::string & protocol)281 void set_protocol(const std::string& protocol) override { 282 RTC_DCHECK(IsRtpProtocol(protocol)); 283 protocol_ = protocol; 284 } 285 286 typedef C CodecType; 287 288 // Codecs should be in preference order (most preferred codec first). codecs()289 virtual const std::vector<C>& codecs() const { return codecs_; } set_codecs(const std::vector<C> & codecs)290 virtual void set_codecs(const std::vector<C>& codecs) { codecs_ = codecs; } has_codecs()291 bool has_codecs() const override { return !codecs_.empty(); } HasCodec(int id)292 virtual bool HasCodec(int id) { 293 bool found = false; 294 for (typename std::vector<C>::iterator iter = codecs_.begin(); 295 iter != codecs_.end(); ++iter) { 296 if (iter->id == id) { 297 found = true; 298 break; 299 } 300 } 301 return found; 302 } AddCodec(const C & codec)303 virtual void AddCodec(const C& codec) { codecs_.push_back(codec); } AddOrReplaceCodec(const C & codec)304 virtual void AddOrReplaceCodec(const C& codec) { 305 for (typename std::vector<C>::iterator iter = codecs_.begin(); 306 iter != codecs_.end(); ++iter) { 307 if (iter->id == codec.id) { 308 *iter = codec; 309 return; 310 } 311 } 312 AddCodec(codec); 313 } AddCodecs(const std::vector<C> & codecs)314 virtual void AddCodecs(const std::vector<C>& codecs) { 315 typename std::vector<C>::const_iterator codec; 316 for (codec = codecs.begin(); codec != codecs.end(); ++codec) { 317 AddCodec(*codec); 318 } 319 } 320 321 private: 322 std::vector<C> codecs_; 323 }; 324 325 class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> { 326 public: AudioContentDescription()327 AudioContentDescription() {} 328 type()329 virtual MediaType type() const { return MEDIA_TYPE_AUDIO; } as_audio()330 virtual AudioContentDescription* as_audio() { return this; } as_audio()331 virtual const AudioContentDescription* as_audio() const { return this; } 332 333 private: CloneInternal()334 virtual AudioContentDescription* CloneInternal() const { 335 return new AudioContentDescription(*this); 336 } 337 }; 338 339 class VideoContentDescription : public MediaContentDescriptionImpl<VideoCodec> { 340 public: type()341 virtual MediaType type() const { return MEDIA_TYPE_VIDEO; } as_video()342 virtual VideoContentDescription* as_video() { return this; } as_video()343 virtual const VideoContentDescription* as_video() const { return this; } 344 345 private: CloneInternal()346 virtual VideoContentDescription* CloneInternal() const { 347 return new VideoContentDescription(*this); 348 } 349 }; 350 351 class RtpDataContentDescription 352 : public MediaContentDescriptionImpl<RtpDataCodec> { 353 public: RtpDataContentDescription()354 RtpDataContentDescription() {} type()355 MediaType type() const override { return MEDIA_TYPE_DATA; } as_rtp_data()356 RtpDataContentDescription* as_rtp_data() override { return this; } as_rtp_data()357 const RtpDataContentDescription* as_rtp_data() const override { return this; } 358 359 private: CloneInternal()360 RtpDataContentDescription* CloneInternal() const override { 361 return new RtpDataContentDescription(*this); 362 } 363 }; 364 365 class SctpDataContentDescription : public MediaContentDescription { 366 public: SctpDataContentDescription()367 SctpDataContentDescription() {} SctpDataContentDescription(const SctpDataContentDescription & o)368 SctpDataContentDescription(const SctpDataContentDescription& o) 369 : MediaContentDescription(o), 370 use_sctpmap_(o.use_sctpmap_), 371 port_(o.port_), 372 max_message_size_(o.max_message_size_) {} type()373 MediaType type() const override { return MEDIA_TYPE_DATA; } as_sctp()374 SctpDataContentDescription* as_sctp() override { return this; } as_sctp()375 const SctpDataContentDescription* as_sctp() const override { return this; } 376 has_codecs()377 bool has_codecs() const override { return false; } set_protocol(const std::string & protocol)378 void set_protocol(const std::string& protocol) override { 379 RTC_DCHECK(IsSctpProtocol(protocol)); 380 protocol_ = protocol; 381 } 382 use_sctpmap()383 bool use_sctpmap() const { return use_sctpmap_; } set_use_sctpmap(bool enable)384 void set_use_sctpmap(bool enable) { use_sctpmap_ = enable; } port()385 int port() const { return port_; } set_port(int port)386 void set_port(int port) { port_ = port; } max_message_size()387 int max_message_size() const { return max_message_size_; } set_max_message_size(int max_message_size)388 void set_max_message_size(int max_message_size) { 389 max_message_size_ = max_message_size; 390 } 391 392 private: CloneInternal()393 SctpDataContentDescription* CloneInternal() const override { 394 return new SctpDataContentDescription(*this); 395 } 396 bool use_sctpmap_ = true; // Note: "true" is no longer conformant. 397 // Defaults should be constants imported from SCTP. Quick hack. 398 int port_ = 5000; 399 // draft-ietf-mmusic-sdp-sctp-23: Max message size default is 64K 400 int max_message_size_ = 64 * 1024; 401 }; 402 403 // Protocol used for encoding media. This is the "top level" protocol that may 404 // be wrapped by zero or many transport protocols (UDP, ICE, etc.). 405 enum class MediaProtocolType { 406 kRtp, // Section will use the RTP protocol (e.g., for audio or video). 407 // https://tools.ietf.org/html/rfc3550 408 kSctp // Section will use the SCTP protocol (e.g., for a data channel). 409 // https://tools.ietf.org/html/rfc4960 410 }; 411 412 // Represents a session description section. Most information about the section 413 // is stored in the description, which is a subclass of MediaContentDescription. 414 // Owns the description. 415 class RTC_EXPORT ContentInfo { 416 public: ContentInfo(MediaProtocolType type)417 explicit ContentInfo(MediaProtocolType type) : type(type) {} 418 ~ContentInfo(); 419 // Copy 420 ContentInfo(const ContentInfo& o); 421 ContentInfo& operator=(const ContentInfo& o); 422 ContentInfo(ContentInfo&& o) = default; 423 ContentInfo& operator=(ContentInfo&& o) = default; 424 425 // Alias for |name|. mid()426 std::string mid() const { return name; } set_mid(const std::string & mid)427 void set_mid(const std::string& mid) { this->name = mid; } 428 429 // Alias for |description|. 430 MediaContentDescription* media_description(); 431 const MediaContentDescription* media_description() const; 432 set_media_description(std::unique_ptr<MediaContentDescription> desc)433 void set_media_description(std::unique_ptr<MediaContentDescription> desc) { 434 description_ = std::move(desc); 435 } 436 437 // TODO(bugs.webrtc.org/8620): Rename this to mid. 438 std::string name; 439 MediaProtocolType type; 440 bool rejected = false; 441 bool bundle_only = false; 442 443 private: 444 friend class SessionDescription; 445 std::unique_ptr<MediaContentDescription> description_; 446 }; 447 448 typedef std::vector<std::string> ContentNames; 449 450 // This class provides a mechanism to aggregate different media contents into a 451 // group. This group can also be shared with the peers in a pre-defined format. 452 // GroupInfo should be populated only with the |content_name| of the 453 // MediaDescription. 454 class ContentGroup { 455 public: 456 explicit ContentGroup(const std::string& semantics); 457 ContentGroup(const ContentGroup&); 458 ContentGroup(ContentGroup&&); 459 ContentGroup& operator=(const ContentGroup&); 460 ContentGroup& operator=(ContentGroup&&); 461 ~ContentGroup(); 462 semantics()463 const std::string& semantics() const { return semantics_; } content_names()464 const ContentNames& content_names() const { return content_names_; } 465 466 const std::string* FirstContentName() const; 467 bool HasContentName(const std::string& content_name) const; 468 void AddContentName(const std::string& content_name); 469 bool RemoveContentName(const std::string& content_name); 470 471 private: 472 std::string semantics_; 473 ContentNames content_names_; 474 }; 475 476 typedef std::vector<ContentInfo> ContentInfos; 477 typedef std::vector<ContentGroup> ContentGroups; 478 479 const ContentInfo* FindContentInfoByName(const ContentInfos& contents, 480 const std::string& name); 481 const ContentInfo* FindContentInfoByType(const ContentInfos& contents, 482 const std::string& type); 483 484 // Determines how the MSID will be signaled in the SDP. These can be used as 485 // flags to indicate both or none. 486 enum MsidSignaling { 487 // Signal MSID with one a=msid line in the media section. 488 kMsidSignalingMediaSection = 0x1, 489 // Signal MSID with a=ssrc: msid lines in the media section. 490 kMsidSignalingSsrcAttribute = 0x2 491 }; 492 493 // Describes a collection of contents, each with its own name and 494 // type. Analogous to a <jingle> or <session> stanza. Assumes that 495 // contents are unique be name, but doesn't enforce that. 496 class SessionDescription { 497 public: 498 SessionDescription(); 499 ~SessionDescription(); 500 501 std::unique_ptr<SessionDescription> Clone() const; 502 503 // Content accessors. contents()504 const ContentInfos& contents() const { return contents_; } contents()505 ContentInfos& contents() { return contents_; } 506 const ContentInfo* GetContentByName(const std::string& name) const; 507 ContentInfo* GetContentByName(const std::string& name); 508 const MediaContentDescription* GetContentDescriptionByName( 509 const std::string& name) const; 510 MediaContentDescription* GetContentDescriptionByName(const std::string& name); 511 const ContentInfo* FirstContentByType(MediaProtocolType type) const; 512 const ContentInfo* FirstContent() const; 513 514 // Content mutators. 515 // Adds a content to this description. Takes ownership of ContentDescription*. 516 void AddContent(const std::string& name, 517 MediaProtocolType type, 518 std::unique_ptr<MediaContentDescription> description); 519 void AddContent(const std::string& name, 520 MediaProtocolType type, 521 bool rejected, 522 std::unique_ptr<MediaContentDescription> description); 523 void AddContent(const std::string& name, 524 MediaProtocolType type, 525 bool rejected, 526 bool bundle_only, 527 std::unique_ptr<MediaContentDescription> description); 528 void AddContent(ContentInfo&& content); 529 530 bool RemoveContentByName(const std::string& name); 531 532 // Transport accessors. transport_infos()533 const TransportInfos& transport_infos() const { return transport_infos_; } transport_infos()534 TransportInfos& transport_infos() { return transport_infos_; } 535 const TransportInfo* GetTransportInfoByName(const std::string& name) const; 536 TransportInfo* GetTransportInfoByName(const std::string& name); GetTransportDescriptionByName(const std::string & name)537 const TransportDescription* GetTransportDescriptionByName( 538 const std::string& name) const { 539 const TransportInfo* tinfo = GetTransportInfoByName(name); 540 return tinfo ? &tinfo->description : NULL; 541 } 542 543 // Transport mutators. set_transport_infos(const TransportInfos & transport_infos)544 void set_transport_infos(const TransportInfos& transport_infos) { 545 transport_infos_ = transport_infos; 546 } 547 // Adds a TransportInfo to this description. 548 void AddTransportInfo(const TransportInfo& transport_info); 549 bool RemoveTransportInfoByName(const std::string& name); 550 551 // Group accessors. groups()552 const ContentGroups& groups() const { return content_groups_; } 553 const ContentGroup* GetGroupByName(const std::string& name) const; 554 bool HasGroup(const std::string& name) const; 555 556 // Group mutators. AddGroup(const ContentGroup & group)557 void AddGroup(const ContentGroup& group) { content_groups_.push_back(group); } 558 // Remove the first group with the same semantics specified by |name|. 559 void RemoveGroupByName(const std::string& name); 560 561 // Global attributes. set_msid_supported(bool supported)562 void set_msid_supported(bool supported) { msid_supported_ = supported; } msid_supported()563 bool msid_supported() const { return msid_supported_; } 564 565 // Determines how the MSIDs were/will be signaled. Flag value composed of 566 // MsidSignaling bits (see enum above). set_msid_signaling(int msid_signaling)567 void set_msid_signaling(int msid_signaling) { 568 msid_signaling_ = msid_signaling; 569 } msid_signaling()570 int msid_signaling() const { return msid_signaling_; } 571 572 // Determines if it's allowed to mix one- and two-byte rtp header extensions 573 // within the same rtp stream. set_extmap_allow_mixed(bool supported)574 void set_extmap_allow_mixed(bool supported) { 575 extmap_allow_mixed_ = supported; 576 MediaContentDescription::ExtmapAllowMixed media_level_setting = 577 supported ? MediaContentDescription::kSession 578 : MediaContentDescription::kNo; 579 for (auto& content : contents_) { 580 // Do not set to kNo if the current setting is kMedia. 581 if (supported || content.media_description()->extmap_allow_mixed_enum() != 582 MediaContentDescription::kMedia) { 583 content.media_description()->set_extmap_allow_mixed_enum( 584 media_level_setting); 585 } 586 } 587 } extmap_allow_mixed()588 bool extmap_allow_mixed() const { return extmap_allow_mixed_; } 589 590 private: 591 SessionDescription(const SessionDescription&); 592 593 ContentInfos contents_; 594 TransportInfos transport_infos_; 595 ContentGroups content_groups_; 596 bool msid_supported_ = true; 597 // Default to what Plan B would do. 598 // TODO(bugs.webrtc.org/8530): Change default to kMsidSignalingMediaSection. 599 int msid_signaling_ = kMsidSignalingSsrcAttribute; 600 // TODO(webrtc:9985): Activate mixed one- and two-byte header extension in 601 // offer at session level. It's currently not included in offer by default 602 // because clients prior to https://bugs.webrtc.org/9712 cannot parse this 603 // correctly. If it's included in offer to us we will respond that we support 604 // it. 605 bool extmap_allow_mixed_ = false; 606 }; 607 608 // Indicates whether a session description was sent by the local client or 609 // received from the remote client. 610 enum ContentSource { CS_LOCAL, CS_REMOTE }; 611 612 } // namespace cricket 613 614 #endif // PC_SESSION_DESCRIPTION_H_ 615