• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
LocalAudioSinkAdapter()59 LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(NULL) {}
60 
~LocalAudioSinkAdapter()61 LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
62   rtc::CritScope lock(&lock_);
63   if (sink_)
64     sink_->OnClose();
65 }
66 
OnData(const void * audio_data,int bits_per_sample,int sample_rate,int number_of_channels,int number_of_frames)67 void LocalAudioSinkAdapter::OnData(const void* audio_data,
68                                    int bits_per_sample,
69                                    int sample_rate,
70                                    int number_of_channels,
71                                    int number_of_frames) {
72   rtc::CritScope lock(&lock_);
73   if (sink_) {
74     sink_->OnData(audio_data, bits_per_sample, sample_rate,
75                   number_of_channels, number_of_frames);
76   }
77 }
78 
SetSink(cricket::AudioRenderer::Sink * sink)79 void LocalAudioSinkAdapter::SetSink(cricket::AudioRenderer::Sink* sink) {
80   rtc::CritScope lock(&lock_);
81   ASSERT(!sink || !sink_);
82   sink_ = sink;
83 }
84 
LocalAudioTrackHandler(AudioTrackInterface * track,uint32 ssrc,AudioProviderInterface * provider)85 LocalAudioTrackHandler::LocalAudioTrackHandler(
86     AudioTrackInterface* track,
87     uint32 ssrc,
88     AudioProviderInterface* provider)
89     : TrackHandler(track, ssrc),
90       audio_track_(track),
91       provider_(provider),
92       sink_adapter_(new LocalAudioSinkAdapter()) {
93   OnEnabledChanged();
94   track->AddSink(sink_adapter_.get());
95 }
96 
~LocalAudioTrackHandler()97 LocalAudioTrackHandler::~LocalAudioTrackHandler() {
98 }
99 
OnStateChanged()100 void LocalAudioTrackHandler::OnStateChanged() {
101   // TODO(perkj): What should happen when the state change?
102 }
103 
Stop()104 void LocalAudioTrackHandler::Stop() {
105   audio_track_->RemoveSink(sink_adapter_.get());
106   cricket::AudioOptions options;
107   provider_->SetAudioSend(ssrc(), false, options, NULL);
108 }
109 
OnEnabledChanged()110 void LocalAudioTrackHandler::OnEnabledChanged() {
111   cricket::AudioOptions options;
112   if (audio_track_->enabled() && audio_track_->GetSource()) {
113     // TODO(xians): Remove this static_cast since we should be able to connect
114     // a remote audio track to peer connection.
115     options = static_cast<LocalAudioSource*>(
116         audio_track_->GetSource())->options();
117   }
118 
119   // Use the renderer if the audio track has one, otherwise use the sink
120   // adapter owned by this class.
121   cricket::AudioRenderer* renderer = audio_track_->GetRenderer() ?
122       audio_track_->GetRenderer() : sink_adapter_.get();
123   ASSERT(renderer != NULL);
124   provider_->SetAudioSend(ssrc(), audio_track_->enabled(), options, renderer);
125 }
126 
RemoteAudioTrackHandler(AudioTrackInterface * track,uint32 ssrc,AudioProviderInterface * provider)127 RemoteAudioTrackHandler::RemoteAudioTrackHandler(
128     AudioTrackInterface* track,
129     uint32 ssrc,
130     AudioProviderInterface* provider)
131     : TrackHandler(track, ssrc),
132       audio_track_(track),
133       provider_(provider) {
134   track->GetSource()->RegisterAudioObserver(this);
135   OnEnabledChanged();
136 }
137 
~RemoteAudioTrackHandler()138 RemoteAudioTrackHandler::~RemoteAudioTrackHandler() {
139   audio_track_->GetSource()->UnregisterAudioObserver(this);
140 }
141 
Stop()142 void RemoteAudioTrackHandler::Stop() {
143   provider_->SetAudioPlayout(ssrc(), false, NULL);
144 }
145 
OnStateChanged()146 void RemoteAudioTrackHandler::OnStateChanged() {
147 }
148 
OnEnabledChanged()149 void RemoteAudioTrackHandler::OnEnabledChanged() {
150   provider_->SetAudioPlayout(ssrc(), audio_track_->enabled(),
151                              audio_track_->GetRenderer());
152 }
153 
OnSetVolume(double volume)154 void RemoteAudioTrackHandler::OnSetVolume(double volume) {
155   // When the track is disabled, the volume of the source, which is the
156   // corresponding WebRtc Voice Engine channel will be 0. So we do not allow
157   // setting the volume to the source when the track is disabled.
158   if (audio_track_->enabled())
159     provider_->SetAudioPlayoutVolume(ssrc(), volume);
160 }
161 
LocalVideoTrackHandler(VideoTrackInterface * track,uint32 ssrc,VideoProviderInterface * provider)162 LocalVideoTrackHandler::LocalVideoTrackHandler(
163     VideoTrackInterface* track,
164     uint32 ssrc,
165     VideoProviderInterface* provider)
166     : TrackHandler(track, ssrc),
167       local_video_track_(track),
168       provider_(provider) {
169   VideoSourceInterface* source = local_video_track_->GetSource();
170   if (source)
171     provider_->SetCaptureDevice(ssrc, source->GetVideoCapturer());
172   OnEnabledChanged();
173 }
174 
~LocalVideoTrackHandler()175 LocalVideoTrackHandler::~LocalVideoTrackHandler() {
176 }
177 
OnStateChanged()178 void LocalVideoTrackHandler::OnStateChanged() {
179 }
180 
Stop()181 void LocalVideoTrackHandler::Stop() {
182   provider_->SetCaptureDevice(ssrc(), NULL);
183   provider_->SetVideoSend(ssrc(), false, NULL);
184 }
185 
OnEnabledChanged()186 void LocalVideoTrackHandler::OnEnabledChanged() {
187   const cricket::VideoOptions* options = NULL;
188   VideoSourceInterface* source = local_video_track_->GetSource();
189   if (local_video_track_->enabled() && source) {
190     options = source->options();
191   }
192   provider_->SetVideoSend(ssrc(), local_video_track_->enabled(), options);
193 }
194 
RemoteVideoTrackHandler(VideoTrackInterface * track,uint32 ssrc,VideoProviderInterface * provider)195 RemoteVideoTrackHandler::RemoteVideoTrackHandler(
196     VideoTrackInterface* track,
197     uint32 ssrc,
198     VideoProviderInterface* provider)
199     : TrackHandler(track, ssrc),
200       remote_video_track_(track),
201       provider_(provider) {
202   OnEnabledChanged();
203   provider_->SetVideoPlayout(ssrc, true,
204                              remote_video_track_->GetSource()->FrameInput());
205 }
206 
~RemoteVideoTrackHandler()207 RemoteVideoTrackHandler::~RemoteVideoTrackHandler() {
208 }
209 
Stop()210 void RemoteVideoTrackHandler::Stop() {
211   // Since cricket::VideoRenderer is not reference counted
212   // we need to remove the renderer before we are deleted.
213   provider_->SetVideoPlayout(ssrc(), false, NULL);
214 }
215 
OnStateChanged()216 void RemoteVideoTrackHandler::OnStateChanged() {
217 }
218 
OnEnabledChanged()219 void RemoteVideoTrackHandler::OnEnabledChanged() {
220 }
221 
MediaStreamHandler(MediaStreamInterface * stream,AudioProviderInterface * audio_provider,VideoProviderInterface * video_provider)222 MediaStreamHandler::MediaStreamHandler(MediaStreamInterface* stream,
223                                        AudioProviderInterface* audio_provider,
224                                        VideoProviderInterface* video_provider)
225     : stream_(stream),
226       audio_provider_(audio_provider),
227       video_provider_(video_provider) {
228 }
229 
~MediaStreamHandler()230 MediaStreamHandler::~MediaStreamHandler() {
231   for (TrackHandlers::iterator it = track_handlers_.begin();
232        it != track_handlers_.end(); ++it) {
233     delete *it;
234   }
235 }
236 
RemoveTrack(MediaStreamTrackInterface * track)237 void MediaStreamHandler::RemoveTrack(MediaStreamTrackInterface* track) {
238   for (TrackHandlers::iterator it = track_handlers_.begin();
239        it != track_handlers_.end(); ++it) {
240     if ((*it)->track() == track) {
241       TrackHandler* track = *it;
242       track->Stop();
243       delete track;
244       track_handlers_.erase(it);
245       break;
246     }
247   }
248 }
249 
FindTrackHandler(MediaStreamTrackInterface * track)250 TrackHandler* MediaStreamHandler::FindTrackHandler(
251     MediaStreamTrackInterface* track) {
252   TrackHandlers::iterator it = track_handlers_.begin();
253   for (; it != track_handlers_.end(); ++it) {
254     if ((*it)->track() == track) {
255       return *it;
256       break;
257     }
258   }
259   return NULL;
260 }
261 
stream()262 MediaStreamInterface* MediaStreamHandler::stream() {
263   return stream_.get();
264 }
265 
OnChanged()266 void MediaStreamHandler::OnChanged() {
267 }
268 
Stop()269 void MediaStreamHandler::Stop() {
270   for (TrackHandlers::const_iterator it = track_handlers_.begin();
271       it != track_handlers_.end(); ++it) {
272     (*it)->Stop();
273   }
274 }
275 
LocalMediaStreamHandler(MediaStreamInterface * stream,AudioProviderInterface * audio_provider,VideoProviderInterface * video_provider)276 LocalMediaStreamHandler::LocalMediaStreamHandler(
277     MediaStreamInterface* stream,
278     AudioProviderInterface* audio_provider,
279     VideoProviderInterface* video_provider)
280     : MediaStreamHandler(stream, audio_provider, video_provider) {
281 }
282 
~LocalMediaStreamHandler()283 LocalMediaStreamHandler::~LocalMediaStreamHandler() {
284 }
285 
AddAudioTrack(AudioTrackInterface * audio_track,uint32 ssrc)286 void LocalMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
287                                             uint32 ssrc) {
288   ASSERT(!FindTrackHandler(audio_track));
289 
290   TrackHandler* handler(new LocalAudioTrackHandler(audio_track, ssrc,
291                                                    audio_provider_));
292   track_handlers_.push_back(handler);
293 }
294 
AddVideoTrack(VideoTrackInterface * video_track,uint32 ssrc)295 void LocalMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
296                                             uint32 ssrc) {
297   ASSERT(!FindTrackHandler(video_track));
298 
299   TrackHandler* handler(new LocalVideoTrackHandler(video_track, ssrc,
300                                                    video_provider_));
301   track_handlers_.push_back(handler);
302 }
303 
RemoteMediaStreamHandler(MediaStreamInterface * stream,AudioProviderInterface * audio_provider,VideoProviderInterface * video_provider)304 RemoteMediaStreamHandler::RemoteMediaStreamHandler(
305     MediaStreamInterface* stream,
306     AudioProviderInterface* audio_provider,
307     VideoProviderInterface* video_provider)
308     : MediaStreamHandler(stream, audio_provider, video_provider) {
309 }
310 
~RemoteMediaStreamHandler()311 RemoteMediaStreamHandler::~RemoteMediaStreamHandler() {
312 }
313 
AddAudioTrack(AudioTrackInterface * audio_track,uint32 ssrc)314 void RemoteMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
315                                              uint32 ssrc) {
316   ASSERT(!FindTrackHandler(audio_track));
317   TrackHandler* handler(
318       new RemoteAudioTrackHandler(audio_track, ssrc, audio_provider_));
319   track_handlers_.push_back(handler);
320 }
321 
AddVideoTrack(VideoTrackInterface * video_track,uint32 ssrc)322 void RemoteMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
323                                              uint32 ssrc) {
324   ASSERT(!FindTrackHandler(video_track));
325   TrackHandler* handler(
326       new RemoteVideoTrackHandler(video_track, ssrc, video_provider_));
327   track_handlers_.push_back(handler);
328 }
329 
MediaStreamHandlerContainer(AudioProviderInterface * audio_provider,VideoProviderInterface * video_provider)330 MediaStreamHandlerContainer::MediaStreamHandlerContainer(
331     AudioProviderInterface* audio_provider,
332     VideoProviderInterface* video_provider)
333     : audio_provider_(audio_provider),
334       video_provider_(video_provider) {
335 }
336 
~MediaStreamHandlerContainer()337 MediaStreamHandlerContainer::~MediaStreamHandlerContainer() {
338   ASSERT(remote_streams_handlers_.empty());
339   ASSERT(local_streams_handlers_.empty());
340 }
341 
TearDown()342 void MediaStreamHandlerContainer::TearDown() {
343   for (StreamHandlerList::iterator it = remote_streams_handlers_.begin();
344        it != remote_streams_handlers_.end(); ++it) {
345     (*it)->Stop();
346     delete *it;
347   }
348   remote_streams_handlers_.clear();
349   for (StreamHandlerList::iterator it = local_streams_handlers_.begin();
350        it != local_streams_handlers_.end(); ++it) {
351     (*it)->Stop();
352     delete *it;
353   }
354   local_streams_handlers_.clear();
355 }
356 
RemoveRemoteStream(MediaStreamInterface * stream)357 void MediaStreamHandlerContainer::RemoveRemoteStream(
358     MediaStreamInterface* stream) {
359   DeleteStreamHandler(&remote_streams_handlers_, stream);
360 }
361 
AddRemoteAudioTrack(MediaStreamInterface * stream,AudioTrackInterface * audio_track,uint32 ssrc)362 void MediaStreamHandlerContainer::AddRemoteAudioTrack(
363     MediaStreamInterface* stream,
364     AudioTrackInterface* audio_track,
365     uint32 ssrc) {
366   MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
367                                                   stream);
368   if (handler == NULL) {
369     handler = CreateRemoteStreamHandler(stream);
370   }
371   handler->AddAudioTrack(audio_track, ssrc);
372 }
373 
AddRemoteVideoTrack(MediaStreamInterface * stream,VideoTrackInterface * video_track,uint32 ssrc)374 void MediaStreamHandlerContainer::AddRemoteVideoTrack(
375     MediaStreamInterface* stream,
376     VideoTrackInterface* video_track,
377     uint32 ssrc) {
378   MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
379                                                   stream);
380   if (handler == NULL) {
381     handler = CreateRemoteStreamHandler(stream);
382   }
383   handler->AddVideoTrack(video_track, ssrc);
384 }
385 
RemoveRemoteTrack(MediaStreamInterface * stream,MediaStreamTrackInterface * track)386 void MediaStreamHandlerContainer::RemoveRemoteTrack(
387     MediaStreamInterface* stream,
388     MediaStreamTrackInterface* track) {
389   MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
390                                                   stream);
391   if (!VERIFY(handler != NULL)) {
392     LOG(LS_WARNING) << "Local MediaStreamHandler for stream  with id "
393                     << stream->label() << "doesnt't exist.";
394     return;
395   }
396   handler->RemoveTrack(track);
397 }
398 
RemoveLocalStream(MediaStreamInterface * stream)399 void MediaStreamHandlerContainer::RemoveLocalStream(
400     MediaStreamInterface* stream) {
401   DeleteStreamHandler(&local_streams_handlers_, stream);
402 }
403 
AddLocalAudioTrack(MediaStreamInterface * stream,AudioTrackInterface * audio_track,uint32 ssrc)404 void MediaStreamHandlerContainer::AddLocalAudioTrack(
405     MediaStreamInterface* stream,
406     AudioTrackInterface* audio_track,
407     uint32 ssrc) {
408   MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
409                                                   stream);
410   if (handler == NULL) {
411     handler = CreateLocalStreamHandler(stream);
412   }
413   handler->AddAudioTrack(audio_track, ssrc);
414 }
415 
AddLocalVideoTrack(MediaStreamInterface * stream,VideoTrackInterface * video_track,uint32 ssrc)416 void MediaStreamHandlerContainer::AddLocalVideoTrack(
417     MediaStreamInterface* stream,
418     VideoTrackInterface* video_track,
419     uint32 ssrc) {
420   MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
421                                                   stream);
422   if (handler == NULL) {
423     handler = CreateLocalStreamHandler(stream);
424   }
425   handler->AddVideoTrack(video_track, ssrc);
426 }
427 
RemoveLocalTrack(MediaStreamInterface * stream,MediaStreamTrackInterface * track)428 void MediaStreamHandlerContainer::RemoveLocalTrack(
429     MediaStreamInterface* stream,
430     MediaStreamTrackInterface* track) {
431   MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
432                                                   stream);
433   if (!VERIFY(handler != NULL)) {
434     LOG(LS_WARNING) << "Remote MediaStreamHandler for stream with id "
435                     << stream->label() << "doesnt't exist.";
436     return;
437   }
438   handler->RemoveTrack(track);
439 }
440 
CreateRemoteStreamHandler(MediaStreamInterface * stream)441 MediaStreamHandler* MediaStreamHandlerContainer::CreateRemoteStreamHandler(
442     MediaStreamInterface* stream) {
443   ASSERT(!FindStreamHandler(remote_streams_handlers_, stream));
444 
445   RemoteMediaStreamHandler* handler =
446       new RemoteMediaStreamHandler(stream, audio_provider_, video_provider_);
447   remote_streams_handlers_.push_back(handler);
448   return handler;
449 }
450 
CreateLocalStreamHandler(MediaStreamInterface * stream)451 MediaStreamHandler* MediaStreamHandlerContainer::CreateLocalStreamHandler(
452     MediaStreamInterface* stream) {
453   ASSERT(!FindStreamHandler(local_streams_handlers_, stream));
454 
455   LocalMediaStreamHandler* handler =
456       new LocalMediaStreamHandler(stream, audio_provider_, video_provider_);
457   local_streams_handlers_.push_back(handler);
458   return handler;
459 }
460 
FindStreamHandler(const StreamHandlerList & handlers,MediaStreamInterface * stream)461 MediaStreamHandler* MediaStreamHandlerContainer::FindStreamHandler(
462     const StreamHandlerList& handlers,
463     MediaStreamInterface* stream) {
464   StreamHandlerList::const_iterator it = handlers.begin();
465   for (; it != handlers.end(); ++it) {
466     if ((*it)->stream() == stream) {
467       return *it;
468     }
469   }
470   return NULL;
471 }
472 
DeleteStreamHandler(StreamHandlerList * streamhandlers,MediaStreamInterface * stream)473 void MediaStreamHandlerContainer::DeleteStreamHandler(
474     StreamHandlerList* streamhandlers, MediaStreamInterface* stream) {
475   StreamHandlerList::iterator it = streamhandlers->begin();
476   for (; it != streamhandlers->end(); ++it) {
477     if ((*it)->stream() == stream) {
478       (*it)->Stop();
479       delete *it;
480       streamhandlers->erase(it);
481       break;
482     }
483   }
484 }
485 
486 }  // namespace webrtc
487