blob: 27b781f385c895741d3a439f70ec934511b95486 [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
Harald Alvestrand5fc28b12019-05-13 13:36:16 +020021#include "absl/memory/memory.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "api/crypto_params.h"
23#include "api/media_types.h"
24#include "api/rtp_parameters.h"
25#include "api/rtp_transceiver_interface.h"
26#include "media/base/media_channel.h"
27#include "media/base/stream_params.h"
28#include "p2p/base/transport_description.h"
29#include "p2p/base/transport_info.h"
Harald Alvestrand5fc28b12019-05-13 13:36:16 +020030#include "pc/media_protocol_names.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "pc/simulcast_description.h"
Harald Alvestrand8da35a62019-05-10 09:31:04 +020032#include "rtc_base/deprecation.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "rtc_base/socket_address.h"
Steve Anton4ab68ee2017-12-19 14:26:11 -080034
35namespace cricket {
36
Steve Antonafd8e8c2017-12-19 16:35:35 -080037typedef std::vector<AudioCodec> AudioCodecs;
38typedef std::vector<VideoCodec> VideoCodecs;
Harald Alvestrand5fc28b12019-05-13 13:36:16 +020039typedef std::vector<RtpDataCodec> RtpDataCodecs;
Steve Antonafd8e8c2017-12-19 16:35:35 -080040typedef std::vector<CryptoParams> CryptoParamsVec;
41typedef std::vector<webrtc::RtpExtension> RtpHeaderExtensions;
42
43// RTC4585 RTP/AVPF
44extern const char kMediaProtocolAvpf[];
45// RFC5124 RTP/SAVPF
46extern const char kMediaProtocolSavpf[];
47
48extern const char kMediaProtocolDtlsSavpf[];
49
Steve Antonafd8e8c2017-12-19 16:35:35 -080050
51// Options to control how session descriptions are generated.
52const int kAutoBandwidth = -1;
53
Steve Anton5adfafd2017-12-20 16:34:00 -080054class AudioContentDescription;
Steve Anton46afbf92019-05-10 11:15:18 -070055class VideoContentDescription;
Harald Alvestrand5fc28b12019-05-13 13:36:16 +020056class DataContentDescription;
57class RtpDataContentDescription;
58class SctpDataContentDescription;
Steve Anton4ab68ee2017-12-19 14:26:11 -080059
Steve Anton5adfafd2017-12-20 16:34:00 -080060// Describes a session description media section. There are subclasses for each
61// media type (audio, video, data) that will have additional information.
62class MediaContentDescription {
Steve Antonafd8e8c2017-12-19 16:35:35 -080063 public:
Steve Anton5adfafd2017-12-20 16:34:00 -080064 MediaContentDescription() = default;
65 virtual ~MediaContentDescription() = default;
Steve Antonafd8e8c2017-12-19 16:35:35 -080066
67 virtual MediaType type() const = 0;
Steve Anton5adfafd2017-12-20 16:34:00 -080068
69 // Try to cast this media description to an AudioContentDescription. Returns
70 // nullptr if the cast fails.
71 virtual AudioContentDescription* as_audio() { return nullptr; }
72 virtual const AudioContentDescription* as_audio() const { return nullptr; }
73
74 // Try to cast this media description to a VideoContentDescription. Returns
75 // nullptr if the cast fails.
76 virtual VideoContentDescription* as_video() { return nullptr; }
77 virtual const VideoContentDescription* as_video() const { return nullptr; }
78
Harald Alvestrand5fc28b12019-05-13 13:36:16 +020079 // Backwards compatible shim: Return a shim object that allows
80 // callers to ignore the distinction between RtpDataContentDescription
81 // and SctpDataContentDescription objects.
Steve Anton5adfafd2017-12-20 16:34:00 -080082 virtual DataContentDescription* as_data() { return nullptr; }
83 virtual const DataContentDescription* as_data() const { return nullptr; }
84
Harald Alvestrand5fc28b12019-05-13 13:36:16 +020085 virtual RtpDataContentDescription* as_rtp_data() { return nullptr; }
86 virtual const RtpDataContentDescription* as_rtp_data() const {
87 return nullptr;
88 }
89
90 virtual SctpDataContentDescription* as_sctp() { return nullptr; }
91 virtual const SctpDataContentDescription* as_sctp() const { return nullptr; }
92
Steve Antonafd8e8c2017-12-19 16:35:35 -080093 virtual bool has_codecs() const = 0;
94
Steve Anton5adfafd2017-12-20 16:34:00 -080095 virtual MediaContentDescription* Copy() const = 0;
96
Steve Antonafd8e8c2017-12-19 16:35:35 -080097 // |protocol| is the expected media transport protocol, such as RTP/AVPF,
98 // RTP/SAVPF or SCTP/DTLS.
Harald Alvestrand5fc28b12019-05-13 13:36:16 +020099 virtual std::string protocol() const { return protocol_; }
100 virtual void set_protocol(const std::string& protocol) {
101 protocol_ = protocol;
102 }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800103
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200104 virtual webrtc::RtpTransceiverDirection direction() const {
105 return direction_;
106 }
107 virtual void set_direction(webrtc::RtpTransceiverDirection direction) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800108 direction_ = direction;
109 }
110
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200111 virtual bool rtcp_mux() const { return rtcp_mux_; }
112 virtual void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800113
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200114 virtual bool rtcp_reduced_size() const { return rtcp_reduced_size_; }
115 virtual void set_rtcp_reduced_size(bool reduced_size) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800116 rtcp_reduced_size_ = reduced_size;
117 }
118
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200119 virtual int bandwidth() const { return bandwidth_; }
120 virtual void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800121
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200122 virtual const std::vector<CryptoParams>& cryptos() const { return cryptos_; }
123 virtual void AddCrypto(const CryptoParams& params) {
124 cryptos_.push_back(params);
125 }
126 virtual void set_cryptos(const std::vector<CryptoParams>& cryptos) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800127 cryptos_ = cryptos;
128 }
129
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200130 virtual const RtpHeaderExtensions& rtp_header_extensions() const {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800131 return rtp_header_extensions_;
132 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200133 virtual void set_rtp_header_extensions(
134 const RtpHeaderExtensions& extensions) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800135 rtp_header_extensions_ = extensions;
136 rtp_header_extensions_set_ = true;
137 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200138 virtual void AddRtpHeaderExtension(const webrtc::RtpExtension& ext) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800139 rtp_header_extensions_.push_back(ext);
140 rtp_header_extensions_set_ = true;
141 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200142 virtual void AddRtpHeaderExtension(const cricket::RtpHeaderExtension& ext) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800143 webrtc::RtpExtension webrtc_extension;
144 webrtc_extension.uri = ext.uri;
145 webrtc_extension.id = ext.id;
146 rtp_header_extensions_.push_back(webrtc_extension);
147 rtp_header_extensions_set_ = true;
148 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200149 virtual void ClearRtpHeaderExtensions() {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800150 rtp_header_extensions_.clear();
151 rtp_header_extensions_set_ = true;
152 }
153 // We can't always tell if an empty list of header extensions is
154 // because the other side doesn't support them, or just isn't hooked up to
155 // signal them. For now we assume an empty list means no signaling, but
156 // provide the ClearRtpHeaderExtensions method to allow "no support" to be
157 // clearly indicated (i.e. when derived from other information).
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200158 virtual bool rtp_header_extensions_set() const {
159 return rtp_header_extensions_set_;
160 }
161 virtual const StreamParamsVec& streams() const { return send_streams_; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800162 // TODO(pthatcher): Remove this by giving mediamessage.cc access
163 // to MediaContentDescription
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200164 virtual StreamParamsVec& mutable_streams() { return send_streams_; }
165 virtual void AddStream(const StreamParams& stream) {
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800166 send_streams_.push_back(stream);
167 }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800168 // Legacy streams have an ssrc, but nothing else.
169 void AddLegacyStream(uint32_t ssrc) {
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200170 AddStream(StreamParams::CreateLegacy(ssrc));
Steve Antonafd8e8c2017-12-19 16:35:35 -0800171 }
172 void AddLegacyStream(uint32_t ssrc, uint32_t fid_ssrc) {
173 StreamParams sp = StreamParams::CreateLegacy(ssrc);
174 sp.AddFidSsrc(ssrc, fid_ssrc);
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200175 AddStream(sp);
Steve Antonafd8e8c2017-12-19 16:35:35 -0800176 }
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800177
Steve Antonafd8e8c2017-12-19 16:35:35 -0800178 // Sets the CNAME of all StreamParams if it have not been set.
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200179 virtual void SetCnameIfEmpty(const std::string& cname) {
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800180 for (cricket::StreamParamsVec::iterator it = send_streams_.begin();
181 it != send_streams_.end(); ++it) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800182 if (it->cname.empty())
183 it->cname = cname;
184 }
185 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200186 virtual uint32_t first_ssrc() const {
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800187 if (send_streams_.empty()) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800188 return 0;
189 }
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800190 return send_streams_[0].first_ssrc();
Steve Antonafd8e8c2017-12-19 16:35:35 -0800191 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200192 virtual bool has_ssrcs() const {
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800193 if (send_streams_.empty()) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800194 return false;
195 }
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800196 return send_streams_[0].has_ssrcs();
Steve Antonafd8e8c2017-12-19 16:35:35 -0800197 }
198
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200199 virtual void set_conference_mode(bool enable) { conference_mode_ = enable; }
200 virtual bool conference_mode() const { return conference_mode_; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800201
202 // https://tools.ietf.org/html/rfc4566#section-5.7
203 // May be present at the media or session level of SDP. If present at both
204 // levels, the media-level attribute overwrites the session-level one.
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200205 virtual void set_connection_address(const rtc::SocketAddress& address) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800206 connection_address_ = address;
207 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200208 virtual const rtc::SocketAddress& connection_address() const {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800209 return connection_address_;
210 }
211
Johannes Kron0854eb62018-10-10 22:33:20 +0200212 // Determines if it's allowed to mix one- and two-byte rtp header extensions
213 // within the same rtp stream.
Johannes Kron9581bc42018-10-23 10:17:39 +0200214 enum ExtmapAllowMixed { kNo, kSession, kMedia };
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200215 virtual void set_extmap_allow_mixed_enum(
216 ExtmapAllowMixed new_extmap_allow_mixed) {
Johannes Kron9ac3c912018-10-12 10:54:26 +0200217 if (new_extmap_allow_mixed == kMedia &&
Johannes Kron9581bc42018-10-23 10:17:39 +0200218 extmap_allow_mixed_enum_ == kSession) {
Johannes Kron0854eb62018-10-10 22:33:20 +0200219 // Do not downgrade from session level to media level.
220 return;
221 }
Johannes Kron9581bc42018-10-23 10:17:39 +0200222 extmap_allow_mixed_enum_ = new_extmap_allow_mixed;
Johannes Kron0854eb62018-10-10 22:33:20 +0200223 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200224 virtual ExtmapAllowMixed extmap_allow_mixed_enum() const {
Johannes Kron9581bc42018-10-23 10:17:39 +0200225 return extmap_allow_mixed_enum_;
Johannes Kron9ac3c912018-10-12 10:54:26 +0200226 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200227 virtual bool extmap_allow_mixed() const {
228 return extmap_allow_mixed_enum_ != kNo;
229 }
Johannes Kron0854eb62018-10-10 22:33:20 +0200230
Amit Hilbucha2012042018-12-03 11:35:05 -0800231 // Simulcast functionality.
232 virtual bool HasSimulcast() const { return !simulcast_.empty(); }
233 virtual SimulcastDescription& simulcast_description() { return simulcast_; }
234 virtual const SimulcastDescription& simulcast_description() const {
235 return simulcast_;
236 }
237 virtual void set_simulcast_description(
238 const SimulcastDescription& simulcast) {
239 simulcast_ = simulcast;
240 }
241
Steve Antonafd8e8c2017-12-19 16:35:35 -0800242 protected:
243 bool rtcp_mux_ = false;
244 bool rtcp_reduced_size_ = false;
245 int bandwidth_ = kAutoBandwidth;
246 std::string protocol_;
247 std::vector<CryptoParams> cryptos_;
248 std::vector<webrtc::RtpExtension> rtp_header_extensions_;
249 bool rtp_header_extensions_set_ = false;
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800250 StreamParamsVec send_streams_;
Steve Antonafd8e8c2017-12-19 16:35:35 -0800251 bool conference_mode_ = false;
252 webrtc::RtpTransceiverDirection direction_ =
253 webrtc::RtpTransceiverDirection::kSendRecv;
254 rtc::SocketAddress connection_address_;
Johannes Kron0854eb62018-10-10 22:33:20 +0200255 // Mixed one- and two-byte header not included in offer on media level or
256 // session level, but we will respond that we support it. The plan is to add
257 // it to our offer on session level. See todo in SessionDescription.
Johannes Kron9581bc42018-10-23 10:17:39 +0200258 ExtmapAllowMixed extmap_allow_mixed_enum_ = kNo;
Amit Hilbucha2012042018-12-03 11:35:05 -0800259
260 SimulcastDescription simulcast_;
Steve Antonafd8e8c2017-12-19 16:35:35 -0800261};
262
Steve Anton5adfafd2017-12-20 16:34:00 -0800263// TODO(bugs.webrtc.org/8620): Remove this alias once downstream projects have
264// updated.
265using ContentDescription = MediaContentDescription;
266
Steve Antonafd8e8c2017-12-19 16:35:35 -0800267template <class C>
268class MediaContentDescriptionImpl : public MediaContentDescription {
269 public:
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200270 void set_protocol(const std::string& protocol) override {
271 RTC_DCHECK(IsRtpProtocol(protocol));
272 protocol_ = protocol;
273 }
274
Steve Antonafd8e8c2017-12-19 16:35:35 -0800275 typedef C CodecType;
276
277 // Codecs should be in preference order (most preferred codec first).
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200278 virtual const std::vector<C>& codecs() const { return codecs_; }
279 virtual void set_codecs(const std::vector<C>& codecs) { codecs_ = codecs; }
280 bool has_codecs() const override { return !codecs_.empty(); }
281 virtual bool HasCodec(int id) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800282 bool found = false;
283 for (typename std::vector<C>::iterator iter = codecs_.begin();
284 iter != codecs_.end(); ++iter) {
285 if (iter->id == id) {
286 found = true;
287 break;
288 }
289 }
290 return found;
291 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200292 virtual void AddCodec(const C& codec) { codecs_.push_back(codec); }
293 virtual void AddOrReplaceCodec(const C& codec) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800294 for (typename std::vector<C>::iterator iter = codecs_.begin();
295 iter != codecs_.end(); ++iter) {
296 if (iter->id == codec.id) {
297 *iter = codec;
298 return;
299 }
300 }
301 AddCodec(codec);
302 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200303 virtual void AddCodecs(const std::vector<C>& codecs) {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800304 typename std::vector<C>::const_iterator codec;
305 for (codec = codecs.begin(); codec != codecs.end(); ++codec) {
306 AddCodec(*codec);
307 }
308 }
309
310 private:
311 std::vector<C> codecs_;
312};
313
314class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> {
315 public:
316 AudioContentDescription() {}
317
Steve Antonb1c1de12017-12-21 15:14:30 -0800318 virtual AudioContentDescription* Copy() const {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800319 return new AudioContentDescription(*this);
320 }
321 virtual MediaType type() const { return MEDIA_TYPE_AUDIO; }
Steve Anton5adfafd2017-12-20 16:34:00 -0800322 virtual AudioContentDescription* as_audio() { return this; }
323 virtual const AudioContentDescription* as_audio() const { return this; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800324};
325
326class VideoContentDescription : public MediaContentDescriptionImpl<VideoCodec> {
327 public:
Steve Antonb1c1de12017-12-21 15:14:30 -0800328 virtual VideoContentDescription* Copy() const {
Steve Antonafd8e8c2017-12-19 16:35:35 -0800329 return new VideoContentDescription(*this);
330 }
331 virtual MediaType type() const { return MEDIA_TYPE_VIDEO; }
Steve Anton5adfafd2017-12-20 16:34:00 -0800332 virtual VideoContentDescription* as_video() { return this; }
333 virtual const VideoContentDescription* as_video() const { return this; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800334};
335
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200336// The DataContentDescription is a shim over the RtpDataContentDescription
337// and SctpDataContentDescription classes that is used for external callers
338// into this internal API.
339// It is a templated derivation of MediaContentDescriptionImpl because
340// that's what the external caller expects it to be.
341// TODO(bugs.webrtc.org/10597): Declare this class obsolete and remove it
342// once external callers have been updated.
Steve Antonafd8e8c2017-12-19 16:35:35 -0800343class DataContentDescription : public MediaContentDescriptionImpl<DataCodec> {
344 public:
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200345 DataContentDescription();
346 MediaType type() const override { return MEDIA_TYPE_DATA; }
347 DataContentDescription* as_data() override { return this; }
348 const DataContentDescription* as_data() const override { return this; }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800349
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200350 // Override all methods defined in MediaContentDescription.
351 bool has_codecs() const override;
352 DataContentDescription* Copy() const override {
353 return new DataContentDescription(this);
Steve Antonafd8e8c2017-12-19 16:35:35 -0800354 }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200355 std::string protocol() const override;
356 void set_protocol(const std::string& protocol) override;
357 webrtc::RtpTransceiverDirection direction() const override;
358 void set_direction(webrtc::RtpTransceiverDirection direction) override;
359 bool rtcp_mux() const override;
360 void set_rtcp_mux(bool mux) override;
361 bool rtcp_reduced_size() const override;
362 void set_rtcp_reduced_size(bool) override;
363 int bandwidth() const override;
364 void set_bandwidth(int bandwidth) override;
365 const std::vector<CryptoParams>& cryptos() const override;
366 void AddCrypto(const CryptoParams& params) override;
367 void set_cryptos(const std::vector<CryptoParams>& cryptos) override;
368 const RtpHeaderExtensions& rtp_header_extensions() const override;
369 void set_rtp_header_extensions(
370 const RtpHeaderExtensions& extensions) override;
371 void AddRtpHeaderExtension(const webrtc::RtpExtension& ext) override;
372 void AddRtpHeaderExtension(const cricket::RtpHeaderExtension& ext) override;
373 void ClearRtpHeaderExtensions() override;
374 bool rtp_header_extensions_set() const override;
375 const StreamParamsVec& streams() const override;
376 StreamParamsVec& mutable_streams() override;
377 void AddStream(const StreamParams& stream) override;
378 void SetCnameIfEmpty(const std::string& cname) override;
379 uint32_t first_ssrc() const override;
380 bool has_ssrcs() const override;
381 void set_conference_mode(bool enable) override;
382 bool conference_mode() const override;
383 void set_connection_address(const rtc::SocketAddress& address) override;
384 const rtc::SocketAddress& connection_address() const override;
385 void set_extmap_allow_mixed_enum(ExtmapAllowMixed) override;
386 ExtmapAllowMixed extmap_allow_mixed_enum() const override;
387 bool HasSimulcast() const override;
388 SimulcastDescription& simulcast_description() override;
389 const SimulcastDescription& simulcast_description() const override;
390 void set_simulcast_description(
391 const SimulcastDescription& simulcast) override;
392
393 // Override all methods defined in MediaContentDescriptionImpl.
394 const std::vector<CodecType>& codecs() const override;
395 void set_codecs(const std::vector<CodecType>& codecs) override;
396 bool HasCodec(int id) override;
397 void AddCodec(const CodecType& codec) override;
398 void AddOrReplaceCodec(const CodecType& codec) override;
399 void AddCodecs(const std::vector<CodecType>& codec) override;
400
401 private:
402 typedef MediaContentDescriptionImpl<DataCodec> Super;
403 // Friend classes are allowed to create proxies for themselves.
404 friend class RtpDataContentDescription; // for constructors
405 friend class SctpDataContentDescription;
406 friend class SessionDescription; // for Unshim()
407 // Copy constructor. A copy results in an object that owns its
408 // real description, which is a copy of the original description
409 // (whether that was owned or not).
410 explicit DataContentDescription(const DataContentDescription* o);
411
412 explicit DataContentDescription(RtpDataContentDescription*);
413 explicit DataContentDescription(SctpDataContentDescription*);
414
415 // Exposed for internal use - new clients should not use this class.
416 RtpDataContentDescription* as_rtp_data() override;
417 SctpDataContentDescription* as_sctp() override;
418
419 // Create a shimmed object, owned by the shim.
420 void CreateShimTarget(bool is_sctp);
421
422 // Return the shimmed object, passing ownership if owned, and set
423 // |should_delete| to true if it was the owner. If |should_delete|
424 // is true on return, the caller should immediately delete the
425 // DataContentDescription object.
426 MediaContentDescription* Unshim(bool* should_delete);
427
428 // Returns whether SCTP is in use. False when it's not decided.
429 bool IsSctp() const;
430 // Check function for use when caller obviously assumes RTP.
431 void EnsureIsRtp();
432
433 MediaContentDescription* real_description_ = nullptr;
434 std::unique_ptr<MediaContentDescription> owned_description_;
435};
436
437class RtpDataContentDescription
438 : public MediaContentDescriptionImpl<RtpDataCodec> {
439 public:
440 RtpDataContentDescription() {}
441 RtpDataContentDescription(const RtpDataContentDescription& o)
442 : MediaContentDescriptionImpl<RtpDataCodec>(o), shim_(nullptr) {}
443 RtpDataContentDescription& operator=(const RtpDataContentDescription& o) {
444 this->MediaContentDescriptionImpl<RtpDataCodec>::operator=(o);
445 // Do not copy the shim.
446 return *this;
447 }
448
449 RtpDataContentDescription* Copy() const override {
450 return new RtpDataContentDescription(*this);
451 }
452 MediaType type() const override { return MEDIA_TYPE_DATA; }
453 RtpDataContentDescription* as_rtp_data() override { return this; }
454 const RtpDataContentDescription* as_rtp_data() const override { return this; }
455 // Shim support
456 DataContentDescription* as_data() override;
457 const DataContentDescription* as_data() const override;
458
459 private:
460 std::unique_ptr<DataContentDescription> shim_;
461};
462
463class SctpDataContentDescription : public MediaContentDescription {
464 public:
465 SctpDataContentDescription() {}
466 SctpDataContentDescription(const SctpDataContentDescription& o)
467 : MediaContentDescription(o),
468 use_sctpmap_(o.use_sctpmap_),
469 port_(o.port_),
470 max_message_size_(o.max_message_size_),
471 shim_(nullptr) {}
472 SctpDataContentDescription* Copy() const override {
473 return new SctpDataContentDescription(*this);
474 }
475 MediaType type() const override { return MEDIA_TYPE_DATA; }
476 SctpDataContentDescription* as_sctp() override { return this; }
477 const SctpDataContentDescription* as_sctp() const override { return this; }
478 // Shim support
479 DataContentDescription* as_data() override;
480 const DataContentDescription* as_data() const override;
481
482 bool has_codecs() const override { return false; }
483 void set_protocol(const std::string& protocol) override {
484 RTC_DCHECK(IsSctpProtocol(protocol));
485 protocol_ = protocol;
486 }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800487
488 bool use_sctpmap() const { return use_sctpmap_; }
489 void set_use_sctpmap(bool enable) { use_sctpmap_ = enable; }
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200490 int port() const { return port_; }
491 void set_port(int port) { port_ = port; }
492 int max_message_size() const { return max_message_size_; }
493 void set_max_message_size(int max_message_size) {
494 max_message_size_ = max_message_size;
495 }
Steve Antonafd8e8c2017-12-19 16:35:35 -0800496
497 private:
Harald Alvestrand5fc28b12019-05-13 13:36:16 +0200498 bool use_sctpmap_ = true; // Note: "true" is no longer conformant.
499 // Defaults should be constants imported from SCTP. Quick hack.
500 int port_ = 5000;
501 int max_message_size_ = 256 * 1024;
502 std::unique_ptr<DataContentDescription> shim_;
Steve Antonafd8e8c2017-12-19 16:35:35 -0800503};
504
Steve Anton5adfafd2017-12-20 16:34:00 -0800505// Protocol used for encoding media. This is the "top level" protocol that may
506// be wrapped by zero or many transport protocols (UDP, ICE, etc.).
507enum class MediaProtocolType {
508 kRtp, // Section will use the RTP protocol (e.g., for audio or video).
509 // https://tools.ietf.org/html/rfc3550
510 kSctp // Section will use the SCTP protocol (e.g., for a data channel).
511 // https://tools.ietf.org/html/rfc4960
512};
513
514// TODO(bugs.webrtc.org/8620): Remove once downstream projects have updated.
515constexpr MediaProtocolType NS_JINGLE_RTP = MediaProtocolType::kRtp;
516constexpr MediaProtocolType NS_JINGLE_DRAFT_SCTP = MediaProtocolType::kSctp;
517
518// Represents a session description section. Most information about the section
519// is stored in the description, which is a subclass of MediaContentDescription.
Steve Anton4ab68ee2017-12-19 14:26:11 -0800520struct ContentInfo {
Steve Antonb1c1de12017-12-21 15:14:30 -0800521 friend class SessionDescription;
522
Steve Anton5adfafd2017-12-20 16:34:00 -0800523 explicit ContentInfo(MediaProtocolType type) : type(type) {}
524
525 // Alias for |name|.
526 std::string mid() const { return name; }
527 void set_mid(const std::string& mid) { this->name = mid; }
528
529 // Alias for |description|.
530 MediaContentDescription* media_description() { return description; }
531 const MediaContentDescription* media_description() const {
532 return description;
533 }
Steve Anton81712112018-01-05 11:27:54 -0800534 void set_media_description(MediaContentDescription* desc) {
535 description = desc;
Steve Anton5adfafd2017-12-20 16:34:00 -0800536 }
537
Steve Anton81712112018-01-05 11:27:54 -0800538 // TODO(bugs.webrtc.org/8620): Rename this to mid.
Steve Anton4ab68ee2017-12-19 14:26:11 -0800539 std::string name;
Steve Anton5adfafd2017-12-20 16:34:00 -0800540 MediaProtocolType type;
Steve Anton4ab68ee2017-12-19 14:26:11 -0800541 bool rejected = false;
542 bool bundle_only = false;
Steve Anton81712112018-01-05 11:27:54 -0800543 // TODO(bugs.webrtc.org/8620): Switch to the getter and setter, and make this
544 // private.
Steve Antonb1c1de12017-12-21 15:14:30 -0800545 MediaContentDescription* description = nullptr;
Steve Anton4ab68ee2017-12-19 14:26:11 -0800546};
547
548typedef std::vector<std::string> ContentNames;
549
550// This class provides a mechanism to aggregate different media contents into a
551// group. This group can also be shared with the peers in a pre-defined format.
552// GroupInfo should be populated only with the |content_name| of the
553// MediaDescription.
554class ContentGroup {
555 public:
556 explicit ContentGroup(const std::string& semantics);
557 ContentGroup(const ContentGroup&);
558 ContentGroup(ContentGroup&&);
559 ContentGroup& operator=(const ContentGroup&);
560 ContentGroup& operator=(ContentGroup&&);
561 ~ContentGroup();
562
563 const std::string& semantics() const { return semantics_; }
564 const ContentNames& content_names() const { return content_names_; }
565
566 const std::string* FirstContentName() const;
567 bool HasContentName(const std::string& content_name) const;
568 void AddContentName(const std::string& content_name);
569 bool RemoveContentName(const std::string& content_name);
570
571 private:
572 std::string semantics_;
573 ContentNames content_names_;
574};
575
576typedef std::vector<ContentInfo> ContentInfos;
577typedef std::vector<ContentGroup> ContentGroups;
578
579const ContentInfo* FindContentInfoByName(const ContentInfos& contents,
580 const std::string& name);
581const ContentInfo* FindContentInfoByType(const ContentInfos& contents,
582 const std::string& type);
583
Steve Antone831b8c2018-02-01 12:22:16 -0800584// Determines how the MSID will be signaled in the SDP. These can be used as
585// flags to indicate both or none.
586enum MsidSignaling {
587 // Signal MSID with one a=msid line in the media section.
588 kMsidSignalingMediaSection = 0x1,
589 // Signal MSID with a=ssrc: msid lines in the media section.
590 kMsidSignalingSsrcAttribute = 0x2
591};
592
Steve Anton4ab68ee2017-12-19 14:26:11 -0800593// Describes a collection of contents, each with its own name and
594// type. Analogous to a <jingle> or <session> stanza. Assumes that
595// contents are unique be name, but doesn't enforce that.
596class SessionDescription {
597 public:
598 SessionDescription();
Steve Anton4ab68ee2017-12-19 14:26:11 -0800599 ~SessionDescription();
600
Harald Alvestrand4d7160e2019-04-12 07:01:29 +0200601 std::unique_ptr<SessionDescription> Clone() const;
Harald Alvestrand8da35a62019-05-10 09:31:04 +0200602 // Older API - deprecated. Still expects caller to take ownership.
603 // Replace with Clone().
604 RTC_DEPRECATED SessionDescription* Copy() const;
Steve Anton4ab68ee2017-12-19 14:26:11 -0800605
Piotr (Peter) Slatala13e570f2019-02-27 11:34:26 -0800606 struct MediaTransportSetting;
607
Steve Anton4ab68ee2017-12-19 14:26:11 -0800608 // Content accessors.
609 const ContentInfos& contents() const { return contents_; }
610 ContentInfos& contents() { return contents_; }
611 const ContentInfo* GetContentByName(const std::string& name) const;
612 ContentInfo* GetContentByName(const std::string& name);
Steve Antonb1c1de12017-12-21 15:14:30 -0800613 const MediaContentDescription* GetContentDescriptionByName(
Steve Anton4ab68ee2017-12-19 14:26:11 -0800614 const std::string& name) const;
Steve Antonb1c1de12017-12-21 15:14:30 -0800615 MediaContentDescription* GetContentDescriptionByName(const std::string& name);
Steve Anton5adfafd2017-12-20 16:34:00 -0800616 const ContentInfo* FirstContentByType(MediaProtocolType type) const;
Steve Anton4ab68ee2017-12-19 14:26:11 -0800617 const ContentInfo* FirstContent() const;
618
619 // Content mutators.
620 // Adds a content to this description. Takes ownership of ContentDescription*.
621 void AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800622 MediaProtocolType type,
Steve Antonb1c1de12017-12-21 15:14:30 -0800623 MediaContentDescription* description);
Steve Anton4ab68ee2017-12-19 14:26:11 -0800624 void AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800625 MediaProtocolType type,
Steve Anton4ab68ee2017-12-19 14:26:11 -0800626 bool rejected,
Steve Antonb1c1de12017-12-21 15:14:30 -0800627 MediaContentDescription* description);
Steve Anton4ab68ee2017-12-19 14:26:11 -0800628 void AddContent(const std::string& name,
Steve Anton5adfafd2017-12-20 16:34:00 -0800629 MediaProtocolType type,
Steve Anton4ab68ee2017-12-19 14:26:11 -0800630 bool rejected,
631 bool bundle_only,
Steve Antonb1c1de12017-12-21 15:14:30 -0800632 MediaContentDescription* description);
Johannes Kron9ac3c912018-10-12 10:54:26 +0200633 void AddContent(ContentInfo* content);
634
Steve Anton4ab68ee2017-12-19 14:26:11 -0800635 bool RemoveContentByName(const std::string& name);
636
637 // Transport accessors.
638 const TransportInfos& transport_infos() const { return transport_infos_; }
639 TransportInfos& transport_infos() { return transport_infos_; }
640 const TransportInfo* GetTransportInfoByName(const std::string& name) const;
641 TransportInfo* GetTransportInfoByName(const std::string& name);
642 const TransportDescription* GetTransportDescriptionByName(
643 const std::string& name) const {
644 const TransportInfo* tinfo = GetTransportInfoByName(name);
645 return tinfo ? &tinfo->description : NULL;
646 }
647
648 // Transport mutators.
649 void set_transport_infos(const TransportInfos& transport_infos) {
650 transport_infos_ = transport_infos;
651 }
652 // Adds a TransportInfo to this description.
Steve Anton06817cd2018-12-18 15:55:30 -0800653 void AddTransportInfo(const TransportInfo& transport_info);
Steve Anton4ab68ee2017-12-19 14:26:11 -0800654 bool RemoveTransportInfoByName(const std::string& name);
655
656 // Group accessors.
657 const ContentGroups& groups() const { return content_groups_; }
658 const ContentGroup* GetGroupByName(const std::string& name) const;
659 bool HasGroup(const std::string& name) const;
660
661 // Group mutators.
662 void AddGroup(const ContentGroup& group) { content_groups_.push_back(group); }
663 // Remove the first group with the same semantics specified by |name|.
664 void RemoveGroupByName(const std::string& name);
665
666 // Global attributes.
667 void set_msid_supported(bool supported) { msid_supported_ = supported; }
668 bool msid_supported() const { return msid_supported_; }
669
Steve Antone831b8c2018-02-01 12:22:16 -0800670 // Determines how the MSIDs were/will be signaled. Flag value composed of
671 // MsidSignaling bits (see enum above).
672 void set_msid_signaling(int msid_signaling) {
673 msid_signaling_ = msid_signaling;
674 }
675 int msid_signaling() const { return msid_signaling_; }
676
Johannes Kron0854eb62018-10-10 22:33:20 +0200677 // Determines if it's allowed to mix one- and two-byte rtp header extensions
678 // within the same rtp stream.
Johannes Kron9581bc42018-10-23 10:17:39 +0200679 void set_extmap_allow_mixed(bool supported) {
680 extmap_allow_mixed_ = supported;
681 MediaContentDescription::ExtmapAllowMixed media_level_setting =
Johannes Kron0854eb62018-10-10 22:33:20 +0200682 supported ? MediaContentDescription::kSession
683 : MediaContentDescription::kNo;
684 for (auto& content : contents_) {
Johannes Kron9ac3c912018-10-12 10:54:26 +0200685 // Do not set to kNo if the current setting is kMedia.
Johannes Kron9581bc42018-10-23 10:17:39 +0200686 if (supported || content.media_description()->extmap_allow_mixed_enum() !=
687 MediaContentDescription::kMedia) {
688 content.media_description()->set_extmap_allow_mixed_enum(
Johannes Kron9ac3c912018-10-12 10:54:26 +0200689 media_level_setting);
690 }
Johannes Kron0854eb62018-10-10 22:33:20 +0200691 }
692 }
Johannes Kron9581bc42018-10-23 10:17:39 +0200693 bool extmap_allow_mixed() const { return extmap_allow_mixed_; }
Johannes Kron0854eb62018-10-10 22:33:20 +0200694
Piotr (Peter) Slatala13e570f2019-02-27 11:34:26 -0800695 // Adds the media transport setting.
696 // Media transport name uniquely identifies the type of media transport.
697 // The name cannot be empty, or repeated in the previously added transport
698 // settings.
699 void AddMediaTransportSetting(const std::string& media_transport_name,
700 const std::string& media_transport_setting) {
701 RTC_DCHECK(!media_transport_name.empty());
702 for (const auto& setting : media_transport_settings_) {
703 RTC_DCHECK(media_transport_name != setting.transport_name)
704 << "MediaTransportSetting was already registered, transport_name="
705 << setting.transport_name;
706 }
707 media_transport_settings_.push_back(
708 {media_transport_name, media_transport_setting});
709 }
710
711 // Gets the media transport settings, in order of preference.
712 const std::vector<MediaTransportSetting>& MediaTransportSettings() const {
713 return media_transport_settings_;
714 }
715
716 struct MediaTransportSetting {
717 std::string transport_name;
718 std::string transport_setting;
719 };
720
Steve Anton4ab68ee2017-12-19 14:26:11 -0800721 private:
722 SessionDescription(const SessionDescription&);
723
724 ContentInfos contents_;
725 TransportInfos transport_infos_;
726 ContentGroups content_groups_;
727 bool msid_supported_ = true;
Steve Antone831b8c2018-02-01 12:22:16 -0800728 // Default to what Plan B would do.
729 // TODO(bugs.webrtc.org/8530): Change default to kMsidSignalingMediaSection.
730 int msid_signaling_ = kMsidSignalingSsrcAttribute;
Johannes Kron89f874e2018-11-12 10:25:48 +0100731 // TODO(webrtc:9985): Activate mixed one- and two-byte header extension in
732 // offer at session level. It's currently not included in offer by default
733 // because clients prior to https://bugs.webrtc.org/9712 cannot parse this
734 // correctly. If it's included in offer to us we will respond that we support
735 // it.
Johannes Kron9581bc42018-10-23 10:17:39 +0200736 bool extmap_allow_mixed_ = false;
Piotr (Peter) Slatala13e570f2019-02-27 11:34:26 -0800737
738 std::vector<MediaTransportSetting> media_transport_settings_;
Steve Anton4ab68ee2017-12-19 14:26:11 -0800739};
740
Steve Antonb1c1de12017-12-21 15:14:30 -0800741// Indicates whether a session description was sent by the local client or
742// received from the remote client.
Steve Anton4ab68ee2017-12-19 14:26:11 -0800743enum ContentSource { CS_LOCAL, CS_REMOTE };
744
745} // namespace cricket
746
Steve Anton10542f22019-01-11 09:11:00 -0800747#endif // PC_SESSION_DESCRIPTION_H_