From a6db54d4c9a2bfc703bc208eb5cbc19505e9cef3 Mon Sep 17 00:00:00 2001 From: "solenberg@webrtc.org" Date: Mon, 27 May 2013 16:02:56 +0000 Subject: [PATCH] - Created RemoteBitrateEstimator wrapper for use internally in (ViE) ChannelGroup. - Changed implementation of SetReceiveAbsoluteSendTimeStatus API so the RBE instance is changed when at least one channel in a group has the extension enabled. BUG= R=mflodman@webrtc.org, stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1553005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4113 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../include/remote_bitrate_estimator.h | 9 ++ .../remote_bitrate_estimator_single_stream.cc | 6 ++ webrtc/video_engine/include/vie_rtp_rtcp.h | 2 + webrtc/video_engine/vie_channel.cc | 19 +++- webrtc/video_engine/vie_channel.h | 2 + webrtc/video_engine/vie_channel_group.cc | 101 ++++++++++++++++-- webrtc/video_engine/vie_channel_group.h | 1 + webrtc/video_engine/vie_channel_manager.cc | 31 +++++- webrtc/video_engine/vie_channel_manager.h | 4 + webrtc/video_engine/vie_rtp_rtcp_impl.cc | 12 +-- 10 files changed, 166 insertions(+), 21 deletions(-) diff --git a/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h b/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h index a6e0d3a0fc..2ccb92cc55 100644 --- a/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h +++ b/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h @@ -80,6 +80,15 @@ struct RemoteBitrateEstimatorFactory { Clock* clock) const; }; +struct AbsoluteSendTimeRemoteBitrateEstimatorFactory { + AbsoluteSendTimeRemoteBitrateEstimatorFactory() {} + virtual ~AbsoluteSendTimeRemoteBitrateEstimatorFactory() {} + + virtual RemoteBitrateEstimator* Create( + RemoteBitrateObserver* observer, + Clock* clock) const; +}; + struct MultiStreamRemoteBitrateEstimatorFactory : RemoteBitrateEstimatorFactory { MultiStreamRemoteBitrateEstimatorFactory() {} diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc index 6f0e80a7d5..18119f6f93 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc +++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc @@ -225,4 +225,10 @@ RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create( Clock* clock) const { return new RemoteBitrateEstimatorSingleStream(observer, clock); } + +RemoteBitrateEstimator* AbsoluteSendTimeRemoteBitrateEstimatorFactory::Create( + RemoteBitrateObserver* observer, + Clock* clock) const { + return new RemoteBitrateEstimatorSingleStream(observer, clock); +} } // namespace webrtc diff --git a/webrtc/video_engine/include/vie_rtp_rtcp.h b/webrtc/video_engine/include/vie_rtp_rtcp.h index e2f0795442..135f7f834a 100644 --- a/webrtc/video_engine/include/vie_rtp_rtcp.h +++ b/webrtc/video_engine/include/vie_rtp_rtcp.h @@ -248,6 +248,8 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP { bool enable, int id) = 0; + // When enabled for a channel, *all* channels on the same transport will be + // expected to include the absolute send time header extension. virtual int SetReceiveAbsoluteSendTimeStatus(int video_channel, bool enable, int id) = 0; diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index 0eca8b47db..bd40b35416 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -91,6 +91,7 @@ ViEChannel::ViEChannel(int32_t channel_id, rtp_packet_timeout_(false), send_timestamp_extension_id_(kInvalidRtpExtensionId), absolute_send_time_extension_id_(kInvalidRtpExtensionId), + receive_absolute_send_time_enabled_(false), using_packet_spread_(false), external_transport_(NULL), decoder_reset_(true), @@ -914,12 +915,22 @@ int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) { int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { if (enable) { - return rtp_rtcp_->RegisterReceiveRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime, id); + if (rtp_rtcp_->RegisterReceiveRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime, id) != 0) { + return -1; + } } else { - return rtp_rtcp_->DeregisterReceiveRtpHeaderExtension( - kRtpExtensionAbsoluteSendTime); + if (rtp_rtcp_->DeregisterReceiveRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime) != 0) { + return -1; + } } + receive_absolute_send_time_enabled_ = enable; + return 0; +} + +bool ViEChannel::GetReceiveAbsoluteSendTimeStatus() const { + return receive_absolute_send_time_enabled_; } void ViEChannel::SetTransmissionSmoothingStatus(bool enable) { diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h index 489abfb1ba..d36772e6d7 100644 --- a/webrtc/video_engine/vie_channel.h +++ b/webrtc/video_engine/vie_channel.h @@ -125,6 +125,7 @@ class ViEChannel int SetReceiveTimestampOffsetStatus(bool enable, int id); int SetSendAbsoluteSendTimeStatus(bool enable, int id); int SetReceiveAbsoluteSendTimeStatus(bool enable, int id); + bool GetReceiveAbsoluteSendTimeStatus() const; void SetTransmissionSmoothingStatus(bool enable); int32_t EnableTMMBR(const bool enable); int32_t EnableKeyFrameRequestCallback(const bool enable); @@ -385,6 +386,7 @@ class ViEChannel bool rtp_packet_timeout_; int send_timestamp_extension_id_; int absolute_send_time_extension_id_; + bool receive_absolute_send_time_enabled_; bool using_packet_spread_; Transport* external_transport_; diff --git a/webrtc/video_engine/vie_channel_group.cc b/webrtc/video_engine/vie_channel_group.cc index 1b4484fa34..191230df49 100644 --- a/webrtc/video_engine/vie_channel_group.cc +++ b/webrtc/video_engine/vie_channel_group.cc @@ -15,6 +15,7 @@ #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" #include "webrtc/modules/utility/interface/process_thread.h" +#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" #include "webrtc/video_engine/call_stats.h" #include "webrtc/video_engine/encoder_state_feedback.h" #include "webrtc/video_engine/vie_channel.h" @@ -22,30 +23,114 @@ #include "webrtc/video_engine/vie_remb.h" namespace webrtc { +namespace { + +class WrappingBitrateEstimator : public RemoteBitrateEstimator { + public: + WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock, + ProcessThread* process_thread) + : observer_(observer), + clock_(clock), + process_thread_(process_thread), + crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), + rbe_(RemoteBitrateEstimatorFactory().Create(observer_, clock_)), + receive_absolute_send_time_(false) { + assert(process_thread_ != NULL); + process_thread_->RegisterModule(rbe_.get()); + } + virtual ~WrappingBitrateEstimator() { + process_thread_->DeRegisterModule(rbe_.get()); + } + + void SetReceiveAbsoluteSendTimeStatus(bool enable) { + CriticalSectionScoped cs(crit_sect_.get()); + if (enable == receive_absolute_send_time_) { + return; + } + + process_thread_->DeRegisterModule(rbe_.get()); + if (enable) { + rbe_.reset(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create( + observer_, clock_)); + } else { + rbe_.reset(RemoteBitrateEstimatorFactory().Create(observer_, clock_)); + } + process_thread_->RegisterModule(rbe_.get()); + + receive_absolute_send_time_ = enable; + } + + virtual void IncomingRtcp(unsigned int ssrc, uint32_t ntp_secs, + uint32_t ntp_frac, uint32_t rtp_timestamp) { + CriticalSectionScoped cs(crit_sect_.get()); + rbe_->IncomingRtcp(ssrc, ntp_secs, ntp_frac, rtp_timestamp); + } + + virtual void IncomingPacket(int64_t arrival_time_ms, + int payload_size, + const WebRtcRTPHeader& header) { + CriticalSectionScoped cs(crit_sect_.get()); + rbe_->IncomingPacket(arrival_time_ms, payload_size, header); + } + + virtual int32_t Process() { + assert(false && "Not supposed to register the WrappingBitrateEstimator!"); + return 0; + } + + virtual int32_t TimeUntilNextProcess() { + assert(false && "Not supposed to register the WrappingBitrateEstimator!"); + return 0; + } + + virtual void OnRttUpdate(uint32_t rtt) { + CriticalSectionScoped cs(crit_sect_.get()); + rbe_->OnRttUpdate(rtt); + } + + virtual void RemoveStream(unsigned int ssrc) { + CriticalSectionScoped cs(crit_sect_.get()); + rbe_->RemoveStream(ssrc); + } + + virtual bool LatestEstimate(std::vector* ssrcs, + unsigned int* bitrate_bps) const { + CriticalSectionScoped cs(crit_sect_.get()); + return rbe_->LatestEstimate(ssrcs, bitrate_bps); + } + + private: + RemoteBitrateObserver* observer_; + Clock* clock_; + ProcessThread* process_thread_; + scoped_ptr crit_sect_; + scoped_ptr rbe_; + bool receive_absolute_send_time_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator); +}; +} // namespace ChannelGroup::ChannelGroup(ProcessThread* process_thread, const Config& config) : remb_(new VieRemb()), bitrate_controller_(BitrateController::CreateBitrateController()), call_stats_(new CallStats()), - remote_bitrate_estimator_( - config.Get().Create( - remb_.get(), - Clock::GetRealTimeClock())), + remote_bitrate_estimator_(new WrappingBitrateEstimator(remb_.get(), + Clock::GetRealTimeClock(), process_thread)), encoder_state_feedback_(new EncoderStateFeedback()), process_thread_(process_thread) { call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get()); process_thread->RegisterModule(call_stats_.get()); - process_thread->RegisterModule(remote_bitrate_estimator_.get()); } ChannelGroup::~ChannelGroup() { call_stats_->DeregisterStatsObserver(remote_bitrate_estimator_.get()); process_thread_->DeRegisterModule(call_stats_.get()); - process_thread_->DeRegisterModule(remote_bitrate_estimator_.get()); assert(channels_.empty()); assert(!remb_->InUse()); } + void ChannelGroup::AddChannel(int channel_id) { channels_.insert(channel_id); } @@ -104,4 +189,8 @@ bool ChannelGroup::SetChannelRembStatus(int channel_id, bool sender, return true; } +void ChannelGroup::SetReceiveAbsoluteSendTimeStatus(bool enable) { + static_cast(remote_bitrate_estimator_.get())-> + SetReceiveAbsoluteSendTimeStatus(enable); +} } // namespace webrtc diff --git a/webrtc/video_engine/vie_channel_group.h b/webrtc/video_engine/vie_channel_group.h index fb68803748..d46a30a77d 100644 --- a/webrtc/video_engine/vie_channel_group.h +++ b/webrtc/video_engine/vie_channel_group.h @@ -42,6 +42,7 @@ class ChannelGroup { bool SetChannelRembStatus(int channel_id, bool sender, bool receiver, ViEChannel* channel); + void SetReceiveAbsoluteSendTimeStatus(bool enable); BitrateController* GetBitrateController(); CallStats* GetCallStats(); diff --git a/webrtc/video_engine/vie_channel_manager.cc b/webrtc/video_engine/vie_channel_manager.cc index 6afa4ad2ac..3c121fe0e3 100644 --- a/webrtc/video_engine/vie_channel_manager.cc +++ b/webrtc/video_engine/vie_channel_manager.cc @@ -367,10 +367,39 @@ bool ViEChannelManager::SetRembStatus(int channel_id, bool sender, return group->SetChannelRembStatus(channel_id, sender, receiver, channel); } +bool ViEChannelManager::SetReceiveAbsoluteSendTimeStatus(int channel_id, + bool enable, + int id) { + CriticalSectionScoped cs(channel_id_critsect_); + ViEChannel* channel = ViEChannelPtr(channel_id); + if (!channel) { + return false; + } + if (channel->SetReceiveAbsoluteSendTimeStatus(enable, id) != 0) { + return false; + } + + // Enable absolute send time extension on the group if at least one of the + // channels use it. + ChannelGroup* group = FindGroup(channel_id); + assert(group); + bool any_enabled = false; + for (ChannelMap::const_iterator c_it = channel_map_.begin(); + c_it != channel_map_.end(); ++c_it) { + if (group->HasChannel(c_it->first) && + c_it->second->GetReceiveAbsoluteSendTimeStatus()) { + any_enabled = true; + break; + } + } + group->SetReceiveAbsoluteSendTimeStatus(any_enabled); + return true; +} + void ViEChannelManager::UpdateSsrcs(int channel_id, const std::list& ssrcs) { CriticalSectionScoped cs(channel_id_critsect_); - ChannelGroup* channel_group = FindGroup(channel_id); + ChannelGroup* channel_group = FindGroup(channel_id); if (channel_group == NULL) { return; } diff --git a/webrtc/video_engine/vie_channel_manager.h b/webrtc/video_engine/vie_channel_manager.h index 19932136d3..1a2460bd7b 100644 --- a/webrtc/video_engine/vie_channel_manager.h +++ b/webrtc/video_engine/vie_channel_manager.h @@ -75,6 +75,10 @@ class ViEChannelManager: private ViEManagerBase { // Adds a channel to include when sending REMB. bool SetRembStatus(int channel_id, bool sender, bool receiver); + // Switches a channel and its associated group to use (or not) the absolute + // send time header extension with |id|. + bool SetReceiveAbsoluteSendTimeStatus(int channel_id, bool enable, int id); + // Updates the SSRCs for a channel. If one of the SSRCs already is registered, // it will simply be ignored and no error is returned. void UpdateSsrcs(int channel_id, const std::list& ssrcs); diff --git a/webrtc/video_engine/vie_rtp_rtcp_impl.cc b/webrtc/video_engine/vie_rtp_rtcp_impl.cc index 7148a471de..d8ead1278d 100644 --- a/webrtc/video_engine/vie_rtp_rtcp_impl.cc +++ b/webrtc/video_engine/vie_rtp_rtcp_impl.cc @@ -796,16 +796,8 @@ int ViERTP_RTCPImpl::SetReceiveAbsoluteSendTimeStatus(int video_channel, ViEId(shared_data_->instance_id(), video_channel), "ViERTP_RTCPImpl::SetReceiveAbsoluteSendTimeStatus(%d, %d, %d)", video_channel, enable, id); - ViEChannelManagerScoped cs(*(shared_data_->channel_manager())); - ViEChannel* vie_channel = cs.Channel(video_channel); - if (!vie_channel) { - WEBRTC_TRACE(kTraceError, kTraceVideo, - ViEId(shared_data_->instance_id(), video_channel), - "%s: Channel %d doesn't exist", __FUNCTION__, video_channel); - shared_data_->SetLastError(kViERtpRtcpInvalidChannelId); - return -1; - } - if (vie_channel->SetReceiveAbsoluteSendTimeStatus(enable, id) != 0) { + if (!shared_data_->channel_manager()->SetReceiveAbsoluteSendTimeStatus( + video_channel, enable, id)) { shared_data_->SetLastError(kViERtpRtcpUnknownError); return -1; }