| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| 11 * this list of conditions and the following disclaimer in the documentation | 11 * this list of conditions and the following disclaimer in the documentation |
| 12 * and/or other materials provided with the distribution. | 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 | 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. | 14 * derived from this software without specific prior written permission. |
| 15 * | 15 * |
| 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | 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 | 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
| 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | 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, | 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | 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 | 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 */ | 26 */ |
| 27 | 27 |
| 28 #ifndef TALK_APP_WEBRTC_MEDIASTREAMSIGNALING_H_ | 28 // TODO(deadbeef): Remove this file once Chrome build files don't reference it. |
| 29 #define TALK_APP_WEBRTC_MEDIASTREAMSIGNALING_H_ | |
| 30 | |
| 31 #include <map> | |
| 32 #include <string> | |
| 33 #include <vector> | |
| 34 | |
| 35 #include "talk/app/webrtc/datachannel.h" | |
| 36 #include "talk/app/webrtc/mediastream.h" | |
| 37 #include "talk/app/webrtc/peerconnectioninterface.h" | |
| 38 #include "talk/app/webrtc/streamcollection.h" | |
| 39 #include "talk/session/media/mediasession.h" | |
| 40 #include "webrtc/base/scoped_ref_ptr.h" | |
| 41 #include "webrtc/base/sigslot.h" | |
| 42 | |
| 43 namespace rtc { | |
| 44 class Thread; | |
| 45 } // namespace rtc | |
| 46 | |
| 47 namespace webrtc { | |
| 48 | |
| 49 class RemoteMediaStreamFactory; | |
| 50 | |
| 51 // A MediaStreamSignalingObserver is notified when events happen to | |
| 52 // MediaStreams, MediaStreamTracks or DataChannels associated with the observed | |
| 53 // MediaStreamSignaling object. The notifications identify the stream, track or | |
| 54 // channel. | |
| 55 class MediaStreamSignalingObserver { | |
| 56 public: | |
| 57 // Triggered when the remote SessionDescription has a new stream. | |
| 58 virtual void OnAddRemoteStream(MediaStreamInterface* stream) = 0; | |
| 59 | |
| 60 // Triggered when the remote SessionDescription removes a stream. | |
| 61 virtual void OnRemoveRemoteStream(MediaStreamInterface* stream) = 0; | |
| 62 | |
| 63 // Triggered when the remote SessionDescription has a new data channel. | |
| 64 virtual void OnAddDataChannel(DataChannelInterface* data_channel) = 0; | |
| 65 | |
| 66 // Triggered when the remote SessionDescription has a new audio track. | |
| 67 virtual void OnAddRemoteAudioTrack(MediaStreamInterface* stream, | |
| 68 AudioTrackInterface* audio_track, | |
| 69 uint32_t ssrc) = 0; | |
| 70 | |
| 71 // Triggered when the remote SessionDescription has a new video track. | |
| 72 virtual void OnAddRemoteVideoTrack(MediaStreamInterface* stream, | |
| 73 VideoTrackInterface* video_track, | |
| 74 uint32_t ssrc) = 0; | |
| 75 | |
| 76 // Triggered when the remote SessionDescription has removed an audio track. | |
| 77 virtual void OnRemoveRemoteAudioTrack(MediaStreamInterface* stream, | |
| 78 AudioTrackInterface* audio_track) = 0; | |
| 79 | |
| 80 // Triggered when the remote SessionDescription has removed a video track. | |
| 81 virtual void OnRemoveRemoteVideoTrack(MediaStreamInterface* stream, | |
| 82 VideoTrackInterface* video_track) = 0; | |
| 83 | |
| 84 // Triggered when the local SessionDescription has a new audio track. | |
| 85 virtual void OnAddLocalAudioTrack(MediaStreamInterface* stream, | |
| 86 AudioTrackInterface* audio_track, | |
| 87 uint32_t ssrc) = 0; | |
| 88 | |
| 89 // Triggered when the local SessionDescription has a new video track. | |
| 90 virtual void OnAddLocalVideoTrack(MediaStreamInterface* stream, | |
| 91 VideoTrackInterface* video_track, | |
| 92 uint32_t ssrc) = 0; | |
| 93 | |
| 94 // Triggered when the local SessionDescription has removed an audio track. | |
| 95 virtual void OnRemoveLocalAudioTrack(MediaStreamInterface* stream, | |
| 96 AudioTrackInterface* audio_track, | |
| 97 uint32_t ssrc) = 0; | |
| 98 | |
| 99 // Triggered when the local SessionDescription has removed a video track. | |
| 100 virtual void OnRemoveLocalVideoTrack(MediaStreamInterface* stream, | |
| 101 VideoTrackInterface* video_track) = 0; | |
| 102 | |
| 103 // Triggered when RemoveLocalStream is called. |stream| is no longer used | |
| 104 // when negotiating and all tracks in |stream| should stop providing data to | |
| 105 // this PeerConnection. This doesn't mean that the local session description | |
| 106 // has changed and OnRemoveLocalAudioTrack and OnRemoveLocalVideoTrack is not | |
| 107 // called for each individual track. | |
| 108 virtual void OnRemoveLocalStream(MediaStreamInterface* stream) = 0; | |
| 109 | |
| 110 protected: | |
| 111 ~MediaStreamSignalingObserver() {} | |
| 112 }; | |
| 113 | |
| 114 // MediaStreamSignaling works as a glue between MediaStreams and a cricket | |
| 115 // classes for SessionDescriptions. | |
| 116 // It is used for creating cricket::MediaSessionOptions given the local | |
| 117 // MediaStreams and data channels. | |
| 118 // | |
| 119 // It is responsible for creating remote MediaStreams given a remote | |
| 120 // SessionDescription and creating cricket::MediaSessionOptions given | |
| 121 // local MediaStreams. | |
| 122 // | |
| 123 // To signal that a DataChannel should be established: | |
| 124 // 1. Call AddDataChannel with the new DataChannel. Next time | |
| 125 // GetMediaSessionOptions will include the description of the DataChannel. | |
| 126 // 2. When a local session description is set, call UpdateLocalStreams with the | |
| 127 // session description. This will set the SSRC used for sending data on | |
| 128 // this DataChannel. | |
| 129 // 3. When remote session description is set, call UpdateRemoteStream with the | |
| 130 // session description. If the DataChannel label and a SSRC is included in | |
| 131 // the description, the DataChannel is updated with SSRC that will be used | |
| 132 // for receiving data. | |
| 133 // 4. When both the local and remote SSRC of a DataChannel is set the state of | |
| 134 // the DataChannel change to kOpen. | |
| 135 // | |
| 136 // To setup a DataChannel initialized by the remote end. | |
| 137 // 1. When remote session description is set, call UpdateRemoteStream with the | |
| 138 // session description. If a label and a SSRC of a new DataChannel is found | |
| 139 // MediaStreamSignalingObserver::OnAddDataChannel with the label and SSRC is | |
| 140 // triggered. | |
| 141 // 2. Create a DataChannel instance with the label and set the remote SSRC. | |
| 142 // 3. Call AddDataChannel with this new DataChannel. GetMediaSessionOptions | |
| 143 // will include the description of the DataChannel. | |
| 144 // 4. Create a local session description and call UpdateLocalStreams. This will | |
| 145 // set the local SSRC used by the DataChannel. | |
| 146 // 5. When both the local and remote SSRC of a DataChannel is set the state of | |
| 147 // the DataChannel change to kOpen. | |
| 148 // | |
| 149 // To close a DataChannel: | |
| 150 // 1. Call DataChannel::Close. This will change the state of the DataChannel to | |
| 151 // kClosing. GetMediaSessionOptions will not | |
| 152 // include the description of the DataChannel. | |
| 153 // 2. When a local session description is set, call UpdateLocalStreams with the | |
| 154 // session description. The description will no longer contain the | |
| 155 // DataChannel label or SSRC. | |
| 156 // 3. When remote session description is set, call UpdateRemoteStream with the | |
| 157 // session description. The description will no longer contain the | |
| 158 // DataChannel label or SSRC. The DataChannel SSRC is updated with SSRC=0. | |
| 159 // The DataChannel change state to kClosed. | |
| 160 | |
| 161 class MediaStreamSignaling : public sigslot::has_slots<> { | |
| 162 public: | |
| 163 typedef std::map<std::string, rtc::scoped_refptr<DataChannel> > | |
| 164 RtpDataChannels; | |
| 165 typedef std::vector<rtc::scoped_refptr<DataChannel>> SctpDataChannels; | |
| 166 | |
| 167 MediaStreamSignaling(rtc::Thread* signaling_thread, | |
| 168 MediaStreamSignalingObserver* stream_observer, | |
| 169 cricket::ChannelManager* channel_manager); | |
| 170 virtual ~MediaStreamSignaling(); | |
| 171 | |
| 172 // Notify all referenced objects that MediaStreamSignaling will be teared | |
| 173 // down. This method must be called prior to the dtor. | |
| 174 void TearDown(); | |
| 175 | |
| 176 // Set a factory for creating data channels that are initiated by the remote | |
| 177 // peer. | |
| 178 void SetDataChannelFactory(DataChannelFactory* data_channel_factory) { | |
| 179 data_channel_factory_ = data_channel_factory; | |
| 180 } | |
| 181 | |
| 182 // Checks if |id| is available to be assigned to a new SCTP data channel. | |
| 183 bool IsSctpSidAvailable(int sid) const; | |
| 184 | |
| 185 // Gets the first available SCTP id that is not assigned to any existing | |
| 186 // data channels. | |
| 187 bool AllocateSctpSid(rtc::SSLRole role, int* sid); | |
| 188 | |
| 189 // Adds |local_stream| to the collection of known MediaStreams that will be | |
| 190 // offered in a SessionDescription. | |
| 191 bool AddLocalStream(MediaStreamInterface* local_stream); | |
| 192 | |
| 193 // Removes |local_stream| from the collection of known MediaStreams that will | |
| 194 // be offered in a SessionDescription. | |
| 195 void RemoveLocalStream(MediaStreamInterface* local_stream); | |
| 196 | |
| 197 // Checks if any data channel has been added. | |
| 198 bool HasDataChannels() const; | |
| 199 // Adds |data_channel| to the collection of DataChannels that will be | |
| 200 // be offered in a SessionDescription. | |
| 201 bool AddDataChannel(DataChannel* data_channel); | |
| 202 // After we receive an OPEN message, create a data channel and add it. | |
| 203 bool AddDataChannelFromOpenMessage(const cricket::ReceiveDataParams& params, | |
| 204 const rtc::Buffer& payload); | |
| 205 void RemoveSctpDataChannel(int sid); | |
| 206 | |
| 207 // Returns a MediaSessionOptions struct with options decided by |options|, | |
| 208 // the local MediaStreams and DataChannels. | |
| 209 virtual bool GetOptionsForOffer( | |
| 210 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, | |
| 211 cricket::MediaSessionOptions* session_options); | |
| 212 | |
| 213 // Returns a MediaSessionOptions struct with options decided by | |
| 214 // |constraints|, the local MediaStreams and DataChannels. | |
| 215 virtual bool GetOptionsForAnswer( | |
| 216 const MediaConstraintsInterface* constraints, | |
| 217 cricket::MediaSessionOptions* options); | |
| 218 | |
| 219 // Called when the remote session description has changed. The purpose is to | |
| 220 // update remote MediaStreams and DataChannels with the current | |
| 221 // session state. | |
| 222 // If the remote SessionDescription contain information about a new remote | |
| 223 // MediaStreams a new remote MediaStream is created and | |
| 224 // MediaStreamSignalingObserver::OnAddStream is called. | |
| 225 // If a remote MediaStream is missing from | |
| 226 // the remote SessionDescription MediaStreamSignalingObserver::OnRemoveStream | |
| 227 // is called. | |
| 228 // If the SessionDescription contains information about a new DataChannel, | |
| 229 // MediaStreamSignalingObserver::OnAddDataChannel is called with the | |
| 230 // DataChannel. | |
| 231 void OnRemoteDescriptionChanged(const SessionDescriptionInterface* desc); | |
| 232 | |
| 233 // Called when the local session description has changed. The purpose is to | |
| 234 // update local and remote MediaStreams and DataChannels with the current | |
| 235 // session state. | |
| 236 // If |desc| indicates that the media type should be rejected, the method | |
| 237 // ends the remote MediaStreamTracks. | |
| 238 // It also updates local DataChannels with information about its local SSRC. | |
| 239 void OnLocalDescriptionChanged(const SessionDescriptionInterface* desc); | |
| 240 | |
| 241 // Called when the audio channel closes. | |
| 242 void OnAudioChannelClose(); | |
| 243 // Called when the video channel closes. | |
| 244 void OnVideoChannelClose(); | |
| 245 // Called when the data channel closes. | |
| 246 void OnDataChannelClose(); | |
| 247 | |
| 248 // Returns all current known local MediaStreams. | |
| 249 StreamCollectionInterface* local_streams() const { return local_streams_;} | |
| 250 | |
| 251 // Returns all current remote MediaStreams. | |
| 252 StreamCollectionInterface* remote_streams() const { | |
| 253 return remote_streams_.get(); | |
| 254 } | |
| 255 void OnDataTransportCreatedForSctp(); | |
| 256 void OnDtlsRoleReadyForSctp(rtc::SSLRole role); | |
| 257 void OnRemoteSctpDataChannelClosed(uint32_t sid); | |
| 258 | |
| 259 const SctpDataChannels& sctp_data_channels() const { | |
| 260 return sctp_data_channels_; | |
| 261 } | |
| 262 | |
| 263 private: | |
| 264 struct RemotePeerInfo { | |
| 265 RemotePeerInfo() | |
| 266 : msid_supported(false), | |
| 267 default_audio_track_needed(false), | |
| 268 default_video_track_needed(false) { | |
| 269 } | |
| 270 // True if it has been discovered that the remote peer support MSID. | |
| 271 bool msid_supported; | |
| 272 // The remote peer indicates in the session description that audio will be | |
| 273 // sent but no MSID is given. | |
| 274 bool default_audio_track_needed; | |
| 275 // The remote peer indicates in the session description that video will be | |
| 276 // sent but no MSID is given. | |
| 277 bool default_video_track_needed; | |
| 278 | |
| 279 bool IsDefaultMediaStreamNeeded() { | |
| 280 return !msid_supported && (default_audio_track_needed || | |
| 281 default_video_track_needed); | |
| 282 } | |
| 283 }; | |
| 284 | |
| 285 struct TrackInfo { | |
| 286 TrackInfo() : ssrc(0) {} | |
| 287 TrackInfo(const std::string& stream_label, | |
| 288 const std::string track_id, | |
| 289 uint32_t ssrc) | |
| 290 : stream_label(stream_label), track_id(track_id), ssrc(ssrc) {} | |
| 291 std::string stream_label; | |
| 292 std::string track_id; | |
| 293 uint32_t ssrc; | |
| 294 }; | |
| 295 typedef std::vector<TrackInfo> TrackInfos; | |
| 296 | |
| 297 // Makes sure a MediaStream Track is created for each StreamParam in | |
| 298 // |streams|. |media_type| is the type of the |streams| and can be either | |
| 299 // audio or video. | |
| 300 // If a new MediaStream is created it is added to |new_streams|. | |
| 301 void UpdateRemoteStreamsList( | |
| 302 const std::vector<cricket::StreamParams>& streams, | |
| 303 cricket::MediaType media_type, | |
| 304 StreamCollection* new_streams); | |
| 305 | |
| 306 // Triggered when a remote track has been seen for the first time in a remote | |
| 307 // session description. It creates a remote MediaStreamTrackInterface | |
| 308 // implementation and triggers MediaStreamSignaling::OnAddRemoteAudioTrack or | |
| 309 // MediaStreamSignaling::OnAddRemoteVideoTrack. | |
| 310 void OnRemoteTrackSeen(const std::string& stream_label, | |
| 311 const std::string& track_id, | |
| 312 uint32_t ssrc, | |
| 313 cricket::MediaType media_type); | |
| 314 | |
| 315 // Triggered when a remote track has been removed from a remote session | |
| 316 // description. It removes the remote track with id |track_id| from a remote | |
| 317 // MediaStream and triggers MediaStreamSignaling::OnRemoveRemoteAudioTrack or | |
| 318 // MediaStreamSignaling::OnRemoveRemoteVideoTrack. | |
| 319 void OnRemoteTrackRemoved(const std::string& stream_label, | |
| 320 const std::string& track_id, | |
| 321 cricket::MediaType media_type); | |
| 322 | |
| 323 // Set the MediaStreamTrackInterface::TrackState to |kEnded| on all remote | |
| 324 // tracks of type |media_type|. | |
| 325 void RejectRemoteTracks(cricket::MediaType media_type); | |
| 326 | |
| 327 // Finds remote MediaStreams without any tracks and removes them from | |
| 328 // |remote_streams_| and notifies the observer that the MediaStream no longer | |
| 329 // exist. | |
| 330 void UpdateEndedRemoteMediaStreams(); | |
| 331 void MaybeCreateDefaultStream(); | |
| 332 TrackInfos* GetRemoteTracks(cricket::MediaType type); | |
| 333 | |
| 334 // Returns a map of currently negotiated LocalTrackInfo of type |type|. | |
| 335 TrackInfos* GetLocalTracks(cricket::MediaType type); | |
| 336 bool FindLocalTrack(const std::string& track_id, cricket::MediaType type); | |
| 337 | |
| 338 // Loops through the vector of |streams| and finds added and removed | |
| 339 // StreamParams since last time this method was called. | |
| 340 // For each new or removed StreamParam NotifyLocalTrackAdded or | |
| 341 // NotifyLocalTrackRemoved in invoked. | |
| 342 void UpdateLocalTracks(const std::vector<cricket::StreamParams>& streams, | |
| 343 cricket::MediaType media_type); | |
| 344 | |
| 345 // Triggered when a local track has been seen for the first time in a local | |
| 346 // session description. | |
| 347 // This method triggers MediaStreamSignaling::OnAddLocalAudioTrack or | |
| 348 // MediaStreamSignaling::OnAddLocalVideoTrack if the rtp streams in the local | |
| 349 // SessionDescription can be mapped to a MediaStreamTrack in a MediaStream in | |
| 350 // |local_streams_| | |
| 351 void OnLocalTrackSeen(const std::string& stream_label, | |
| 352 const std::string& track_id, | |
| 353 uint32_t ssrc, | |
| 354 cricket::MediaType media_type); | |
| 355 | |
| 356 // Triggered when a local track has been removed from a local session | |
| 357 // description. | |
| 358 // This method triggers MediaStreamSignaling::OnRemoveLocalAudioTrack or | |
| 359 // MediaStreamSignaling::OnRemoveLocalVideoTrack if a stream has been removed | |
| 360 // from the local SessionDescription and the stream can be mapped to a | |
| 361 // MediaStreamTrack in a MediaStream in |local_streams_|. | |
| 362 void OnLocalTrackRemoved(const std::string& stream_label, | |
| 363 const std::string& track_id, | |
| 364 uint32_t ssrc, | |
| 365 cricket::MediaType media_type); | |
| 366 | |
| 367 void UpdateLocalRtpDataChannels(const cricket::StreamParamsVec& streams); | |
| 368 void UpdateRemoteRtpDataChannels(const cricket::StreamParamsVec& streams); | |
| 369 void UpdateClosingDataChannels( | |
| 370 const std::vector<std::string>& active_channels, bool is_local_update); | |
| 371 void CreateRemoteDataChannel(const std::string& label, uint32_t remote_ssrc); | |
| 372 | |
| 373 const TrackInfo* FindTrackInfo(const TrackInfos& infos, | |
| 374 const std::string& stream_label, | |
| 375 const std::string track_id) const; | |
| 376 | |
| 377 // Returns the index of the specified SCTP DataChannel in sctp_data_channels_, | |
| 378 // or -1 if not found. | |
| 379 int FindDataChannelBySid(int sid) const; | |
| 380 | |
| 381 RemotePeerInfo remote_info_; | |
| 382 rtc::Thread* signaling_thread_; | |
| 383 DataChannelFactory* data_channel_factory_; | |
| 384 MediaStreamSignalingObserver* stream_observer_; | |
| 385 rtc::scoped_refptr<StreamCollection> local_streams_; | |
| 386 rtc::scoped_refptr<StreamCollection> remote_streams_; | |
| 387 rtc::scoped_ptr<RemoteMediaStreamFactory> remote_stream_factory_; | |
| 388 | |
| 389 TrackInfos remote_audio_tracks_; | |
| 390 TrackInfos remote_video_tracks_; | |
| 391 TrackInfos local_audio_tracks_; | |
| 392 TrackInfos local_video_tracks_; | |
| 393 | |
| 394 int last_allocated_sctp_even_sid_; | |
| 395 int last_allocated_sctp_odd_sid_; | |
| 396 | |
| 397 RtpDataChannels rtp_data_channels_; | |
| 398 SctpDataChannels sctp_data_channels_; | |
| 399 }; | |
| 400 | |
| 401 } // namespace webrtc | |
| 402 | |
| 403 #endif // TALK_APP_WEBRTC_MEDIASTREAMSIGNALING_H_ | |
| OLD | NEW |