Home | History | Annotate | Download | only in media
      1 /*
      2  * libjingle
      3  * Copyright 2004 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 <string>
     29 #include "talk/media/base/constants.h"
     30 #include "talk/media/base/screencastid.h"
     31 #include "talk/p2p/base/parsing.h"
     32 #include "talk/session/media/call.h"
     33 #include "talk/session/media/currentspeakermonitor.h"
     34 #include "talk/session/media/mediasessionclient.h"
     35 #include "webrtc/base/helpers.h"
     36 #include "webrtc/base/logging.h"
     37 #include "webrtc/base/thread.h"
     38 #include "webrtc/base/window.h"
     39 
     40 namespace cricket {
     41 
     42 const uint32 MSG_CHECKAUTODESTROY = 1;
     43 const uint32 MSG_TERMINATECALL = 2;
     44 const uint32 MSG_PLAYDTMF = 3;
     45 
     46 namespace {
     47 const int kDTMFDelay = 300;  // msec
     48 const size_t kMaxDTMFDigits = 30;
     49 const int kSendToVoicemailTimeout = 1000*20;
     50 const int kNoVoicemailTimeout = 1000*180;
     51 const int kMediaMonitorInterval = 1000*15;
     52 // In order to be the same as the server-side switching, this must be 100.
     53 const int kAudioMonitorPollPeriodMillis = 100;
     54 
     55 // V is a pointer type.
     56 template<class K, class V>
     57 V FindOrNull(const std::map<K, V>& map,
     58              const K& key) {
     59   typename std::map<K, V>::const_iterator it = map.find(key);
     60   return (it != map.end()) ? it->second : NULL;
     61 }
     62 
     63 
     64 bool ContentContainsCrypto(const cricket::ContentInfo* content) {
     65   if (content != NULL) {
     66     const cricket::MediaContentDescription* desc =
     67         static_cast<const cricket::MediaContentDescription*>(
     68             content->description);
     69     if (!desc || desc->cryptos().empty()) {
     70       return false;
     71     }
     72   }
     73   return true;
     74 }
     75 
     76 }
     77 
     78 AudioSourceProxy::AudioSourceProxy(Call* call)
     79     : call_(call) {
     80   call_->SignalAudioMonitor.connect(this, &AudioSourceProxy::OnAudioMonitor);
     81   call_->SignalMediaStreamsUpdate.connect(
     82       this, &AudioSourceProxy::OnMediaStreamsUpdate);
     83 }
     84 
     85 void AudioSourceProxy::OnAudioMonitor(Call* call, const AudioInfo& info) {
     86   SignalAudioMonitor(this, info);
     87 }
     88 
     89 void AudioSourceProxy::OnMediaStreamsUpdate(Call* call, Session* session,
     90     const MediaStreams& added, const MediaStreams& removed) {
     91   SignalMediaStreamsUpdate(this, session, added, removed);
     92 }
     93 
     94 Call::Call(MediaSessionClient* session_client)
     95     : id_(rtc::CreateRandomId()),
     96       session_client_(session_client),
     97       has_video_(false),
     98       has_data_(false),
     99       muted_(false),
    100       video_muted_(false),
    101       send_to_voicemail_(true),
    102       playing_dtmf_(false) {
    103   audio_source_proxy_.reset(new AudioSourceProxy(this));
    104 }
    105 
    106 Call::~Call() {
    107   while (media_session_map_.begin() != media_session_map_.end()) {
    108     Session* session = media_session_map_.begin()->second.session;
    109     RemoveSession(session);
    110     session_client_->session_manager()->DestroySession(session);
    111   }
    112   rtc::Thread::Current()->Clear(this);
    113 }
    114 
    115 Session* Call::InitiateSession(const buzz::Jid& to,
    116                                const buzz::Jid& initiator,
    117                                const CallOptions& options) {
    118   std::string id;
    119   std::string initiator_name = initiator.Str();
    120   return InternalInitiateSession(id, to, initiator_name, options);
    121 }
    122 
    123 Session *Call::InitiateSession(const std::string& id,
    124                                const buzz::Jid& to,
    125                                const CallOptions& options) {
    126   std::string initiator_name;
    127   return InternalInitiateSession(id, to, initiator_name, options);
    128 }
    129 
    130 void Call::IncomingSession(Session* session, const SessionDescription* offer) {
    131   AddSession(session, offer);
    132 
    133   // Make sure the session knows about the incoming ssrcs. This needs to be done
    134   // prior to the SignalSessionState call, because that may trigger handling of
    135   // these new SSRCs, so they need to be registered before then.
    136   UpdateRemoteMediaStreams(session, offer->contents(), false);
    137 
    138   // Missed the first state, the initiate, which is needed by
    139   // call_client.
    140   SignalSessionState(this, session, Session::STATE_RECEIVEDINITIATE);
    141 }
    142 
    143 void Call::AcceptSession(Session* session,
    144                          const cricket::CallOptions& options) {
    145   MediaSessionMap::iterator it = media_session_map_.find(session->id());
    146   if (it != media_session_map_.end()) {
    147     const SessionDescription* answer = session_client_->CreateAnswer(
    148         session->remote_description(), options);
    149     it->second.session->Accept(answer);
    150   }
    151 }
    152 
    153 void Call::RejectSession(Session* session) {
    154   // Assume polite decline.
    155   MediaSessionMap::iterator it = media_session_map_.find(session->id());
    156   if (it != media_session_map_.end())
    157     it->second.session->Reject(STR_TERMINATE_DECLINE);
    158 }
    159 
    160 void Call::TerminateSession(Session* session) {
    161   MediaSessionMap::iterator it = media_session_map_.find(session->id());
    162   if (it != media_session_map_.end()) {
    163     // Assume polite terminations.
    164     it->second.session->Terminate();
    165   }
    166 }
    167 
    168 void Call::Terminate() {
    169   // Copy the list so that we can iterate over it in a stable way
    170   std::vector<Session*> sessions = this->sessions();
    171 
    172   // There may be more than one session to terminate
    173   std::vector<Session*>::iterator it;
    174   for (it = sessions.begin(); it != sessions.end(); ++it) {
    175     TerminateSession(*it);
    176   }
    177 }
    178 
    179 bool Call::SendViewRequest(Session* session,
    180                            const ViewRequest& view_request) {
    181   StaticVideoViews::const_iterator it;
    182   for (it = view_request.static_video_views.begin();
    183        it != view_request.static_video_views.end(); ++it) {
    184     StreamParams found_stream;
    185     bool found = false;
    186     MediaStreams* recv_streams = GetMediaStreams(session);
    187     if (recv_streams)
    188       found = recv_streams->GetVideoStream(it->selector, &found_stream);
    189     if (!found) {
    190       LOG(LS_WARNING) << "Trying to send view request for ("
    191                       << it->selector.ssrc << ", '"
    192                       << it->selector.groupid << "', '"
    193                       << it->selector.streamid << "'"
    194                       << ") is not in the local streams.";
    195       return false;
    196     }
    197   }
    198 
    199   XmlElements elems;
    200   WriteError error;
    201   if (!WriteJingleViewRequest(CN_VIDEO, view_request, &elems, &error)) {
    202     LOG(LS_ERROR) << "Couldn't write out view request: " << error.text;
    203     return false;
    204   }
    205 
    206   return session->SendInfoMessage(elems, session->remote_name());
    207 }
    208 
    209 void Call::SetVideoRenderer(Session* session, uint32 ssrc,
    210                             VideoRenderer* renderer) {
    211   VideoChannel* video_channel = GetVideoChannel(session);
    212   if (video_channel) {
    213     video_channel->SetRenderer(ssrc, renderer);
    214     LOG(LS_INFO) << "Set renderer of ssrc " << ssrc
    215                  << " to " << renderer << ".";
    216   } else {
    217     LOG(LS_INFO) << "Failed to set renderer of ssrc " << ssrc << ".";
    218   }
    219 }
    220 
    221 void Call::OnMessage(rtc::Message* message) {
    222   switch (message->message_id) {
    223   case MSG_CHECKAUTODESTROY:
    224     // If no more sessions for this call, delete it
    225     if (media_session_map_.empty())
    226       session_client_->DestroyCall(this);
    227     break;
    228   case MSG_TERMINATECALL:
    229     // Signal to the user that a timeout has happened and the call should
    230     // be sent to voicemail.
    231     if (send_to_voicemail_) {
    232       SignalSetupToCallVoicemail();
    233     }
    234 
    235     // Callee didn't answer - terminate call
    236     Terminate();
    237     break;
    238   case MSG_PLAYDTMF:
    239     ContinuePlayDTMF();
    240   }
    241 }
    242 
    243 std::vector<Session*> Call::sessions() {
    244   std::vector<Session*> sessions;
    245   MediaSessionMap::iterator it;
    246   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it)
    247     sessions.push_back(it->second.session);
    248 
    249   return sessions;
    250 }
    251 
    252 bool Call::AddSession(Session* session, const SessionDescription* offer) {
    253   bool succeeded = true;
    254   MediaSession media_session;
    255   media_session.session = session;
    256   media_session.voice_channel = NULL;
    257   media_session.video_channel = NULL;
    258   media_session.data_channel = NULL;
    259   media_session.recv_streams = NULL;
    260 
    261   const ContentInfo* audio_offer = GetFirstAudioContent(offer);
    262   const ContentInfo* video_offer = GetFirstVideoContent(offer);
    263   const ContentInfo* data_offer = GetFirstDataContent(offer);
    264   has_video_ = (video_offer != NULL);
    265   has_data_ = (data_offer != NULL);
    266 
    267   ASSERT(audio_offer != NULL);
    268   // Create voice channel and start a media monitor.
    269   media_session.voice_channel =
    270       session_client_->channel_manager()->CreateVoiceChannel(
    271           session, audio_offer->name, has_video_);
    272   // voice_channel can be NULL in case of NullVoiceEngine.
    273   if (media_session.voice_channel) {
    274     media_session.voice_channel->SignalMediaMonitor.connect(
    275         this, &Call::OnMediaMonitor);
    276     media_session.voice_channel->StartMediaMonitor(kMediaMonitorInterval);
    277   } else {
    278     succeeded = false;
    279   }
    280 
    281   // If desired, create video channel and start a media monitor.
    282   if (has_video_ && succeeded) {
    283     media_session.video_channel =
    284         session_client_->channel_manager()->CreateVideoChannel(
    285             session, video_offer->name, true, media_session.voice_channel);
    286     // video_channel can be NULL in case of NullVideoEngine.
    287     if (media_session.video_channel) {
    288       media_session.video_channel->SignalMediaMonitor.connect(
    289           this, &Call::OnMediaMonitor);
    290       media_session.video_channel->StartMediaMonitor(kMediaMonitorInterval);
    291     } else {
    292       succeeded = false;
    293     }
    294   }
    295 
    296   // If desired, create data channel.
    297   if (has_data_ && succeeded) {
    298     const DataContentDescription* data = GetFirstDataContentDescription(offer);
    299     if (data == NULL) {
    300       succeeded = false;
    301     } else {
    302       DataChannelType data_channel_type = DCT_RTP;
    303       if ((data->protocol() == kMediaProtocolSctp) ||
    304           (data->protocol() == kMediaProtocolDtlsSctp)) {
    305         data_channel_type = DCT_SCTP;
    306       }
    307 
    308       bool rtcp = false;
    309       media_session.data_channel =
    310           session_client_->channel_manager()->CreateDataChannel(
    311               session, data_offer->name, rtcp, data_channel_type);
    312       if (media_session.data_channel) {
    313         media_session.data_channel->SignalDataReceived.connect(
    314             this, &Call::OnDataReceived);
    315       } else {
    316         succeeded = false;
    317       }
    318     }
    319   }
    320 
    321   if (succeeded) {
    322     // Add session to list, create channels for this session.
    323     media_session.recv_streams = new MediaStreams;
    324     media_session_map_[session->id()] = media_session;
    325     session->SignalState.connect(this, &Call::OnSessionState);
    326     session->SignalError.connect(this, &Call::OnSessionError);
    327     session->SignalInfoMessage.connect(
    328         this, &Call::OnSessionInfoMessage);
    329     session->SignalRemoteDescriptionUpdate.connect(
    330         this, &Call::OnRemoteDescriptionUpdate);
    331     session->SignalReceivedTerminateReason
    332       .connect(this, &Call::OnReceivedTerminateReason);
    333 
    334     // If this call has the focus, enable this session's channels.
    335     if (session_client_->GetFocus() == this) {
    336       EnableSessionChannels(session, true);
    337     }
    338 
    339     // Signal client.
    340     SignalAddSession(this, session);
    341   }
    342 
    343   return succeeded;
    344 }
    345 
    346 void Call::RemoveSession(Session* session) {
    347   MediaSessionMap::iterator it = media_session_map_.find(session->id());
    348   if (it == media_session_map_.end())
    349     return;
    350 
    351   // Remove all the screencasts, if they haven't been already.
    352   while (!it->second.started_screencasts.empty()) {
    353     uint32 ssrc = it->second.started_screencasts.begin()->first;
    354     if (!StopScreencastWithoutSendingUpdate(it->second.session, ssrc)) {
    355       LOG(LS_ERROR) << "Unable to stop screencast with ssrc " << ssrc;
    356       ASSERT(false);
    357     }
    358   }
    359 
    360   // Destroy video channel
    361   VideoChannel* video_channel = it->second.video_channel;
    362   if (video_channel != NULL)
    363     session_client_->channel_manager()->DestroyVideoChannel(video_channel);
    364 
    365   // Destroy voice channel
    366   VoiceChannel* voice_channel = it->second.voice_channel;
    367   if (voice_channel != NULL)
    368     session_client_->channel_manager()->DestroyVoiceChannel(voice_channel);
    369 
    370   // Destroy data channel
    371   DataChannel* data_channel = it->second.data_channel;
    372   if (data_channel != NULL)
    373     session_client_->channel_manager()->DestroyDataChannel(data_channel);
    374 
    375   delete it->second.recv_streams;
    376   media_session_map_.erase(it);
    377 
    378   // Destroy speaker monitor
    379   StopSpeakerMonitor(session);
    380 
    381   // Signal client
    382   SignalRemoveSession(this, session);
    383 
    384   // The call auto destroys when the last session is removed
    385   rtc::Thread::Current()->Post(this, MSG_CHECKAUTODESTROY);
    386 }
    387 
    388 VoiceChannel* Call::GetVoiceChannel(Session* session) const {
    389   MediaSessionMap::const_iterator it = media_session_map_.find(session->id());
    390   return (it != media_session_map_.end()) ? it->second.voice_channel : NULL;
    391 }
    392 
    393 VideoChannel* Call::GetVideoChannel(Session* session) const {
    394   MediaSessionMap::const_iterator it = media_session_map_.find(session->id());
    395   return (it != media_session_map_.end()) ? it->second.video_channel : NULL;
    396 }
    397 
    398 DataChannel* Call::GetDataChannel(Session* session) const {
    399   MediaSessionMap::const_iterator it = media_session_map_.find(session->id());
    400   return (it != media_session_map_.end()) ? it->second.data_channel : NULL;
    401 }
    402 
    403 MediaStreams* Call::GetMediaStreams(Session* session) const {
    404   MediaSessionMap::const_iterator it = media_session_map_.find(session->id());
    405   return (it != media_session_map_.end()) ? it->second.recv_streams : NULL;
    406 }
    407 
    408 void Call::EnableChannels(bool enable) {
    409   MediaSessionMap::iterator it;
    410   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) {
    411     EnableSessionChannels(it->second.session, enable);
    412   }
    413 }
    414 
    415 void Call::EnableSessionChannels(Session* session, bool enable) {
    416   MediaSessionMap::iterator it = media_session_map_.find(session->id());
    417   if (it == media_session_map_.end())
    418     return;
    419 
    420   VoiceChannel* voice_channel = it->second.voice_channel;
    421   VideoChannel* video_channel = it->second.video_channel;
    422   DataChannel* data_channel = it->second.data_channel;
    423   if (voice_channel != NULL)
    424     voice_channel->Enable(enable);
    425   if (video_channel != NULL)
    426     video_channel->Enable(enable);
    427   if (data_channel != NULL)
    428     data_channel->Enable(enable);
    429 }
    430 
    431 void Call::Mute(bool mute) {
    432   muted_ = mute;
    433   MediaSessionMap::iterator it;
    434   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) {
    435     if (it->second.voice_channel != NULL)
    436       it->second.voice_channel->MuteStream(0, mute);
    437   }
    438 }
    439 
    440 void Call::MuteVideo(bool mute) {
    441   video_muted_ = mute;
    442   MediaSessionMap::iterator it;
    443   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) {
    444     if (it->second.video_channel != NULL)
    445       it->second.video_channel->MuteStream(0, mute);
    446   }
    447 }
    448 
    449 bool Call::SendData(Session* session,
    450                     const SendDataParams& params,
    451                     const rtc::Buffer& payload,
    452                     SendDataResult* result) {
    453   DataChannel* data_channel = GetDataChannel(session);
    454   if (!data_channel) {
    455     LOG(LS_WARNING) << "Could not send data: no data channel.";
    456     return false;
    457   }
    458 
    459   return data_channel->SendData(params, payload, result);
    460 }
    461 
    462 void Call::PressDTMF(int event) {
    463   // Queue up this digit
    464   if (queued_dtmf_.size() < kMaxDTMFDigits) {
    465     LOG(LS_INFO) << "Call::PressDTMF(" << event << ")";
    466 
    467     queued_dtmf_.push_back(event);
    468 
    469     if (!playing_dtmf_) {
    470       ContinuePlayDTMF();
    471     }
    472   }
    473 }
    474 
    475 cricket::VideoFormat ScreencastFormatFromFps(int fps) {
    476   // The capturer pretty much ignore this, but just in case we give it
    477   // a resolution big enough to cover any expected desktop.  In any
    478   // case, it can't be 0x0, or the CaptureManager will fail to use it.
    479   return cricket::VideoFormat(
    480       1, 1,
    481       cricket::VideoFormat::FpsToInterval(fps), cricket::FOURCC_ANY);
    482 }
    483 
    484 bool Call::StartScreencast(Session* session,
    485                            const std::string& streamid, uint32 ssrc,
    486                            const ScreencastId& screenid, int fps) {
    487   MediaSessionMap::iterator it = media_session_map_.find(session->id());
    488   if (it == media_session_map_.end()) {
    489     return false;
    490   }
    491 
    492   VideoChannel *video_channel = GetVideoChannel(session);
    493   if (!video_channel) {
    494     LOG(LS_WARNING) << "Cannot add screencast"
    495                     << " because there is no video channel.";
    496     return false;
    497   }
    498 
    499   VideoCapturer* capturer = session_client_->channel_manager()->
    500       CreateScreenCapturer(screenid);
    501   if (!capturer) {
    502     LOG(LS_WARNING) << "Could not create screencast capturer.";
    503     return false;
    504   }
    505 
    506   if (!video_channel->AddScreencast(ssrc, capturer)) {
    507     delete capturer;
    508     LOG(LS_WARNING) << "Could not add screencast capturer.";
    509     return false;
    510   }
    511 
    512   VideoFormat format = ScreencastFormatFromFps(fps);
    513   if (!session_client_->channel_manager()->StartVideoCapture(
    514           capturer, format)) {
    515     LOG(LS_WARNING) << "Could not start video capture.";
    516     video_channel->RemoveScreencast(ssrc);
    517     return false;
    518   }
    519 
    520   if (!video_channel->SetCapturer(ssrc, capturer)) {
    521     LOG(LS_WARNING) << "Could not start sending screencast.";
    522     session_client_->channel_manager()->StopVideoCapture(
    523         capturer, ScreencastFormatFromFps(fps));
    524     video_channel->RemoveScreencast(ssrc);
    525   }
    526 
    527   // TODO(pthatcher): Once the CaptureManager has a nicer interface
    528   // for removing captures (such as having StartCapture return a
    529   // handle), remove this StartedCapture stuff.
    530   it->second.started_screencasts.insert(
    531       std::make_pair(ssrc, StartedCapture(capturer, format)));
    532 
    533   // TODO(pthatcher): Verify we aren't re-using an existing id or
    534   // ssrc.
    535   StreamParams stream;
    536   stream.id = streamid;
    537   stream.ssrcs.push_back(ssrc);
    538   VideoContentDescription* video = CreateVideoStreamUpdate(stream);
    539 
    540   // TODO(pthatcher): Wait until view request before sending video.
    541   video_channel->SetLocalContent(video, CA_UPDATE, NULL);
    542   SendVideoStreamUpdate(session, video);
    543   return true;
    544 }
    545 
    546 bool Call::StopScreencast(Session* session,
    547                           const std::string& streamid, uint32 ssrc) {
    548   if (!StopScreencastWithoutSendingUpdate(session, ssrc)) {
    549     return false;
    550   }
    551 
    552   VideoChannel *video_channel = GetVideoChannel(session);
    553   if (!video_channel) {
    554     LOG(LS_WARNING) << "Cannot add screencast"
    555                     << " because there is no video channel.";
    556     return false;
    557   }
    558 
    559   StreamParams stream;
    560   stream.id = streamid;
    561   // No ssrcs
    562   VideoContentDescription* video = CreateVideoStreamUpdate(stream);
    563 
    564   video_channel->SetLocalContent(video, CA_UPDATE, NULL);
    565   SendVideoStreamUpdate(session, video);
    566   return true;
    567 }
    568 
    569 bool Call::StopScreencastWithoutSendingUpdate(
    570     Session* session, uint32 ssrc) {
    571   MediaSessionMap::iterator it = media_session_map_.find(session->id());
    572   if (it == media_session_map_.end()) {
    573     return false;
    574   }
    575 
    576   VideoChannel *video_channel = GetVideoChannel(session);
    577   if (!video_channel) {
    578     LOG(LS_WARNING) << "Cannot remove screencast"
    579                     << " because there is no video channel.";
    580     return false;
    581   }
    582 
    583   StartedScreencastMap::const_iterator screencast_iter =
    584       it->second.started_screencasts.find(ssrc);
    585   if (screencast_iter == it->second.started_screencasts.end()) {
    586     LOG(LS_WARNING) << "Could not stop screencast " << ssrc
    587                     << " because there is no capturer.";
    588     return false;
    589   }
    590 
    591   VideoCapturer* capturer = screencast_iter->second.capturer;
    592   VideoFormat format = screencast_iter->second.format;
    593   video_channel->SetCapturer(ssrc, NULL);
    594   if (!session_client_->channel_manager()->StopVideoCapture(
    595           capturer, format)) {
    596     LOG(LS_WARNING) << "Could not stop screencast " << ssrc
    597                     << " because could not stop capture.";
    598     return false;
    599   }
    600   video_channel->RemoveScreencast(ssrc);
    601   it->second.started_screencasts.erase(ssrc);
    602   return true;
    603 }
    604 
    605 VideoContentDescription* Call::CreateVideoStreamUpdate(
    606     const StreamParams& stream) {
    607   VideoContentDescription* video = new VideoContentDescription();
    608   video->set_multistream(true);
    609   video->set_partial(true);
    610   video->AddStream(stream);
    611   return video;
    612 }
    613 
    614 void Call::SendVideoStreamUpdate(
    615     Session* session, VideoContentDescription* video) {
    616   // Takes the ownership of |video|.
    617   rtc::scoped_ptr<VideoContentDescription> description(video);
    618   const ContentInfo* video_info =
    619       GetFirstVideoContent(session->local_description());
    620   if (video_info == NULL) {
    621     LOG(LS_WARNING) << "Cannot send stream update for video.";
    622     return;
    623   }
    624 
    625   std::vector<ContentInfo> contents;
    626   contents.push_back(
    627       ContentInfo(video_info->name, video_info->type, description.get()));
    628 
    629   session->SendDescriptionInfoMessage(contents);
    630 }
    631 
    632 void Call::ContinuePlayDTMF() {
    633   playing_dtmf_ = false;
    634 
    635   // Check to see if we have a queued tone
    636   if (queued_dtmf_.size() > 0) {
    637     playing_dtmf_ = true;
    638 
    639     int tone = queued_dtmf_.front();
    640     queued_dtmf_.pop_front();
    641 
    642     LOG(LS_INFO) << "Call::ContinuePlayDTMF(" << tone << ")";
    643     for (MediaSessionMap::iterator it = media_session_map_.begin();
    644          it != media_session_map_.end(); ++it) {
    645       if (it->second.voice_channel != NULL) {
    646         it->second.voice_channel->PressDTMF(tone, true);
    647       }
    648     }
    649 
    650     // Post a message to play the next tone or at least clear the playing_dtmf_
    651     // bit.
    652     rtc::Thread::Current()->PostDelayed(kDTMFDelay, this, MSG_PLAYDTMF);
    653   }
    654 }
    655 
    656 void Call::Join(Call* call, bool enable) {
    657   for (MediaSessionMap::iterator it = call->media_session_map_.begin();
    658        it != call->media_session_map_.end(); ++it) {
    659     // Shouldn't already exist.
    660     ASSERT(media_session_map_.find(it->first) == media_session_map_.end());
    661     media_session_map_[it->first] = it->second;
    662 
    663     it->second.session->SignalState.connect(this, &Call::OnSessionState);
    664     it->second.session->SignalError.connect(this, &Call::OnSessionError);
    665     it->second.session->SignalReceivedTerminateReason
    666       .connect(this, &Call::OnReceivedTerminateReason);
    667 
    668     EnableSessionChannels(it->second.session, enable);
    669   }
    670 
    671   // Moved all the sessions over, so the other call should no longer have any.
    672   call->media_session_map_.clear();
    673 }
    674 
    675 void Call::StartConnectionMonitor(Session* session, int cms) {
    676   VoiceChannel* voice_channel = GetVoiceChannel(session);
    677   if (voice_channel) {
    678     voice_channel->SignalConnectionMonitor.connect(this,
    679         &Call::OnConnectionMonitor);
    680     voice_channel->StartConnectionMonitor(cms);
    681   }
    682 
    683   VideoChannel* video_channel = GetVideoChannel(session);
    684   if (video_channel) {
    685     video_channel->SignalConnectionMonitor.connect(this,
    686         &Call::OnConnectionMonitor);
    687     video_channel->StartConnectionMonitor(cms);
    688   }
    689 }
    690 
    691 void Call::StopConnectionMonitor(Session* session) {
    692   VoiceChannel* voice_channel = GetVoiceChannel(session);
    693   if (voice_channel) {
    694     voice_channel->StopConnectionMonitor();
    695     voice_channel->SignalConnectionMonitor.disconnect(this);
    696   }
    697 
    698   VideoChannel* video_channel = GetVideoChannel(session);
    699   if (video_channel) {
    700     video_channel->StopConnectionMonitor();
    701     video_channel->SignalConnectionMonitor.disconnect(this);
    702   }
    703 }
    704 
    705 void Call::StartAudioMonitor(Session* session, int cms) {
    706   VoiceChannel* voice_channel = GetVoiceChannel(session);
    707   if (voice_channel) {
    708     voice_channel->SignalAudioMonitor.connect(this, &Call::OnAudioMonitor);
    709     voice_channel->StartAudioMonitor(cms);
    710   }
    711 }
    712 
    713 void Call::StopAudioMonitor(Session* session) {
    714   VoiceChannel* voice_channel = GetVoiceChannel(session);
    715   if (voice_channel) {
    716     voice_channel->StopAudioMonitor();
    717     voice_channel->SignalAudioMonitor.disconnect(this);
    718   }
    719 }
    720 
    721 bool Call::IsAudioMonitorRunning(Session* session) {
    722   VoiceChannel* voice_channel = GetVoiceChannel(session);
    723   if (voice_channel) {
    724     return voice_channel->IsAudioMonitorRunning();
    725   } else {
    726     return false;
    727   }
    728 }
    729 
    730 void Call::StartSpeakerMonitor(Session* session) {
    731   if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
    732     if (!IsAudioMonitorRunning(session)) {
    733       StartAudioMonitor(session, kAudioMonitorPollPeriodMillis);
    734     }
    735     CurrentSpeakerMonitor* speaker_monitor =
    736         new cricket::CurrentSpeakerMonitor(
    737             audio_source_proxy_.get(), session);
    738     speaker_monitor->SignalUpdate.connect(this, &Call::OnSpeakerMonitor);
    739     speaker_monitor->Start();
    740     speaker_monitor_map_[session->id()] = speaker_monitor;
    741   } else {
    742     LOG(LS_WARNING) << "Already started speaker monitor for session "
    743                     << session->id() << ".";
    744   }
    745 }
    746 
    747 void Call::StopSpeakerMonitor(Session* session) {
    748   if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
    749     LOG(LS_WARNING) << "Speaker monitor for session "
    750                     << session->id() << " already stopped.";
    751   } else {
    752     CurrentSpeakerMonitor* monitor = speaker_monitor_map_[session->id()];
    753     monitor->Stop();
    754     speaker_monitor_map_.erase(session->id());
    755     delete monitor;
    756   }
    757 }
    758 
    759 void Call::OnConnectionMonitor(VoiceChannel* channel,
    760                                const std::vector<ConnectionInfo> &infos) {
    761   SignalConnectionMonitor(this, infos);
    762 }
    763 
    764 void Call::OnMediaMonitor(VoiceChannel* channel, const VoiceMediaInfo& info) {
    765   last_voice_media_info_ = info;
    766   SignalMediaMonitor(this, info);
    767 }
    768 
    769 void Call::OnAudioMonitor(VoiceChannel* channel, const AudioInfo& info) {
    770   SignalAudioMonitor(this, info);
    771 }
    772 
    773 void Call::OnSpeakerMonitor(CurrentSpeakerMonitor* monitor, uint32 ssrc) {
    774   Session* session = static_cast<Session*>(monitor->session());
    775   MediaStreams* recv_streams = GetMediaStreams(session);
    776   if (recv_streams) {
    777     StreamParams stream;
    778     recv_streams->GetAudioStream(StreamSelector(ssrc), &stream);
    779     SignalSpeakerMonitor(this, session, stream);
    780   }
    781 }
    782 
    783 void Call::OnConnectionMonitor(VideoChannel* channel,
    784                                const std::vector<ConnectionInfo> &infos) {
    785   SignalVideoConnectionMonitor(this, infos);
    786 }
    787 
    788 void Call::OnMediaMonitor(VideoChannel* channel, const VideoMediaInfo& info) {
    789   SignalVideoMediaMonitor(this, info);
    790 }
    791 
    792 void Call::OnDataReceived(DataChannel* channel,
    793                           const ReceiveDataParams& params,
    794                           const rtc::Buffer& payload) {
    795   SignalDataReceived(this, params, payload);
    796 }
    797 
    798 uint32 Call::id() {
    799   return id_;
    800 }
    801 
    802 void Call::OnSessionState(BaseSession* base_session, BaseSession::State state) {
    803   Session* session = static_cast<Session*>(base_session);
    804   switch (state) {
    805     case Session::STATE_RECEIVEDACCEPT:
    806       UpdateRemoteMediaStreams(session,
    807           session->remote_description()->contents(), false);
    808       session_client_->session_manager()->signaling_thread()->Clear(this,
    809           MSG_TERMINATECALL);
    810       break;
    811     case Session::STATE_RECEIVEDREJECT:
    812     case Session::STATE_RECEIVEDTERMINATE:
    813       session_client_->session_manager()->signaling_thread()->Clear(this,
    814           MSG_TERMINATECALL);
    815       break;
    816     default:
    817       break;
    818   }
    819   SignalSessionState(this, session, state);
    820 }
    821 
    822 void Call::OnSessionError(BaseSession* base_session, Session::Error error) {
    823   session_client_->session_manager()->signaling_thread()->Clear(this,
    824       MSG_TERMINATECALL);
    825   SignalSessionError(this, static_cast<Session*>(base_session), error);
    826 }
    827 
    828 void Call::OnSessionInfoMessage(Session* session,
    829                                 const buzz::XmlElement* action_elem) {
    830   if (!IsJingleViewRequest(action_elem)) {
    831     return;
    832   }
    833 
    834   ViewRequest view_request;
    835   ParseError error;
    836   if (!ParseJingleViewRequest(action_elem, &view_request, &error)) {
    837     LOG(LS_WARNING) << "Failed to parse view request: " << error.text;
    838     return;
    839   }
    840 
    841   VideoChannel* video_channel = GetVideoChannel(session);
    842   if (video_channel == NULL) {
    843     LOG(LS_WARNING) << "Ignore view request since we have no video channel.";
    844     return;
    845   }
    846 
    847   if (!video_channel->ApplyViewRequest(view_request)) {
    848     LOG(LS_WARNING) << "Failed to ApplyViewRequest.";
    849   }
    850 }
    851 
    852 void Call::OnRemoteDescriptionUpdate(BaseSession* base_session,
    853                                      const ContentInfos& updated_contents) {
    854   Session* session = static_cast<Session*>(base_session);
    855 
    856   const ContentInfo* audio_content = GetFirstAudioContent(updated_contents);
    857   if (audio_content) {
    858     const AudioContentDescription* audio_update =
    859         static_cast<const AudioContentDescription*>(audio_content->description);
    860     if (!audio_update->codecs().empty()) {
    861       UpdateVoiceChannelRemoteContent(session, audio_update);
    862     }
    863   }
    864 
    865   const ContentInfo* video_content = GetFirstVideoContent(updated_contents);
    866   if (video_content) {
    867     const VideoContentDescription* video_update =
    868         static_cast<const VideoContentDescription*>(video_content->description);
    869     if (!video_update->codecs().empty()) {
    870       UpdateVideoChannelRemoteContent(session, video_update);
    871     }
    872   }
    873 
    874   const ContentInfo* data_content = GetFirstDataContent(updated_contents);
    875   if (data_content) {
    876     const DataContentDescription* data_update =
    877         static_cast<const DataContentDescription*>(data_content->description);
    878     if (!data_update->codecs().empty()) {
    879       UpdateDataChannelRemoteContent(session, data_update);
    880     }
    881   }
    882 
    883   UpdateRemoteMediaStreams(session, updated_contents, true);
    884 }
    885 
    886 bool Call::UpdateVoiceChannelRemoteContent(
    887     Session* session, const AudioContentDescription* audio) {
    888   VoiceChannel* voice_channel = GetVoiceChannel(session);
    889   if (!voice_channel->SetRemoteContent(audio, CA_UPDATE, NULL)) {
    890     const std::string error_desc =
    891         "Failure in audio SetRemoteContent with CA_UPDATE";
    892     LOG(LS_ERROR) << error_desc;
    893     session->SetError(BaseSession::ERROR_CONTENT, error_desc);
    894     return false;
    895   }
    896   return true;
    897 }
    898 
    899 bool Call::UpdateVideoChannelRemoteContent(
    900     Session* session, const VideoContentDescription* video) {
    901   VideoChannel* video_channel = GetVideoChannel(session);
    902   if (!video_channel->SetRemoteContent(video, CA_UPDATE, NULL)) {
    903     const std::string error_desc =
    904         "Failure in video SetRemoteContent with CA_UPDATE";
    905     LOG(LS_ERROR) << error_desc;
    906     session->SetError(BaseSession::ERROR_CONTENT, error_desc);
    907     return false;
    908   }
    909   return true;
    910 }
    911 
    912 bool Call::UpdateDataChannelRemoteContent(
    913     Session* session, const DataContentDescription* data) {
    914   DataChannel* data_channel = GetDataChannel(session);
    915   if (!data_channel->SetRemoteContent(data, CA_UPDATE, NULL)) {
    916     const std::string error_desc =
    917         "Failure in data SetRemoteContent with CA_UPDATE";
    918     LOG(LS_ERROR) << error_desc;
    919     session->SetError(BaseSession::ERROR_CONTENT, error_desc);
    920     return false;
    921   }
    922   return true;
    923 }
    924 
    925 void Call::UpdateRemoteMediaStreams(Session* session,
    926                                     const ContentInfos& updated_contents,
    927                                     bool update_channels) {
    928   MediaStreams* recv_streams = GetMediaStreams(session);
    929   if (!recv_streams)
    930     return;
    931 
    932   cricket::MediaStreams added_streams;
    933   cricket::MediaStreams removed_streams;
    934 
    935   const ContentInfo* audio_content = GetFirstAudioContent(updated_contents);
    936   if (audio_content) {
    937     const AudioContentDescription* audio_update =
    938         static_cast<const AudioContentDescription*>(audio_content->description);
    939     UpdateRecvStreams(audio_update->streams(),
    940                       update_channels ? GetVoiceChannel(session) : NULL,
    941                       recv_streams->mutable_audio(),
    942                       added_streams.mutable_audio(),
    943                       removed_streams.mutable_audio());
    944   }
    945 
    946   const ContentInfo* video_content = GetFirstVideoContent(updated_contents);
    947   if (video_content) {
    948     const VideoContentDescription* video_update =
    949         static_cast<const VideoContentDescription*>(video_content->description);
    950     UpdateRecvStreams(video_update->streams(),
    951                       update_channels ? GetVideoChannel(session) : NULL,
    952                       recv_streams->mutable_video(),
    953                       added_streams.mutable_video(),
    954                       removed_streams.mutable_video());
    955   }
    956 
    957   const ContentInfo* data_content = GetFirstDataContent(updated_contents);
    958   if (data_content) {
    959     const DataContentDescription* data_update =
    960         static_cast<const DataContentDescription*>(data_content->description);
    961     UpdateRecvStreams(data_update->streams(),
    962                       update_channels ? GetDataChannel(session) : NULL,
    963                       recv_streams->mutable_data(),
    964                       added_streams.mutable_data(),
    965                       removed_streams.mutable_data());
    966   }
    967 
    968   if (!added_streams.empty() || !removed_streams.empty()) {
    969     SignalMediaStreamsUpdate(this, session, added_streams, removed_streams);
    970   }
    971 }
    972 
    973 void FindStreamChanges(const std::vector<StreamParams>& streams,
    974                        const std::vector<StreamParams>& updates,
    975                        std::vector<StreamParams>* added_streams,
    976                        std::vector<StreamParams>* removed_streams) {
    977   for (std::vector<StreamParams>::const_iterator update = updates.begin();
    978        update != updates.end(); ++update) {
    979     StreamParams stream;
    980     if (GetStreamByIds(streams, update->groupid, update->id, &stream)) {
    981       if (!update->has_ssrcs()) {
    982         removed_streams->push_back(stream);
    983       }
    984     } else {
    985       // There's a bug on reflector that will send <stream>s even
    986       // though there is not ssrc (which means there isn't really a
    987       // stream).  To work around it, we simply ignore new <stream>s
    988       // that don't have any ssrcs.
    989       if (update->has_ssrcs()) {
    990         added_streams->push_back(*update);
    991       }
    992     }
    993   }
    994 }
    995 
    996 void Call::UpdateRecvStreams(const std::vector<StreamParams>& update_streams,
    997                              BaseChannel* channel,
    998                              std::vector<StreamParams>* recv_streams,
    999                              std::vector<StreamParams>* added_streams,
   1000                              std::vector<StreamParams>* removed_streams) {
   1001   FindStreamChanges(*recv_streams,
   1002                     update_streams, added_streams, removed_streams);
   1003   AddRecvStreams(*added_streams,
   1004                  channel, recv_streams);
   1005   RemoveRecvStreams(*removed_streams,
   1006                     channel, recv_streams);
   1007 }
   1008 
   1009 void Call::AddRecvStreams(const std::vector<StreamParams>& added_streams,
   1010                           BaseChannel* channel,
   1011                           std::vector<StreamParams>* recv_streams) {
   1012   std::vector<StreamParams>::const_iterator stream;
   1013   for (stream = added_streams.begin();
   1014        stream != added_streams.end();
   1015        ++stream) {
   1016     AddRecvStream(*stream, channel, recv_streams);
   1017   }
   1018 }
   1019 
   1020 void Call::AddRecvStream(const StreamParams& stream,
   1021                          BaseChannel* channel,
   1022                          std::vector<StreamParams>* recv_streams) {
   1023   if (channel && stream.has_ssrcs()) {
   1024     channel->AddRecvStream(stream);
   1025   }
   1026   recv_streams->push_back(stream);
   1027 }
   1028 
   1029 void Call::RemoveRecvStreams(const std::vector<StreamParams>& removed_streams,
   1030                              BaseChannel* channel,
   1031                              std::vector<StreamParams>* recv_streams) {
   1032   std::vector<StreamParams>::const_iterator stream;
   1033   for (stream = removed_streams.begin();
   1034        stream != removed_streams.end();
   1035        ++stream) {
   1036     RemoveRecvStream(*stream, channel, recv_streams);
   1037   }
   1038 }
   1039 
   1040 void Call::RemoveRecvStream(const StreamParams& stream,
   1041                             BaseChannel* channel,
   1042                             std::vector<StreamParams>* recv_streams) {
   1043   if (channel && stream.has_ssrcs()) {
   1044     // TODO(pthatcher): Change RemoveRecvStream to take a stream argument.
   1045     channel->RemoveRecvStream(stream.first_ssrc());
   1046   }
   1047   RemoveStreamByIds(recv_streams, stream.groupid, stream.id);
   1048 }
   1049 
   1050 void Call::OnReceivedTerminateReason(Session* session,
   1051                                      const std::string& reason) {
   1052   session_client_->session_manager()->signaling_thread()->Clear(this,
   1053     MSG_TERMINATECALL);
   1054   SignalReceivedTerminateReason(this, session, reason);
   1055 }
   1056 
   1057 // TODO(mdodd): Get ride of this method since all Hangouts are using a secure
   1058 // connection.
   1059 bool Call::secure() const {
   1060   if (session_client_->secure() == SEC_DISABLED) {
   1061     return false;
   1062   }
   1063 
   1064   bool ret = true;
   1065   int i = 0;
   1066 
   1067   MediaSessionMap::const_iterator it;
   1068   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) {
   1069     LOG_F(LS_VERBOSE) << "session[" << i
   1070                       << "], check local and remote descriptions";
   1071     i++;
   1072 
   1073     if (!SessionDescriptionContainsCrypto(
   1074             it->second.session->local_description()) ||
   1075         !SessionDescriptionContainsCrypto(
   1076             it->second.session->remote_description())) {
   1077       ret = false;
   1078       break;
   1079     }
   1080   }
   1081 
   1082   LOG_F(LS_VERBOSE) << "secure=" << ret;
   1083   return ret;
   1084 }
   1085 
   1086 bool Call::SessionDescriptionContainsCrypto(
   1087     const SessionDescription* sdesc) const {
   1088   if (sdesc == NULL) {
   1089     LOG_F(LS_VERBOSE) << "sessionDescription is NULL";
   1090     return false;
   1091   }
   1092 
   1093   return ContentContainsCrypto(sdesc->GetContentByName(CN_AUDIO)) &&
   1094          ContentContainsCrypto(sdesc->GetContentByName(CN_VIDEO));
   1095 }
   1096 
   1097 Session* Call::InternalInitiateSession(const std::string& id,
   1098                                        const buzz::Jid& to,
   1099                                        const std::string& initiator_name,
   1100                                        const CallOptions& options) {
   1101   const SessionDescription* offer = session_client_->CreateOffer(options);
   1102 
   1103   Session* session = session_client_->CreateSession(id, this);
   1104   // Only override the initiator_name if it was manually supplied. Otherwise,
   1105   // session_client_ will supply the local jid as initiator in CreateOffer.
   1106   if (!initiator_name.empty()) {
   1107     session->set_initiator_name(initiator_name);
   1108   }
   1109 
   1110   AddSession(session, offer);
   1111   session->Initiate(to.Str(), offer);
   1112 
   1113   // After this timeout, terminate the call because the callee isn't
   1114   // answering
   1115   session_client_->session_manager()->signaling_thread()->Clear(this,
   1116       MSG_TERMINATECALL);
   1117   session_client_->session_manager()->signaling_thread()->PostDelayed(
   1118     send_to_voicemail_ ? kSendToVoicemailTimeout : kNoVoicemailTimeout,
   1119     this, MSG_TERMINATECALL);
   1120   return session;
   1121 }
   1122 
   1123 AudioSourceProxy* Call::GetAudioSourceProxy() {
   1124   return audio_source_proxy_.get();
   1125 }
   1126 
   1127 }  // namespace cricket
   1128