3 * Copyright 2004 Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 // Types and classes used in media session descriptions.
30 #ifndef TALK_SESSION_MEDIA_MEDIASESSION_H_
31 #define TALK_SESSION_MEDIA_MEDIASESSION_H_
37 #include "talk/base/scoped_ptr.h"
38 #include "talk/media/base/codec.h"
39 #include "talk/media/base/constants.h"
40 #include "talk/media/base/cryptoparams.h"
41 #include "talk/media/base/mediachannel.h"
42 #include "talk/media/base/mediaengine.h" // For DataChannelType
43 #include "talk/media/base/streamparams.h"
44 #include "talk/p2p/base/sessiondescription.h"
45 #include "talk/p2p/base/transport.h"
46 #include "talk/p2p/base/transportdescriptionfactory.h"
51 typedef std::vector<AudioCodec> AudioCodecs;
52 typedef std::vector<VideoCodec> VideoCodecs;
53 typedef std::vector<DataCodec> DataCodecs;
54 typedef std::vector<CryptoParams> CryptoParamsVec;
55 typedef std::vector<RtpHeaderExtension> RtpHeaderExtensions;
63 std::string MediaTypeToString(MediaType type);
65 enum MediaContentDirection {
79 extern const char kMediaProtocolAvpf[];
81 extern const char kMediaProtocolSavpf[];
83 extern const char kMediaProtocolRtpPrefix[];
85 extern const char kMediaProtocolSctp[];
86 extern const char kMediaProtocolDtlsSctp[];
88 // Options to control how session descriptions are generated.
89 const int kAutoBandwidth = -1;
90 const int kBufferedModeDisabled = 0;
92 struct MediaSessionOptions {
93 MediaSessionOptions() :
94 has_audio(true), // Audio enabled by default.
96 data_channel_type(DCT_NONE),
98 vad_enabled(true), // When disabled, removes all CN codecs from SDP.
99 rtcp_mux_enabled(true),
100 bundle_enabled(false),
101 video_bandwidth(kAutoBandwidth),
102 data_bandwidth(kDataMaxBandwidth) {
105 bool has_data() const { return data_channel_type != DCT_NONE; }
107 // Add a stream with MediaType type and id.
108 // All streams with the same sync_label will get the same CNAME.
109 // All ids must be unique.
110 void AddStream(MediaType type,
111 const std::string& id,
112 const std::string& sync_label);
113 void AddVideoStream(const std::string& id,
114 const std::string& sync_label,
116 void RemoveStream(MediaType type, const std::string& id);
120 void AddStreamInternal(MediaType type,
121 const std::string& id,
122 const std::string& sync_label,
127 DataChannelType data_channel_type;
130 bool rtcp_mux_enabled;
135 TransportOptions transport_options;
138 Stream(MediaType type,
139 const std::string& id,
140 const std::string& sync_label,
142 : type(type), id(id), sync_label(sync_label),
143 num_sim_layers(num_sim_layers) {
147 std::string sync_label;
151 typedef std::vector<Stream> Streams;
155 // "content" (as used in XEP-0166) descriptions for voice and video.
156 class MediaContentDescription : public ContentDescription {
158 MediaContentDescription()
160 bandwidth_(kAutoBandwidth),
161 crypto_required_(CT_NONE),
162 rtp_header_extensions_set_(false),
164 conference_mode_(false),
166 buffered_mode_latency_(kBufferedModeDisabled),
167 direction_(MD_SENDRECV) {
170 virtual MediaType type() const = 0;
171 virtual bool has_codecs() const = 0;
173 // |protocol| is the expected media transport protocol, such as RTP/AVPF,
174 // RTP/SAVPF or SCTP/DTLS.
175 std::string protocol() const { return protocol_; }
176 void set_protocol(const std::string& protocol) { protocol_ = protocol; }
178 MediaContentDirection direction() const { return direction_; }
179 void set_direction(MediaContentDirection direction) {
180 direction_ = direction;
183 bool rtcp_mux() const { return rtcp_mux_; }
184 void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; }
186 int bandwidth() const { return bandwidth_; }
187 void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; }
189 const std::vector<CryptoParams>& cryptos() const { return cryptos_; }
190 void AddCrypto(const CryptoParams& params) {
191 cryptos_.push_back(params);
193 void set_cryptos(const std::vector<CryptoParams>& cryptos) {
197 CryptoType crypto_required() const { return crypto_required_; }
198 void set_crypto_required(CryptoType type) {
199 crypto_required_ = type;
202 const RtpHeaderExtensions& rtp_header_extensions() const {
203 return rtp_header_extensions_;
205 void set_rtp_header_extensions(const RtpHeaderExtensions& extensions) {
206 rtp_header_extensions_ = extensions;
207 rtp_header_extensions_set_ = true;
209 void AddRtpHeaderExtension(const RtpHeaderExtension& ext) {
210 rtp_header_extensions_.push_back(ext);
211 rtp_header_extensions_set_ = true;
213 void ClearRtpHeaderExtensions() {
214 rtp_header_extensions_.clear();
215 rtp_header_extensions_set_ = true;
217 // We can't always tell if an empty list of header extensions is
218 // because the other side doesn't support them, or just isn't hooked up to
219 // signal them. For now we assume an empty list means no signaling, but
220 // provide the ClearRtpHeaderExtensions method to allow "no support" to be
221 // clearly indicated (i.e. when derived from other information).
222 bool rtp_header_extensions_set() const {
223 return rtp_header_extensions_set_;
225 // True iff the client supports multiple streams.
226 void set_multistream(bool multistream) { multistream_ = multistream; }
227 bool multistream() const { return multistream_; }
228 const StreamParamsVec& streams() const {
231 // TODO(pthatcher): Remove this by giving mediamessage.cc access
232 // to MediaContentDescription
233 StreamParamsVec& mutable_streams() {
236 void AddStream(const StreamParams& stream) {
237 streams_.push_back(stream);
239 // Legacy streams have an ssrc, but nothing else.
240 void AddLegacyStream(uint32 ssrc) {
241 streams_.push_back(StreamParams::CreateLegacy(ssrc));
243 void AddLegacyStream(uint32 ssrc, uint32 fid_ssrc) {
244 StreamParams sp = StreamParams::CreateLegacy(ssrc);
245 sp.AddFidSsrc(ssrc, fid_ssrc);
246 streams_.push_back(sp);
248 // Sets the CNAME of all StreamParams if it have not been set.
249 // This can be used to set the CNAME of legacy streams.
250 void SetCnameIfEmpty(const std::string& cname) {
251 for (cricket::StreamParamsVec::iterator it = streams_.begin();
252 it != streams_.end(); ++it) {
253 if (it->cname.empty())
257 uint32 first_ssrc() const {
258 if (streams_.empty()) {
261 return streams_[0].first_ssrc();
263 bool has_ssrcs() const {
264 if (streams_.empty()) {
267 return streams_[0].has_ssrcs();
270 void set_conference_mode(bool enable) { conference_mode_ = enable; }
271 bool conference_mode() const { return conference_mode_; }
273 void set_partial(bool partial) { partial_ = partial; }
274 bool partial() const { return partial_; }
276 void set_buffered_mode_latency(int latency) {
277 buffered_mode_latency_ = latency;
279 int buffered_mode_latency() const { return buffered_mode_latency_; }
284 std::string protocol_;
285 std::vector<CryptoParams> cryptos_;
286 CryptoType crypto_required_;
287 std::vector<RtpHeaderExtension> rtp_header_extensions_;
288 bool rtp_header_extensions_set_;
290 StreamParamsVec streams_;
291 bool conference_mode_;
293 int buffered_mode_latency_;
294 MediaContentDirection direction_;
298 class MediaContentDescriptionImpl : public MediaContentDescription {
300 struct PreferenceSort {
301 bool operator()(C a, C b) { return a.preference > b.preference; }
304 const std::vector<C>& codecs() const { return codecs_; }
305 void set_codecs(const std::vector<C>& codecs) { codecs_ = codecs; }
306 virtual bool has_codecs() const { return !codecs_.empty(); }
307 bool HasCodec(int id) {
309 for (typename std::vector<C>::iterator iter = codecs_.begin();
310 iter != codecs_.end(); ++iter) {
311 if (iter->id == id) {
318 void AddCodec(const C& codec) {
319 codecs_.push_back(codec);
321 void AddCodecs(const std::vector<C>& codecs) {
322 typename std::vector<C>::const_iterator codec;
323 for (codec = codecs.begin(); codec != codecs.end(); ++codec) {
328 std::sort(codecs_.begin(), codecs_.end(), PreferenceSort());
332 std::vector<C> codecs_;
335 class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> {
337 AudioContentDescription() :
338 agc_minus_10db_(false) {}
340 virtual ContentDescription* Copy() const {
341 return new AudioContentDescription(*this);
343 virtual MediaType type() const { return MEDIA_TYPE_AUDIO; }
345 const std::string &lang() const { return lang_; }
346 void set_lang(const std::string &lang) { lang_ = lang; }
348 bool agc_minus_10db() const { return agc_minus_10db_; }
349 void set_agc_minus_10db(bool enable) {
350 agc_minus_10db_ = enable;
354 bool agc_minus_10db_;
360 class VideoContentDescription : public MediaContentDescriptionImpl<VideoCodec> {
362 virtual ContentDescription* Copy() const {
363 return new VideoContentDescription(*this);
365 virtual MediaType type() const { return MEDIA_TYPE_VIDEO; }
368 class DataContentDescription : public MediaContentDescriptionImpl<DataCodec> {
370 virtual ContentDescription* Copy() const {
371 return new DataContentDescription(*this);
373 virtual MediaType type() const { return MEDIA_TYPE_DATA; }
376 // Creates media session descriptions according to the supplied codecs and
377 // other fields, as well as the supplied per-call options.
378 // When creating answers, performs the appropriate negotiation
379 // of the various fields to determine the proper result.
380 class MediaSessionDescriptionFactory {
382 // Default ctor; use methods below to set configuration.
383 // The TransportDescriptionFactory is not owned by MediaSessionDescFactory,
384 // so it must be kept alive by the user of this class.
385 explicit MediaSessionDescriptionFactory(
386 const TransportDescriptionFactory* factory);
387 // This helper automatically sets up the factory to get its configuration
388 // from the specified ChannelManager.
389 MediaSessionDescriptionFactory(ChannelManager* cmanager,
390 const TransportDescriptionFactory* factory);
392 const AudioCodecs& audio_codecs() const { return audio_codecs_; }
393 void set_audio_codecs(const AudioCodecs& codecs) { audio_codecs_ = codecs; }
394 void set_audio_rtp_header_extensions(const RtpHeaderExtensions& extensions) {
395 audio_rtp_extensions_ = extensions;
397 const RtpHeaderExtensions& audio_rtp_header_extensions() const {
398 return audio_rtp_extensions_;
400 const VideoCodecs& video_codecs() const { return video_codecs_; }
401 void set_video_codecs(const VideoCodecs& codecs) { video_codecs_ = codecs; }
402 void set_video_rtp_header_extensions(const RtpHeaderExtensions& extensions) {
403 video_rtp_extensions_ = extensions;
405 const RtpHeaderExtensions& video_rtp_header_extensions() const {
406 return video_rtp_extensions_;
408 const DataCodecs& data_codecs() const { return data_codecs_; }
409 void set_data_codecs(const DataCodecs& codecs) { data_codecs_ = codecs; }
410 SecurePolicy secure() const { return secure_; }
411 void set_secure(SecurePolicy s) { secure_ = s; }
412 // Decides if a StreamParams shall be added to the audio and video media
413 // content in SessionDescription when CreateOffer and CreateAnswer is called
414 // even if |options| don't include a Stream. This is needed to support legacy
415 // applications. |add_legacy_| is true per default.
416 void set_add_legacy_streams(bool add_legacy) { add_legacy_ = add_legacy; }
418 SessionDescription* CreateOffer(
419 const MediaSessionOptions& options,
420 const SessionDescription* current_description) const;
421 SessionDescription* CreateAnswer(
422 const SessionDescription* offer,
423 const MediaSessionOptions& options,
424 const SessionDescription* current_description) const;
427 void GetCodecsToOffer(const SessionDescription* current_description,
428 AudioCodecs* audio_codecs,
429 VideoCodecs* video_codecs,
430 DataCodecs* data_codecs) const;
431 void GetRtpHdrExtsToOffer(const SessionDescription* current_description,
432 RtpHeaderExtensions* audio_extensions,
433 RtpHeaderExtensions* video_extensions) const;
434 bool AddTransportOffer(
435 const std::string& content_name,
436 const TransportOptions& transport_options,
437 const SessionDescription* current_desc,
438 SessionDescription* offer) const;
440 TransportDescription* CreateTransportAnswer(
441 const std::string& content_name,
442 const SessionDescription* offer_desc,
443 const TransportOptions& transport_options,
444 const SessionDescription* current_desc) const;
446 bool AddTransportAnswer(
447 const std::string& content_name,
448 const TransportDescription& transport_desc,
449 SessionDescription* answer_desc) const;
451 AudioCodecs audio_codecs_;
452 RtpHeaderExtensions audio_rtp_extensions_;
453 VideoCodecs video_codecs_;
454 RtpHeaderExtensions video_rtp_extensions_;
455 DataCodecs data_codecs_;
456 SecurePolicy secure_;
459 const TransportDescriptionFactory* transport_desc_factory_;
462 // Convenience functions.
463 bool IsMediaContent(const ContentInfo* content);
464 bool IsAudioContent(const ContentInfo* content);
465 bool IsVideoContent(const ContentInfo* content);
466 bool IsDataContent(const ContentInfo* content);
467 const ContentInfo* GetFirstAudioContent(const ContentInfos& contents);
468 const ContentInfo* GetFirstVideoContent(const ContentInfos& contents);
469 const ContentInfo* GetFirstDataContent(const ContentInfos& contents);
470 const ContentInfo* GetFirstAudioContent(const SessionDescription* sdesc);
471 const ContentInfo* GetFirstVideoContent(const SessionDescription* sdesc);
472 const ContentInfo* GetFirstDataContent(const SessionDescription* sdesc);
473 const AudioContentDescription* GetFirstAudioContentDescription(
474 const SessionDescription* sdesc);
475 const VideoContentDescription* GetFirstVideoContentDescription(
476 const SessionDescription* sdesc);
477 const DataContentDescription* GetFirstDataContentDescription(
478 const SessionDescription* sdesc);
479 bool GetStreamBySsrc(
480 const SessionDescription* sdesc, MediaType media_type,
481 uint32 ssrc, StreamParams* stream_out);
483 const SessionDescription* sdesc, MediaType media_type,
484 const std::string& groupid, const std::string& id,
485 StreamParams* stream_out);
487 // Functions for translating media candidate names.
489 // For converting between media ICE component and G-ICE channel
490 // names. For example:
494 // "video_rtcp" <=> 2
495 // Will not convert in the general case of arbitrary channel names,
496 // but is useful for cases where we have candidates for media
498 // returns false if there is no mapping.
499 bool GetMediaChannelNameFromComponent(
500 int component, cricket::MediaType media_type, std::string* channel_name);
501 bool GetMediaComponentFromChannelName(
502 const std::string& channel_name, int* component);
503 bool GetMediaTypeFromChannelName(
504 const std::string& channel_name, cricket::MediaType* media_type);
506 void GetSupportedAudioCryptoSuites(std::vector<std::string>* crypto_suites);
507 void GetSupportedVideoCryptoSuites(std::vector<std::string>* crypto_suites);
508 void GetSupportedDataCryptoSuites(std::vector<std::string>* crypto_suites);
509 void GetSupportedDefaultCryptoSuites(std::vector<std::string>* crypto_suites);
510 } // namespace cricket
512 #endif // TALK_SESSION_MEDIA_MEDIASESSION_H_