1 /*
2 * libjingle
3 * Copyright 2012, 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 #include "talk/app/webrtc/mediastreamhandler.h"
29
30 #include "talk/app/webrtc/localaudiosource.h"
31 #include "talk/app/webrtc/videosource.h"
32 #include "talk/app/webrtc/videosourceinterface.h"
33
34 namespace webrtc {
35
TrackHandler(MediaStreamTrackInterface * track,uint32 ssrc)36 TrackHandler::TrackHandler(MediaStreamTrackInterface* track, uint32 ssrc)
37 : track_(track),
38 ssrc_(ssrc),
39 state_(track->state()),
40 enabled_(track->enabled()) {
41 track_->RegisterObserver(this);
42 }
43
~TrackHandler()44 TrackHandler::~TrackHandler() {
45 track_->UnregisterObserver(this);
46 }
47
OnChanged()48 void TrackHandler::OnChanged() {
49 if (state_ != track_->state()) {
50 state_ = track_->state();
51 OnStateChanged();
52 }
53 if (enabled_ != track_->enabled()) {
54 enabled_ = track_->enabled();
55 OnEnabledChanged();
56 }
57 }
58
LocalAudioTrackHandler(AudioTrackInterface * track,uint32 ssrc,AudioProviderInterface * provider)59 LocalAudioTrackHandler::LocalAudioTrackHandler(
60 AudioTrackInterface* track,
61 uint32 ssrc,
62 AudioProviderInterface* provider)
63 : TrackHandler(track, ssrc),
64 audio_track_(track),
65 provider_(provider) {
66 OnEnabledChanged();
67 }
68
~LocalAudioTrackHandler()69 LocalAudioTrackHandler::~LocalAudioTrackHandler() {
70 }
71
OnStateChanged()72 void LocalAudioTrackHandler::OnStateChanged() {
73 // TODO(perkj): What should happen when the state change?
74 }
75
Stop()76 void LocalAudioTrackHandler::Stop() {
77 cricket::AudioOptions options;
78 provider_->SetAudioSend(ssrc(), false, options, NULL);
79 }
80
OnEnabledChanged()81 void LocalAudioTrackHandler::OnEnabledChanged() {
82 cricket::AudioOptions options;
83 if (audio_track_->enabled() && audio_track_->GetSource()) {
84 options = static_cast<LocalAudioSource*>(
85 audio_track_->GetSource())->options();
86 }
87 provider_->SetAudioSend(ssrc(), audio_track_->enabled(), options,
88 audio_track_->GetRenderer());
89 }
90
RemoteAudioTrackHandler(AudioTrackInterface * track,uint32 ssrc,AudioProviderInterface * provider)91 RemoteAudioTrackHandler::RemoteAudioTrackHandler(
92 AudioTrackInterface* track,
93 uint32 ssrc,
94 AudioProviderInterface* provider)
95 : TrackHandler(track, ssrc),
96 audio_track_(track),
97 provider_(provider) {
98 OnEnabledChanged();
99 }
100
~RemoteAudioTrackHandler()101 RemoteAudioTrackHandler::~RemoteAudioTrackHandler() {
102 }
103
Stop()104 void RemoteAudioTrackHandler::Stop() {
105 provider_->SetAudioPlayout(ssrc(), false, NULL);
106 }
107
OnStateChanged()108 void RemoteAudioTrackHandler::OnStateChanged() {
109 }
110
OnEnabledChanged()111 void RemoteAudioTrackHandler::OnEnabledChanged() {
112 provider_->SetAudioPlayout(ssrc(), audio_track_->enabled(),
113 audio_track_->GetRenderer());
114 }
115
LocalVideoTrackHandler(VideoTrackInterface * track,uint32 ssrc,VideoProviderInterface * provider)116 LocalVideoTrackHandler::LocalVideoTrackHandler(
117 VideoTrackInterface* track,
118 uint32 ssrc,
119 VideoProviderInterface* provider)
120 : TrackHandler(track, ssrc),
121 local_video_track_(track),
122 provider_(provider) {
123 VideoSourceInterface* source = local_video_track_->GetSource();
124 if (source)
125 provider_->SetCaptureDevice(ssrc, source->GetVideoCapturer());
126 OnEnabledChanged();
127 }
128
~LocalVideoTrackHandler()129 LocalVideoTrackHandler::~LocalVideoTrackHandler() {
130 }
131
OnStateChanged()132 void LocalVideoTrackHandler::OnStateChanged() {
133 }
134
Stop()135 void LocalVideoTrackHandler::Stop() {
136 provider_->SetCaptureDevice(ssrc(), NULL);
137 provider_->SetVideoSend(ssrc(), false, NULL);
138 }
139
OnEnabledChanged()140 void LocalVideoTrackHandler::OnEnabledChanged() {
141 const cricket::VideoOptions* options = NULL;
142 VideoSourceInterface* source = local_video_track_->GetSource();
143 if (local_video_track_->enabled() && source) {
144 options = source->options();
145 }
146 provider_->SetVideoSend(ssrc(), local_video_track_->enabled(), options);
147 }
148
RemoteVideoTrackHandler(VideoTrackInterface * track,uint32 ssrc,VideoProviderInterface * provider)149 RemoteVideoTrackHandler::RemoteVideoTrackHandler(
150 VideoTrackInterface* track,
151 uint32 ssrc,
152 VideoProviderInterface* provider)
153 : TrackHandler(track, ssrc),
154 remote_video_track_(track),
155 provider_(provider) {
156 OnEnabledChanged();
157 provider_->SetVideoPlayout(ssrc, true,
158 remote_video_track_->GetSource()->FrameInput());
159 }
160
~RemoteVideoTrackHandler()161 RemoteVideoTrackHandler::~RemoteVideoTrackHandler() {
162 }
163
Stop()164 void RemoteVideoTrackHandler::Stop() {
165 // Since cricket::VideoRenderer is not reference counted
166 // we need to remove the renderer before we are deleted.
167 provider_->SetVideoPlayout(ssrc(), false, NULL);
168 }
169
OnStateChanged()170 void RemoteVideoTrackHandler::OnStateChanged() {
171 }
172
OnEnabledChanged()173 void RemoteVideoTrackHandler::OnEnabledChanged() {
174 }
175
MediaStreamHandler(MediaStreamInterface * stream,AudioProviderInterface * audio_provider,VideoProviderInterface * video_provider)176 MediaStreamHandler::MediaStreamHandler(MediaStreamInterface* stream,
177 AudioProviderInterface* audio_provider,
178 VideoProviderInterface* video_provider)
179 : stream_(stream),
180 audio_provider_(audio_provider),
181 video_provider_(video_provider) {
182 }
183
~MediaStreamHandler()184 MediaStreamHandler::~MediaStreamHandler() {
185 for (TrackHandlers::iterator it = track_handlers_.begin();
186 it != track_handlers_.end(); ++it) {
187 delete *it;
188 }
189 }
190
RemoveTrack(MediaStreamTrackInterface * track)191 void MediaStreamHandler::RemoveTrack(MediaStreamTrackInterface* track) {
192 for (TrackHandlers::iterator it = track_handlers_.begin();
193 it != track_handlers_.end(); ++it) {
194 if ((*it)->track() == track) {
195 TrackHandler* track = *it;
196 track->Stop();
197 delete track;
198 track_handlers_.erase(it);
199 break;
200 }
201 }
202 }
203
FindTrackHandler(MediaStreamTrackInterface * track)204 TrackHandler* MediaStreamHandler::FindTrackHandler(
205 MediaStreamTrackInterface* track) {
206 TrackHandlers::iterator it = track_handlers_.begin();
207 for (; it != track_handlers_.end(); ++it) {
208 if ((*it)->track() == track) {
209 return *it;
210 break;
211 }
212 }
213 return NULL;
214 }
215
stream()216 MediaStreamInterface* MediaStreamHandler::stream() {
217 return stream_.get();
218 }
219
OnChanged()220 void MediaStreamHandler::OnChanged() {
221 }
222
Stop()223 void MediaStreamHandler::Stop() {
224 for (TrackHandlers::const_iterator it = track_handlers_.begin();
225 it != track_handlers_.end(); ++it) {
226 (*it)->Stop();
227 }
228 }
229
LocalMediaStreamHandler(MediaStreamInterface * stream,AudioProviderInterface * audio_provider,VideoProviderInterface * video_provider)230 LocalMediaStreamHandler::LocalMediaStreamHandler(
231 MediaStreamInterface* stream,
232 AudioProviderInterface* audio_provider,
233 VideoProviderInterface* video_provider)
234 : MediaStreamHandler(stream, audio_provider, video_provider) {
235 }
236
~LocalMediaStreamHandler()237 LocalMediaStreamHandler::~LocalMediaStreamHandler() {
238 }
239
AddAudioTrack(AudioTrackInterface * audio_track,uint32 ssrc)240 void LocalMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
241 uint32 ssrc) {
242 ASSERT(!FindTrackHandler(audio_track));
243
244 TrackHandler* handler(new LocalAudioTrackHandler(audio_track, ssrc,
245 audio_provider_));
246 track_handlers_.push_back(handler);
247 }
248
AddVideoTrack(VideoTrackInterface * video_track,uint32 ssrc)249 void LocalMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
250 uint32 ssrc) {
251 ASSERT(!FindTrackHandler(video_track));
252
253 TrackHandler* handler(new LocalVideoTrackHandler(video_track, ssrc,
254 video_provider_));
255 track_handlers_.push_back(handler);
256 }
257
RemoteMediaStreamHandler(MediaStreamInterface * stream,AudioProviderInterface * audio_provider,VideoProviderInterface * video_provider)258 RemoteMediaStreamHandler::RemoteMediaStreamHandler(
259 MediaStreamInterface* stream,
260 AudioProviderInterface* audio_provider,
261 VideoProviderInterface* video_provider)
262 : MediaStreamHandler(stream, audio_provider, video_provider) {
263 }
264
~RemoteMediaStreamHandler()265 RemoteMediaStreamHandler::~RemoteMediaStreamHandler() {
266 }
267
AddAudioTrack(AudioTrackInterface * audio_track,uint32 ssrc)268 void RemoteMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
269 uint32 ssrc) {
270 ASSERT(!FindTrackHandler(audio_track));
271 TrackHandler* handler(
272 new RemoteAudioTrackHandler(audio_track, ssrc, audio_provider_));
273 track_handlers_.push_back(handler);
274 }
275
AddVideoTrack(VideoTrackInterface * video_track,uint32 ssrc)276 void RemoteMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
277 uint32 ssrc) {
278 ASSERT(!FindTrackHandler(video_track));
279 TrackHandler* handler(
280 new RemoteVideoTrackHandler(video_track, ssrc, video_provider_));
281 track_handlers_.push_back(handler);
282 }
283
MediaStreamHandlerContainer(AudioProviderInterface * audio_provider,VideoProviderInterface * video_provider)284 MediaStreamHandlerContainer::MediaStreamHandlerContainer(
285 AudioProviderInterface* audio_provider,
286 VideoProviderInterface* video_provider)
287 : audio_provider_(audio_provider),
288 video_provider_(video_provider) {
289 }
290
~MediaStreamHandlerContainer()291 MediaStreamHandlerContainer::~MediaStreamHandlerContainer() {
292 ASSERT(remote_streams_handlers_.empty());
293 ASSERT(local_streams_handlers_.empty());
294 }
295
TearDown()296 void MediaStreamHandlerContainer::TearDown() {
297 for (StreamHandlerList::iterator it = remote_streams_handlers_.begin();
298 it != remote_streams_handlers_.end(); ++it) {
299 (*it)->Stop();
300 delete *it;
301 }
302 remote_streams_handlers_.clear();
303 for (StreamHandlerList::iterator it = local_streams_handlers_.begin();
304 it != local_streams_handlers_.end(); ++it) {
305 (*it)->Stop();
306 delete *it;
307 }
308 local_streams_handlers_.clear();
309 }
310
RemoveRemoteStream(MediaStreamInterface * stream)311 void MediaStreamHandlerContainer::RemoveRemoteStream(
312 MediaStreamInterface* stream) {
313 DeleteStreamHandler(&remote_streams_handlers_, stream);
314 }
315
AddRemoteAudioTrack(MediaStreamInterface * stream,AudioTrackInterface * audio_track,uint32 ssrc)316 void MediaStreamHandlerContainer::AddRemoteAudioTrack(
317 MediaStreamInterface* stream,
318 AudioTrackInterface* audio_track,
319 uint32 ssrc) {
320 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
321 stream);
322 if (handler == NULL) {
323 handler = CreateRemoteStreamHandler(stream);
324 }
325 handler->AddAudioTrack(audio_track, ssrc);
326 }
327
AddRemoteVideoTrack(MediaStreamInterface * stream,VideoTrackInterface * video_track,uint32 ssrc)328 void MediaStreamHandlerContainer::AddRemoteVideoTrack(
329 MediaStreamInterface* stream,
330 VideoTrackInterface* video_track,
331 uint32 ssrc) {
332 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
333 stream);
334 if (handler == NULL) {
335 handler = CreateRemoteStreamHandler(stream);
336 }
337 handler->AddVideoTrack(video_track, ssrc);
338 }
339
RemoveRemoteTrack(MediaStreamInterface * stream,MediaStreamTrackInterface * track)340 void MediaStreamHandlerContainer::RemoveRemoteTrack(
341 MediaStreamInterface* stream,
342 MediaStreamTrackInterface* track) {
343 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
344 stream);
345 if (!VERIFY(handler != NULL)) {
346 LOG(LS_WARNING) << "Local MediaStreamHandler for stream with id "
347 << stream->label() << "doesnt't exist.";
348 return;
349 }
350 handler->RemoveTrack(track);
351 }
352
RemoveLocalStream(MediaStreamInterface * stream)353 void MediaStreamHandlerContainer::RemoveLocalStream(
354 MediaStreamInterface* stream) {
355 DeleteStreamHandler(&local_streams_handlers_, stream);
356 }
357
AddLocalAudioTrack(MediaStreamInterface * stream,AudioTrackInterface * audio_track,uint32 ssrc)358 void MediaStreamHandlerContainer::AddLocalAudioTrack(
359 MediaStreamInterface* stream,
360 AudioTrackInterface* audio_track,
361 uint32 ssrc) {
362 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
363 stream);
364 if (handler == NULL) {
365 handler = CreateLocalStreamHandler(stream);
366 }
367 handler->AddAudioTrack(audio_track, ssrc);
368 }
369
AddLocalVideoTrack(MediaStreamInterface * stream,VideoTrackInterface * video_track,uint32 ssrc)370 void MediaStreamHandlerContainer::AddLocalVideoTrack(
371 MediaStreamInterface* stream,
372 VideoTrackInterface* video_track,
373 uint32 ssrc) {
374 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
375 stream);
376 if (handler == NULL) {
377 handler = CreateLocalStreamHandler(stream);
378 }
379 handler->AddVideoTrack(video_track, ssrc);
380 }
381
RemoveLocalTrack(MediaStreamInterface * stream,MediaStreamTrackInterface * track)382 void MediaStreamHandlerContainer::RemoveLocalTrack(
383 MediaStreamInterface* stream,
384 MediaStreamTrackInterface* track) {
385 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
386 stream);
387 if (!VERIFY(handler != NULL)) {
388 LOG(LS_WARNING) << "Remote MediaStreamHandler for stream with id "
389 << stream->label() << "doesnt't exist.";
390 return;
391 }
392 handler->RemoveTrack(track);
393 }
394
CreateRemoteStreamHandler(MediaStreamInterface * stream)395 MediaStreamHandler* MediaStreamHandlerContainer::CreateRemoteStreamHandler(
396 MediaStreamInterface* stream) {
397 ASSERT(!FindStreamHandler(remote_streams_handlers_, stream));
398
399 RemoteMediaStreamHandler* handler =
400 new RemoteMediaStreamHandler(stream, audio_provider_, video_provider_);
401 remote_streams_handlers_.push_back(handler);
402 return handler;
403 }
404
CreateLocalStreamHandler(MediaStreamInterface * stream)405 MediaStreamHandler* MediaStreamHandlerContainer::CreateLocalStreamHandler(
406 MediaStreamInterface* stream) {
407 ASSERT(!FindStreamHandler(local_streams_handlers_, stream));
408
409 LocalMediaStreamHandler* handler =
410 new LocalMediaStreamHandler(stream, audio_provider_, video_provider_);
411 local_streams_handlers_.push_back(handler);
412 return handler;
413 }
414
FindStreamHandler(const StreamHandlerList & handlers,MediaStreamInterface * stream)415 MediaStreamHandler* MediaStreamHandlerContainer::FindStreamHandler(
416 const StreamHandlerList& handlers,
417 MediaStreamInterface* stream) {
418 StreamHandlerList::const_iterator it = handlers.begin();
419 for (; it != handlers.end(); ++it) {
420 if ((*it)->stream() == stream) {
421 return *it;
422 }
423 }
424 return NULL;
425 }
426
DeleteStreamHandler(StreamHandlerList * streamhandlers,MediaStreamInterface * stream)427 void MediaStreamHandlerContainer::DeleteStreamHandler(
428 StreamHandlerList* streamhandlers, MediaStreamInterface* stream) {
429 StreamHandlerList::iterator it = streamhandlers->begin();
430 for (; it != streamhandlers->end(); ++it) {
431 if ((*it)->stream() == stream) {
432 (*it)->Stop();
433 delete *it;
434 streamhandlers->erase(it);
435 break;
436 }
437 }
438 }
439
440 } // namespace webrtc
441