blob: ca8e1053c906dbc33c4d3f0a00f218f89e93a3d0 [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()) {
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000109 // TODO(xians): Remove this static_cast since we should be able to connect
110 // a remote audio track to peer connection.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000111 options = static_cast<LocalAudioSource*>(
112 audio_track_->GetSource())->options();
113 }
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +0000114
115 // Use the renderer if the audio track has one, otherwise use the sink
116 // adapter owned by this class.
117 cricket::AudioRenderer* renderer = audio_track_->GetRenderer() ?
118 audio_track_->GetRenderer() : sink_adapter_.get();
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +0000119 ASSERT(renderer != NULL);
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +0000120 provider_->SetAudioSend(ssrc(), audio_track_->enabled(), options, renderer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121}
122
123RemoteAudioTrackHandler::RemoteAudioTrackHandler(
124 AudioTrackInterface* track,
125 uint32 ssrc,
126 AudioProviderInterface* provider)
127 : TrackHandler(track, ssrc),
128 audio_track_(track),
129 provider_(provider) {
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000130 track->GetSource()->RegisterAudioObserver(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131 OnEnabledChanged();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000132}
133
134RemoteAudioTrackHandler::~RemoteAudioTrackHandler() {
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000135 audio_track_->GetSource()->UnregisterAudioObserver(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136}
137
138void RemoteAudioTrackHandler::Stop() {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000139 provider_->SetAudioPlayout(ssrc(), false, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140}
141
142void RemoteAudioTrackHandler::OnStateChanged() {
143}
144
145void RemoteAudioTrackHandler::OnEnabledChanged() {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000146 provider_->SetAudioPlayout(ssrc(), audio_track_->enabled(),
147 audio_track_->GetRenderer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148}
149
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +0000150void RemoteAudioTrackHandler::OnSetVolume(double volume) {
151 // When the track is disabled, the volume of the source, which is the
152 // corresponding WebRtc Voice Engine channel will be 0. So we do not allow
153 // setting the volume to the source when the track is disabled.
154 if (audio_track_->enabled())
155 provider_->SetAudioPlayoutVolume(ssrc(), volume);
156}
157
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158LocalVideoTrackHandler::LocalVideoTrackHandler(
159 VideoTrackInterface* track,
160 uint32 ssrc,
161 VideoProviderInterface* provider)
162 : TrackHandler(track, ssrc),
163 local_video_track_(track),
164 provider_(provider) {
165 VideoSourceInterface* source = local_video_track_->GetSource();
166 if (source)
167 provider_->SetCaptureDevice(ssrc, source->GetVideoCapturer());
168 OnEnabledChanged();
169}
170
171LocalVideoTrackHandler::~LocalVideoTrackHandler() {
172}
173
174void LocalVideoTrackHandler::OnStateChanged() {
175}
176
177void LocalVideoTrackHandler::Stop() {
178 provider_->SetCaptureDevice(ssrc(), NULL);
179 provider_->SetVideoSend(ssrc(), false, NULL);
180}
181
182void LocalVideoTrackHandler::OnEnabledChanged() {
183 const cricket::VideoOptions* options = NULL;
184 VideoSourceInterface* source = local_video_track_->GetSource();
185 if (local_video_track_->enabled() && source) {
186 options = source->options();
187 }
188 provider_->SetVideoSend(ssrc(), local_video_track_->enabled(), options);
189}
190
191RemoteVideoTrackHandler::RemoteVideoTrackHandler(
192 VideoTrackInterface* track,
193 uint32 ssrc,
194 VideoProviderInterface* provider)
195 : TrackHandler(track, ssrc),
196 remote_video_track_(track),
197 provider_(provider) {
198 OnEnabledChanged();
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000199 provider_->SetVideoPlayout(ssrc, true,
200 remote_video_track_->GetSource()->FrameInput());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000201}
202
203RemoteVideoTrackHandler::~RemoteVideoTrackHandler() {
204}
205
206void RemoteVideoTrackHandler::Stop() {
207 // Since cricket::VideoRenderer is not reference counted
208 // we need to remove the renderer before we are deleted.
209 provider_->SetVideoPlayout(ssrc(), false, NULL);
210}
211
212void RemoteVideoTrackHandler::OnStateChanged() {
213}
214
215void RemoteVideoTrackHandler::OnEnabledChanged() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000216}
217
218MediaStreamHandler::MediaStreamHandler(MediaStreamInterface* stream,
219 AudioProviderInterface* audio_provider,
220 VideoProviderInterface* video_provider)
221 : stream_(stream),
222 audio_provider_(audio_provider),
223 video_provider_(video_provider) {
224}
225
226MediaStreamHandler::~MediaStreamHandler() {
227 for (TrackHandlers::iterator it = track_handlers_.begin();
228 it != track_handlers_.end(); ++it) {
229 delete *it;
230 }
231}
232
233void MediaStreamHandler::RemoveTrack(MediaStreamTrackInterface* track) {
234 for (TrackHandlers::iterator it = track_handlers_.begin();
235 it != track_handlers_.end(); ++it) {
236 if ((*it)->track() == track) {
237 TrackHandler* track = *it;
238 track->Stop();
239 delete track;
240 track_handlers_.erase(it);
241 break;
242 }
243 }
244}
245
246TrackHandler* MediaStreamHandler::FindTrackHandler(
247 MediaStreamTrackInterface* track) {
248 TrackHandlers::iterator it = track_handlers_.begin();
249 for (; it != track_handlers_.end(); ++it) {
250 if ((*it)->track() == track) {
251 return *it;
252 break;
253 }
254 }
255 return NULL;
256}
257
258MediaStreamInterface* MediaStreamHandler::stream() {
259 return stream_.get();
260}
261
262void MediaStreamHandler::OnChanged() {
263}
264
265void MediaStreamHandler::Stop() {
266 for (TrackHandlers::const_iterator it = track_handlers_.begin();
267 it != track_handlers_.end(); ++it) {
268 (*it)->Stop();
269 }
270}
271
272LocalMediaStreamHandler::LocalMediaStreamHandler(
273 MediaStreamInterface* stream,
274 AudioProviderInterface* audio_provider,
275 VideoProviderInterface* video_provider)
276 : MediaStreamHandler(stream, audio_provider, video_provider) {
277}
278
279LocalMediaStreamHandler::~LocalMediaStreamHandler() {
280}
281
282void LocalMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
283 uint32 ssrc) {
284 ASSERT(!FindTrackHandler(audio_track));
285
286 TrackHandler* handler(new LocalAudioTrackHandler(audio_track, ssrc,
287 audio_provider_));
288 track_handlers_.push_back(handler);
289}
290
291void LocalMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
292 uint32 ssrc) {
293 ASSERT(!FindTrackHandler(video_track));
294
295 TrackHandler* handler(new LocalVideoTrackHandler(video_track, ssrc,
296 video_provider_));
297 track_handlers_.push_back(handler);
298}
299
300RemoteMediaStreamHandler::RemoteMediaStreamHandler(
301 MediaStreamInterface* stream,
302 AudioProviderInterface* audio_provider,
303 VideoProviderInterface* video_provider)
304 : MediaStreamHandler(stream, audio_provider, video_provider) {
305}
306
307RemoteMediaStreamHandler::~RemoteMediaStreamHandler() {
308}
309
310void RemoteMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
311 uint32 ssrc) {
312 ASSERT(!FindTrackHandler(audio_track));
313 TrackHandler* handler(
314 new RemoteAudioTrackHandler(audio_track, ssrc, audio_provider_));
315 track_handlers_.push_back(handler);
316}
317
318void RemoteMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
319 uint32 ssrc) {
320 ASSERT(!FindTrackHandler(video_track));
321 TrackHandler* handler(
322 new RemoteVideoTrackHandler(video_track, ssrc, video_provider_));
323 track_handlers_.push_back(handler);
324}
325
326MediaStreamHandlerContainer::MediaStreamHandlerContainer(
327 AudioProviderInterface* audio_provider,
328 VideoProviderInterface* video_provider)
329 : audio_provider_(audio_provider),
330 video_provider_(video_provider) {
331}
332
333MediaStreamHandlerContainer::~MediaStreamHandlerContainer() {
334 ASSERT(remote_streams_handlers_.empty());
335 ASSERT(local_streams_handlers_.empty());
336}
337
338void MediaStreamHandlerContainer::TearDown() {
339 for (StreamHandlerList::iterator it = remote_streams_handlers_.begin();
340 it != remote_streams_handlers_.end(); ++it) {
341 (*it)->Stop();
342 delete *it;
343 }
344 remote_streams_handlers_.clear();
345 for (StreamHandlerList::iterator it = local_streams_handlers_.begin();
346 it != local_streams_handlers_.end(); ++it) {
347 (*it)->Stop();
348 delete *it;
349 }
350 local_streams_handlers_.clear();
351}
352
353void MediaStreamHandlerContainer::RemoveRemoteStream(
354 MediaStreamInterface* stream) {
355 DeleteStreamHandler(&remote_streams_handlers_, stream);
356}
357
358void MediaStreamHandlerContainer::AddRemoteAudioTrack(
359 MediaStreamInterface* stream,
360 AudioTrackInterface* audio_track,
361 uint32 ssrc) {
362 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
363 stream);
364 if (handler == NULL) {
365 handler = CreateRemoteStreamHandler(stream);
366 }
367 handler->AddAudioTrack(audio_track, ssrc);
368}
369
370void MediaStreamHandlerContainer::AddRemoteVideoTrack(
371 MediaStreamInterface* stream,
372 VideoTrackInterface* video_track,
373 uint32 ssrc) {
374 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
375 stream);
376 if (handler == NULL) {
377 handler = CreateRemoteStreamHandler(stream);
378 }
379 handler->AddVideoTrack(video_track, ssrc);
380}
381
382void MediaStreamHandlerContainer::RemoveRemoteTrack(
383 MediaStreamInterface* stream,
384 MediaStreamTrackInterface* track) {
385 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
386 stream);
387 if (!VERIFY(handler != NULL)) {
388 LOG(LS_WARNING) << "Local MediaStreamHandler for stream with id "
389 << stream->label() << "doesnt't exist.";
390 return;
391 }
392 handler->RemoveTrack(track);
393}
394
395void MediaStreamHandlerContainer::RemoveLocalStream(
396 MediaStreamInterface* stream) {
397 DeleteStreamHandler(&local_streams_handlers_, stream);
398}
399
400void MediaStreamHandlerContainer::AddLocalAudioTrack(
401 MediaStreamInterface* stream,
402 AudioTrackInterface* audio_track,
403 uint32 ssrc) {
404 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
405 stream);
406 if (handler == NULL) {
407 handler = CreateLocalStreamHandler(stream);
408 }
409 handler->AddAudioTrack(audio_track, ssrc);
410}
411
412void MediaStreamHandlerContainer::AddLocalVideoTrack(
413 MediaStreamInterface* stream,
414 VideoTrackInterface* video_track,
415 uint32 ssrc) {
416 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
417 stream);
418 if (handler == NULL) {
419 handler = CreateLocalStreamHandler(stream);
420 }
421 handler->AddVideoTrack(video_track, ssrc);
422}
423
424void MediaStreamHandlerContainer::RemoveLocalTrack(
425 MediaStreamInterface* stream,
426 MediaStreamTrackInterface* track) {
427 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
428 stream);
429 if (!VERIFY(handler != NULL)) {
430 LOG(LS_WARNING) << "Remote MediaStreamHandler for stream with id "
431 << stream->label() << "doesnt't exist.";
432 return;
433 }
434 handler->RemoveTrack(track);
435}
436
437MediaStreamHandler* MediaStreamHandlerContainer::CreateRemoteStreamHandler(
438 MediaStreamInterface* stream) {
439 ASSERT(!FindStreamHandler(remote_streams_handlers_, stream));
440
441 RemoteMediaStreamHandler* handler =
442 new RemoteMediaStreamHandler(stream, audio_provider_, video_provider_);
443 remote_streams_handlers_.push_back(handler);
444 return handler;
445}
446
447MediaStreamHandler* MediaStreamHandlerContainer::CreateLocalStreamHandler(
448 MediaStreamInterface* stream) {
449 ASSERT(!FindStreamHandler(local_streams_handlers_, stream));
450
451 LocalMediaStreamHandler* handler =
452 new LocalMediaStreamHandler(stream, audio_provider_, video_provider_);
453 local_streams_handlers_.push_back(handler);
454 return handler;
455}
456
457MediaStreamHandler* MediaStreamHandlerContainer::FindStreamHandler(
458 const StreamHandlerList& handlers,
459 MediaStreamInterface* stream) {
460 StreamHandlerList::const_iterator it = handlers.begin();
461 for (; it != handlers.end(); ++it) {
462 if ((*it)->stream() == stream) {
463 return *it;
464 }
465 }
466 return NULL;
467}
468
469void MediaStreamHandlerContainer::DeleteStreamHandler(
470 StreamHandlerList* streamhandlers, MediaStreamInterface* stream) {
471 StreamHandlerList::iterator it = streamhandlers->begin();
472 for (; it != streamhandlers->end(); ++it) {
473 if ((*it)->stream() == stream) {
474 (*it)->Stop();
475 delete *it;
476 streamhandlers->erase(it);
477 break;
478 }
479 }
480}
481
482} // namespace webrtc