Home | History | Annotate | Download | only in webrtc
      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 
     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 
     44 TrackHandler::~TrackHandler() {
     45   track_->UnregisterObserver(this);
     46 }
     47 
     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 
     59 LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(NULL) {}
     60 
     61 LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
     62   talk_base::CritScope lock(&lock_);
     63   if (sink_)
     64     sink_->OnClose();
     65 }
     66 
     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   talk_base::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 
     79 void LocalAudioSinkAdapter::SetSink(cricket::AudioRenderer::Sink* sink) {
     80   talk_base::CritScope lock(&lock_);
     81   ASSERT(!sink || !sink_);
     82   sink_ = sink;
     83 }
     84 
     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 
     97 LocalAudioTrackHandler::~LocalAudioTrackHandler() {
     98 }
     99 
    100 void LocalAudioTrackHandler::OnStateChanged() {
    101   // TODO(perkj): What should happen when the state change?
    102 }
    103 
    104 void LocalAudioTrackHandler::Stop() {
    105   audio_track_->RemoveSink(sink_adapter_.get());
    106   cricket::AudioOptions options;
    107   provider_->SetAudioSend(ssrc(), false, options, NULL);
    108 }
    109 
    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 
    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 
    138 RemoteAudioTrackHandler::~RemoteAudioTrackHandler() {
    139   audio_track_->GetSource()->UnregisterAudioObserver(this);
    140 }
    141 
    142 void RemoteAudioTrackHandler::Stop() {
    143   provider_->SetAudioPlayout(ssrc(), false, NULL);
    144 }
    145 
    146 void RemoteAudioTrackHandler::OnStateChanged() {
    147 }
    148 
    149 void RemoteAudioTrackHandler::OnEnabledChanged() {
    150   provider_->SetAudioPlayout(ssrc(), audio_track_->enabled(),
    151                              audio_track_->GetRenderer());
    152 }
    153 
    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 
    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 
    175 LocalVideoTrackHandler::~LocalVideoTrackHandler() {
    176 }
    177 
    178 void LocalVideoTrackHandler::OnStateChanged() {
    179 }
    180 
    181 void LocalVideoTrackHandler::Stop() {
    182   provider_->SetCaptureDevice(ssrc(), NULL);
    183   provider_->SetVideoSend(ssrc(), false, NULL);
    184 }
    185 
    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 
    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 
    207 RemoteVideoTrackHandler::~RemoteVideoTrackHandler() {
    208 }
    209 
    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 
    216 void RemoteVideoTrackHandler::OnStateChanged() {
    217 }
    218 
    219 void RemoteVideoTrackHandler::OnEnabledChanged() {
    220 }
    221 
    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 
    230 MediaStreamHandler::~MediaStreamHandler() {
    231   for (TrackHandlers::iterator it = track_handlers_.begin();
    232        it != track_handlers_.end(); ++it) {
    233     delete *it;
    234   }
    235 }
    236 
    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 
    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 
    262 MediaStreamInterface* MediaStreamHandler::stream() {
    263   return stream_.get();
    264 }
    265 
    266 void MediaStreamHandler::OnChanged() {
    267 }
    268 
    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 
    276 LocalMediaStreamHandler::LocalMediaStreamHandler(
    277     MediaStreamInterface* stream,
    278     AudioProviderInterface* audio_provider,
    279     VideoProviderInterface* video_provider)
    280     : MediaStreamHandler(stream, audio_provider, video_provider) {
    281 }
    282 
    283 LocalMediaStreamHandler::~LocalMediaStreamHandler() {
    284 }
    285 
    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 
    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 
    304 RemoteMediaStreamHandler::RemoteMediaStreamHandler(
    305     MediaStreamInterface* stream,
    306     AudioProviderInterface* audio_provider,
    307     VideoProviderInterface* video_provider)
    308     : MediaStreamHandler(stream, audio_provider, video_provider) {
    309 }
    310 
    311 RemoteMediaStreamHandler::~RemoteMediaStreamHandler() {
    312 }
    313 
    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 
    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 
    330 MediaStreamHandlerContainer::MediaStreamHandlerContainer(
    331     AudioProviderInterface* audio_provider,
    332     VideoProviderInterface* video_provider)
    333     : audio_provider_(audio_provider),
    334       video_provider_(video_provider) {
    335 }
    336 
    337 MediaStreamHandlerContainer::~MediaStreamHandlerContainer() {
    338   ASSERT(remote_streams_handlers_.empty());
    339   ASSERT(local_streams_handlers_.empty());
    340 }
    341 
    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 
    357 void MediaStreamHandlerContainer::RemoveRemoteStream(
    358     MediaStreamInterface* stream) {
    359   DeleteStreamHandler(&remote_streams_handlers_, stream);
    360 }
    361 
    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 
    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 
    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 
    399 void MediaStreamHandlerContainer::RemoveLocalStream(
    400     MediaStreamInterface* stream) {
    401   DeleteStreamHandler(&local_streams_handlers_, stream);
    402 }
    403 
    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 
    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 
    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 
    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 
    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 
    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 
    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