blob: 648b27dc1c8642d7e4fd69e2b4f5d607217d4eb6 [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
11#ifndef PC_SESSIONDESCRIPTION_H_
12#define PC_SESSIONDESCRIPTION_H_
13
14#include <string>
15#include <vector>
16
Steve Antonafd8e8c2017-12-19 16:35:35 -080017#include "api/cryptoparams.h"
18#include "api/rtpparameters.h"
19#include "api/rtptransceiverinterface.h"
20#include "media/base/codec.h"
21#include "media/base/mediachannel.h"
22#include "media/base/streamparams.h"
Steve Anton4ab68ee2017-12-19 14:26:11 -080023#include "p2p/base/transportinfo.h"
24#include "rtc_base/constructormagic.h"
25
26namespace cricket {
27
Steve Antonafd8e8c2017-12-19 16:35:35 -080028typedef std::vector<AudioCodec> AudioCodecs;
29typedef std::vector<VideoCodec> VideoCodecs;
30typedef std::vector<DataCodec> DataCodecs;
31typedef std::vector<CryptoParams> CryptoParamsVec;
32typedef std::vector<webrtc::RtpExtension> RtpHeaderExtensions;
33
34// RTC4585 RTP/AVPF
35extern const char kMediaProtocolAvpf[];
36// RFC5124 RTP/SAVPF
37extern const char kMediaProtocolSavpf[];
38
39extern const char kMediaProtocolDtlsSavpf[];
40
41extern const char kMediaProtocolRtpPrefix[];
42
43extern const char kMediaProtocolSctp[];
44extern const char kMediaProtocolDtlsSctp[];
45extern const char kMediaProtocolUdpDtlsSctp[];
46extern const char kMediaProtocolTcpDtlsSctp[];
47
48// Options to control how session descriptions are generated.
49const int kAutoBandwidth = -1;
50
Steve Anton4ab68ee2017-12-19 14:26:11 -080051// Describes a session content. Individual content types inherit from
52// this class. Analagous to a <jingle><content><description> or
53// <session><description>.
54class ContentDescription {
55 public:
56 virtual ~ContentDescription() {}
57 virtual ContentDescription* Copy() const = 0;
58};
59
Steve Antonafd8e8c2017-12-19 16:35:35 -080060// "content" (as used in XEP-0166) descriptions for voice and video.
61class MediaContentDescription : public ContentDescription {
62 public:
63 MediaContentDescription() {}
64
65 virtual MediaType type() const = 0;
66 virtual bool has_codecs() const = 0;
67
68 // |protocol| is the expected media transport protocol, such as RTP/AVPF,
69 // RTP/SAVPF or SCTP/DTLS.
70 std::string protocol() const { return protocol_; }
71 void set_protocol(const std::string& protocol) { protocol_ = protocol; }
72
73 webrtc::RtpTransceiverDirection direction() const { return direction_; }
74 void set_direction(webrtc::RtpTransceiverDirection direction) {
75 direction_ = direction;
76 }
77
78 bool rtcp_mux() const { return rtcp_mux_; }
79 void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; }
80
81 bool rtcp_reduced_size() const { return rtcp_reduced_size_; }
82 void set_rtcp_reduced_size(bool reduced_size) {
83 rtcp_reduced_size_ = reduced_size;
84 }
85
86 int bandwidth() const { return bandwidth_; }
87 void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; }
88
89 const std::vector<CryptoParams>& cryptos() const { return cryptos_; }
90 void AddCrypto(const CryptoParams& params) { cryptos_.push_back(params); }
91 void set_cryptos(const std::vector<CryptoParams>& cryptos) {
92 cryptos_ = cryptos;
93 }
94
95 const RtpHeaderExtensions& rtp_header_extensions() const {
96 return rtp_header_extensions_;
97 }
98 void set_rtp_header_extensions(const RtpHeaderExtensions& extensions) {
99 rtp_header_extensions_ = extensions;
100 rtp_header_extensions_set_ = true;
101 }
102 void AddRtpHeaderExtension(const webrtc::RtpExtension& ext) {
103 rtp_header_extensions_.push_back(ext);
104 rtp_header_extensions_set_ = true;
105 }
106 void AddRtpHeaderExtension(const cricket::RtpHeaderExtension& ext) {
107 webrtc::RtpExtension webrtc_extension;
108 webrtc_extension.uri = ext.uri;
109 webrtc_extension.id = ext.id;
110 rtp_header_extensions_.push_back(webrtc_extension);
111 rtp_header_extensions_set_ = true;
112 }
113 void ClearRtpHeaderExtensions() {
114 rtp_header_extensions_.clear();
115 rtp_header_extensions_set_ = true;
116 }
117 // We can't always tell if an empty list of header extensions is
118 // because the other side doesn't support them, or just isn't hooked up to
119 // signal them. For now we assume an empty list means no signaling, but
120 // provide the ClearRtpHeaderExtensions method to allow "no support" to be
121 // clearly indicated (i.e. when derived from other information).
122 bool rtp_header_extensions_set() const { return rtp_header_extensions_set_; }
123 const StreamParamsVec& streams() const { return streams_; }
124 // TODO(pthatcher): Remove this by giving mediamessage.cc access
125 // to MediaContentDescription
126 StreamParamsVec& mutable_streams() { return streams_; }
127 void AddStream(const StreamParams& stream) { streams_.push_back(stream); }
128 // Legacy streams have an ssrc, but nothing else.
129 void AddLegacyStream(uint32_t ssrc) {
130 streams_.push_back(StreamParams::CreateLegacy(ssrc));
131 }
132 void AddLegacyStream(uint32_t ssrc, uint32_t fid_ssrc) {
133 StreamParams sp = StreamParams::CreateLegacy(ssrc);
134 sp.AddFidSsrc(ssrc, fid_ssrc);
135 streams_.push_back(sp);
136 }
137 // Sets the CNAME of all StreamParams if it have not been set.
138 void SetCnameIfEmpty(const std::string& cname) {
139 for (cricket::StreamParamsVec::iterator it = streams_.begin();
140 it != streams_.end(); ++it) {
141 if (it->cname.empty())
142 it->cname = cname;
143 }
144 }
145 uint32_t first_ssrc() const {
146 if (streams_.empty()) {
147 return 0;
148 }
149 return streams_[0].first_ssrc();
150 }
151 bool has_ssrcs() const {
152 if (streams_.empty()) {
153 return false;
154 }
155 return streams_[0].has_ssrcs();
156 }
157
158 void set_conference_mode(bool enable) { conference_mode_ = enable; }
159 bool conference_mode() const { return conference_mode_; }
160
161 // https://tools.ietf.org/html/rfc4566#section-5.7
162 // May be present at the media or session level of SDP. If present at both
163 // levels, the media-level attribute overwrites the session-level one.
164 void set_connection_address(const rtc::SocketAddress& address) {
165 connection_address_ = address;
166 }
167 const rtc::SocketAddress& connection_address() const {
168 return connection_address_;
169 }
170
171 protected:
172 bool rtcp_mux_ = false;
173 bool rtcp_reduced_size_ = false;
174 int bandwidth_ = kAutoBandwidth;
175 std::string protocol_;
176 std::vector<CryptoParams> cryptos_;
177 std::vector<webrtc::RtpExtension> rtp_header_extensions_;
178 bool rtp_header_extensions_set_ = false;
179 StreamParamsVec streams_;
180 bool conference_mode_ = false;
181 webrtc::RtpTransceiverDirection direction_ =
182 webrtc::RtpTransceiverDirection::kSendRecv;
183 rtc::SocketAddress connection_address_;
184};
185
186template <class C>
187class MediaContentDescriptionImpl : public MediaContentDescription {
188 public:
189 typedef C CodecType;
190
191 // Codecs should be in preference order (most preferred codec first).
192 const std::vector<C>& codecs() const { return codecs_; }
193 void set_codecs(const std::vector<C>& codecs) { codecs_ = codecs; }
194 virtual bool has_codecs() const { return !codecs_.empty(); }
195 bool HasCodec(int id) {
196 bool found = false;
197 for (typename std::vector<C>::iterator iter = codecs_.begin();
198 iter != codecs_.end(); ++iter) {
199 if (iter->id == id) {
200 found = true;
201 break;
202 }
203 }
204 return found;
205 }
206 void AddCodec(const C& codec) { codecs_.push_back(codec); }
207 void AddOrReplaceCodec(const C& codec) {
208 for (typename std::vector<C>::iterator iter = codecs_.begin();
209 iter != codecs_.end(); ++iter) {
210 if (iter->id == codec.id) {
211 *iter = codec;
212 return;
213 }
214 }
215 AddCodec(codec);
216 }
217 void AddCodecs(const std::vector<C>& codecs) {
218 typename std::vector<C>::const_iterator codec;
219 for (codec = codecs.begin(); codec != codecs.end(); ++codec) {
220 AddCodec(*codec);
221 }
222 }
223
224 private:
225 std::vector<C> codecs_;
226};
227
228class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> {
229 public:
230 AudioContentDescription() {}
231
232 virtual ContentDescription* Copy() const {
233 return new AudioContentDescription(*this);
234 }
235 virtual MediaType type() const { return MEDIA_TYPE_AUDIO; }
236};
237
238class VideoContentDescription : public MediaContentDescriptionImpl<VideoCodec> {
239 public:
240 virtual ContentDescription* Copy() const {
241 return new VideoContentDescription(*this);
242 }
243 virtual MediaType type() const { return MEDIA_TYPE_VIDEO; }
244};
245
246class DataContentDescription : public MediaContentDescriptionImpl<DataCodec> {
247 public:
248 DataContentDescription() {}
249
250 virtual ContentDescription* Copy() const {
251 return new DataContentDescription(*this);
252 }
253 virtual MediaType type() const { return MEDIA_TYPE_DATA; }
254
255 bool use_sctpmap() const { return use_sctpmap_; }
256 void set_use_sctpmap(bool enable) { use_sctpmap_ = enable; }
257
258 private:
259 bool use_sctpmap_ = true;
260};
261
Steve Anton4ab68ee2017-12-19 14:26:11 -0800262// Analagous to a <jingle><content> or <session><description>.
263// name = name of <content name="...">
264// type = xmlns of <content>
265struct ContentInfo {
266 ContentInfo() {}
267 ContentInfo(const std::string& name,
268 const std::string& type,
269 ContentDescription* description)
270 : name(name), type(type), description(description) {}
271 ContentInfo(const std::string& name,
272 const std::string& type,
273 bool rejected,
274 ContentDescription* description)
275 : name(name), type(type), rejected(rejected), description(description) {}
276 ContentInfo(const std::string& name,
277 const std::string& type,
278 bool rejected,
279 bool bundle_only,
280 ContentDescription* description)
281 : name(name),
282 type(type),
283 rejected(rejected),
284 bundle_only(bundle_only),
285 description(description) {}
286 std::string name;
287 std::string type;
288 bool rejected = false;
289 bool bundle_only = false;
290 ContentDescription* description = nullptr;
291};
292
293typedef std::vector<std::string> ContentNames;
294
295// This class provides a mechanism to aggregate different media contents into a
296// group. This group can also be shared with the peers in a pre-defined format.
297// GroupInfo should be populated only with the |content_name| of the
298// MediaDescription.
299class ContentGroup {
300 public:
301 explicit ContentGroup(const std::string& semantics);
302 ContentGroup(const ContentGroup&);
303 ContentGroup(ContentGroup&&);
304 ContentGroup& operator=(const ContentGroup&);
305 ContentGroup& operator=(ContentGroup&&);
306 ~ContentGroup();
307
308 const std::string& semantics() const { return semantics_; }
309 const ContentNames& content_names() const { return content_names_; }
310
311 const std::string* FirstContentName() const;
312 bool HasContentName(const std::string& content_name) const;
313 void AddContentName(const std::string& content_name);
314 bool RemoveContentName(const std::string& content_name);
315
316 private:
317 std::string semantics_;
318 ContentNames content_names_;
319};
320
321typedef std::vector<ContentInfo> ContentInfos;
322typedef std::vector<ContentGroup> ContentGroups;
323
324const ContentInfo* FindContentInfoByName(const ContentInfos& contents,
325 const std::string& name);
326const ContentInfo* FindContentInfoByType(const ContentInfos& contents,
327 const std::string& type);
328
329// Describes a collection of contents, each with its own name and
330// type. Analogous to a <jingle> or <session> stanza. Assumes that
331// contents are unique be name, but doesn't enforce that.
332class SessionDescription {
333 public:
334 SessionDescription();
335 explicit SessionDescription(const ContentInfos& contents);
336 SessionDescription(const ContentInfos& contents, const ContentGroups& groups);
337 SessionDescription(const ContentInfos& contents,
338 const TransportInfos& transports,
339 const ContentGroups& groups);
340 ~SessionDescription();
341
342 SessionDescription* Copy() const;
343
344 // Content accessors.
345 const ContentInfos& contents() const { return contents_; }
346 ContentInfos& contents() { return contents_; }
347 const ContentInfo* GetContentByName(const std::string& name) const;
348 ContentInfo* GetContentByName(const std::string& name);
349 const ContentDescription* GetContentDescriptionByName(
350 const std::string& name) const;
351 ContentDescription* GetContentDescriptionByName(const std::string& name);
352 const ContentInfo* FirstContentByType(const std::string& type) const;
353 const ContentInfo* FirstContent() const;
354
355 // Content mutators.
356 // Adds a content to this description. Takes ownership of ContentDescription*.
357 void AddContent(const std::string& name,
358 const std::string& type,
359 ContentDescription* description);
360 void AddContent(const std::string& name,
361 const std::string& type,
362 bool rejected,
363 ContentDescription* description);
364 void AddContent(const std::string& name,
365 const std::string& type,
366 bool rejected,
367 bool bundle_only,
368 ContentDescription* description);
369 bool RemoveContentByName(const std::string& name);
370
371 // Transport accessors.
372 const TransportInfos& transport_infos() const { return transport_infos_; }
373 TransportInfos& transport_infos() { return transport_infos_; }
374 const TransportInfo* GetTransportInfoByName(const std::string& name) const;
375 TransportInfo* GetTransportInfoByName(const std::string& name);
376 const TransportDescription* GetTransportDescriptionByName(
377 const std::string& name) const {
378 const TransportInfo* tinfo = GetTransportInfoByName(name);
379 return tinfo ? &tinfo->description : NULL;
380 }
381
382 // Transport mutators.
383 void set_transport_infos(const TransportInfos& transport_infos) {
384 transport_infos_ = transport_infos;
385 }
386 // Adds a TransportInfo to this description.
387 // Returns false if a TransportInfo with the same name already exists.
388 bool AddTransportInfo(const TransportInfo& transport_info);
389 bool RemoveTransportInfoByName(const std::string& name);
390
391 // Group accessors.
392 const ContentGroups& groups() const { return content_groups_; }
393 const ContentGroup* GetGroupByName(const std::string& name) const;
394 bool HasGroup(const std::string& name) const;
395
396 // Group mutators.
397 void AddGroup(const ContentGroup& group) { content_groups_.push_back(group); }
398 // Remove the first group with the same semantics specified by |name|.
399 void RemoveGroupByName(const std::string& name);
400
401 // Global attributes.
402 void set_msid_supported(bool supported) { msid_supported_ = supported; }
403 bool msid_supported() const { return msid_supported_; }
404
405 private:
406 SessionDescription(const SessionDescription&);
407
408 ContentInfos contents_;
409 TransportInfos transport_infos_;
410 ContentGroups content_groups_;
411 bool msid_supported_ = true;
412};
413
414// Indicates whether a ContentDescription was sent by the local client
415// or received from the remote client.
416enum ContentSource { CS_LOCAL, CS_REMOTE };
417
418} // namespace cricket
419
420#endif // PC_SESSIONDESCRIPTION_H_