1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/* 2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle 3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2007, Google Inc. 4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without 6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met: 7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 1. Redistributions of source code must retain the above copyright notice, 9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer. 10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright notice, 11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer in the documentation 12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * and/or other materials provided with the distribution. 13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 3. The name of the author may not be used to endorse or promote products 14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * derived from this software without specific prior written permission. 15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */ 27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/session/phone/channel.h" 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "talk/base/buffer.h" 31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/byteorder.h" 32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h" 33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/logging.h" 34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/transportchannel.h" 35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/session/phone/channelmanager.h" 36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/session/phone/mediasessionclient.h" 374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "talk/session/phone/mediasink.h" 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "talk/session/phone/rtcpmuxfilter.h" 39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace cricket { 41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstruct PacketMessageData : public talk_base::MessageData { 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen talk_base::Buffer packet; 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstruct VoiceChannelErrorMessageData : public talk_base::MessageData { 47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VoiceChannelErrorMessageData(uint32 in_ssrc, 48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VoiceMediaChannel::Error in_error) 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : ssrc(in_ssrc), 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen error(in_error) {} 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 ssrc; 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VoiceMediaChannel::Error error; 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstruct VideoChannelErrorMessageData : public talk_base::MessageData { 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VideoChannelErrorMessageData(uint32 in_ssrc, 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VideoMediaChannel::Error in_error) 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : ssrc(in_ssrc), 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen error(in_error) {} 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 ssrc; 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VideoMediaChannel::Error error; 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic const char* PacketType(bool rtcp) { 65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (!rtcp) ? "RTP" : "RTCP"; 66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic bool ValidPacket(bool rtcp, const talk_base::Buffer* packet) { 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check the packet size. We could check the header too if needed. 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return (packet && 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen packet->length() >= (!rtcp ? kMinRtpPacketLen : kMinRtcpPacketLen) && 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen packet->length() <= kMaxRtpPacketLen); 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic uint16 GetRtpSeqNum(const talk_base::Buffer* packet) { 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return (packet->length() >= kMinRtpPacketLen) ? 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen talk_base::GetBE16(packet->data() + 2) : 0; 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic uint32 GetRtpSsrc(const talk_base::Buffer* packet) { 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return (packet->length() >= kMinRtpPacketLen) ? 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen talk_base::GetBE32(packet->data() + 8) : 0; 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic int GetRtcpType(const talk_base::Buffer* packet) { 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return (packet->length() >= kMinRtcpPacketLen) ? 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static_cast<int>(packet->data()[1]) : 0; 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochBaseChannel::BaseChannel(talk_base::Thread* thread, MediaEngine* media_engine, 91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch MediaChannel* media_channel, BaseSession* session, 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& content_name, 93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch TransportChannel* transport_channel) 944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch : worker_thread_(thread), 954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch media_engine_(media_engine), 964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch session_(session), 974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch media_channel_(media_channel), 984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch received_media_sink_(NULL), 994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch sent_media_sink_(NULL), 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content_name_(content_name), 1014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch transport_channel_(transport_channel), 1024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch rtcp_transport_channel_(NULL), 1034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch enabled_(false), 1044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch writable_(false), 1054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch has_codec_(false), 1064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch muted_(false) { 107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread_ == talk_base::Thread::Current()); 108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_channel_->SetInterface(this); 109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch transport_channel_->SignalWritableState.connect( 110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, &BaseChannel::OnWritableState); 111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch transport_channel_->SignalReadPacket.connect( 112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, &BaseChannel::OnChannelRead); 113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Created channel"; 115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->SignalState.connect(this, &BaseChannel::OnSessionState); 117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochBaseChannel::~BaseChannel() { 120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread_ == talk_base::Thread::Current()); 121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StopConnectionMonitor(); 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FlushRtcpMessages(); // Send any outstanding RTCP packets. 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Clear(); // eats any outstanding messages or packets 124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // We must destroy the media channel before the transport channel, otherwise 125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // the media channel may try to send on the dead transport channel. NULLing 126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // is not an effective strategy since the sends will come on another thread. 127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete media_channel_; 128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch set_rtcp_transport_channel(NULL); 129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (transport_channel_ != NULL) 130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_->DestroyChannel(content_name_, transport_channel_->name()); 131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Destroyed channel"; 132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool BaseChannel::Enable(bool enable) { 135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Can be called from thread other than worker thread 136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(enable ? MSG_ENABLE : MSG_DISABLE); 137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool BaseChannel::Mute(bool mute) { 141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Can be called from thread other than worker thread 142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(mute ? MSG_MUTE : MSG_UNMUTE); 143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool BaseChannel::RemoveStream(uint32 ssrc) { 147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StreamMessageData data(ssrc, 0); 148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(MSG_REMOVESTREAM, &data); 149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool BaseChannel::SetRtcpCName(const std::string& cname) { 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetRtcpCNameData data(cname); 1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Send(MSG_SETRTCPCNAME, &data); 155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return data.result; 156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool BaseChannel::SetLocalContent(const MediaContentDescription* content, 1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentAction action) { 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetContentData data(content, action); 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Send(MSG_SETLOCALCONTENT, &data); 1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return data.result; 1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool BaseChannel::SetRemoteContent(const MediaContentDescription* content, 1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentAction action) { 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetContentData data(content, action); 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Send(MSG_SETREMOTECONTENT, &data); 169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return data.result; 170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool BaseChannel::SetMaxSendBandwidth(int max_bandwidth) { 173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetBandwidthData data(max_bandwidth); 174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(MSG_SETMAXSENDBANDWIDTH, &data); 175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return data.result; 176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::StartConnectionMonitor(int cms) { 179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch socket_monitor_.reset(new SocketMonitor(transport_channel_, 180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch worker_thread(), 181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch talk_base::Thread::Current())); 182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch socket_monitor_->SignalUpdate.connect( 183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, &BaseChannel::OnConnectionMonitorUpdate); 184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch socket_monitor_->Start(cms); 185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::StopConnectionMonitor() { 188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (socket_monitor_.get()) { 189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch socket_monitor_->Stop(); 190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch socket_monitor_.reset(); 191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::set_rtcp_transport_channel(TransportChannel* channel) { 195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (rtcp_transport_channel_ != channel) { 196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (rtcp_transport_channel_) { 197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session_->DestroyChannel(content_name_, rtcp_transport_channel_->name()); 198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch rtcp_transport_channel_ = channel; 200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (rtcp_transport_channel_) { 201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch rtcp_transport_channel_->SignalWritableState.connect( 202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, &BaseChannel::OnWritableState); 203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch rtcp_transport_channel_->SignalReadPacket.connect( 204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, &BaseChannel::OnChannelRead); 205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool BaseChannel::SendPacket(talk_base::Buffer* packet) { 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return SendPacket(false, packet); 211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool BaseChannel::SendRtcp(talk_base::Buffer* packet) { 214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return SendPacket(true, packet); 215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint BaseChannel::SetOption(SocketType type, talk_base::Socket::Option opt, 218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int value) { 219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (type) { 220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case ST_RTP: return transport_channel_->SetOption(opt, value); 221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case ST_RTCP: return rtcp_transport_channel_->SetOption(opt, value); 222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: return -1; 223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::OnWritableState(TransportChannel* channel) { 227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); 228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (transport_channel_->writable() 229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch && (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { 230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ChannelWritable_w(); 231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ChannelNotWritable_w(); 233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::OnChannelRead(TransportChannel* channel, 237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const char* data, size_t len) { 238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine 239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread_ == talk_base::Thread::Current()); 240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen talk_base::Buffer packet(data, len); 242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // When using RTCP multiplexing we might get RTCP packets on the RTP 243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. 244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool rtcp = (channel == rtcp_transport_channel_ || 245dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen rtcp_mux_filter_.DemuxRtcp(packet.data(), packet.length())); 246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HandlePacket(rtcp, &packet); 247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 248dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool BaseChannel::SendPacket(bool rtcp, talk_base::Buffer* packet) { 250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // SendPacket gets called from MediaEngine, typically on an encoder thread. 251dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // If the thread is not our worker thread, we will post to our worker 252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // so that the real work happens on our worker. This avoids us having to 253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // synchronize access to all the pieces of the send path, including 254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // SRTP and the inner workings of the transport channels. 255dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // The only downside is that we can't return a proper failure code if 256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // needed. Since UDP is unreliable anyway, this should be a non-issue. 257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (talk_base::Thread::Current() != worker_thread_) { 258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Avoid a copy by transferring the ownership of the packet data. 259dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int message_id = (!rtcp) ? MSG_RTPPACKET : MSG_RTCPPACKET; 260dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PacketMessageData* data = new PacketMessageData; 261dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen packet->TransferTo(&data->packet); 262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen worker_thread_->Post(this, message_id, data); 263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Make sure we have a place to send this packet before doing anything. 267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // (We might get RTCP packets that we don't intend to send.) 268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // If we've negotiated RTCP mux, send RTCP over the RTP transport. 269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch TransportChannel* channel = (!rtcp || rtcp_mux_filter_.IsActive()) ? 270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch transport_channel_ : rtcp_transport_channel_; 271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!channel) { 272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 275dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Protect ourselves against crazy data. 276dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!ValidPacket(rtcp, packet)) { 277dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " " 278dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << PacketType(rtcp) << " packet: wrong size=" 279dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << packet->length(); 280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 283dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Push the packet down to the media sink. 284dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Need to do this before protecting the packet. 2854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch { 2864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch talk_base::CritScope cs(&sink_critical_section_); 2874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (sent_media_sink_) { 2884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!rtcp) { 289dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sent_media_sink_->OnRtpPacket(packet->data(), packet->length()); 2904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } else { 291dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sent_media_sink_->OnRtcpPacket(packet->data(), packet->length()); 2924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 2934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 2944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 2954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 296dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Protect if needed. 297dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (srtp_filter_.IsActive()) { 298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool res; 299dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char* data = packet->data(); 300dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int len = packet->length(); 301dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!rtcp) { 302dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen res = srtp_filter_.ProtectRtp(data, len, packet->capacity(), &len); 303dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!res) { 304dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failed to protect " << content_name_ 305dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << " RTP packet: size=" << len 306dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << ", seqnum=" << GetRtpSeqNum(packet) 307dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << ", SSRC=" << GetRtpSsrc(packet); 308dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 309dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 310dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 311dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen res = srtp_filter_.ProtectRtcp(data, len, packet->capacity(), &len); 312dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!res) { 313dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failed to protect " << content_name_ 314dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << " RTCP packet: size=" << len 315dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << ", type=" << GetRtcpType(packet); 316dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 317dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 318dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 320dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Update the length of the packet now that we've added the auth tag. 321dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen packet->SetLength(len); 322dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 323dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 324dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Bon voyage. 325dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return (channel->SendPacket(packet->data(), packet->length()) 326dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen == static_cast<int>(packet->length())); 327f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 328f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 329dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid BaseChannel::HandlePacket(bool rtcp, talk_base::Buffer* packet) { 330f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Protect ourselvs against crazy data. 331dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!ValidPacket(rtcp, packet)) { 332dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " 333dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << PacketType(rtcp) << " packet: wrong size=" 334dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << packet->length(); 335f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 336f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 337f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 338f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Unprotect the packet, if needed. 339f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (srtp_filter_.IsActive()) { 340dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char* data = packet->data(); 341dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int len = packet->length(); 342f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool res; 343f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!rtcp) { 344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen res = srtp_filter_.UnprotectRtp(data, len, &len); 345dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!res) { 346dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failed to unprotect " << content_name_ 347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << " RTP packet: size=" << len 348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << ", seqnum=" << GetRtpSeqNum(packet) 349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << ", SSRC=" << GetRtpSsrc(packet); 350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 352f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 353dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen res = srtp_filter_.UnprotectRtcp(data, len, &len); 354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!res) { 355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failed to unprotect " << content_name_ 356dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << " RTCP packet: size=" << len 357dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << ", type=" << GetRtcpType(packet); 358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 359dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 360f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 361dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 362dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen packet->SetLength(len); 363f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 364f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 365f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Push it down to the media channel. 366f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!rtcp) { 367dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen media_channel_->OnPacketReceived(packet); 368f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 369dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen media_channel_->OnRtcpReceived(packet); 370f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 3714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 372dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Push it down to the media sink. 3734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch { 3744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch talk_base::CritScope cs(&sink_critical_section_); 3754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (received_media_sink_) { 3764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!rtcp) { 377dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen received_media_sink_->OnRtpPacket(packet->data(), packet->length()); 3784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } else { 379dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen received_media_sink_->OnRtcpPacket(packet->data(), packet->length()); 3804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 3814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 3824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 383f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 384f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 385f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::OnSessionState(BaseSession* session, 386f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BaseSession::State state) { 3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const MediaContentDescription* content = NULL; 388f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (state) { 389f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case Session::STATE_SENTINITIATE: 3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick content = GetFirstContent(session->local_description()); 391dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (content && !SetLocalContent(content, CA_OFFER)) { 392dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failure in SetLocalContent with CA_OFFER"; 393dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen session->SetError(BaseSession::ERROR_CONTENT); 3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 396f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case Session::STATE_SENTACCEPT: 3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick content = GetFirstContent(session->local_description()); 398dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (content && !SetLocalContent(content, CA_ANSWER)) { 399dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failure in SetLocalContent with CA_ANSWER"; 400dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen session->SetError(BaseSession::ERROR_CONTENT); 401f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 402f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 403f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case Session::STATE_RECEIVEDINITIATE: 4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick content = GetFirstContent(session->remote_description()); 405dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (content && !SetRemoteContent(content, CA_OFFER)) { 406dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failure in SetRemoteContent with CA_OFFER"; 407dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen session->SetError(BaseSession::ERROR_CONTENT); 4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 410f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case Session::STATE_RECEIVEDACCEPT: 4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick content = GetFirstContent(session->remote_description()); 412dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (content && !SetRemoteContent(content, CA_ANSWER)) { 413dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failure in SetRemoteContent with CA_ANSWER"; 414dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen session->SetError(BaseSession::ERROR_CONTENT); 415f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 416f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 417f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 418f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 419f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 420f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 421f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 422f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::EnableMedia_w() { 423f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread_ == talk_base::Thread::Current()); 424f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (enabled_) 425f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 426f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 427f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Channel enabled"; 428f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch enabled_ = true; 429f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ChangeState(); 430f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 431f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 432f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::DisableMedia_w() { 433f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread_ == talk_base::Thread::Current()); 434f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!enabled_) 435f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 436f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 437f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Channel disabled"; 438f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch enabled_ = false; 439f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ChangeState(); 440f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 441f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 442f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::MuteMedia_w() { 443f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread_ == talk_base::Thread::Current()); 444f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (muted_) 445f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 446f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 447f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (media_channel()->Mute(true)) { 448f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Channel muted"; 449f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch muted_ = true; 450f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 451f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 452f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 453f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::UnmuteMedia_w() { 454f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread_ == talk_base::Thread::Current()); 455f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!muted_) 456f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 457f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 458f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (media_channel()->Mute(false)) { 459f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Channel unmuted"; 460f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch muted_ = false; 461f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 462f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 463f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 464f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::ChannelWritable_w() { 465f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread_ == talk_base::Thread::Current()); 466f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (writable_) 467f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 468f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Channel socket writable (" 469f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch << transport_channel_->name().c_str() << ")"; 470f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch writable_ = true; 471f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ChangeState(); 472f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 473f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 474f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::ChannelNotWritable_w() { 475f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread_ == talk_base::Thread::Current()); 476f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!writable_) 477f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 478f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 479f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Channel socket not writable (" 480f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch << transport_channel_->name().c_str() << ")"; 481f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch writable_ = false; 482f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ChangeState(); 483f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 484f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 4854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Sets the maximum video bandwidth for automatic bandwidth adjustment. 486f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool BaseChannel::SetMaxSendBandwidth_w(int max_bandwidth) { 4874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return media_channel()->SetSendBandwidth(true, max_bandwidth); 488f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 489f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 4903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool BaseChannel::SetRtcpCName_w(const std::string& cname) { 4913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return media_channel()->SetRtcpCName(cname); 4923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 494f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos, 4953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentAction action, ContentSource src) { 496f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool ret; 4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (action == CA_OFFER) { 498f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ret = srtp_filter_.SetOffer(cryptos, src); 4993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (action == CA_ANSWER) { 500f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ret = srtp_filter_.SetAnswer(cryptos, src); 501f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 5023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // CA_UPDATE, no crypto params. 503f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ret = true; 504f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 505f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ret; 506f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 507f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 5083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action, 5093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentSource src) { 510f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool ret; 5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (action == CA_OFFER) { 512f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ret = rtcp_mux_filter_.SetOffer(enable, src); 5133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (action == CA_ANSWER) { 514f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ret = rtcp_mux_filter_.SetAnswer(enable, src); 515f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret && rtcp_mux_filter_.IsActive()) { 516f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // We activated RTCP mux, close down the RTCP transport. 517f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch set_rtcp_transport_channel(NULL); 518f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // If the RTP transport is already writable, then so are we. 519f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (transport_channel_->writable()) { 520f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ChannelWritable_w(); 521f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 522f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 523f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 5243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // CA_UPDATE, no RTCP mux info. 525f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ret = true; 526f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 527f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ret; 528f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 529f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 530f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::OnMessage(talk_base::Message *pmsg) { 531f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (pmsg->message_id) { 532f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_ENABLE: 533f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch EnableMedia_w(); 534f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 535f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_DISABLE: 536f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DisableMedia_w(); 537f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 538f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 539f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_MUTE: 540f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch MuteMedia_w(); 541f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 542f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_UNMUTE: 543f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UnmuteMedia_w(); 544f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 545f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 5463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case MSG_SETRTCPCNAME: { 5473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetRtcpCNameData* data = static_cast<SetRtcpCNameData*>(pmsg->pdata); 5483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->result = SetRtcpCName_w(data->cname); 5493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 5503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case MSG_SETLOCALCONTENT: { 5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetContentData* data = static_cast<SetContentData*>(pmsg->pdata); 5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->result = SetLocalContent_w(data->content, data->action); 555f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 556f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 5573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case MSG_SETREMOTECONTENT: { 5583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetContentData* data = static_cast<SetContentData*>(pmsg->pdata); 5593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data->result = SetRemoteContent_w(data->content, data->action); 560f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 561f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 562f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 563f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_REMOVESTREAM: { 564f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata); 565f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch RemoveStream_w(data->ssrc1); 566f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 567f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 568f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 569f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_SETMAXSENDBANDWIDTH: { 570f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetBandwidthData* data = static_cast<SetBandwidthData*>(pmsg->pdata); 571f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data->result = SetMaxSendBandwidth_w(data->value); 572f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 573f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 574dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 575dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case MSG_RTPPACKET: 576dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case MSG_RTCPPACKET: { 577dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata); 578dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet); 579dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete data; // because it is Posted 580dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen break; 581dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 582f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 583f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 584f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 585f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::Send(uint32 id, talk_base::MessageData *pdata) { 586f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch worker_thread_->Send(this, id, pdata); 587f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 588f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 589f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::Post(uint32 id, talk_base::MessageData *pdata) { 590f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch worker_thread_->Post(this, id, pdata); 591f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 592f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 593f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::PostDelayed(int cmsDelay, uint32 id, 594f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch talk_base::MessageData *pdata) { 595f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch worker_thread_->PostDelayed(cmsDelay, this, id, pdata); 596f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 597f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 598f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid BaseChannel::Clear(uint32 id, talk_base::MessageList* removed) { 599f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch worker_thread_->Clear(this, id, removed); 600f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 601f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 602dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid BaseChannel::FlushRtcpMessages() { 603dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Flush all remaining RTCP messages. This should only be called in 604dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // destructor. 605dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASSERT(talk_base::Thread::Current() == worker_thread_); 606dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen talk_base::MessageList rtcp_messages; 607dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Clear(MSG_RTCPPACKET, &rtcp_messages); 608dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (talk_base::MessageList::iterator it = rtcp_messages.begin(); 609dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen it != rtcp_messages.end(); ++it) { 610dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Send(MSG_RTCPPACKET, it->pdata); 611dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 612dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 613dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 614f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochVoiceChannel::VoiceChannel(talk_base::Thread* thread, 615f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch MediaEngine* media_engine, 616f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch VoiceMediaChannel* media_channel, 617f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BaseSession* session, 618731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& content_name, 619f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool rtcp) 620731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : BaseChannel(thread, media_engine, media_channel, session, content_name, 621731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session->CreateChannel(content_name, "rtp")), 622f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch received_media_(false) { 623f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (rtcp) { 624731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick set_rtcp_transport_channel(session->CreateChannel(content_name, "rtcp")); 625f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 626731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Can't go in BaseChannel because certain session states will 627731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // trigger pure virtual functions, such as GetFirstContent(). 628731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick OnSessionState(session, session->state()); 629dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 630dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen media_channel->SignalMediaError.connect( 631dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this, &VoiceChannel::OnVoiceChannelError); 632f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 633f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 634f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochVoiceChannel::~VoiceChannel() { 635f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StopAudioMonitor(); 636f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StopMediaMonitor(); 637f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // this can't be done in the base class, since it calls a virtual 638f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DisableMedia_w(); 639f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 640f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 641f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool VoiceChannel::AddStream(uint32 ssrc) { 642f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StreamMessageData data(ssrc, 0); 643f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(MSG_ADDSTREAM, &data); 644f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 645f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 646f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 647f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool VoiceChannel::SetRingbackTone(const void* buf, int len) { 648f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetRingbackToneMessageData data(buf, len); 649f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(MSG_SETRINGBACKTONE, &data); 650f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 651f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 652f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 653731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// TODO: Handle early media the right way. We should get an explicit 654f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// ringing message telling us to start playing local ringback, which we cancel 655f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// if any early media actually arrives. For now, we do the opposite, which is 656f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// to wait 1 second for early media, and start playing local ringback if none 657f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// arrives. 658f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::SetEarlyMedia(bool enable) { 659f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (enable) { 660f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Start the early media timeout 661f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch PostDelayed(kEarlyMediaTimeout, MSG_EARLYMEDIATIMEOUT); 662f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 663f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Stop the timeout if currently going. 664f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Clear(MSG_EARLYMEDIATIMEOUT); 665f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 666f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 667f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 668f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool VoiceChannel::PlayRingbackTone(bool play, bool loop) { 669f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch PlayRingbackToneMessageData data(play, loop); 670f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(MSG_PLAYRINGBACKTONE, &data); 671f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return data.result; 672f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 673f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 674f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool VoiceChannel::PressDTMF(int digit, bool playout) { 675f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DtmfMessageData data(digit, playout); 676f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(MSG_PRESSDTMF, &data); 677f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return data.result; 678f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 679f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 680f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::StartMediaMonitor(int cms) { 681f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_.reset(new VoiceMediaMonitor(media_channel(), worker_thread(), 682f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch talk_base::Thread::Current())); 683f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_->SignalUpdate.connect( 684f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, &VoiceChannel::OnMediaMonitorUpdate); 685f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_->Start(cms); 686f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 687f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 688f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::StopMediaMonitor() { 689f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (media_monitor_.get()) { 690f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_->Stop(); 691f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_->SignalUpdate.disconnect(this); 692f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_.reset(); 693f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 694f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 695f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 696f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::StartAudioMonitor(int cms) { 697f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch audio_monitor_.reset(new AudioMonitor(this, talk_base::Thread::Current())); 698f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch audio_monitor_ 699f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ->SignalUpdate.connect(this, &VoiceChannel::OnAudioMonitorUpdate); 700f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch audio_monitor_->Start(cms); 701f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 702f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 703f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::StopAudioMonitor() { 704f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (audio_monitor_.get()) { 705f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch audio_monitor_->Stop(); 706f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch audio_monitor_.reset(); 707f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 708f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 709f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 710f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint VoiceChannel::GetInputLevel_w() { 711f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return media_engine()->GetInputLevel(); 712f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 713f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 714f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint VoiceChannel::GetOutputLevel_w() { 715f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return media_channel()->GetOutputLevel(); 716f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 717f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 718f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::GetActiveStreams_w(AudioInfo::StreamList* actives) { 719f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_channel()->GetActiveStreams(actives); 720f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 721f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 722f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::OnChannelRead(TransportChannel* channel, 723f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const char* data, size_t len) { 724f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BaseChannel::OnChannelRead(channel, data, len); 725f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 726f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Set a flag when we've received an RTP packet. If we're waiting for early 727f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // media, this will disable the timeout. 728f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // If we were playing out our local ringback, make sure it is stopped to 729f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // prevent it from interfering with the incoming media. 730f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!received_media_) { 731dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!PlayRingbackTone_w(false, false)) { 732dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failed to stop ringback tone."; 733dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendLastMediaError(); 734dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 735f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 736f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 737f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 738f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::ChangeState() { 739f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // render incoming data if we are the active call 740f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // we receive data on the default channel and multiplexed streams 741f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool recv = enabled(); 742dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!media_channel()->SetPlayout(recv)) { 743dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendLastMediaError(); 744dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 745f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 746f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // send outgoing data if we are the active call, have the 747f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // remote party's codec, and have a writable transport 748f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // we only send data on the default channel 749f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool send = enabled() && has_codec() && writable(); 750dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendFlags send_flag = send ? SEND_MICROPHONE : SEND_NOTHING; 751dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!media_channel()->SetSend(send_flag)) { 752dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failed to SetSend " << send_flag << " on voice channel"; 753dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SendLastMediaError(); 754dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 755f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 756f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send; 757f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 758f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 7593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst MediaContentDescription* VoiceChannel::GetFirstContent( 7603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SessionDescription* sdesc) { 7613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ContentInfo* cinfo = GetFirstAudioContent(sdesc); 7623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cinfo == NULL) 7633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 7643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return static_cast<const MediaContentDescription*>(cinfo->description); 7663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content, 7693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentAction action) { 770f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread() == talk_base::Thread::Current()); 771f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Setting local voice description"; 772f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 7733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const AudioContentDescription* audio = 7743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<const AudioContentDescription*>(content); 7753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(audio != NULL); 7763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 777f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool ret; 778f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set SRTP 7793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = SetSrtp_w(audio->cryptos(), action, CS_LOCAL); 780f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set RTCP mux 781f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 7823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = SetRtcpMux_w(audio->rtcp_mux(), action, CS_LOCAL); 783f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 784f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set payload type and config for voice codecs 785f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 7863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = media_channel()->SetRecvCodecs(audio->codecs()); 787f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 788f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ret; 789f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 790f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 7913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, 7923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentAction action) { 793f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread() == talk_base::Thread::Current()); 794f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Setting remote voice description"; 795f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 7963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const AudioContentDescription* audio = 7973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<const AudioContentDescription*>(content); 7983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(audio != NULL); 7993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 800f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool ret; 801f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set the sending SSRC, if the remote side gave us one 8023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (audio->ssrc_set()) { 8033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick media_channel()->SetSendSsrc(audio->ssrc()); 804f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 805f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set SRTP 8063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = SetSrtp_w(audio->cryptos(), action, CS_REMOTE); 807f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set RTCP mux 808f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 8093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = SetRtcpMux_w(audio->rtcp_mux(), action, CS_REMOTE); 810f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 811f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set codecs and payload types 812f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 8133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = media_channel()->SetSendCodecs(audio->codecs()); 814f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 815731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 816dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int audio_options = 0; 817dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (audio->conference_mode()) { 818dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen audio_options |= OPT_CONFERENCE; 819dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 8204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!media_channel()->SetOptions(audio_options)) { 8214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Log an error on failure, but don't abort the call. 8224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch LOG(LS_ERROR) << "Failed to set voice channel options"; 8234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 824731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 825f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // update state 826f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 827f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch set_has_codec(true); 828f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ChangeState(); 829f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 830f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ret; 831f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 832f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 833f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::AddStream_w(uint32 ssrc) { 834f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread() == talk_base::Thread::Current()); 835f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_channel()->AddStream(ssrc); 836f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 837f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 838f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::RemoveStream_w(uint32 ssrc) { 839f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_channel()->RemoveStream(ssrc); 840f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 841f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 842f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::SetRingbackTone_w(const void* buf, int len) { 843f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread() == talk_base::Thread::Current()); 844f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_channel()->SetRingbackTone(static_cast<const char*>(buf), len); 845f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 846f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 847f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool VoiceChannel::PlayRingbackTone_w(bool play, bool loop) { 848f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread() == talk_base::Thread::Current()); 849f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (play) { 850f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Playing ringback tone, loop=" << loop; 851f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 852f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Stopping ringback tone"; 853f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 854f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return media_channel()->PlayRingbackTone(play, loop); 855f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 856f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 857f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::HandleEarlyMediaTimeout() { 858f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // This occurs on the main thread, not the worker thread. 859f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!received_media_) { 860f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "No early media received before timeout"; 861f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalEarlyMediaTimeout(this); 862f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 863f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 864f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 865f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool VoiceChannel::PressDTMF_w(int digit, bool playout) { 866f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!enabled() || !writable()) { 867f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 868f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 869f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 870f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return media_channel()->PressDTMF(digit, playout); 871f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 872f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 873f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::OnMessage(talk_base::Message *pmsg) { 874f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (pmsg->message_id) { 875f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_ADDSTREAM: { 876f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata); 877f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AddStream_w(data->ssrc1); 878f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 879f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 880f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_SETRINGBACKTONE: { 881f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetRingbackToneMessageData* data = 882f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static_cast<SetRingbackToneMessageData*>(pmsg->pdata); 883f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetRingbackTone_w(data->buf, data->len); 884f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 885f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 886f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_PLAYRINGBACKTONE: { 887f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch PlayRingbackToneMessageData* data = 888f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static_cast<PlayRingbackToneMessageData*>(pmsg->pdata); 889f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data->result = PlayRingbackTone_w(data->play, data->loop); 890f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 891f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 892f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_EARLYMEDIATIMEOUT: 893f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch HandleEarlyMediaTimeout(); 894f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 895f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_PRESSDTMF: { 896f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DtmfMessageData* data = static_cast<DtmfMessageData*>(pmsg->pdata); 897f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data->result = PressDTMF_w(data->digit, data->playout); 898f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 899f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 900dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case MSG_CHANNEL_ERROR: { 901dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VoiceChannelErrorMessageData* data = 902dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static_cast<VoiceChannelErrorMessageData*>(pmsg->pdata); 903dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SignalMediaError(this, data->ssrc, data->error); 904dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete data; 905dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen break; 906dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 907f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 908f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 909f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BaseChannel::OnMessage(pmsg); 910f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 911f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 912f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 913f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 914f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::OnConnectionMonitorUpdate( 915f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos) { 916f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalConnectionMonitor(this, infos); 917f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 918f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 919f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::OnMediaMonitorUpdate( 920f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch VoiceMediaChannel* media_channel, const VoiceMediaInfo& info) { 921f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(media_channel == this->media_channel()); 922f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalMediaMonitor(this, info); 923f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 924f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 925f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VoiceChannel::OnAudioMonitorUpdate(AudioMonitor* monitor, 926f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const AudioInfo& info) { 927f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalAudioMonitor(this, info); 928f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 929f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 930dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid VoiceChannel::OnVoiceChannelError( 931dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 ssrc, VoiceMediaChannel::Error error) { 932dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VoiceChannelErrorMessageData *data = new VoiceChannelErrorMessageData( 933dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ssrc, error); 934dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data); 935dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 936dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 937f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochVideoChannel::VideoChannel(talk_base::Thread* thread, 938f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch MediaEngine* media_engine, 939f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch VideoMediaChannel* media_channel, 940731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BaseSession* session, 941731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& content_name, 942731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool rtcp, 943f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch VoiceChannel* voice_channel) 944731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : BaseChannel(thread, media_engine, media_channel, session, content_name, 945731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session->CreateChannel(content_name, "video_rtp")), 946f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch voice_channel_(voice_channel), renderer_(NULL) { 947f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (rtcp) { 948731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick set_rtcp_transport_channel( 949731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session->CreateChannel(content_name, "video_rtcp")); 950f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 951731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Can't go in BaseChannel because certain session states will 952731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // trigger pure virtual functions, such as GetFirstContent() 953731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick OnSessionState(session, session->state()); 9544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 955dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen media_channel->SignalMediaError.connect( 956dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this, &VideoChannel::OnVideoChannelError); 957dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 958dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 959dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid VoiceChannel::SendLastMediaError() { 960dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 ssrc; 961dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VoiceMediaChannel::Error error; 962dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen media_channel()->GetLastMediaError(&ssrc, &error); 963dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SignalMediaError(this, ssrc, error); 964f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 965f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 966f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochVideoChannel::~VideoChannel() { 967f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StopMediaMonitor(); 968f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // this can't be done in the base class, since it calls a virtual 969f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DisableMedia_w(); 970f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 971f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 972f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool VideoChannel::AddStream(uint32 ssrc, uint32 voice_ssrc) { 973f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StreamMessageData data(ssrc, voice_ssrc); 974f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(MSG_ADDSTREAM, &data); 975f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 976f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 977f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 978f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool VideoChannel::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 979f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch RenderMessageData data(ssrc, renderer); 980f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Send(MSG_SETRENDERER, &data); 981f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 982f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 983f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 984f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 9854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 9864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool VideoChannel::SendIntraFrame() { 9874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch Send(MSG_SENDINTRAFRAME); 9884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return true; 9894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 9904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool VideoChannel::RequestIntraFrame() { 9914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch Send(MSG_REQUESTINTRAFRAME); 9924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return true; 9934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 9944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 995f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VideoChannel::ChangeState() { 996f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // render incoming data if we are the active call 997f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // we receive data on the default channel and multiplexed streams 998f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool recv = enabled(); 999dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!media_channel()->SetRender(recv)) { 1000dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failed to SetRender on video channel"; 1001dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO: Report error back to server. 1002dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1003f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1004f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // send outgoing data if we are the active call, have the 1005f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // remote party's codec, and have a writable transport 1006f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // we only send data on the default channel 1007f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool send = enabled() && has_codec() && writable(); 1008dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!media_channel()->SetSend(send)) { 1009dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(LS_ERROR) << "Failed to SetSend on video channel"; 1010dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO: Report error back to server. 1011dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1012f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1013f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Changing video state, recv=" << recv << " send=" << send; 1014f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1015f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1016f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VideoChannel::StartMediaMonitor(int cms) { 1017f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_.reset(new VideoMediaMonitor(media_channel(), worker_thread(), 1018f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch talk_base::Thread::Current())); 1019f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_->SignalUpdate.connect( 1020f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, &VideoChannel::OnMediaMonitorUpdate); 1021f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_->Start(cms); 1022f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1023f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1024f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VideoChannel::StopMediaMonitor() { 1025f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (media_monitor_.get()) { 1026f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_->Stop(); 1027f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_monitor_.reset(); 1028f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1029f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1030f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 10313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst MediaContentDescription* VideoChannel::GetFirstContent( 10323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SessionDescription* sdesc) { 10333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ContentInfo* cinfo = GetFirstVideoContent(sdesc); 10343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cinfo == NULL) 10353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 10363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return static_cast<const MediaContentDescription*>(cinfo->description); 10383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 10393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool VideoChannel::SetLocalContent_w(const MediaContentDescription* content, 10413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentAction action) { 1042f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread() == talk_base::Thread::Current()); 1043f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Setting local video description"; 1044f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 10453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const VideoContentDescription* video = 10463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<const VideoContentDescription*>(content); 10473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(video != NULL); 10483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1049f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool ret; 1050f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set SRTP 10513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = SetSrtp_w(video->cryptos(), action, CS_LOCAL); 1052f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set RTCP mux 1053f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 10543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = SetRtcpMux_w(video->rtcp_mux(), action, CS_LOCAL); 1055f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1056f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set payload types and config for receiving video 1057f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 10583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = media_channel()->SetRecvCodecs(video->codecs()); 1059f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1060f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ret; 1061f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1062f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 10633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, 10643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentAction action) { 1065f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(worker_thread() == talk_base::Thread::Current()); 1066f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "Setting remote video description"; 1067f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 10683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const VideoContentDescription* video = 10693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<const VideoContentDescription*>(content); 10703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(video != NULL); 10713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1072f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool ret; 1073f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set the sending SSRC, if the remote side gave us one 1074731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: remove this, since it's not needed. 10753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (video->ssrc_set()) { 10763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick media_channel()->SetSendSsrc(video->ssrc()); 1077f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1078f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set SRTP 10793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = SetSrtp_w(video->cryptos(), action, CS_REMOTE); 1080f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // set RTCP mux 1081f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 10823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = SetRtcpMux_w(video->rtcp_mux(), action, CS_REMOTE); 1083f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 10844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Set video bandwidth parameters. 10854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (ret) { 10864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int bandwidth_bps = video->bandwidth(); 10874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bool auto_bandwidth = (bandwidth_bps == kAutoBandwidth); 10884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ret = media_channel()->SetSendBandwidth(auto_bandwidth, bandwidth_bps); 10894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 1090f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 10913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = media_channel()->SetSendCodecs(video->codecs()); 1092f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 10933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick media_channel()->SetRtpExtensionHeaders(!video->rtp_headers_disabled()); 1094f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ret) { 1095f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch set_has_codec(true); 1096f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ChangeState(); 1097f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1098f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ret; 1099f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VideoChannel::AddStream_w(uint32 ssrc, uint32 voice_ssrc) { 1102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_channel()->AddStream(ssrc, voice_ssrc); 1103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VideoChannel::RemoveStream_w(uint32 ssrc) { 1106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_channel()->RemoveStream(ssrc); 1107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VideoChannel::SetRenderer_w(uint32 ssrc, VideoRenderer* renderer) { 1110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch media_channel()->SetRenderer(ssrc, renderer); 1111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VideoChannel::OnMessage(talk_base::Message *pmsg) { 1115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (pmsg->message_id) { 1116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_ADDSTREAM: { 1117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata); 1118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch AddStream_w(data->ssrc1, data->ssrc2); 1119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 1120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case MSG_SETRENDERER: { 1122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch RenderMessageData* data = static_cast<RenderMessageData*>(pmsg->pdata); 1123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetRenderer_w(data->ssrc, data->renderer); 1124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 1125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 11264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch case MSG_SENDINTRAFRAME: 11274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch SendIntraFrame_w(); 11284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch break; 11294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch case MSG_REQUESTINTRAFRAME: 11304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch RequestIntraFrame_w(); 11314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch break; 1132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case MSG_CHANNEL_ERROR: { 1133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const VideoChannelErrorMessageData* data = 1134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static_cast<VideoChannelErrorMessageData*>(pmsg->pdata); 1135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SignalMediaError(this, data->ssrc, data->error); 1136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete data; 1137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen break; 1138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen default: 1140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BaseChannel::OnMessage(pmsg); 1141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen break; 1142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VideoChannel::OnConnectionMonitorUpdate( 1146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos) { 1147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalConnectionMonitor(this, infos); 1148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid VideoChannel::OnMediaMonitorUpdate( 1151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch VideoMediaChannel* media_channel, const VideoMediaInfo &info) { 1152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(media_channel == this->media_channel()); 1153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalMediaMonitor(this, info); 1154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 11564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid VideoChannel::OnVideoChannelError(uint32 ssrc, 1158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VideoMediaChannel::Error error) { 1159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VideoChannelErrorMessageData* data = new VideoChannelErrorMessageData( 1160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ssrc, error); 1161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data); 1162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} // namespace cricket 1165