1 /* 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include <assert.h> 12 #include <string.h> 13 14 #include <map> 15 #include <vector> 16 17 #include "webrtc/call.h" 18 #include "webrtc/common.h" 19 #include "webrtc/config.h" 20 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 21 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 22 #include "webrtc/system_wrappers/interface/rw_lock_wrapper.h" 23 #include "webrtc/system_wrappers/interface/scoped_ptr.h" 24 #include "webrtc/system_wrappers/interface/thread_annotations.h" 25 #include "webrtc/system_wrappers/interface/trace.h" 26 #include "webrtc/video/video_receive_stream.h" 27 #include "webrtc/video/video_send_stream.h" 28 #include "webrtc/video_engine/include/vie_base.h" 29 #include "webrtc/video_engine/include/vie_codec.h" 30 #include "webrtc/video_engine/include/vie_rtp_rtcp.h" 31 32 namespace webrtc { 33 const char* RtpExtension::kTOffset = "urn:ietf:params:rtp-hdrext:toffset"; 34 const char* RtpExtension::kAbsSendTime = 35 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"; 36 namespace internal { 37 38 class CpuOveruseObserverProxy : public webrtc::CpuOveruseObserver { 39 public: 40 CpuOveruseObserverProxy(OveruseCallback* overuse_callback) 41 : crit_(CriticalSectionWrapper::CreateCriticalSection()), 42 overuse_callback_(overuse_callback) { 43 assert(overuse_callback != NULL); 44 } 45 46 virtual ~CpuOveruseObserverProxy() {} 47 48 virtual void OveruseDetected() OVERRIDE { 49 CriticalSectionScoped lock(crit_.get()); 50 overuse_callback_->OnOveruse(); 51 } 52 53 virtual void NormalUsage() OVERRIDE { 54 CriticalSectionScoped lock(crit_.get()); 55 overuse_callback_->OnNormalUse(); 56 } 57 58 private: 59 const scoped_ptr<CriticalSectionWrapper> crit_; 60 OveruseCallback* overuse_callback_ GUARDED_BY(crit_); 61 }; 62 63 class Call : public webrtc::Call, public PacketReceiver { 64 public: 65 Call(webrtc::VideoEngine* video_engine, const Call::Config& config); 66 virtual ~Call(); 67 68 virtual PacketReceiver* Receiver() OVERRIDE; 69 70 virtual VideoSendStream::Config GetDefaultSendConfig() OVERRIDE; 71 72 virtual VideoSendStream* CreateVideoSendStream( 73 const VideoSendStream::Config& config, 74 const std::vector<VideoStream>& video_streams, 75 const void* encoder_settings) OVERRIDE; 76 77 virtual void DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) 78 OVERRIDE; 79 80 virtual VideoReceiveStream::Config GetDefaultReceiveConfig() OVERRIDE; 81 82 virtual VideoReceiveStream* CreateVideoReceiveStream( 83 const VideoReceiveStream::Config& config) OVERRIDE; 84 85 virtual void DestroyVideoReceiveStream( 86 webrtc::VideoReceiveStream* receive_stream) OVERRIDE; 87 88 virtual uint32_t SendBitrateEstimate() OVERRIDE; 89 virtual uint32_t ReceiveBitrateEstimate() OVERRIDE; 90 91 virtual DeliveryStatus DeliverPacket(const uint8_t* packet, 92 size_t length) OVERRIDE; 93 94 private: 95 DeliveryStatus DeliverRtcp(const uint8_t* packet, size_t length); 96 DeliveryStatus DeliverRtp(const RTPHeader& header, 97 const uint8_t* packet, 98 size_t length); 99 100 Call::Config config_; 101 102 std::map<uint32_t, VideoReceiveStream*> receive_ssrcs_ 103 GUARDED_BY(receive_lock_); 104 scoped_ptr<RWLockWrapper> receive_lock_; 105 106 std::map<uint32_t, VideoSendStream*> send_ssrcs_ GUARDED_BY(send_lock_); 107 scoped_ptr<RWLockWrapper> send_lock_; 108 109 scoped_ptr<RtpHeaderParser> rtp_header_parser_; 110 111 scoped_ptr<CpuOveruseObserverProxy> overuse_observer_proxy_; 112 113 VideoEngine* video_engine_; 114 ViERTP_RTCP* rtp_rtcp_; 115 ViECodec* codec_; 116 ViEBase* base_; 117 int base_channel_id_; 118 119 DISALLOW_COPY_AND_ASSIGN(Call); 120 }; 121 } // namespace internal 122 123 Call* Call::Create(const Call::Config& config) { 124 VideoEngine* video_engine = config.webrtc_config != NULL 125 ? VideoEngine::Create(*config.webrtc_config) 126 : VideoEngine::Create(); 127 assert(video_engine != NULL); 128 129 return new internal::Call(video_engine, config); 130 } 131 132 namespace internal { 133 134 const int kDefaultVideoStreamBitrateBps = 300000; 135 136 Call::Call(webrtc::VideoEngine* video_engine, const Call::Config& config) 137 : config_(config), 138 receive_lock_(RWLockWrapper::CreateRWLock()), 139 send_lock_(RWLockWrapper::CreateRWLock()), 140 rtp_header_parser_(RtpHeaderParser::Create()), 141 video_engine_(video_engine), 142 base_channel_id_(-1) { 143 assert(video_engine != NULL); 144 assert(config.send_transport != NULL); 145 146 if (config.overuse_callback) { 147 overuse_observer_proxy_.reset( 148 new CpuOveruseObserverProxy(config.overuse_callback)); 149 } 150 151 rtp_rtcp_ = ViERTP_RTCP::GetInterface(video_engine_); 152 assert(rtp_rtcp_ != NULL); 153 154 codec_ = ViECodec::GetInterface(video_engine_); 155 assert(codec_ != NULL); 156 157 // As a workaround for non-existing calls in the old API, create a base 158 // channel used as default channel when creating send and receive streams. 159 base_ = ViEBase::GetInterface(video_engine_); 160 assert(base_ != NULL); 161 162 base_->CreateChannel(base_channel_id_); 163 assert(base_channel_id_ != -1); 164 } 165 166 Call::~Call() { 167 base_->DeleteChannel(base_channel_id_); 168 base_->Release(); 169 codec_->Release(); 170 rtp_rtcp_->Release(); 171 webrtc::VideoEngine::Delete(video_engine_); 172 } 173 174 PacketReceiver* Call::Receiver() { return this; } 175 176 VideoSendStream::Config Call::GetDefaultSendConfig() { 177 VideoSendStream::Config config; 178 return config; 179 } 180 181 VideoSendStream* Call::CreateVideoSendStream( 182 const VideoSendStream::Config& config, 183 const std::vector<VideoStream>& video_streams, 184 const void* encoder_settings) { 185 assert(config.rtp.ssrcs.size() > 0); 186 187 // TODO(mflodman): Base the start bitrate on a current bandwidth estimate, if 188 // the call has already started. 189 VideoSendStream* send_stream = new VideoSendStream( 190 config_.send_transport, 191 overuse_observer_proxy_.get(), 192 video_engine_, 193 config, 194 video_streams, 195 encoder_settings, 196 base_channel_id_, 197 config_.start_bitrate_bps != -1 ? config_.start_bitrate_bps 198 : kDefaultVideoStreamBitrateBps); 199 200 WriteLockScoped write_lock(*send_lock_); 201 for (size_t i = 0; i < config.rtp.ssrcs.size(); ++i) { 202 assert(send_ssrcs_.find(config.rtp.ssrcs[i]) == send_ssrcs_.end()); 203 send_ssrcs_[config.rtp.ssrcs[i]] = send_stream; 204 } 205 return send_stream; 206 } 207 208 void Call::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) { 209 assert(send_stream != NULL); 210 211 VideoSendStream* send_stream_impl = NULL; 212 { 213 WriteLockScoped write_lock(*send_lock_); 214 for (std::map<uint32_t, VideoSendStream*>::iterator it = 215 send_ssrcs_.begin(); 216 it != send_ssrcs_.end(); 217 ++it) { 218 if (it->second == static_cast<VideoSendStream*>(send_stream)) { 219 send_stream_impl = it->second; 220 send_ssrcs_.erase(it); 221 break; 222 } 223 } 224 } 225 226 assert(send_stream_impl != NULL); 227 delete send_stream_impl; 228 } 229 230 VideoReceiveStream::Config Call::GetDefaultReceiveConfig() { 231 VideoReceiveStream::Config config; 232 config.rtp.remb = true; 233 return config; 234 } 235 236 VideoReceiveStream* Call::CreateVideoReceiveStream( 237 const VideoReceiveStream::Config& config) { 238 VideoReceiveStream* receive_stream = 239 new VideoReceiveStream(video_engine_, 240 config, 241 config_.send_transport, 242 config_.voice_engine, 243 base_channel_id_); 244 245 WriteLockScoped write_lock(*receive_lock_); 246 assert(receive_ssrcs_.find(config.rtp.remote_ssrc) == receive_ssrcs_.end()); 247 receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; 248 // TODO(pbos): Configure different RTX payloads per receive payload. 249 VideoReceiveStream::Config::Rtp::RtxMap::const_iterator it = 250 config.rtp.rtx.begin(); 251 if (it != config.rtp.rtx.end()) 252 receive_ssrcs_[it->second.ssrc] = receive_stream; 253 254 return receive_stream; 255 } 256 257 void Call::DestroyVideoReceiveStream( 258 webrtc::VideoReceiveStream* receive_stream) { 259 assert(receive_stream != NULL); 260 261 VideoReceiveStream* receive_stream_impl = NULL; 262 { 263 WriteLockScoped write_lock(*receive_lock_); 264 // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a 265 // separate SSRC there can be either one or two. 266 std::map<uint32_t, VideoReceiveStream*>::iterator it = 267 receive_ssrcs_.begin(); 268 while (it != receive_ssrcs_.end()) { 269 if (it->second == static_cast<VideoReceiveStream*>(receive_stream)) { 270 assert(receive_stream_impl == NULL || 271 receive_stream_impl == it->second); 272 receive_stream_impl = it->second; 273 receive_ssrcs_.erase(it++); 274 } else { 275 ++it; 276 } 277 } 278 } 279 280 assert(receive_stream_impl != NULL); 281 delete receive_stream_impl; 282 } 283 284 uint32_t Call::SendBitrateEstimate() { 285 // TODO(pbos): Return send-bitrate estimate 286 return 0; 287 } 288 289 uint32_t Call::ReceiveBitrateEstimate() { 290 // TODO(pbos): Return receive-bitrate estimate 291 return 0; 292 } 293 294 Call::PacketReceiver::DeliveryStatus Call::DeliverRtcp(const uint8_t* packet, 295 size_t length) { 296 // TODO(pbos): Figure out what channel needs it actually. 297 // Do NOT broadcast! Also make sure it's a valid packet. 298 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that 299 // there's no receiver of the packet. 300 bool rtcp_delivered = false; 301 { 302 ReadLockScoped read_lock(*receive_lock_); 303 for (std::map<uint32_t, VideoReceiveStream*>::iterator it = 304 receive_ssrcs_.begin(); 305 it != receive_ssrcs_.end(); 306 ++it) { 307 if (it->second->DeliverRtcp(packet, length)) 308 rtcp_delivered = true; 309 } 310 } 311 312 { 313 ReadLockScoped read_lock(*send_lock_); 314 for (std::map<uint32_t, VideoSendStream*>::iterator it = 315 send_ssrcs_.begin(); 316 it != send_ssrcs_.end(); 317 ++it) { 318 if (it->second->DeliverRtcp(packet, length)) 319 rtcp_delivered = true; 320 } 321 } 322 return rtcp_delivered ? DELIVERY_OK : DELIVERY_PACKET_ERROR; 323 } 324 325 Call::PacketReceiver::DeliveryStatus Call::DeliverRtp(const RTPHeader& header, 326 const uint8_t* packet, 327 size_t length) { 328 ReadLockScoped read_lock(*receive_lock_); 329 std::map<uint32_t, VideoReceiveStream*>::iterator it = 330 receive_ssrcs_.find(header.ssrc); 331 332 if (it == receive_ssrcs_.end()) 333 return DELIVERY_UNKNOWN_SSRC; 334 335 return it->second->DeliverRtp(static_cast<const uint8_t*>(packet), length) 336 ? DELIVERY_OK 337 : DELIVERY_PACKET_ERROR; 338 } 339 340 Call::PacketReceiver::DeliveryStatus Call::DeliverPacket(const uint8_t* packet, 341 size_t length) { 342 // TODO(pbos): ExtensionMap if there are extensions. 343 if (RtpHeaderParser::IsRtcp(packet, static_cast<int>(length))) 344 return DeliverRtcp(packet, length); 345 346 RTPHeader rtp_header; 347 if (!rtp_header_parser_->Parse(packet, static_cast<int>(length), &rtp_header)) 348 return DELIVERY_PACKET_ERROR; 349 350 return DeliverRtp(rtp_header, packet, length); 351 } 352 353 } // namespace internal 354 } // namespace webrtc 355