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 |