blob: a94eef322aeab56b71aca6d3d228d6b0616489bb [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
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"
wu@webrtc.org967bfff2013-09-19 05:49:50 +000031#include "talk/app/webrtc/videosource.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032#include "talk/app/webrtc/videosourceinterface.h"
33
34namespace webrtc {
35
36TrackHandler::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
44TrackHandler::~TrackHandler() {
45 track_->UnregisterObserver(this);
46}
47
48void 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
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +000059LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(NULL) {}
60
61LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {}
62
63void LocalAudioSinkAdapter::OnData(const void* audio_data,
64 int bits_per_sample,
65 int sample_rate,
66 int number_of_channels,
67 int number_of_frames) {
68 talk_base::CritScope lock(&lock_);
69 if (sink_) {
70 sink_->OnData(audio_data, bits_per_sample, sample_rate,
71 number_of_channels, number_of_frames);
72 }
73}
74
75void LocalAudioSinkAdapter::SetSink(cricket::AudioRenderer::Sink* sink) {
76 talk_base::CritScope lock(&lock_);
77 ASSERT(!sink || !sink_);
78 sink_ = sink;
79}
80
henrike@webrtc.org28e20752013-07-10 00:45:36 +000081LocalAudioTrackHandler::LocalAudioTrackHandler(
82 AudioTrackInterface* track,
83 uint32 ssrc,
84 AudioProviderInterface* provider)
85 : TrackHandler(track, ssrc),
86 audio_track_(track),
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +000087 provider_(provider),
88 sink_adapter_(new LocalAudioSinkAdapter()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000089 OnEnabledChanged();
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +000090 track->AddSink(sink_adapter_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000091}
92
93LocalAudioTrackHandler::~LocalAudioTrackHandler() {
94}
95
96void LocalAudioTrackHandler::OnStateChanged() {
97 // TODO(perkj): What should happen when the state change?
98}
99
100void LocalAudioTrackHandler::Stop() {
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +0000101 audio_track_->RemoveSink(sink_adapter_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000102 cricket::AudioOptions options;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000103 provider_->SetAudioSend(ssrc(), false, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000104}
105
106void LocalAudioTrackHandler::OnEnabledChanged() {
107 cricket::AudioOptions options;
108 if (audio_track_->enabled() && audio_track_->GetSource()) {
109 options = static_cast<LocalAudioSource*>(
110 audio_track_->GetSource())->options();
111 }
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +0000112
113 // Use the renderer if the audio track has one, otherwise use the sink
114 // adapter owned by this class.
115 cricket::AudioRenderer* renderer = audio_track_->GetRenderer() ?
116 audio_track_->GetRenderer() : sink_adapter_.get();
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +0000117 ASSERT(renderer != NULL);
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +0000118 provider_->SetAudioSend(ssrc(), audio_track_->enabled(), options, renderer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119}
120
121RemoteAudioTrackHandler::RemoteAudioTrackHandler(
122 AudioTrackInterface* track,
123 uint32 ssrc,
124 AudioProviderInterface* provider)
125 : TrackHandler(track, ssrc),
126 audio_track_(track),
127 provider_(provider) {
128 OnEnabledChanged();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129}
130
131RemoteAudioTrackHandler::~RemoteAudioTrackHandler() {
132}
133
134void RemoteAudioTrackHandler::Stop() {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000135 provider_->SetAudioPlayout(ssrc(), false, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136}
137
138void RemoteAudioTrackHandler::OnStateChanged() {
139}
140
141void RemoteAudioTrackHandler::OnEnabledChanged() {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000142 provider_->SetAudioPlayout(ssrc(), audio_track_->enabled(),
143 audio_track_->GetRenderer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000144}
145
146LocalVideoTrackHandler::LocalVideoTrackHandler(
147 VideoTrackInterface* track,
148 uint32 ssrc,
149 VideoProviderInterface* provider)
150 : TrackHandler(track, ssrc),
151 local_video_track_(track),
152 provider_(provider) {
153 VideoSourceInterface* source = local_video_track_->GetSource();
154 if (source)
155 provider_->SetCaptureDevice(ssrc, source->GetVideoCapturer());
156 OnEnabledChanged();
157}
158
159LocalVideoTrackHandler::~LocalVideoTrackHandler() {
160}
161
162void LocalVideoTrackHandler::OnStateChanged() {
163}
164
165void LocalVideoTrackHandler::Stop() {
166 provider_->SetCaptureDevice(ssrc(), NULL);
167 provider_->SetVideoSend(ssrc(), false, NULL);
168}
169
170void LocalVideoTrackHandler::OnEnabledChanged() {
171 const cricket::VideoOptions* options = NULL;
172 VideoSourceInterface* source = local_video_track_->GetSource();
173 if (local_video_track_->enabled() && source) {
174 options = source->options();
175 }
176 provider_->SetVideoSend(ssrc(), local_video_track_->enabled(), options);
177}
178
179RemoteVideoTrackHandler::RemoteVideoTrackHandler(
180 VideoTrackInterface* track,
181 uint32 ssrc,
182 VideoProviderInterface* provider)
183 : TrackHandler(track, ssrc),
184 remote_video_track_(track),
185 provider_(provider) {
186 OnEnabledChanged();
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000187 provider_->SetVideoPlayout(ssrc, true,
188 remote_video_track_->GetSource()->FrameInput());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000189}
190
191RemoteVideoTrackHandler::~RemoteVideoTrackHandler() {
192}
193
194void RemoteVideoTrackHandler::Stop() {
195 // Since cricket::VideoRenderer is not reference counted
196 // we need to remove the renderer before we are deleted.
197 provider_->SetVideoPlayout(ssrc(), false, NULL);
198}
199
200void RemoteVideoTrackHandler::OnStateChanged() {
201}
202
203void RemoteVideoTrackHandler::OnEnabledChanged() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204}
205
206MediaStreamHandler::MediaStreamHandler(MediaStreamInterface* stream,
207 AudioProviderInterface* audio_provider,
208 VideoProviderInterface* video_provider)
209 : stream_(stream),
210 audio_provider_(audio_provider),
211 video_provider_(video_provider) {
212}
213
214MediaStreamHandler::~MediaStreamHandler() {
215 for (TrackHandlers::iterator it = track_handlers_.begin();
216 it != track_handlers_.end(); ++it) {
217 delete *it;
218 }
219}
220
221void MediaStreamHandler::RemoveTrack(MediaStreamTrackInterface* track) {
222 for (TrackHandlers::iterator it = track_handlers_.begin();
223 it != track_handlers_.end(); ++it) {
224 if ((*it)->track() == track) {
225 TrackHandler* track = *it;
226 track->Stop();
227 delete track;
228 track_handlers_.erase(it);
229 break;
230 }
231 }
232}
233
234TrackHandler* MediaStreamHandler::FindTrackHandler(
235 MediaStreamTrackInterface* track) {
236 TrackHandlers::iterator it = track_handlers_.begin();
237 for (; it != track_handlers_.end(); ++it) {
238 if ((*it)->track() == track) {
239 return *it;
240 break;
241 }
242 }
243 return NULL;
244}
245
246MediaStreamInterface* MediaStreamHandler::stream() {
247 return stream_.get();
248}
249
250void MediaStreamHandler::OnChanged() {
251}
252
253void MediaStreamHandler::Stop() {
254 for (TrackHandlers::const_iterator it = track_handlers_.begin();
255 it != track_handlers_.end(); ++it) {
256 (*it)->Stop();
257 }
258}
259
260LocalMediaStreamHandler::LocalMediaStreamHandler(
261 MediaStreamInterface* stream,
262 AudioProviderInterface* audio_provider,
263 VideoProviderInterface* video_provider)
264 : MediaStreamHandler(stream, audio_provider, video_provider) {
265}
266
267LocalMediaStreamHandler::~LocalMediaStreamHandler() {
268}
269
270void LocalMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
271 uint32 ssrc) {
272 ASSERT(!FindTrackHandler(audio_track));
273
274 TrackHandler* handler(new LocalAudioTrackHandler(audio_track, ssrc,
275 audio_provider_));
276 track_handlers_.push_back(handler);
277}
278
279void LocalMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
280 uint32 ssrc) {
281 ASSERT(!FindTrackHandler(video_track));
282
283 TrackHandler* handler(new LocalVideoTrackHandler(video_track, ssrc,
284 video_provider_));
285 track_handlers_.push_back(handler);
286}
287
288RemoteMediaStreamHandler::RemoteMediaStreamHandler(
289 MediaStreamInterface* stream,
290 AudioProviderInterface* audio_provider,
291 VideoProviderInterface* video_provider)
292 : MediaStreamHandler(stream, audio_provider, video_provider) {
293}
294
295RemoteMediaStreamHandler::~RemoteMediaStreamHandler() {
296}
297
298void RemoteMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
299 uint32 ssrc) {
300 ASSERT(!FindTrackHandler(audio_track));
301 TrackHandler* handler(
302 new RemoteAudioTrackHandler(audio_track, ssrc, audio_provider_));
303 track_handlers_.push_back(handler);
304}
305
306void RemoteMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
307 uint32 ssrc) {
308 ASSERT(!FindTrackHandler(video_track));
309 TrackHandler* handler(
310 new RemoteVideoTrackHandler(video_track, ssrc, video_provider_));
311 track_handlers_.push_back(handler);
312}
313
314MediaStreamHandlerContainer::MediaStreamHandlerContainer(
315 AudioProviderInterface* audio_provider,
316 VideoProviderInterface* video_provider)
317 : audio_provider_(audio_provider),
318 video_provider_(video_provider) {
319}
320
321MediaStreamHandlerContainer::~MediaStreamHandlerContainer() {
322 ASSERT(remote_streams_handlers_.empty());
323 ASSERT(local_streams_handlers_.empty());
324}
325
326void MediaStreamHandlerContainer::TearDown() {
327 for (StreamHandlerList::iterator it = remote_streams_handlers_.begin();
328 it != remote_streams_handlers_.end(); ++it) {
329 (*it)->Stop();
330 delete *it;
331 }
332 remote_streams_handlers_.clear();
333 for (StreamHandlerList::iterator it = local_streams_handlers_.begin();
334 it != local_streams_handlers_.end(); ++it) {
335 (*it)->Stop();
336 delete *it;
337 }
338 local_streams_handlers_.clear();
339}
340
341void MediaStreamHandlerContainer::RemoveRemoteStream(
342 MediaStreamInterface* stream) {
343 DeleteStreamHandler(&remote_streams_handlers_, stream);
344}
345
346void MediaStreamHandlerContainer::AddRemoteAudioTrack(
347 MediaStreamInterface* stream,
348 AudioTrackInterface* audio_track,
349 uint32 ssrc) {
350 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
351 stream);
352 if (handler == NULL) {
353 handler = CreateRemoteStreamHandler(stream);
354 }
355 handler->AddAudioTrack(audio_track, ssrc);
356}
357
358void MediaStreamHandlerContainer::AddRemoteVideoTrack(
359 MediaStreamInterface* stream,
360 VideoTrackInterface* video_track,
361 uint32 ssrc) {
362 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
363 stream);
364 if (handler == NULL) {
365 handler = CreateRemoteStreamHandler(stream);
366 }
367 handler->AddVideoTrack(video_track, ssrc);
368}
369
370void MediaStreamHandlerContainer::RemoveRemoteTrack(
371 MediaStreamInterface* stream,
372 MediaStreamTrackInterface* track) {
373 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
374 stream);
375 if (!VERIFY(handler != NULL)) {
376 LOG(LS_WARNING) << "Local MediaStreamHandler for stream with id "
377 << stream->label() << "doesnt't exist.";
378 return;
379 }
380 handler->RemoveTrack(track);
381}
382
383void MediaStreamHandlerContainer::RemoveLocalStream(
384 MediaStreamInterface* stream) {
385 DeleteStreamHandler(&local_streams_handlers_, stream);
386}
387
388void MediaStreamHandlerContainer::AddLocalAudioTrack(
389 MediaStreamInterface* stream,
390 AudioTrackInterface* audio_track,
391 uint32 ssrc) {
392 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
393 stream);
394 if (handler == NULL) {
395 handler = CreateLocalStreamHandler(stream);
396 }
397 handler->AddAudioTrack(audio_track, ssrc);
398}
399
400void MediaStreamHandlerContainer::AddLocalVideoTrack(
401 MediaStreamInterface* stream,
402 VideoTrackInterface* video_track,
403 uint32 ssrc) {
404 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
405 stream);
406 if (handler == NULL) {
407 handler = CreateLocalStreamHandler(stream);
408 }
409 handler->AddVideoTrack(video_track, ssrc);
410}
411
412void MediaStreamHandlerContainer::RemoveLocalTrack(
413 MediaStreamInterface* stream,
414 MediaStreamTrackInterface* track) {
415 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
416 stream);
417 if (!VERIFY(handler != NULL)) {
418 LOG(LS_WARNING) << "Remote MediaStreamHandler for stream with id "
419 << stream->label() << "doesnt't exist.";
420 return;
421 }
422 handler->RemoveTrack(track);
423}
424
425MediaStreamHandler* MediaStreamHandlerContainer::CreateRemoteStreamHandler(
426 MediaStreamInterface* stream) {
427 ASSERT(!FindStreamHandler(remote_streams_handlers_, stream));
428
429 RemoteMediaStreamHandler* handler =
430 new RemoteMediaStreamHandler(stream, audio_provider_, video_provider_);
431 remote_streams_handlers_.push_back(handler);
432 return handler;
433}
434
435MediaStreamHandler* MediaStreamHandlerContainer::CreateLocalStreamHandler(
436 MediaStreamInterface* stream) {
437 ASSERT(!FindStreamHandler(local_streams_handlers_, stream));
438
439 LocalMediaStreamHandler* handler =
440 new LocalMediaStreamHandler(stream, audio_provider_, video_provider_);
441 local_streams_handlers_.push_back(handler);
442 return handler;
443}
444
445MediaStreamHandler* MediaStreamHandlerContainer::FindStreamHandler(
446 const StreamHandlerList& handlers,
447 MediaStreamInterface* stream) {
448 StreamHandlerList::const_iterator it = handlers.begin();
449 for (; it != handlers.end(); ++it) {
450 if ((*it)->stream() == stream) {
451 return *it;
452 }
453 }
454 return NULL;
455}
456
457void MediaStreamHandlerContainer::DeleteStreamHandler(
458 StreamHandlerList* streamhandlers, MediaStreamInterface* stream) {
459 StreamHandlerList::iterator it = streamhandlers->begin();
460 for (; it != streamhandlers->end(); ++it) {
461 if ((*it)->stream() == stream) {
462 (*it)->Stop();
463 delete *it;
464 streamhandlers->erase(it);
465 break;
466 }
467 }
468}
469
470} // namespace webrtc