1 /*
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 // Types and classes used in media session descriptions.
12 
13 #ifndef PC_MEDIA_SESSION_H_
14 #define PC_MEDIA_SESSION_H_
15 
16 #include <map>
17 #include <memory>
18 #include <string>
19 #include <vector>
20 
21 #include "api/media_types.h"
22 #include "media/base/media_constants.h"
23 #include "media/base/media_engine.h"  // For DataChannelType
24 #include "p2p/base/ice_credentials_iterator.h"
25 #include "p2p/base/transport_description_factory.h"
26 #include "pc/jsep_transport.h"
27 #include "pc/media_protocol_names.h"
28 #include "pc/session_description.h"
29 #include "rtc_base/unique_id_generator.h"
30 
31 namespace cricket {
32 
33 class ChannelManager;
34 
35 // Default RTCP CNAME for unit tests.
36 const char kDefaultRtcpCname[] = "DefaultRtcpCname";
37 
38 // Options for an RtpSender contained with an media description/"m=" section.
39 // Note: Spec-compliant Simulcast and legacy simulcast are mutually exclusive.
40 struct SenderOptions {
41   std::string track_id;
42   std::vector<std::string> stream_ids;
43   // Use RIDs and Simulcast Layers to indicate spec-compliant Simulcast.
44   std::vector<RidDescription> rids;
45   SimulcastLayerList simulcast_layers;
46   // Use |num_sim_layers| to indicate legacy simulcast.
47   int num_sim_layers;
48 };
49 
50 // Options for an individual media description/"m=" section.
51 struct MediaDescriptionOptions {
MediaDescriptionOptionsMediaDescriptionOptions52   MediaDescriptionOptions(MediaType type,
53                           const std::string& mid,
54                           webrtc::RtpTransceiverDirection direction,
55                           bool stopped)
56       : type(type), mid(mid), direction(direction), stopped(stopped) {}
57 
58   // TODO(deadbeef): When we don't support Plan B, there will only be one
59   // sender per media description and this can be simplified.
60   void AddAudioSender(const std::string& track_id,
61                       const std::vector<std::string>& stream_ids);
62   void AddVideoSender(const std::string& track_id,
63                       const std::vector<std::string>& stream_ids,
64                       const std::vector<RidDescription>& rids,
65                       const SimulcastLayerList& simulcast_layers,
66                       int num_sim_layers);
67 
68   // Internally just uses sender_options.
69   void AddRtpDataChannel(const std::string& track_id,
70                          const std::string& stream_id);
71 
72   MediaType type;
73   std::string mid;
74   webrtc::RtpTransceiverDirection direction;
75   bool stopped;
76   TransportOptions transport_options;
77   // Note: There's no equivalent "RtpReceiverOptions" because only send
78   // stream information goes in the local descriptions.
79   std::vector<SenderOptions> sender_options;
80   std::vector<webrtc::RtpCodecCapability> codec_preferences;
81   std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions;
82 
83  private:
84   // Doesn't DCHECK on |type|.
85   void AddSenderInternal(const std::string& track_id,
86                          const std::vector<std::string>& stream_ids,
87                          const std::vector<RidDescription>& rids,
88                          const SimulcastLayerList& simulcast_layers,
89                          int num_sim_layers);
90 };
91 
92 // Provides a mechanism for describing how m= sections should be generated.
93 // The m= section with index X will use media_description_options[X]. There
94 // must be an option for each existing section if creating an answer, or a
95 // subsequent offer.
96 struct MediaSessionOptions {
MediaSessionOptionsMediaSessionOptions97   MediaSessionOptions() {}
98 
has_audioMediaSessionOptions99   bool has_audio() const { return HasMediaDescription(MEDIA_TYPE_AUDIO); }
has_videoMediaSessionOptions100   bool has_video() const { return HasMediaDescription(MEDIA_TYPE_VIDEO); }
has_dataMediaSessionOptions101   bool has_data() const { return HasMediaDescription(MEDIA_TYPE_DATA); }
102 
103   bool HasMediaDescription(MediaType type) const;
104 
105   DataChannelType data_channel_type = DCT_NONE;
106   bool vad_enabled = true;  // When disabled, removes all CN codecs from SDP.
107   bool rtcp_mux_enabled = true;
108   bool bundle_enabled = false;
109   bool offer_extmap_allow_mixed = false;
110   bool raw_packetization_for_video = false;
111   std::string rtcp_cname = kDefaultRtcpCname;
112   webrtc::CryptoOptions crypto_options;
113   // List of media description options in the same order that the media
114   // descriptions will be generated.
115   std::vector<MediaDescriptionOptions> media_description_options;
116   std::vector<IceParameters> pooled_ice_credentials;
117 
118   // Use the draft-ietf-mmusic-sctp-sdp-03 obsolete syntax for SCTP
119   // datachannels.
120   // Default is true for backwards compatibility with clients that use
121   // this internal interface.
122   bool use_obsolete_sctp_sdp = true;
123 };
124 
125 // Creates media session descriptions according to the supplied codecs and
126 // other fields, as well as the supplied per-call options.
127 // When creating answers, performs the appropriate negotiation
128 // of the various fields to determine the proper result.
129 class MediaSessionDescriptionFactory {
130  public:
131   // Simple constructor that does not set any configuration for the factory.
132   // When using this constructor, the methods below can be used to set the
133   // configuration.
134   // The TransportDescriptionFactory and the UniqueRandomIdGenerator are not
135   // owned by MediaSessionDescriptionFactory, so they must be kept alive by the
136   // user of this class.
137   MediaSessionDescriptionFactory(const TransportDescriptionFactory* factory,
138                                  rtc::UniqueRandomIdGenerator* ssrc_generator);
139   // This helper automatically sets up the factory to get its configuration
140   // from the specified ChannelManager.
141   MediaSessionDescriptionFactory(ChannelManager* cmanager,
142                                  const TransportDescriptionFactory* factory,
143                                  rtc::UniqueRandomIdGenerator* ssrc_generator);
144 
145   const AudioCodecs& audio_sendrecv_codecs() const;
146   const AudioCodecs& audio_send_codecs() const;
147   const AudioCodecs& audio_recv_codecs() const;
148   void set_audio_codecs(const AudioCodecs& send_codecs,
149                         const AudioCodecs& recv_codecs);
150   const VideoCodecs& video_sendrecv_codecs() const;
151   const VideoCodecs& video_send_codecs() const;
152   const VideoCodecs& video_recv_codecs() const;
153   void set_video_codecs(const VideoCodecs& send_codecs,
154                         const VideoCodecs& recv_codecs);
155   RtpHeaderExtensions filtered_rtp_header_extensions(
156       RtpHeaderExtensions extensions) const;
rtp_data_codecs()157   const RtpDataCodecs& rtp_data_codecs() const { return rtp_data_codecs_; }
set_rtp_data_codecs(const RtpDataCodecs & codecs)158   void set_rtp_data_codecs(const RtpDataCodecs& codecs) {
159     rtp_data_codecs_ = codecs;
160   }
secure()161   SecurePolicy secure() const { return secure_; }
set_secure(SecurePolicy s)162   void set_secure(SecurePolicy s) { secure_ = s; }
163 
set_enable_encrypted_rtp_header_extensions(bool enable)164   void set_enable_encrypted_rtp_header_extensions(bool enable) {
165     enable_encrypted_rtp_header_extensions_ = enable;
166   }
167 
set_is_unified_plan(bool is_unified_plan)168   void set_is_unified_plan(bool is_unified_plan) {
169     is_unified_plan_ = is_unified_plan;
170   }
171 
172   std::unique_ptr<SessionDescription> CreateOffer(
173       const MediaSessionOptions& options,
174       const SessionDescription* current_description) const;
175   std::unique_ptr<SessionDescription> CreateAnswer(
176       const SessionDescription* offer,
177       const MediaSessionOptions& options,
178       const SessionDescription* current_description) const;
179 
180  private:
181   struct AudioVideoRtpHeaderExtensions {
182     RtpHeaderExtensions audio;
183     RtpHeaderExtensions video;
184   };
185 
186   const AudioCodecs& GetAudioCodecsForOffer(
187       const webrtc::RtpTransceiverDirection& direction) const;
188   const AudioCodecs& GetAudioCodecsForAnswer(
189       const webrtc::RtpTransceiverDirection& offer,
190       const webrtc::RtpTransceiverDirection& answer) const;
191   const VideoCodecs& GetVideoCodecsForOffer(
192       const webrtc::RtpTransceiverDirection& direction) const;
193   const VideoCodecs& GetVideoCodecsForAnswer(
194       const webrtc::RtpTransceiverDirection& offer,
195       const webrtc::RtpTransceiverDirection& answer) const;
196   void GetCodecsForOffer(
197       const std::vector<const ContentInfo*>& current_active_contents,
198       AudioCodecs* audio_codecs,
199       VideoCodecs* video_codecs,
200       RtpDataCodecs* rtp_data_codecs) const;
201   void GetCodecsForAnswer(
202       const std::vector<const ContentInfo*>& current_active_contents,
203       const SessionDescription& remote_offer,
204       AudioCodecs* audio_codecs,
205       VideoCodecs* video_codecs,
206       RtpDataCodecs* rtp_data_codecs) const;
207   AudioVideoRtpHeaderExtensions GetOfferedRtpHeaderExtensionsWithIds(
208       const std::vector<const ContentInfo*>& current_active_contents,
209       bool extmap_allow_mixed,
210       const std::vector<MediaDescriptionOptions>& media_description_options)
211       const;
212   bool AddTransportOffer(const std::string& content_name,
213                          const TransportOptions& transport_options,
214                          const SessionDescription* current_desc,
215                          SessionDescription* offer,
216                          IceCredentialsIterator* ice_credentials) const;
217 
218   std::unique_ptr<TransportDescription> CreateTransportAnswer(
219       const std::string& content_name,
220       const SessionDescription* offer_desc,
221       const TransportOptions& transport_options,
222       const SessionDescription* current_desc,
223       bool require_transport_attributes,
224       IceCredentialsIterator* ice_credentials) const;
225 
226   bool AddTransportAnswer(const std::string& content_name,
227                           const TransportDescription& transport_desc,
228                           SessionDescription* answer_desc) const;
229 
230   // Helpers for adding media contents to the SessionDescription. Returns true
231   // it succeeds or the media content is not needed, or false if there is any
232   // error.
233 
234   bool AddAudioContentForOffer(
235       const MediaDescriptionOptions& media_description_options,
236       const MediaSessionOptions& session_options,
237       const ContentInfo* current_content,
238       const SessionDescription* current_description,
239       const RtpHeaderExtensions& audio_rtp_extensions,
240       const AudioCodecs& audio_codecs,
241       StreamParamsVec* current_streams,
242       SessionDescription* desc,
243       IceCredentialsIterator* ice_credentials) const;
244 
245   bool AddVideoContentForOffer(
246       const MediaDescriptionOptions& media_description_options,
247       const MediaSessionOptions& session_options,
248       const ContentInfo* current_content,
249       const SessionDescription* current_description,
250       const RtpHeaderExtensions& video_rtp_extensions,
251       const VideoCodecs& video_codecs,
252       StreamParamsVec* current_streams,
253       SessionDescription* desc,
254       IceCredentialsIterator* ice_credentials) const;
255 
256   bool AddSctpDataContentForOffer(
257       const MediaDescriptionOptions& media_description_options,
258       const MediaSessionOptions& session_options,
259       const ContentInfo* current_content,
260       const SessionDescription* current_description,
261       StreamParamsVec* current_streams,
262       SessionDescription* desc,
263       IceCredentialsIterator* ice_credentials) const;
264   bool AddRtpDataContentForOffer(
265       const MediaDescriptionOptions& media_description_options,
266       const MediaSessionOptions& session_options,
267       const ContentInfo* current_content,
268       const SessionDescription* current_description,
269       const RtpDataCodecs& rtp_data_codecs,
270       StreamParamsVec* current_streams,
271       SessionDescription* desc,
272       IceCredentialsIterator* ice_credentials) const;
273   // This function calls either AddRtpDataContentForOffer or
274   // AddSctpDataContentForOffer depending on protocol.
275   // The codecs argument is ignored for SCTP.
276   bool AddDataContentForOffer(
277       const MediaDescriptionOptions& media_description_options,
278       const MediaSessionOptions& session_options,
279       const ContentInfo* current_content,
280       const SessionDescription* current_description,
281       const RtpDataCodecs& rtp_data_codecs,
282       StreamParamsVec* current_streams,
283       SessionDescription* desc,
284       IceCredentialsIterator* ice_credentials) const;
285 
286   bool AddAudioContentForAnswer(
287       const MediaDescriptionOptions& media_description_options,
288       const MediaSessionOptions& session_options,
289       const ContentInfo* offer_content,
290       const SessionDescription* offer_description,
291       const ContentInfo* current_content,
292       const SessionDescription* current_description,
293       const TransportInfo* bundle_transport,
294       const AudioCodecs& audio_codecs,
295       const RtpHeaderExtensions& default_audio_rtp_header_extensions,
296       StreamParamsVec* current_streams,
297       SessionDescription* answer,
298       IceCredentialsIterator* ice_credentials) const;
299 
300   bool AddVideoContentForAnswer(
301       const MediaDescriptionOptions& media_description_options,
302       const MediaSessionOptions& session_options,
303       const ContentInfo* offer_content,
304       const SessionDescription* offer_description,
305       const ContentInfo* current_content,
306       const SessionDescription* current_description,
307       const TransportInfo* bundle_transport,
308       const VideoCodecs& video_codecs,
309       const RtpHeaderExtensions& default_video_rtp_header_extensions,
310       StreamParamsVec* current_streams,
311       SessionDescription* answer,
312       IceCredentialsIterator* ice_credentials) const;
313 
314   bool AddDataContentForAnswer(
315       const MediaDescriptionOptions& media_description_options,
316       const MediaSessionOptions& session_options,
317       const ContentInfo* offer_content,
318       const SessionDescription* offer_description,
319       const ContentInfo* current_content,
320       const SessionDescription* current_description,
321       const TransportInfo* bundle_transport,
322       const RtpDataCodecs& rtp_data_codecs,
323       StreamParamsVec* current_streams,
324       SessionDescription* answer,
325       IceCredentialsIterator* ice_credentials) const;
326 
327   void ComputeAudioCodecsIntersectionAndUnion();
328 
329   void ComputeVideoCodecsIntersectionAndUnion();
330 
331   bool is_unified_plan_ = false;
332   AudioCodecs audio_send_codecs_;
333   AudioCodecs audio_recv_codecs_;
334   // Intersection of send and recv.
335   AudioCodecs audio_sendrecv_codecs_;
336   // Union of send and recv.
337   AudioCodecs all_audio_codecs_;
338   VideoCodecs video_send_codecs_;
339   VideoCodecs video_recv_codecs_;
340   // Intersection of send and recv.
341   VideoCodecs video_sendrecv_codecs_;
342   // Union of send and recv.
343   VideoCodecs all_video_codecs_;
344   RtpDataCodecs rtp_data_codecs_;
345   // This object is not owned by the channel so it must outlive it.
346   rtc::UniqueRandomIdGenerator* const ssrc_generator_;
347   bool enable_encrypted_rtp_header_extensions_ = false;
348   // TODO(zhihuang): Rename secure_ to sdec_policy_; rename the related getter
349   // and setter.
350   SecurePolicy secure_ = SEC_DISABLED;
351   const TransportDescriptionFactory* transport_desc_factory_;
352 };
353 
354 // Convenience functions.
355 bool IsMediaContent(const ContentInfo* content);
356 bool IsAudioContent(const ContentInfo* content);
357 bool IsVideoContent(const ContentInfo* content);
358 bool IsDataContent(const ContentInfo* content);
359 const ContentInfo* GetFirstMediaContent(const ContentInfos& contents,
360                                         MediaType media_type);
361 const ContentInfo* GetFirstAudioContent(const ContentInfos& contents);
362 const ContentInfo* GetFirstVideoContent(const ContentInfos& contents);
363 const ContentInfo* GetFirstDataContent(const ContentInfos& contents);
364 const ContentInfo* GetFirstMediaContent(const SessionDescription* sdesc,
365                                         MediaType media_type);
366 const ContentInfo* GetFirstAudioContent(const SessionDescription* sdesc);
367 const ContentInfo* GetFirstVideoContent(const SessionDescription* sdesc);
368 const ContentInfo* GetFirstDataContent(const SessionDescription* sdesc);
369 const AudioContentDescription* GetFirstAudioContentDescription(
370     const SessionDescription* sdesc);
371 const VideoContentDescription* GetFirstVideoContentDescription(
372     const SessionDescription* sdesc);
373 const RtpDataContentDescription* GetFirstRtpDataContentDescription(
374     const SessionDescription* sdesc);
375 const SctpDataContentDescription* GetFirstSctpDataContentDescription(
376     const SessionDescription* sdesc);
377 // Non-const versions of the above functions.
378 // Useful when modifying an existing description.
379 ContentInfo* GetFirstMediaContent(ContentInfos* contents, MediaType media_type);
380 ContentInfo* GetFirstAudioContent(ContentInfos* contents);
381 ContentInfo* GetFirstVideoContent(ContentInfos* contents);
382 ContentInfo* GetFirstDataContent(ContentInfos* contents);
383 ContentInfo* GetFirstMediaContent(SessionDescription* sdesc,
384                                   MediaType media_type);
385 ContentInfo* GetFirstAudioContent(SessionDescription* sdesc);
386 ContentInfo* GetFirstVideoContent(SessionDescription* sdesc);
387 ContentInfo* GetFirstDataContent(SessionDescription* sdesc);
388 AudioContentDescription* GetFirstAudioContentDescription(
389     SessionDescription* sdesc);
390 VideoContentDescription* GetFirstVideoContentDescription(
391     SessionDescription* sdesc);
392 RtpDataContentDescription* GetFirstRtpDataContentDescription(
393     SessionDescription* sdesc);
394 SctpDataContentDescription* GetFirstSctpDataContentDescription(
395     SessionDescription* sdesc);
396 
397 // Helper functions to return crypto suites used for SDES.
398 void GetSupportedAudioSdesCryptoSuites(
399     const webrtc::CryptoOptions& crypto_options,
400     std::vector<int>* crypto_suites);
401 void GetSupportedVideoSdesCryptoSuites(
402     const webrtc::CryptoOptions& crypto_options,
403     std::vector<int>* crypto_suites);
404 void GetSupportedDataSdesCryptoSuites(
405     const webrtc::CryptoOptions& crypto_options,
406     std::vector<int>* crypto_suites);
407 void GetSupportedAudioSdesCryptoSuiteNames(
408     const webrtc::CryptoOptions& crypto_options,
409     std::vector<std::string>* crypto_suite_names);
410 void GetSupportedVideoSdesCryptoSuiteNames(
411     const webrtc::CryptoOptions& crypto_options,
412     std::vector<std::string>* crypto_suite_names);
413 void GetSupportedDataSdesCryptoSuiteNames(
414     const webrtc::CryptoOptions& crypto_options,
415     std::vector<std::string>* crypto_suite_names);
416 
417 }  // namespace cricket
418 
419 #endif  // PC_MEDIA_SESSION_H_
420