From afb554f404d68e6f3ca5395216f776169370713d Mon Sep 17 00:00:00 2001 From: "pbos@webrtc.org" Date: Tue, 12 Aug 2014 23:17:13 +0000 Subject: [PATCH] Move default-recv-channels to a separate class. BUG=1788,3099 R=pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/20119004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6879 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/media/webrtc/webrtcvideoengine2.cc | 88 +++++++++++++++---------- talk/media/webrtc/webrtcvideoengine2.h | 30 ++++++++- 2 files changed, 82 insertions(+), 36 deletions(-) diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc index 2cd22291ad..1edb1750c9 100644 --- a/talk/media/webrtc/webrtcvideoengine2.cc +++ b/talk/media/webrtc/webrtcvideoengine2.cc @@ -249,6 +249,42 @@ bool WebRtcVideoEncoderFactory2::SupportsCodec(const VideoCodec& codec) { return _stricmp(codec.name.c_str(), kVp8CodecName) == 0; } +DefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() + : default_recv_ssrc_(0), default_renderer_(NULL) {} + +UnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( + VideoMediaChannel* channel, + uint32_t ssrc) { + if (default_recv_ssrc_ != 0) { // Already one default stream. + LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; + return kDropPacket; + } + + StreamParams sp; + sp.ssrcs.push_back(ssrc); + LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; + if (!channel->AddRecvStream(sp)) { + LOG(LS_WARNING) << "Could not create default receive stream."; + } + + channel->SetRenderer(ssrc, default_renderer_); + default_recv_ssrc_ = ssrc; + return kDeliverPacket; +} + +VideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { + return default_renderer_; +} + +void DefaultUnsignalledSsrcHandler::SetDefaultRenderer( + VideoMediaChannel* channel, + VideoRenderer* renderer) { + default_renderer_ = renderer; + if (default_recv_ssrc_ != 0) { + channel->SetRenderer(default_recv_ssrc_, default_renderer_); + } +} + WebRtcVideoEngine2::WebRtcVideoEngine2() { // Construct without a factory or voice engine. Construct(NULL, NULL, new rtc::CpuMonitor(NULL)); @@ -641,7 +677,8 @@ WebRtcVideoChannel2::WebRtcVideoChannel2( WebRtcVideoEngine2* engine, VoiceMediaChannel* voice_channel, WebRtcVideoEncoderFactory2* encoder_factory) - : encoder_factory_(encoder_factory) { + : encoder_factory_(encoder_factory), + unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_) { // TODO(pbos): Connect the video and audio with |voice_channel|. webrtc::Call::Config config(this); Construct(webrtc::Call::Create(config), engine); @@ -651,7 +688,8 @@ WebRtcVideoChannel2::WebRtcVideoChannel2( webrtc::Call* call, WebRtcVideoEngine2* engine, WebRtcVideoEncoderFactory2* encoder_factory) - : encoder_factory_(encoder_factory) { + : encoder_factory_(encoder_factory), + unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_) { Construct(call, engine); } @@ -660,9 +698,7 @@ void WebRtcVideoChannel2::Construct(webrtc::Call* call, rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; sending_ = false; call_.reset(call); - default_renderer_ = NULL; default_send_ssrc_ = 0; - default_recv_ssrc_ = 0; SetDefaultOptions(); } @@ -928,9 +964,6 @@ bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { uint32 ssrc = sp.first_ssrc(); assert(ssrc != 0); // TODO(pbos): Is this ever valid? - if (default_recv_ssrc_ == 0) { - default_recv_ssrc_ = ssrc; - } // TODO(pbos): Check if any of the SSRCs overlap. if (receive_streams_.find(ssrc) != receive_streams_.end()) { @@ -987,7 +1020,8 @@ void WebRtcVideoChannel2::ConfigureReceiverRtp( bool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; if (ssrc == 0) { - ssrc = default_recv_ssrc_; + LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; + return false; } std::map::iterator stream = @@ -999,10 +1033,6 @@ bool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { delete stream->second; receive_streams_.erase(stream); - if (ssrc == default_recv_ssrc_) { - default_recv_ssrc_ = 0; - } - return true; } @@ -1010,11 +1040,7 @@ bool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " << (renderer ? "(ptr)" : "NULL"); if (ssrc == 0) { - if (default_recv_ssrc_!= 0) { - receive_streams_[default_recv_ssrc_]->SetRenderer(renderer); - } - ssrc = default_recv_ssrc_; - default_renderer_ = renderer; + default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); return true; } @@ -1030,11 +1056,8 @@ bool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { bool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { if (ssrc == 0) { - if (default_renderer_ == NULL) { - return false; - } - *renderer = default_renderer_; - return true; + *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); + return *renderer != NULL; } std::map::iterator it = @@ -1117,26 +1140,23 @@ void WebRtcVideoChannel2::OnPacketReceived( } uint32 ssrc = 0; - if (default_recv_ssrc_ != 0) { // Already one default stream. - LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; - return; - } - if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { return; } - StreamParams sp; - sp.ssrcs.push_back(ssrc); - LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; - AddRecvStream(sp); - SetRenderer(0, default_renderer_); + // TODO(pbos): Make sure that the unsignalled SSRC uses the video payload. + // Also figure out whether RTX needs to be handled. + switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { + case UnsignalledSsrcHandler::kDropPacket: + return; + case UnsignalledSsrcHandler::kDeliverPacket: + break; + } if (call_->Receiver()->DeliverPacket( reinterpret_cast(packet->data()), packet->length()) != webrtc::PacketReceiver::DELIVERY_OK) { - LOG(LS_WARNING) << "Failed to deliver RTP packet after creating default " - "receiver."; + LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; return; } } diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h index a718e9c61a..94e9c61780 100644 --- a/talk/media/webrtc/webrtcvideoengine2.h +++ b/talk/media/webrtc/webrtcvideoengine2.h @@ -82,6 +82,31 @@ class WebRtcVideoEngine2; class WebRtcVideoChannel2; class WebRtcVideoRenderer; +class UnsignalledSsrcHandler { + public: + enum Action { + kDropPacket, + kDeliverPacket, + }; + virtual Action OnUnsignalledSsrc(VideoMediaChannel* engine, + uint32_t ssrc) = 0; +}; + +// TODO(pbos): Remove, use external handlers only. +class DefaultUnsignalledSsrcHandler : public UnsignalledSsrcHandler { + public: + DefaultUnsignalledSsrcHandler(); + virtual Action OnUnsignalledSsrc(VideoMediaChannel* engine, + uint32_t ssrc) OVERRIDE; + + VideoRenderer* GetDefaultRenderer() const; + void SetDefaultRenderer(VideoMediaChannel* channel, VideoRenderer* renderer); + + private: + uint32_t default_recv_ssrc_; + VideoRenderer* default_renderer_; +}; + class WebRtcVideoEncoderFactory2 { public: virtual ~WebRtcVideoEncoderFactory2(); @@ -386,8 +411,9 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, bool sending_; rtc::scoped_ptr call_; uint32_t default_send_ssrc_; - uint32_t default_recv_ssrc_; - VideoRenderer* default_renderer_; + + DefaultUnsignalledSsrcHandler default_unsignalled_ssrc_handler_; + UnsignalledSsrcHandler* const unsignalled_ssrc_handler_; // Using primary-ssrc (first ssrc) as key. std::map send_streams_;