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