diff options
Diffstat (limited to 'chromium/third_party/webrtc/video/call.cc')
-rw-r--r-- | chromium/third_party/webrtc/video/call.cc | 240 |
1 files changed, 101 insertions, 139 deletions
diff --git a/chromium/third_party/webrtc/video/call.cc b/chromium/third_party/webrtc/video/call.cc index 12daa8eaaeb..6daa8b07f94 100644 --- a/chromium/third_party/webrtc/video/call.cc +++ b/chromium/third_party/webrtc/video/call.cc @@ -21,6 +21,7 @@ #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" #include "webrtc/system_wrappers/interface/rw_lock_wrapper.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/system_wrappers/interface/thread_annotations.h" #include "webrtc/system_wrappers/interface/trace.h" #include "webrtc/video/video_receive_stream.h" #include "webrtc/video/video_send_stream.h" @@ -33,18 +34,45 @@ const char* RtpExtension::kTOffset = "urn:ietf:params:rtp-hdrext:toffset"; const char* RtpExtension::kAbsSendTime = "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"; namespace internal { + +class CpuOveruseObserverProxy : public webrtc::CpuOveruseObserver { + public: + CpuOveruseObserverProxy(OveruseCallback* overuse_callback) + : crit_(CriticalSectionWrapper::CreateCriticalSection()), + overuse_callback_(overuse_callback) { + assert(overuse_callback != NULL); + } + + virtual ~CpuOveruseObserverProxy() {} + + virtual void OveruseDetected() OVERRIDE { + CriticalSectionScoped lock(crit_.get()); + overuse_callback_->OnOveruse(); + } + + virtual void NormalUsage() OVERRIDE { + CriticalSectionScoped lock(crit_.get()); + overuse_callback_->OnNormalUse(); + } + + private: + const scoped_ptr<CriticalSectionWrapper> crit_; + OveruseCallback* overuse_callback_ GUARDED_BY(crit_); +}; + class Call : public webrtc::Call, public PacketReceiver { public: Call(webrtc::VideoEngine* video_engine, const Call::Config& config); virtual ~Call(); virtual PacketReceiver* Receiver() OVERRIDE; - virtual std::vector<VideoCodec> GetVideoCodecs() OVERRIDE; virtual VideoSendStream::Config GetDefaultSendConfig() OVERRIDE; virtual VideoSendStream* CreateVideoSendStream( - const VideoSendStream::Config& config) OVERRIDE; + const VideoSendStream::Config& config, + const std::vector<VideoStream>& video_streams, + const void* encoder_settings) OVERRIDE; virtual void DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) OVERRIDE; @@ -60,24 +88,28 @@ class Call : public webrtc::Call, public PacketReceiver { virtual uint32_t SendBitrateEstimate() OVERRIDE; virtual uint32_t ReceiveBitrateEstimate() OVERRIDE; - virtual bool DeliverPacket(const uint8_t* packet, size_t length) OVERRIDE; + virtual DeliveryStatus DeliverPacket(const uint8_t* packet, + size_t length) OVERRIDE; private: - bool DeliverRtcp(const uint8_t* packet, size_t length); - bool DeliverRtp(const RTPHeader& header, - const uint8_t* packet, - size_t length); + DeliveryStatus DeliverRtcp(const uint8_t* packet, size_t length); + DeliveryStatus DeliverRtp(const RTPHeader& header, + const uint8_t* packet, + size_t length); Call::Config config_; - std::map<uint32_t, VideoReceiveStream*> receive_ssrcs_; + std::map<uint32_t, VideoReceiveStream*> receive_ssrcs_ + GUARDED_BY(receive_lock_); scoped_ptr<RWLockWrapper> receive_lock_; - std::map<uint32_t, VideoSendStream*> send_ssrcs_; + std::map<uint32_t, VideoSendStream*> send_ssrcs_ GUARDED_BY(send_lock_); scoped_ptr<RWLockWrapper> send_lock_; scoped_ptr<RtpHeaderParser> rtp_header_parser_; + scoped_ptr<CpuOveruseObserverProxy> overuse_observer_proxy_; + VideoEngine* video_engine_; ViERTP_RTCP* rtp_rtcp_; ViECodec* codec_; @@ -88,90 +120,10 @@ class Call : public webrtc::Call, public PacketReceiver { }; } // namespace internal -class TraceDispatcher : public TraceCallback { - public: - TraceDispatcher() - : crit_(CriticalSectionWrapper::CreateCriticalSection()), - initialized_(false), - filter_(kTraceNone) {} - - ~TraceDispatcher() { - if (initialized_) { - Trace::ReturnTrace(); - VideoEngine::SetTraceCallback(NULL); - } - } - - virtual void Print(TraceLevel level, - const char* message, - int length) OVERRIDE { - CriticalSectionScoped lock(crit_.get()); - for (std::map<Call*, Call::Config*>::iterator it = callbacks_.begin(); - it != callbacks_.end(); - ++it) { - if ((level & it->second->trace_filter) != kTraceNone) - it->second->trace_callback->Print(level, message, length); - } - } - - void RegisterCallback(Call* call, Call::Config* config) { - if (config->trace_callback == NULL) - return; - - CriticalSectionScoped lock(crit_.get()); - callbacks_[call] = config; - - filter_ |= config->trace_filter; - if (filter_ != kTraceNone && !initialized_) { - initialized_ = true; - Trace::CreateTrace(); - VideoEngine::SetTraceCallback(this); - } - VideoEngine::SetTraceFilter(filter_); - } - - void DeregisterCallback(Call* call) { - CriticalSectionScoped lock(crit_.get()); - callbacks_.erase(call); - - filter_ = kTraceNone; - for (std::map<Call*, Call::Config*>::iterator it = callbacks_.begin(); - it != callbacks_.end(); - ++it) { - filter_ |= it->second->trace_filter; - } - - VideoEngine::SetTraceFilter(filter_); - } - - private: - scoped_ptr<CriticalSectionWrapper> crit_; - bool initialized_; - unsigned int filter_; - std::map<Call*, Call::Config*> callbacks_; -}; - -namespace internal { -TraceDispatcher* global_trace_dispatcher = NULL; -} // internal - -void CreateTraceDispatcher() { - if (internal::global_trace_dispatcher == NULL) { - TraceDispatcher* dispatcher = new TraceDispatcher(); - // TODO(pbos): Atomic compare and exchange. - if (internal::global_trace_dispatcher == NULL) { - internal::global_trace_dispatcher = dispatcher; - } else { - delete dispatcher; - } - } -} - Call* Call::Create(const Call::Config& config) { - CreateTraceDispatcher(); - - VideoEngine* video_engine = config.webrtc_config != NULL ? - VideoEngine::Create(*config.webrtc_config) : VideoEngine::Create(); + VideoEngine* video_engine = config.webrtc_config != NULL + ? VideoEngine::Create(*config.webrtc_config) + : VideoEngine::Create(); assert(video_engine != NULL); return new internal::Call(video_engine, config); @@ -179,6 +131,8 @@ Call* Call::Create(const Call::Config& config) { namespace internal { +const int kDefaultVideoStreamBitrateBps = 300000; + Call::Call(webrtc::VideoEngine* video_engine, const Call::Config& config) : config_(config), receive_lock_(RWLockWrapper::CreateRWLock()), @@ -189,7 +143,10 @@ Call::Call(webrtc::VideoEngine* video_engine, const Call::Config& config) assert(video_engine != NULL); assert(config.send_transport != NULL); - global_trace_dispatcher->RegisterCallback(this, &config_); + if (config.overuse_callback) { + overuse_observer_proxy_.reset( + new CpuOveruseObserverProxy(config.overuse_callback)); + } rtp_rtcp_ = ViERTP_RTCP::GetInterface(video_engine_); assert(rtp_rtcp_ != NULL); @@ -207,7 +164,6 @@ Call::Call(webrtc::VideoEngine* video_engine, const Call::Config& config) } Call::~Call() { - global_trace_dispatcher->DeregisterCallback(this); base_->DeleteChannel(base_channel_id_); base_->Release(); codec_->Release(); @@ -217,34 +173,29 @@ Call::~Call() { PacketReceiver* Call::Receiver() { return this; } -std::vector<VideoCodec> Call::GetVideoCodecs() { - std::vector<VideoCodec> codecs; - - VideoCodec codec; - for (size_t i = 0; i < static_cast<size_t>(codec_->NumberOfCodecs()); ++i) { - if (codec_->GetCodec(static_cast<unsigned char>(i), codec) == 0) { - codecs.push_back(codec); - } - } - return codecs; -} - VideoSendStream::Config Call::GetDefaultSendConfig() { VideoSendStream::Config config; - codec_->GetCodec(0, config.codec); return config; } VideoSendStream* Call::CreateVideoSendStream( - const VideoSendStream::Config& config) { + const VideoSendStream::Config& config, + const std::vector<VideoStream>& video_streams, + const void* encoder_settings) { assert(config.rtp.ssrcs.size() > 0); - assert(config.rtp.ssrcs.size() >= config.codec.numberOfSimulcastStreams); - VideoSendStream* send_stream = new VideoSendStream(config_.send_transport, - config_.overuse_detection, - video_engine_, - config, - base_channel_id_); + // TODO(mflodman): Base the start bitrate on a current bandwidth estimate, if + // the call has already started. + VideoSendStream* send_stream = new VideoSendStream( + config_.send_transport, + overuse_observer_proxy_.get(), + video_engine_, + config, + video_streams, + encoder_settings, + base_channel_id_, + config_.start_bitrate_bps != -1 ? config_.start_bitrate_bps + : kDefaultVideoStreamBitrateBps); WriteLockScoped write_lock(*send_lock_); for (size_t i = 0; i < config.rtp.ssrcs.size(); ++i) { @@ -294,6 +245,12 @@ VideoReceiveStream* Call::CreateVideoReceiveStream( WriteLockScoped write_lock(*receive_lock_); assert(receive_ssrcs_.find(config.rtp.remote_ssrc) == receive_ssrcs_.end()); receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; + // TODO(pbos): Configure different RTX payloads per receive payload. + VideoReceiveStream::Config::Rtp::RtxMap::const_iterator it = + config.rtp.rtx.begin(); + if (it != config.rtp.rtx.end()) + receive_ssrcs_[it->second.ssrc] = receive_stream; + return receive_stream; } @@ -304,14 +261,18 @@ void Call::DestroyVideoReceiveStream( VideoReceiveStream* receive_stream_impl = NULL; { WriteLockScoped write_lock(*receive_lock_); - for (std::map<uint32_t, VideoReceiveStream*>::iterator it = - receive_ssrcs_.begin(); - it != receive_ssrcs_.end(); - ++it) { + // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a + // separate SSRC there can be either one or two. + std::map<uint32_t, VideoReceiveStream*>::iterator it = + receive_ssrcs_.begin(); + while (it != receive_ssrcs_.end()) { if (it->second == static_cast<VideoReceiveStream*>(receive_stream)) { + assert(receive_stream_impl == NULL || + receive_stream_impl == it->second); receive_stream_impl = it->second; - receive_ssrcs_.erase(it); - break; + receive_ssrcs_.erase(it++); + } else { + ++it; } } } @@ -330,9 +291,12 @@ uint32_t Call::ReceiveBitrateEstimate() { return 0; } -bool Call::DeliverRtcp(const uint8_t* packet, size_t length) { +Call::PacketReceiver::DeliveryStatus Call::DeliverRtcp(const uint8_t* packet, + size_t length) { // TODO(pbos): Figure out what channel needs it actually. // Do NOT broadcast! Also make sure it's a valid packet. + // Return DELIVERY_UNKNOWN_SSRC if it can be determined that + // there's no receiver of the packet. bool rtcp_delivered = false; { ReadLockScoped read_lock(*receive_lock_); @@ -355,35 +319,33 @@ bool Call::DeliverRtcp(const uint8_t* packet, size_t length) { rtcp_delivered = true; } } - return rtcp_delivered; + return rtcp_delivered ? DELIVERY_OK : DELIVERY_PACKET_ERROR; } -bool Call::DeliverRtp(const RTPHeader& header, - const uint8_t* packet, - size_t length) { - VideoReceiveStream* receiver; - { - ReadLockScoped read_lock(*receive_lock_); - std::map<uint32_t, VideoReceiveStream*>::iterator it = - receive_ssrcs_.find(header.ssrc); - if (it == receive_ssrcs_.end()) { - // TODO(pbos): Log some warning, SSRC without receiver. - return false; - } +Call::PacketReceiver::DeliveryStatus Call::DeliverRtp(const RTPHeader& header, + const uint8_t* packet, + size_t length) { + ReadLockScoped read_lock(*receive_lock_); + std::map<uint32_t, VideoReceiveStream*>::iterator it = + receive_ssrcs_.find(header.ssrc); - receiver = it->second; - } - return receiver->DeliverRtp(static_cast<const uint8_t*>(packet), length); + if (it == receive_ssrcs_.end()) + return DELIVERY_UNKNOWN_SSRC; + + return it->second->DeliverRtp(static_cast<const uint8_t*>(packet), length) + ? DELIVERY_OK + : DELIVERY_PACKET_ERROR; } -bool Call::DeliverPacket(const uint8_t* packet, size_t length) { +Call::PacketReceiver::DeliveryStatus Call::DeliverPacket(const uint8_t* packet, + size_t length) { // TODO(pbos): ExtensionMap if there are extensions. if (RtpHeaderParser::IsRtcp(packet, static_cast<int>(length))) return DeliverRtcp(packet, length); RTPHeader rtp_header; if (!rtp_header_parser_->Parse(packet, static_cast<int>(length), &rtp_header)) - return false; + return DELIVERY_PACKET_ERROR; return DeliverRtp(rtp_header, packet, length); } |