blob: 7b70ddf556e0e2fd9da330af0c3beff24f4767e4 [file] [log] [blame]
Steve Anton4ab68ee2017-12-19 14:26:11 -08001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef PC_SESSION_DESCRIPTION_H_
12#define PC_SESSION_DESCRIPTION_H_
Steve Anton4ab68ee2017-12-19 14:26:11 -080013
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <stddef.h>
15#include <stdint.h>
16#include <iosfwd>
Harald Alvestrand4d7160e2019-04-12 07:01:29 +020017#include <memory>
Steve Anton4ab68ee2017-12-19 14:26:11 -080018#include <string>
19#include <vector>
20
Steve Anton10542f22019-01-11 09:11:00 -080021#include "api/crypto_params.h"
22#include "api/media_types.h"
23#include "api/rtp_parameters.h"
24#include "api/rtp_transceiver_interface.h"
25#include "media/base/media_channel.h"
26#include "media/base/stream_params.h"
27#include "p2p/base/transport_description.h"
28#include "p2p/base/transport_info.h"
29#include "pc/simulcast_description.h"
30#include "rtc_base/socket_address.h"
Steve Anton4ab68ee2017-12-19 14:26:11 -080031
32namespace cricket {
33
Steve Antonafd8e8c2017-12-19 16:35:35 -080034typedef std::vector<AudioCodec> AudioCodecs;
35typedef std::vector<VideoCodec> VideoCodecs;
Harald Alvestrand141c0ad2019-05-05 19:00:00 +000036typedef std::vector<DataCodec> DataCodecs;
Steve Antonafd8e8c2017-12-19 16:35:35 -080037typedef std::vector<CryptoParams> CryptoParamsVec;
38typedef std::vector<webrtc::RtpExtension> RtpHeaderExtensions;
39
40// RTC4585 RTP/AVPF
41extern const char kMediaProtocolAvpf[];
42// RFC5124 RTP/SAVPF
43extern const char kMediaProtocolSavpf[];
44
45extern const char kMediaProtocolDtlsSavpf[];
46
Harald Alvestrand141c0ad2019-05-05 19:00:00 +000047extern const char kMediaProtocolRtpPrefix[];
48
49extern const char kMediaProtocolSctp[];
50extern const char kMediaProtocolDtlsSctp[];
51extern const char kMediaProtocolUdpDtlsSctp[];
52extern const char kMediaProtocolTcpDtlsSctp[];
Steve Antonafd8e8c2017-12-19 16:35:35 -080053
54// Options to control how session descriptions are generated.
55const int kAutoBandwidth = -1;
56
Steve Anton5adfafd2017-12-20 16:34:00 -080057class AudioContentDescription;
Harald Alvestrand14b27582019-05-04 11:37:04 +020058class DataContentDescription;
Harald Alvestrand141c0ad2019-05-05 19:00:00 +000059class VideoContentDescription;
Steve Anton4ab68ee2017-12-19 14:26:11 -080060
Steve Anton5adfafd2017-12-20 16:34:00 -080061// Describes a session description media section. There are subclasses for each
62// media type (audio, video, data) that will have additional information.
63class MediaContentDescription {
Steve Antonafd8e8c2017-12-19 16:35:35 -080064 public:
Steve Anton5adfafd2017-12-20 16:34:00 -080065 MediaContentDescription() = default;
66 virtual ~MediaContentDescription() = default;
Steve Antonafd8e8c2017-12-19 16:35:35 -080067
68 virtual MediaType type() const = 0;
Steve Anton5adfafd2017-12-20 16:34:00 -080069
70 // Try to cast this media description to an AudioContentDescription. Returns
71 // nullptr if the cast fails.
72 virtual AudioContentDescription* as_audio() { return nullptr; }
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.
77 virtual VideoContentDescription* as_video() { return nullptr; }
78 virtual const VideoContentDescription* as_video() const { return nullptr; }
79
Harald Alvestrand141c0ad2019-05-05 19:00:00 +000080 // Try to cast this media description to a DataContentDescription. Returns
81 // nullptr if the cast fails.
Steve Anton5adfafd2017-12-20 16:34:00 -080082 virtual DataContentDescription* as_data() { return nullptr; }
83 virtual const DataContentDescription* as_data() const { return nullptr; }
84
Steve Antonafd8e8c2017-12-19 16:35:35 -080085 virtual bool has_codecs() const = 0;
86
Steve Anton5adfafd2017-12-20 16:34:00 -080087 virtual MediaContentDescription* Copy() const = 0;
88
Steve Antonafd8e8c2017-12-19 16:35:35 -080089 // |protocol| is the expected media transport protocol, such as RTP/AVPF,
90 // RTP/SAVPF or SCTP/DTLS.
Harald Alvestrand141c0ad2019-05-05 19:00:00 +000091 std::string protocol() const { return protocol_; }
92 void set_protocol(const std::string& protocol) { protocol_ = protocol; }
Steve Antonafd8e8c2017-12-19 16:35:35 -080093
Harald Alvestrand141c0ad2019-05-05 19:00:00 +000094 webrtc::RtpTransceiverDirection direction() const { return direction_; }
95 void set_direction(webrtc::RtpTransceiverDirection direction) {
Steve Antonafd8e8c2017-12-19 16:35:35 -080096 direction_ = direction;
97 }
98
Harald Alvestrand141c0ad2019-05-05 19:00:00 +000099 bool rtcp_mux() const { return rtcp_mux_; }
100 void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800101
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000102 bool rtcp_reduced_size() const { return rtcp_reduced_size_; }
103 void set_rtcp_reduced_size(bool reduced_size) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800104 rtcp_reduced_size_ = reduced_size;
105 }
106
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000107 int bandwidth() const { return bandwidth_; }
108 void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800109
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000110 const std::vector<CryptoParams>& cryptos() const { return cryptos_; }
111 void AddCrypto(const CryptoParams& params) { cryptos_.push_back(params); }
112 void set_cryptos(const std::vector<CryptoParams>& cryptos) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800113 cryptos_ = cryptos;
114 }
115
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000116 const RtpHeaderExtensions& rtp_header_extensions() const {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800117 return rtp_header_extensions_;
118 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000119 void set_rtp_header_extensions(const RtpHeaderExtensions& extensions) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800120 rtp_header_extensions_ = extensions;
121 rtp_header_extensions_set_ = true;
122 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000123 void AddRtpHeaderExtension(const webrtc::RtpExtension& ext) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800124 rtp_header_extensions_.push_back(ext);
125 rtp_header_extensions_set_ = true;
126 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000127 void AddRtpHeaderExtension(const cricket::RtpHeaderExtension& ext) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800128 webrtc::RtpExtension webrtc_extension;
129 webrtc_extension.uri = ext.uri;
130 webrtc_extension.id = ext.id;
131 rtp_header_extensions_.push_back(webrtc_extension);
132 rtp_header_extensions_set_ = true;
133 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000134 void ClearRtpHeaderExtensions() {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800135 rtp_header_extensions_.clear();
136 rtp_header_extensions_set_ = true;
137 }
138 // We can't always tell if an empty list of header extensions is
139 // because the other side doesn't support them, or just isn't hooked up to
140 // signal them. For now we assume an empty list means no signaling, but
141 // provide the ClearRtpHeaderExtensions method to allow "no support" to be
142 // clearly indicated (i.e. when derived from other information).
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000143 bool rtp_header_extensions_set() const { return rtp_header_extensions_set_; }
144 const StreamParamsVec& streams() const { return send_streams_; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800145 // TODO(pthatcher): Remove this by giving mediamessage.cc access
146 // to MediaContentDescription
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000147 StreamParamsVec& mutable_streams() { return send_streams_; }
148 void AddStream(const StreamParams& stream) {
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800149 send_streams_.push_back(stream);
150 }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800151 // Legacy streams have an ssrc, but nothing else.
152 void AddLegacyStream(uint32_t ssrc) {
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000153 send_streams_.push_back(StreamParams::CreateLegacy(ssrc));
Steve Antonafd8e8c2017-12-19 16:35:35 -0800154 }
155 void AddLegacyStream(uint32_t ssrc, uint32_t fid_ssrc) {
156 StreamParams sp = StreamParams::CreateLegacy(ssrc);
157 sp.AddFidSsrc(ssrc, fid_ssrc);
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000158 send_streams_.push_back(sp);
Steve Antonafd8e8c2017-12-19 16:35:35 -0800159 }
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800160
Steve Antonafd8e8c2017-12-19 16:35:35 -0800161 // Sets the CNAME of all StreamParams if it have not been set.
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000162 void SetCnameIfEmpty(const std::string& cname) {
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800163 for (cricket::StreamParamsVec::iterator it = send_streams_.begin();
164 it != send_streams_.end(); ++it) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800165 if (it->cname.empty())
166 it->cname = cname;
167 }
168 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000169 uint32_t first_ssrc() const {
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800170 if (send_streams_.empty()) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800171 return 0;
172 }
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800173 return send_streams_[0].first_ssrc();
Steve Antonafd8e8c2017-12-19 16:35:35 -0800174 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000175 bool has_ssrcs() const {
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800176 if (send_streams_.empty()) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800177 return false;
178 }
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800179 return send_streams_[0].has_ssrcs();
Steve Antonafd8e8c2017-12-19 16:35:35 -0800180 }
181
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000182 void set_conference_mode(bool enable) { conference_mode_ = enable; }
183 bool conference_mode() const { return conference_mode_; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800184
185 // https://tools.ietf.org/html/rfc4566#section-5.7
186 // May be present at the media or session level of SDP. If present at both
187 // levels, the media-level attribute overwrites the session-level one.
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000188 void set_connection_address(const rtc::SocketAddress& address) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800189 connection_address_ = address;
190 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000191 const rtc::SocketAddress& connection_address() const {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800192 return connection_address_;
193 }
194
Johannes Kron0854eb62018-10-10 22:33:20 +0200195 // Determines if it's allowed to mix one- and two-byte rtp header extensions
196 // within the same rtp stream.
Johannes Kron9581bc42018-10-23 10:17:39 +0200197 enum ExtmapAllowMixed { kNo, kSession, kMedia };
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000198 void set_extmap_allow_mixed_enum(ExtmapAllowMixed new_extmap_allow_mixed) {
Johannes Kron9ac3c912018-10-12 10:54:26 +0200199 if (new_extmap_allow_mixed == kMedia &&
Johannes Kron9581bc42018-10-23 10:17:39 +0200200 extmap_allow_mixed_enum_ == kSession) {
Johannes Kron0854eb62018-10-10 22:33:20 +0200201 // Do not downgrade from session level to media level.
202 return;
203 }
Johannes Kron9581bc42018-10-23 10:17:39 +0200204 extmap_allow_mixed_enum_ = new_extmap_allow_mixed;
Johannes Kron0854eb62018-10-10 22:33:20 +0200205 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000206 ExtmapAllowMixed extmap_allow_mixed_enum() const {
Johannes Kron9581bc42018-10-23 10:17:39 +0200207 return extmap_allow_mixed_enum_;
Johannes Kron9ac3c912018-10-12 10:54:26 +0200208 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000209 bool extmap_allow_mixed() const { return extmap_allow_mixed_enum_ != kNo; }
Johannes Kron0854eb62018-10-10 22:33:20 +0200210
Amit Hilbucha2012042018-12-03 11:35:05 -0800211 // Simulcast functionality.
212 virtual bool HasSimulcast() const { return !simulcast_.empty(); }
213 virtual SimulcastDescription& simulcast_description() { return simulcast_; }
214 virtual const SimulcastDescription& simulcast_description() const {
215 return simulcast_;
216 }
217 virtual void set_simulcast_description(
218 const SimulcastDescription& simulcast) {
219 simulcast_ = simulcast;
220 }
221
Steve Antonafd8e8c2017-12-19 16:35:35 -0800222 protected:
223 bool rtcp_mux_ = false;
224 bool rtcp_reduced_size_ = false;
225 int bandwidth_ = kAutoBandwidth;
226 std::string protocol_;
227 std::vector<CryptoParams> cryptos_;
228 std::vector<webrtc::RtpExtension> rtp_header_extensions_;
229 bool rtp_header_extensions_set_ = false;
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800230 StreamParamsVec send_streams_;
Steve Antonafd8e8c2017-12-19 16:35:35 -0800231 bool conference_mode_ = false;
232 webrtc::RtpTransceiverDirection direction_ =
233 webrtc::RtpTransceiverDirection::kSendRecv;
234 rtc::SocketAddress connection_address_;
Johannes Kron0854eb62018-10-10 22:33:20 +0200235 // Mixed one- and two-byte header not included in offer on media level or
236 // session level, but we will respond that we support it. The plan is to add
237 // it to our offer on session level. See todo in SessionDescription.
Johannes Kron9581bc42018-10-23 10:17:39 +0200238 ExtmapAllowMixed extmap_allow_mixed_enum_ = kNo;
Amit Hilbucha2012042018-12-03 11:35:05 -0800239
240 SimulcastDescription simulcast_;
Steve Antonafd8e8c2017-12-19 16:35:35 -0800241};
242
Steve Anton5adfafd2017-12-20 16:34:00 -0800243// TODO(bugs.webrtc.org/8620): Remove this alias once downstream projects have
244// updated.
245using ContentDescription = MediaContentDescription;
246
Steve Antonafd8e8c2017-12-19 16:35:35 -0800247template <class C>
248class MediaContentDescriptionImpl : public MediaContentDescription {
249 public:
250 typedef C CodecType;
251
252 // Codecs should be in preference order (most preferred codec first).
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000253 const std::vector<C>& codecs() const { return codecs_; }
254 void set_codecs(const std::vector<C>& codecs) { codecs_ = codecs; }
255 virtual bool has_codecs() const { return !codecs_.empty(); }
256 bool HasCodec(int id) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800257 bool found = false;
258 for (typename std::vector<C>::iterator iter = codecs_.begin();
259 iter != codecs_.end(); ++iter) {
260 if (iter->id == id) {
261 found = true;
262 break;
263 }
264 }
265 return found;
266 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000267 void AddCodec(const C& codec) { codecs_.push_back(codec); }
268 void AddOrReplaceCodec(const C& codec) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800269 for (typename std::vector<C>::iterator iter = codecs_.begin();
270 iter != codecs_.end(); ++iter) {
271 if (iter->id == codec.id) {
272 *iter = codec;
273 return;
274 }
275 }
276 AddCodec(codec);
277 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000278 void AddCodecs(const std::vector<C>& codecs) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800279 typename std::vector<C>::const_iterator codec;
280 for (codec = codecs.begin(); codec != codecs.end(); ++codec) {
281 AddCodec(*codec);
282 }
283 }
284
285 private:
286 std::vector<C> codecs_;
287};
288
289class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> {
290 public:
291 AudioContentDescription() {}
292
Steve Antonb1c1de12017-12-21 15:14:30 -0800293 virtual AudioContentDescription* Copy() const {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800294 return new AudioContentDescription(*this);
295 }
296 virtual MediaType type() const { return MEDIA_TYPE_AUDIO; }
Steve Anton5adfafd2017-12-20 16:34:00 -0800297 virtual AudioContentDescription* as_audio() { return this; }
298 virtual const AudioContentDescription* as_audio() const { return this; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800299};
300
301class VideoContentDescription : public MediaContentDescriptionImpl<VideoCodec> {
302 public:
Steve Antonb1c1de12017-12-21 15:14:30 -0800303 virtual VideoContentDescription* Copy() const {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800304 return new VideoContentDescription(*this);
305 }
306 virtual MediaType type() const { return MEDIA_TYPE_VIDEO; }
Steve Anton5adfafd2017-12-20 16:34:00 -0800307 virtual VideoContentDescription* as_video() { return this; }
308 virtual const VideoContentDescription* as_video() const { return this; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800309};
310
311class DataContentDescription : public MediaContentDescriptionImpl<DataCodec> {
312 public:
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000313 DataContentDescription() {}
Steve Antonafd8e8c2017-12-19 16:35:35 -0800314
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000315 virtual DataContentDescription* Copy() const {
316 return new DataContentDescription(*this);
Steve Antonafd8e8c2017-12-19 16:35:35 -0800317 }
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000318 virtual MediaType type() const { return MEDIA_TYPE_DATA; }
319 virtual DataContentDescription* as_data() { return this; }
320 virtual const DataContentDescription* as_data() const { return this; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800321
322 bool use_sctpmap() const { return use_sctpmap_; }
323 void set_use_sctpmap(bool enable) { use_sctpmap_ = enable; }
324
325 private:
Harald Alvestrand141c0ad2019-05-05 19:00:00 +0000326 bool use_sctpmap_ = true;
Steve Antonafd8e8c2017-12-19 16:35:35 -0800327};
328
Steve Anton5adfafd2017-12-20 16:34:00 -0800329// Protocol used for encoding media. This is the "top level" protocol that may
330// be wrapped by zero or many transport protocols (UDP, ICE, etc.).
331enum class MediaProtocolType {
332 kRtp, // Section will use the RTP protocol (e.g., for audio or video).
333 // https://tools.ietf.org/html/rfc3550
334 kSctp // Section will use the SCTP protocol (e.g., for a data channel).
335 // https://tools.ietf.org/html/rfc4960
336};
337
338// TODO(bugs.webrtc.org/8620): Remove once downstream projects have updated.
339constexpr MediaProtocolType NS_JINGLE_RTP = MediaProtocolType::kRtp;
340constexpr MediaProtocolType NS_JINGLE_DRAFT_SCTP = MediaProtocolType::kSctp;
341
342// Represents a session description section. Most information about the section
343// is stored in the description, which is a subclass of MediaContentDescription.
Steve Anton4ab68ee2017-12-19 14:26:11 -0800344struct ContentInfo {
Steve Antonb1c1de12017-12-21 15:14:30 -0800345 friend class SessionDescription;
346
Steve Anton5adfafd2017-12-20 16:34:00 -0800347 explicit ContentInfo(MediaProtocolType type) : type(type) {}
348
349 // Alias for |name|.
350 std::string mid() const { return name; }
351 void set_mid(const std::string& mid) { this->name = mid; }
352
353 // Alias for |description|.
354 MediaContentDescription* media_description() { return description; }
355 const MediaContentDescription* media_description() const {
356 return description;
357 }
Steve Anton81712112018-01-05 11:27:54 -0800358 void set_media_description(MediaContentDescription* desc) {
359 description = desc;
Steve Anton5adfafd2017-12-20 16:34:00 -0800360 }
361
Steve Anton81712112018-01-05 11:27:54 -0800362 // TODO(bugs.webrtc.org/8620): Rename this to mid.
Steve Anton4ab68ee2017-12-19 14:26:11 -0800363 std::string name;
Steve Anton5adfafd2017-12-20 16:34:00 -0800364 MediaProtocolType type;
Steve Anton4ab68ee2017-12-19 14:26:11 -0800365 bool rejected = false;
366 bool bundle_only = false;
Steve Anton81712112018-01-05 11:27:54 -0800367 // TODO(bugs.webrtc.org/8620): Switch to the getter and setter, and make this
368 // private.
Steve Antonb1c1de12017-12-21 15:14:30 -0800369 MediaContentDescription* description = nullptr;
Steve Anton4ab68ee2017-12-19 14:26:11 -0800370};
371
372typedef std::vector<std::string> ContentNames;
373
374// This class provides a mechanism to aggregate different media contents into a
375// group. This group can also be shared with the peers in a pre-defined format.
376// GroupInfo should be populated only with the |content_name| of the
377// MediaDescription.
378class ContentGroup {
379 public:
380 explicit ContentGroup(const std::string& semantics);
381 ContentGroup(const ContentGroup&);
382 ContentGroup(ContentGroup&&);
383 ContentGroup& operator=(const ContentGroup&);
384 ContentGroup& operator=(ContentGroup&&);
385 ~ContentGroup();
386
387 const std::string& semantics() const { return semantics_; }
388 const ContentNames& content_names() const { return content_names_; }
389
390 const std::string* FirstContentName() const;
391 bool HasContentName(const std::string& content_name) const;
392 void AddContentName(const std::string& content_name);
393 bool RemoveContentName(const std::string& content_name);
394
395 private:
396 std::string semantics_;
397 ContentNames content_names_;
398};
399
400typedef std::vector<ContentInfo> ContentInfos;
401typedef std::vector<ContentGroup> ContentGroups;
402
403const ContentInfo* FindContentInfoByName(const ContentInfos& contents,
404 const std::string& name);
405const ContentInfo* FindContentInfoByType(const ContentInfos& contents,
406 const std::string& type);
407
Steve Antone831b8c2018-02-01 12:22:16 -0800408// Determines how the MSID will be signaled in the SDP. These can be used as
409// flags to indicate both or none.
410enum MsidSignaling {
411 // Signal MSID with one a=msid line in the media section.
412 kMsidSignalingMediaSection = 0x1,
413 // Signal MSID with a=ssrc: msid lines in the media section.
414 kMsidSignalingSsrcAttribute = 0x2
415};
416
Steve Anton4ab68ee2017-12-19 14:26:11 -0800417// Describes a collection of contents, each with its own name and
418// type. Analogous to a <jingle> or <session> stanza. Assumes that
419// contents are unique be name, but doesn't enforce that.
420class SessionDescription {
421 public:
422 SessionDescription();
Steve Anton4ab68ee2017-12-19 14:26:11 -0800423 ~SessionDescription();
424
Harald Alvestrand4d7160e2019-04-12 07:01:29 +0200425 std::unique_ptr<SessionDescription> Clone() const;
426 // Older API - to be deprecated. Still expects caller to take ownership.
Steve Anton4ab68ee2017-12-19 14:26:11 -0800427 SessionDescription* Copy() const;
428
Piotr (Peter) Slatala13e570f2019-02-27 11:34:26 -0800429 struct MediaTransportSetting;
430
Steve Anton4ab68ee2017-12-19 14:26:11 -0800431 // Content accessors.
432 const ContentInfos& contents() const { return contents_; }
433 ContentInfos& contents() { return contents_; }
434 const ContentInfo* GetContentByName(const std::string& name) const;
435 ContentInfo* GetContentByName(const std::string& name);
Steve Antonb1c1de12017-12-21 15:14:30 -0800436 const MediaContentDescription* GetContentDescriptionByName(
Steve Anton4ab68ee2017-12-19 14:26:11 -0800437 const std::string& name) const;
Steve Antonb1c1de12017-12-21 15:14:30 -0800438 MediaContentDescription* GetContentDescriptionByName(const std::string& name);
Steve Anton5adfafd2017-12-20 16:34:00 -0800439 const ContentInfo* FirstContentByType(MediaProtocolType type) const;
Steve Anton4ab68ee2017-12-19 14:26:11 -0800440 const ContentInfo* FirstContent() const;
441
442 // Content mutators.
443 // Adds a content to this description. Takes ownership of ContentDescription*.
444 void AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800445 MediaProtocolType type,
Steve Antonb1c1de12017-12-21 15:14:30 -0800446 MediaContentDescription* description);
Steve Anton4ab68ee2017-12-19 14:26:11 -0800447 void AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800448 MediaProtocolType type,
Steve Anton4ab68ee2017-12-19 14:26:11 -0800449 bool rejected,
Steve Antonb1c1de12017-12-21 15:14:30 -0800450 MediaContentDescription* description);
Steve Anton4ab68ee2017-12-19 14:26:11 -0800451 void AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800452 MediaProtocolType type,
Steve Anton4ab68ee2017-12-19 14:26:11 -0800453 bool rejected,
454 bool bundle_only,
Steve Antonb1c1de12017-12-21 15:14:30 -0800455 MediaContentDescription* description);
Johannes Kron9ac3c912018-10-12 10:54:26 +0200456 void AddContent(ContentInfo* content);
457
Steve Anton4ab68ee2017-12-19 14:26:11 -0800458 bool RemoveContentByName(const std::string& name);
459
460 // Transport accessors.
461 const TransportInfos& transport_infos() const { return transport_infos_; }
462 TransportInfos& transport_infos() { return transport_infos_; }
463 const TransportInfo* GetTransportInfoByName(const std::string& name) const;
464 TransportInfo* GetTransportInfoByName(const std::string& name);
465 const TransportDescription* GetTransportDescriptionByName(
466 const std::string& name) const {
467 const TransportInfo* tinfo = GetTransportInfoByName(name);
468 return tinfo ? &tinfo->description : NULL;
469 }
470
471 // Transport mutators.
472 void set_transport_infos(const TransportInfos& transport_infos) {
473 transport_infos_ = transport_infos;
474 }
475 // Adds a TransportInfo to this description.
Steve Anton06817cd2018-12-18 15:55:30 -0800476 void AddTransportInfo(const TransportInfo& transport_info);
Steve Anton4ab68ee2017-12-19 14:26:11 -0800477 bool RemoveTransportInfoByName(const std::string& name);
478
479 // Group accessors.
480 const ContentGroups& groups() const { return content_groups_; }
481 const ContentGroup* GetGroupByName(const std::string& name) const;
482 bool HasGroup(const std::string& name) const;
483
484 // Group mutators.
485 void AddGroup(const ContentGroup& group) { content_groups_.push_back(group); }
486 // Remove the first group with the same semantics specified by |name|.
487 void RemoveGroupByName(const std::string& name);
488
489 // Global attributes.
490 void set_msid_supported(bool supported) { msid_supported_ = supported; }
491 bool msid_supported() const { return msid_supported_; }
492
Steve Antone831b8c2018-02-01 12:22:16 -0800493 // Determines how the MSIDs were/will be signaled. Flag value composed of
494 // MsidSignaling bits (see enum above).
495 void set_msid_signaling(int msid_signaling) {
496 msid_signaling_ = msid_signaling;
497 }
498 int msid_signaling() const { return msid_signaling_; }
499
Johannes Kron0854eb62018-10-10 22:33:20 +0200500 // Determines if it's allowed to mix one- and two-byte rtp header extensions
501 // within the same rtp stream.
Johannes Kron9581bc42018-10-23 10:17:39 +0200502 void set_extmap_allow_mixed(bool supported) {
503 extmap_allow_mixed_ = supported;
504 MediaContentDescription::ExtmapAllowMixed media_level_setting =
Johannes Kron0854eb62018-10-10 22:33:20 +0200505 supported ? MediaContentDescription::kSession
506 : MediaContentDescription::kNo;
507 for (auto& content : contents_) {
Johannes Kron9ac3c912018-10-12 10:54:26 +0200508 // Do not set to kNo if the current setting is kMedia.
Johannes Kron9581bc42018-10-23 10:17:39 +0200509 if (supported || content.media_description()->extmap_allow_mixed_enum() !=
510 MediaContentDescription::kMedia) {
511 content.media_description()->set_extmap_allow_mixed_enum(
Johannes Kron9ac3c912018-10-12 10:54:26 +0200512 media_level_setting);
513 }
Johannes Kron0854eb62018-10-10 22:33:20 +0200514 }
515 }
Johannes Kron9581bc42018-10-23 10:17:39 +0200516 bool extmap_allow_mixed() const { return extmap_allow_mixed_; }
Johannes Kron0854eb62018-10-10 22:33:20 +0200517
Piotr (Peter) Slatala13e570f2019-02-27 11:34:26 -0800518 // Adds the media transport setting.
519 // Media transport name uniquely identifies the type of media transport.
520 // The name cannot be empty, or repeated in the previously added transport
521 // settings.
522 void AddMediaTransportSetting(const std::string& media_transport_name,
523 const std::string& media_transport_setting) {
524 RTC_DCHECK(!media_transport_name.empty());
525 for (const auto& setting : media_transport_settings_) {
526 RTC_DCHECK(media_transport_name != setting.transport_name)
527 << "MediaTransportSetting was already registered, transport_name="
528 << setting.transport_name;
529 }
530 media_transport_settings_.push_back(
531 {media_transport_name, media_transport_setting});
532 }
533
534 // Gets the media transport settings, in order of preference.
535 const std::vector<MediaTransportSetting>& MediaTransportSettings() const {
536 return media_transport_settings_;
537 }
538
539 struct MediaTransportSetting {
540 std::string transport_name;
541 std::string transport_setting;
542 };
543
Steve Anton4ab68ee2017-12-19 14:26:11 -0800544 private:
545 SessionDescription(const SessionDescription&);
546
547 ContentInfos contents_;
548 TransportInfos transport_infos_;
549 ContentGroups content_groups_;
550 bool msid_supported_ = true;
Steve Antone831b8c2018-02-01 12:22:16 -0800551 // Default to what Plan B would do.
552 // TODO(bugs.webrtc.org/8530): Change default to kMsidSignalingMediaSection.
553 int msid_signaling_ = kMsidSignalingSsrcAttribute;
Johannes Kron89f874e2018-11-12 10:25:48 +0100554 // TODO(webrtc:9985): Activate mixed one- and two-byte header extension in
555 // offer at session level. It's currently not included in offer by default
556 // because clients prior to https://bugs.webrtc.org/9712 cannot parse this
557 // correctly. If it's included in offer to us we will respond that we support
558 // it.
Johannes Kron9581bc42018-10-23 10:17:39 +0200559 bool extmap_allow_mixed_ = false;
Piotr (Peter) Slatala13e570f2019-02-27 11:34:26 -0800560
561 std::vector<MediaTransportSetting> media_transport_settings_;
Steve Anton4ab68ee2017-12-19 14:26:11 -0800562};
563
Steve Antonb1c1de12017-12-21 15:14:30 -0800564// Indicates whether a session description was sent by the local client or
565// received from the remote client.
Steve Anton4ab68ee2017-12-19 14:26:11 -0800566enum ContentSource { CS_LOCAL, CS_REMOTE };
567
568} // namespace cricket
569
Steve Anton10542f22019-01-11 09:11:00 -0800570#endif // PC_SESSION_DESCRIPTION_H_