dff254f1a949ded235e0026b959a34cb258e52fe
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / session / media / mediasession.h
1 /*
2  * libjingle
3  * Copyright 2004 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
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.
15  *
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.
26  */
27
28 // Types and classes used in media session descriptions.
29
30 #ifndef TALK_SESSION_MEDIA_MEDIASESSION_H_
31 #define TALK_SESSION_MEDIA_MEDIASESSION_H_
32
33 #include <string>
34 #include <vector>
35 #include <algorithm>
36
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"
47
48 namespace cricket {
49
50 class ChannelManager;
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;
56
57 enum MediaType {
58   MEDIA_TYPE_AUDIO,
59   MEDIA_TYPE_VIDEO,
60   MEDIA_TYPE_DATA
61 };
62
63 std::string MediaTypeToString(MediaType type);
64
65 enum MediaContentDirection {
66   MD_INACTIVE,
67   MD_SENDONLY,
68   MD_RECVONLY,
69   MD_SENDRECV
70 };
71
72 enum CryptoType {
73   CT_NONE,
74   CT_SDES,
75   CT_DTLS
76 };
77
78 // RTC4585 RTP/AVPF
79 extern const char kMediaProtocolAvpf[];
80 // RFC5124 RTP/SAVPF
81 extern const char kMediaProtocolSavpf[];
82
83 extern const char kMediaProtocolRtpPrefix[];
84
85 extern const char kMediaProtocolSctp[];
86 extern const char kMediaProtocolDtlsSctp[];
87
88 // Options to control how session descriptions are generated.
89 const int kAutoBandwidth = -1;
90 const int kBufferedModeDisabled = 0;
91
92 struct MediaSessionOptions {
93   MediaSessionOptions() :
94       has_audio(true),  // Audio enabled by default.
95       has_video(false),
96       data_channel_type(DCT_NONE),
97       is_muc(false),
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) {
103   }
104
105   bool has_data() const { return data_channel_type != DCT_NONE; }
106
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,
115                       int num_sim_layers);
116   void RemoveStream(MediaType type, const std::string& id);
117
118
119   // Helper function.
120   void AddStreamInternal(MediaType type,
121                          const std::string& id,
122                          const std::string& sync_label,
123                          int num_sim_layers);
124
125   bool has_audio;
126   bool has_video;
127   DataChannelType data_channel_type;
128   bool is_muc;
129   bool vad_enabled;
130   bool rtcp_mux_enabled;
131   bool bundle_enabled;
132   // bps. -1 == auto.
133   int video_bandwidth;
134   int data_bandwidth;
135   TransportOptions transport_options;
136
137   struct Stream {
138     Stream(MediaType type,
139            const std::string& id,
140            const std::string& sync_label,
141            int num_sim_layers)
142         : type(type), id(id), sync_label(sync_label),
143           num_sim_layers(num_sim_layers) {
144     }
145     MediaType type;
146     std::string id;
147     std::string sync_label;
148     int num_sim_layers;
149   };
150
151   typedef std::vector<Stream> Streams;
152   Streams streams;
153 };
154
155 // "content" (as used in XEP-0166) descriptions for voice and video.
156 class MediaContentDescription : public ContentDescription {
157  public:
158   MediaContentDescription()
159       : rtcp_mux_(false),
160         bandwidth_(kAutoBandwidth),
161         crypto_required_(CT_NONE),
162         rtp_header_extensions_set_(false),
163         multistream_(false),
164         conference_mode_(false),
165         partial_(false),
166         buffered_mode_latency_(kBufferedModeDisabled),
167         direction_(MD_SENDRECV) {
168   }
169
170   virtual MediaType type() const = 0;
171   virtual bool has_codecs() const = 0;
172
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; }
177
178   MediaContentDirection direction() const { return direction_; }
179   void set_direction(MediaContentDirection direction) {
180     direction_ = direction;
181   }
182
183   bool rtcp_mux() const { return rtcp_mux_; }
184   void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; }
185
186   int bandwidth() const { return bandwidth_; }
187   void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; }
188
189   const std::vector<CryptoParams>& cryptos() const { return cryptos_; }
190   void AddCrypto(const CryptoParams& params) {
191     cryptos_.push_back(params);
192   }
193   void set_cryptos(const std::vector<CryptoParams>& cryptos) {
194     cryptos_ = cryptos;
195   }
196
197   CryptoType crypto_required() const { return crypto_required_; }
198   void set_crypto_required(CryptoType type) {
199     crypto_required_ = type;
200   }
201
202   const RtpHeaderExtensions& rtp_header_extensions() const {
203     return rtp_header_extensions_;
204   }
205   void set_rtp_header_extensions(const RtpHeaderExtensions& extensions) {
206     rtp_header_extensions_ = extensions;
207     rtp_header_extensions_set_ = true;
208   }
209   void AddRtpHeaderExtension(const RtpHeaderExtension& ext) {
210     rtp_header_extensions_.push_back(ext);
211     rtp_header_extensions_set_ = true;
212   }
213   void ClearRtpHeaderExtensions() {
214     rtp_header_extensions_.clear();
215     rtp_header_extensions_set_ = true;
216   }
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_;
224   }
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 {
229     return streams_;
230   }
231   // TODO(pthatcher): Remove this by giving mediamessage.cc access
232   // to MediaContentDescription
233   StreamParamsVec& mutable_streams() {
234     return streams_;
235   }
236   void AddStream(const StreamParams& stream) {
237     streams_.push_back(stream);
238   }
239   // Legacy streams have an ssrc, but nothing else.
240   void AddLegacyStream(uint32 ssrc) {
241     streams_.push_back(StreamParams::CreateLegacy(ssrc));
242   }
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);
247   }
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())
254         it->cname = cname;
255     }
256   }
257   uint32 first_ssrc() const {
258     if (streams_.empty()) {
259       return 0;
260     }
261     return streams_[0].first_ssrc();
262   }
263   bool has_ssrcs() const {
264     if (streams_.empty()) {
265       return false;
266     }
267     return streams_[0].has_ssrcs();
268   }
269
270   void set_conference_mode(bool enable) { conference_mode_ = enable; }
271   bool conference_mode() const { return conference_mode_; }
272
273   void set_partial(bool partial) { partial_ = partial; }
274   bool partial() const { return partial_;  }
275
276   void set_buffered_mode_latency(int latency) {
277     buffered_mode_latency_ = latency;
278   }
279   int buffered_mode_latency() const { return buffered_mode_latency_; }
280
281  protected:
282   bool rtcp_mux_;
283   int bandwidth_;
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_;
289   bool multistream_;
290   StreamParamsVec streams_;
291   bool conference_mode_;
292   bool partial_;
293   int buffered_mode_latency_;
294   MediaContentDirection direction_;
295 };
296
297 template <class C>
298 class MediaContentDescriptionImpl : public MediaContentDescription {
299  public:
300   struct PreferenceSort {
301     bool operator()(C a, C b) { return a.preference > b.preference; }
302   };
303
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) {
308     bool found = false;
309     for (typename std::vector<C>::iterator iter = codecs_.begin();
310          iter != codecs_.end(); ++iter) {
311       if (iter->id == id) {
312         found = true;
313         break;
314       }
315     }
316     return found;
317   }
318   void AddCodec(const C& codec) {
319     codecs_.push_back(codec);
320   }
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) {
324       AddCodec(*codec);
325     }
326   }
327   void SortCodecs() {
328     std::sort(codecs_.begin(), codecs_.end(), PreferenceSort());
329   }
330
331  private:
332   std::vector<C> codecs_;
333 };
334
335 class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> {
336  public:
337   AudioContentDescription() :
338       agc_minus_10db_(false) {}
339
340   virtual ContentDescription* Copy() const {
341     return new AudioContentDescription(*this);
342   }
343   virtual MediaType type() const { return MEDIA_TYPE_AUDIO; }
344
345   const std::string &lang() const { return lang_; }
346   void set_lang(const std::string &lang) { lang_ = lang; }
347
348   bool agc_minus_10db() const { return agc_minus_10db_; }
349   void set_agc_minus_10db(bool enable) {
350     agc_minus_10db_ = enable;
351   }
352
353  private:
354   bool agc_minus_10db_;
355
356  private:
357   std::string lang_;
358 };
359
360 class VideoContentDescription : public MediaContentDescriptionImpl<VideoCodec> {
361  public:
362   virtual ContentDescription* Copy() const {
363     return new VideoContentDescription(*this);
364   }
365   virtual MediaType type() const { return MEDIA_TYPE_VIDEO; }
366 };
367
368 class DataContentDescription : public MediaContentDescriptionImpl<DataCodec> {
369  public:
370   virtual ContentDescription* Copy() const {
371     return new DataContentDescription(*this);
372   }
373   virtual MediaType type() const { return MEDIA_TYPE_DATA; }
374 };
375
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 {
381  public:
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);
391
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;
396   }
397   const RtpHeaderExtensions& audio_rtp_header_extensions() const {
398     return audio_rtp_extensions_;
399   }
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;
404   }
405   const RtpHeaderExtensions& video_rtp_header_extensions() const {
406     return video_rtp_extensions_;
407   }
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; }
417
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;
425
426  private:
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;
439
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;
445
446   bool AddTransportAnswer(
447       const std::string& content_name,
448       const TransportDescription& transport_desc,
449       SessionDescription* answer_desc) const;
450
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_;
457   bool add_legacy_;
458   std::string lang_;
459   const TransportDescriptionFactory* transport_desc_factory_;
460 };
461
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);
482 bool GetStreamByIds(
483     const SessionDescription* sdesc, MediaType media_type,
484     const std::string& groupid, const std::string& id,
485     StreamParams* stream_out);
486
487 // Functions for translating media candidate names.
488
489 // For converting between media ICE component and G-ICE channel
490 // names.  For example:
491 // "rtp" <=> 1
492 // "rtcp" <=> 2
493 // "video_rtp" <=> 1
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
497 // channels.
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);
505
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
511
512 #endif  // TALK_SESSION_MEDIA_MEDIASESSION_H_