diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc index d89588000..1a2f25a69 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc @@ -94,10 +94,10 @@ void RtcpFormatRembTest::SetUp() { configuration.clock = system_clock_; configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get(); dummy_rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration); - rtcp_sender_ = - new RTCPSender(0, false, system_clock_, receive_statistics_.get(), NULL); - rtcp_receiver_ = - new RTCPReceiver(0, system_clock_, NULL, dummy_rtp_rtcp_impl_); + rtcp_sender_ = new RTCPSender(0, false, system_clock_, + receive_statistics_.get(), NULL); + rtcp_receiver_ = new RTCPReceiver(0, system_clock_, NULL, NULL, NULL, + dummy_rtp_rtcp_impl_); test_transport_ = new TestTransport(rtcp_receiver_); EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(test_transport_)); diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc index b1b46dfcf..02f1fa350 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -32,6 +32,8 @@ RTCPReceiver::RTCPReceiver( int32_t id, Clock* clock, RtcpPacketTypeCounterObserver* packet_type_counter_observer, + RtcpBandwidthObserver* rtcp_bandwidth_observer, + RtcpIntraFrameObserver* rtcp_intra_frame_observer, ModuleRtpRtcpImpl* owner) : TMMBRHelp(), _clock(clock), @@ -40,8 +42,8 @@ RTCPReceiver::RTCPReceiver( _rtpRtcp(*owner), _criticalSectionFeedbacks( CriticalSectionWrapper::CreateCriticalSection()), - _cbRtcpBandwidthObserver(NULL), - _cbRtcpIntraFrameObserver(NULL), + _cbRtcpBandwidthObserver(rtcp_bandwidth_observer), + _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer), _criticalSectionRTCPReceiver( CriticalSectionWrapper::CreateCriticalSection()), main_ssrc_(0), @@ -131,14 +133,6 @@ uint32_t RTCPReceiver::RemoteSSRC() const { return _remoteSSRC; } -void RTCPReceiver::RegisterRtcpObservers( - RtcpIntraFrameObserver* intra_frame_callback, - RtcpBandwidthObserver* bandwidth_callback) { - CriticalSectionScoped lock(_criticalSectionFeedbacks); - _cbRtcpIntraFrameObserver = intra_frame_callback; - _cbRtcpBandwidthObserver = bandwidth_callback; -} - void RTCPReceiver::SetSsrcs(uint32_t main_ssrc, const std::set& registered_ssrcs) { uint32_t old_ssrc = 0; @@ -149,7 +143,6 @@ void RTCPReceiver::SetSsrcs(uint32_t main_ssrc, registered_ssrcs_ = registered_ssrcs; } { - CriticalSectionScoped lock(_criticalSectionFeedbacks); if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) { _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc); } @@ -1291,7 +1284,6 @@ int32_t RTCPReceiver::UpdateTMMBR() { // Get net bitrate from bounding set depending on sent packet rate if (CalcMinBitRate(&bitrate)) { // we have a new bandwidth estimate on this channel - CriticalSectionScoped lock(_criticalSectionFeedbacks); if (_cbRtcpBandwidthObserver) { _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000); } @@ -1336,8 +1328,6 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket( } } { - CriticalSectionScoped lock(_criticalSectionFeedbacks); - // We need feedback that we have received a report block(s) so that we // can generate a new packet in a conference relay scenario, one received // report can generate several RTCP packets, based on number relayed/mixed diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h index 919e9669f..2086afcae 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h @@ -32,6 +32,8 @@ public: RTCPReceiver(int32_t id, Clock* clock, RtcpPacketTypeCounterObserver* packet_type_counter_observer, + RtcpBandwidthObserver* rtcp_bandwidth_observer, + RtcpIntraFrameObserver* rtcp_intra_frame_observer, ModuleRtpRtcpImpl* owner); virtual ~RTCPReceiver(); @@ -49,9 +51,6 @@ public: uint32_t RelaySSRC() const; - void RegisterRtcpObservers(RtcpIntraFrameObserver* intra_frame_callback, - RtcpBandwidthObserver* bandwidth_callback); - int32_t IncomingRTCPPacket( RTCPHelp::RTCPPacketInformation& rtcpPacketInformation, RTCPUtility::RTCPParserV2 *rtcpParser); @@ -238,8 +237,8 @@ protected: ModuleRtpRtcpImpl& _rtpRtcp; CriticalSectionWrapper* _criticalSectionFeedbacks; - RtcpBandwidthObserver* _cbRtcpBandwidthObserver; - RtcpIntraFrameObserver* _cbRtcpIntraFrameObserver; + RtcpBandwidthObserver* const _cbRtcpBandwidthObserver; + RtcpIntraFrameObserver* const _cbRtcpIntraFrameObserver; CriticalSectionWrapper* _criticalSectionRTCPReceiver; uint32_t main_ssrc_; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index fc09542d4..fcd4df8de 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -86,7 +86,8 @@ class RtcpReceiverTest : public ::testing::Test { configuration.outgoing_transport = test_transport_; configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get(); rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration); - rtcp_receiver_ = new RTCPReceiver(0, &system_clock_, NULL, rtp_rtcp_impl_); + rtcp_receiver_ = new RTCPReceiver(0, &system_clock_, NULL, NULL, NULL, + rtp_rtcp_impl_); test_transport_->SetRTCPReceiver(rtcp_receiver_); } ~RtcpReceiverTest() { diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc index 4e532e6d0..d548e2664 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc @@ -305,7 +305,8 @@ class RtcpSenderTest : public ::testing::Test { 0, &clock_, test_transport_, NULL, rtp_payload_registry_.get())); rtcp_sender_ = new RTCPSender(0, false, &clock_, receive_statistics_.get(), NULL); - rtcp_receiver_ = new RTCPReceiver(0, &clock_, NULL, rtp_rtcp_impl_); + rtcp_receiver_ = new RTCPReceiver(0, &clock_, NULL, NULL, NULL, + rtp_rtcp_impl_); test_transport_->SetRTCPReceiver(rtcp_receiver_); // Initialize EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(test_transport_)); diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 60e1a2721..9acf5fe98 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -76,6 +76,8 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration) rtcp_receiver_(configuration.id, configuration.clock, configuration.rtcp_packet_type_counter_observer, + configuration.bandwidth_callback, + configuration.intra_frame_callback, this), clock_(configuration.clock), id_(configuration.id), @@ -108,8 +110,6 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration) default_module_->RegisterChildModule(this); } // TODO(pwestin) move to constructors of each rtp/rtcp sender/receiver object. - rtcp_receiver_.RegisterRtcpObservers(configuration.intra_frame_callback, - configuration.bandwidth_callback); rtcp_sender_.RegisterSendTransport(configuration.outgoing_transport); // Make sure that RTCP objects are aware of our SSRC. @@ -970,20 +970,7 @@ int32_t ModuleRtpRtcpImpl::GenericFECStatus( int32_t ModuleRtpRtcpImpl::SetFecParameters( const FecProtectionParams* delta_params, const FecProtectionParams* key_params) { - if (IsDefaultModule()) { - // For default we need to update all child modules too. - CriticalSectionScoped lock(critical_section_module_ptrs_.get()); - - std::vector::iterator it = child_modules_.begin(); - while (it != child_modules_.end()) { - RtpRtcp* module = *it; - if (module) { - module->SetFecParameters(delta_params, key_params); - } - it++; - } - return 0; - } + DCHECK(!IsDefaultModule()); return rtp_sender_.SetFecParameters(delta_params, key_params); } @@ -1015,52 +1002,11 @@ void ModuleRtpRtcpImpl::BitrateSent(uint32_t* total_rate, uint32_t* video_rate, uint32_t* fec_rate, uint32_t* nack_rate) const { - if (IsDefaultModule()) { - // For default we need to update the send bitrate. - CriticalSectionScoped lock(critical_section_module_ptrs_feedback_.get()); - - if (total_rate != NULL) - *total_rate = 0; - if (video_rate != NULL) - *video_rate = 0; - if (fec_rate != NULL) - *fec_rate = 0; - if (nack_rate != NULL) - *nack_rate = 0; - - std::vector::const_iterator it = child_modules_.begin(); - while (it != child_modules_.end()) { - RtpRtcp* module = *it; - if (module) { - uint32_t child_total_rate = 0; - uint32_t child_video_rate = 0; - uint32_t child_fec_rate = 0; - uint32_t child_nack_rate = 0; - module->BitrateSent(&child_total_rate, - &child_video_rate, - &child_fec_rate, - &child_nack_rate); - if (total_rate != NULL && child_total_rate > *total_rate) - *total_rate = child_total_rate; - if (video_rate != NULL && child_video_rate > *video_rate) - *video_rate = child_video_rate; - if (fec_rate != NULL && child_fec_rate > *fec_rate) - *fec_rate = child_fec_rate; - if (nack_rate != NULL && child_nack_rate > *nack_rate) - *nack_rate = child_nack_rate; - } - it++; - } - return; - } - if (total_rate != NULL) - *total_rate = rtp_sender_.BitrateSent(); - if (video_rate != NULL) - *video_rate = rtp_sender_.VideoBitrateSent(); - if (fec_rate != NULL) - *fec_rate = rtp_sender_.FecOverheadRate(); - if (nack_rate != NULL) - *nack_rate = rtp_sender_.NackOverheadRate(); + DCHECK(!IsDefaultModule()); + *total_rate = rtp_sender_.BitrateSent(); + *video_rate = rtp_sender_.VideoBitrateSent(); + *fec_rate = rtp_sender_.FecOverheadRate(); + *nack_rate = rtp_sender_.NackOverheadRate(); } void ModuleRtpRtcpImpl::OnRequestIntraFrame() { diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index 95cba4084..50b8a49d5 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -57,6 +57,26 @@ class ChannelStatsObserver : public CallStatsObserver { owner_->OnRttUpdate(rtt); } + private: + ViEChannel* const owner_; +}; + +class ViEChannelProtectionCallback : public VCMProtectionCallback { + public: + ViEChannelProtectionCallback(ViEChannel* owner) : owner_(owner) {} + ~ViEChannelProtectionCallback() {} + + + int ProtectionRequest( + const FecProtectionParams* delta_fec_params, + const FecProtectionParams* key_fec_params, + uint32_t* sent_video_rate_bps, + uint32_t* sent_nack_rate_bps, + uint32_t* sent_fec_rate_bps) override { + return owner_->ProtectionRequest(delta_fec_params, key_fec_params, + sent_video_rate_bps, sent_nack_rate_bps, + sent_fec_rate_bps); + } private: ViEChannel* owner_; }; @@ -83,6 +103,7 @@ ViEChannel::ViEChannel(int32_t channel_id, rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()), default_rtp_rtcp_(default_rtp_rtcp), send_payload_router_(new PayloadRouter()), + vcm_protection_callback_(new ViEChannelProtectionCallback(this)), vcm_(VideoCodingModule::Create()), vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this), vie_sender_(channel_id), @@ -699,6 +720,23 @@ int32_t ViEChannel::SetFECStatus(const bool enable, return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC); } +bool ViEChannel::IsSendingFecEnabled() { + bool fec_enabled = false; + uint8_t pltype_red = 0; + uint8_t pltype_fec = 0; + rtp_rtcp_->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); + if (fec_enabled) + return true; + + CriticalSectionScoped cs(rtp_rtcp_cs_.get()); + for (auto* module : simulcast_rtp_rtcp_) { + module->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); + if (fec_enabled) + return true; + } + return false; +} + int32_t ViEChannel::ProcessFECRequest( const bool enable, const unsigned char payload_typeRED, @@ -1513,6 +1551,10 @@ scoped_refptr ViEChannel::send_payload_router() { return send_payload_router_; } +VCMProtectionCallback* ViEChannel::vcm_protection_callback() { + return vcm_protection_callback_.get(); +} + CallStatsObserver* ViEChannel::GetStatsObserver() { return stats_observer_.get(); } @@ -1650,6 +1692,30 @@ void ViEChannel::OnRttUpdate(int64_t rtt) { vcm_->SetReceiveChannelParameters(rtt); } +int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params, + const FecProtectionParams* key_fec_params, + uint32_t* video_rate_bps, + uint32_t* nack_rate_bps, + uint32_t* fec_rate_bps) { + uint32_t not_used = 0; + rtp_rtcp_->SetFecParameters(delta_fec_params, key_fec_params); + rtp_rtcp_->BitrateSent(¬_used, video_rate_bps, fec_rate_bps, + nack_rate_bps); + CriticalSectionScoped cs(rtp_rtcp_cs_.get()); + for (auto* module : simulcast_rtp_rtcp_) { + uint32_t child_video_rate = 0; + uint32_t child_fec_rate = 0; + uint32_t child_nack_rate = 0; + module->SetFecParameters(delta_fec_params, key_fec_params); + module->BitrateSent(¬_used, &child_video_rate, &child_fec_rate, + &child_nack_rate); + *video_rate_bps += child_video_rate; + *nack_rate_bps += child_nack_rate; + *fec_rate_bps += child_fec_rate; + } + return 0; +} + void ViEChannel::ReserveRtpRtcpModules(size_t num_modules) { for (size_t total_modules = 1 + simulcast_rtp_rtcp_.size() + removed_rtp_rtcp_.size(); diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h index 59ec250d9..dbb07b194 100644 --- a/webrtc/video_engine/vie_channel.h +++ b/webrtc/video_engine/vie_channel.h @@ -45,6 +45,7 @@ class ReceiveStatisticsProxy; class ReportBlockStats; class RtcpRttStats; class ThreadWrapper; +class ViEChannelProtectionCallback; class ViEDecoderObserver; class ViEEffectFilter; class ViERTPObserver; @@ -63,6 +64,7 @@ class ViEChannel public ViEFrameProviderBase { public: friend class ChannelStatsObserver; + friend class ViEChannelProtectionCallback; ViEChannel(int32_t channel_id, int32_t engine_id, @@ -120,6 +122,7 @@ class ViEChannel int32_t SetHybridNACKFECStatus(const bool enable, const unsigned char payload_typeRED, const unsigned char payload_typeFEC); + bool IsSendingFecEnabled(); int SetSenderBufferingMode(int target_delay_ms); int SetReceiverBufferingMode(int target_delay_ms); int32_t SetKeyFrameRequestMethod(const KeyFrameRequestMethod method); @@ -305,6 +308,8 @@ class ViEChannel // Gets the modules used by the channel. RtpRtcp* rtp_rtcp(); scoped_refptr send_payload_router(); + VCMProtectionCallback* vcm_protection_callback(); + CallStatsObserver* GetStatsObserver(); @@ -372,6 +377,12 @@ class ViEChannel void OnRttUpdate(int64_t rtt); + int ProtectionRequest(const FecProtectionParams* delta_fec_params, + const FecProtectionParams* key_fec_params, + uint32_t* sent_video_rate_bps, + uint32_t* sent_nack_rate_bps, + uint32_t* sent_fec_rate_bps); + private: void ReserveRtpRtcpModules(size_t total_modules) EXCLUSIVE_LOCKS_REQUIRED(rtp_rtcp_cs_); @@ -497,6 +508,7 @@ class ViEChannel std::list simulcast_rtp_rtcp_; std::list removed_rtp_rtcp_; scoped_refptr send_payload_router_; + scoped_ptr vcm_protection_callback_; VideoCodingModule* const vcm_; ViEReceiver vie_receiver_; diff --git a/webrtc/video_engine/vie_channel_manager.cc b/webrtc/video_engine/vie_channel_manager.cc index d0fcaaf75..9a7036414 100644 --- a/webrtc/video_engine/vie_channel_manager.cc +++ b/webrtc/video_engine/vie_channel_manager.cc @@ -118,8 +118,9 @@ int ViEChannelManager::CreateChannel(int* channel_id, return -1; } // Connect the encoder with the send packet router, to enable sending. - vie_encoder->StartThreadsAndSetSendPayloadRouter( - channel_map_[new_channel_id]->send_payload_router()); + vie_encoder->StartThreadsAndSetSharedMembers( + channel_map_[new_channel_id]->send_payload_router(), + channel_map_[new_channel_id]->vcm_protection_callback()); // Add ViEEncoder to EncoderFeedBackObserver. unsigned int ssrc = 0; @@ -184,8 +185,9 @@ int ViEChannelManager::CreateChannel(int* channel_id, vie_encoder = NULL; } // Connect the encoder with the send packet router, to enable sending. - vie_encoder->StartThreadsAndSetSendPayloadRouter( - channel_map_[new_channel_id]->send_payload_router()); + vie_encoder->StartThreadsAndSetSharedMembers( + channel_map_[new_channel_id]->send_payload_router(), + channel_map_[new_channel_id]->vcm_protection_callback()); // Register the ViEEncoder to get key frame requests for this channel. unsigned int ssrc = 0; @@ -254,7 +256,7 @@ int ViEChannelManager::DeleteChannel(int channel_id) { // threads and processing. This must be done before deleting the channel. if (vie_encoder->channel_id() == channel_id) { group->GetEncoderStateFeedback()->RemoveEncoder(vie_encoder); - vie_encoder->StopThreadsAndRemovePayloadRouter(); + vie_encoder->StopThreadsAndRemoveSharedMembers(); } unsigned int remote_ssrc = 0; diff --git a/webrtc/video_engine/vie_codec_impl.cc b/webrtc/video_engine/vie_codec_impl.cc index c64a73886..c442f59df 100644 --- a/webrtc/video_engine/vie_codec_impl.cc +++ b/webrtc/video_engine/vie_codec_impl.cc @@ -243,7 +243,8 @@ int ViECodecImpl::SetSendCodec(const int video_channel, shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs); // Update the protection mode, we might be switching NACK/FEC. - vie_encoder->UpdateProtectionMethod(vie_encoder->nack_enabled()); + vie_encoder->UpdateProtectionMethod(vie_encoder->nack_enabled(), + vie_channel->IsSendingFecEnabled()); // Get new best format for frame provider. ViEFrameProviderBase* frame_provider = is.FrameProvider(vie_encoder); diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc index 832415472..48fa0f0e4 100644 --- a/webrtc/video_engine/vie_encoder.cc +++ b/webrtc/video_engine/vie_encoder.cc @@ -143,6 +143,7 @@ ViEEncoder::ViEEncoder(int32_t engine_id, vpm_(*webrtc::VideoProcessingModule::Create(ViEModuleId(engine_id, channel_id))), send_payload_router_(NULL), + vcm_protection_callback_(NULL), callback_cs_(CriticalSectionWrapper::CreateCriticalSection()), data_cs_(CriticalSectionWrapper::CreateCriticalSection()), bitrate_controller_(bitrate_controller), @@ -228,10 +229,14 @@ bool ViEEncoder::Init() { return true; } -void ViEEncoder::StartThreadsAndSetSendPayloadRouter( - scoped_refptr send_payload_router) { +void ViEEncoder::StartThreadsAndSetSharedMembers( + scoped_refptr send_payload_router, + VCMProtectionCallback* vcm_protection_callback) { DCHECK(send_payload_router_ == NULL); + DCHECK(vcm_protection_callback_ == NULL); + send_payload_router_ = send_payload_router; + vcm_protection_callback_ = vcm_protection_callback; module_process_thread_.RegisterModule(&vcm_); module_process_thread_.RegisterModule(default_rtp_rtcp_.get()); @@ -239,7 +244,9 @@ void ViEEncoder::StartThreadsAndSetSendPayloadRouter( pacer_thread_->Start(); } -void ViEEncoder::StopThreadsAndRemovePayloadRouter() { +void ViEEncoder::StopThreadsAndRemoveSharedMembers() { + vcm_.RegisterProtectionCallback(NULL); + vcm_protection_callback_ = NULL; pacer_thread_->Stop(); pacer_thread_->DeRegisterModule(paced_sender_.get()); module_process_thread_.DeRegisterModule(&vcm_); @@ -651,29 +658,19 @@ int ViEEncoder::CodecTargetBitrate(uint32_t* bitrate) const { return 0; } -int32_t ViEEncoder::UpdateProtectionMethod(bool enable_nack) { +int32_t ViEEncoder::UpdateProtectionMethod(bool nack, bool fec) { DCHECK(send_payload_router_ != NULL); - bool fec_enabled = false; - uint8_t dummy_ptype_red = 0; - uint8_t dummy_ptypeFEC = 0; + DCHECK(vcm_protection_callback_ != NULL); - // Updated protection method to VCM to get correct packetization sizes. - // FEC has larger overhead than NACK -> set FEC if used. - int32_t error = default_rtp_rtcp_->GenericFECStatus(fec_enabled, - dummy_ptype_red, - dummy_ptypeFEC); - if (error) { - return -1; - } - if (fec_enabled_ == fec_enabled && nack_enabled_ == enable_nack) { + if (fec_enabled_ == fec && nack_enabled_ == nack) { // No change needed, we're already in correct state. return 0; } - fec_enabled_ = fec_enabled; - nack_enabled_ = enable_nack; + fec_enabled_ = fec; + nack_enabled_ = nack; // Set Video Protection for VCM. - if (fec_enabled && nack_enabled_) { + if (fec_enabled_ && nack_enabled_) { vcm_.SetVideoProtection(webrtc::kProtectionNackFEC, true); } else { vcm_.SetVideoProtection(webrtc::kProtectionFEC, fec_enabled_); @@ -682,7 +679,7 @@ int32_t ViEEncoder::UpdateProtectionMethod(bool enable_nack) { } if (fec_enabled_ || nack_enabled_) { - vcm_.RegisterProtectionCallback(this); + vcm_.RegisterProtectionCallback(vcm_protection_callback_); // The send codec must be registered to set correct MTU. webrtc::VideoCodec codec; if (vcm_.SendCodec(&codec) == 0) { @@ -741,18 +738,6 @@ int32_t ViEEncoder::SendData( rtp_video_hdr) ? 0 : -1; } -int32_t ViEEncoder::ProtectionRequest( - const FecProtectionParams* delta_fec_params, - const FecProtectionParams* key_fec_params, - uint32_t* sent_video_rate_bps, - uint32_t* sent_nack_rate_bps, - uint32_t* sent_fec_rate_bps) { - default_rtp_rtcp_->SetFecParameters(delta_fec_params, key_fec_params); - default_rtp_rtcp_->BitrateSent(NULL, sent_video_rate_bps, sent_fec_rate_bps, - sent_nack_rate_bps); - return 0; -} - int32_t ViEEncoder::SendStatistics(const uint32_t bit_rate, const uint32_t frame_rate) { bitrate_controller_->SetBitrateSent(bit_rate); diff --git a/webrtc/video_engine/vie_encoder.h b/webrtc/video_engine/vie_encoder.h index 34120bcb9..a862af7fb 100644 --- a/webrtc/video_engine/vie_encoder.h +++ b/webrtc/video_engine/vie_encoder.h @@ -48,7 +48,6 @@ class ViEPacedSenderCallback; class ViEEncoder : public RtcpIntraFrameObserver, public VCMPacketizationCallback, - public VCMProtectionCallback, public VCMSendStatisticsCallback, public ViEFrameCallback { public: @@ -70,12 +69,13 @@ class ViEEncoder // only once. // Ideally this would be done in Init, but the dependencies between ViEEncoder // and ViEChannel makes it really hard to do in a good way. - void StartThreadsAndSetSendPayloadRouter( - scoped_refptr send_payload_router); + void StartThreadsAndSetSharedMembers( + scoped_refptr send_payload_router, + VCMProtectionCallback* vcm_protection_callback); // This function must be called before the corresponding ViEChannel is // deleted. - void StopThreadsAndRemovePayloadRouter(); + void StopThreadsAndRemoveSharedMembers(); void SetNetworkTransmissionState(bool is_transmitting); @@ -129,7 +129,7 @@ class ViEEncoder int CodecTargetBitrate(uint32_t* bitrate) const; // Loss protection. - int32_t UpdateProtectionMethod(bool enable_nack); + int32_t UpdateProtectionMethod(bool nack, bool fec); bool nack_enabled() const { return nack_enabled_; } // Buffering mode. @@ -141,14 +141,6 @@ class ViEEncoder const RTPFragmentationHeader& fragmentation_header, const RTPVideoHeader* rtp_video_hdr) OVERRIDE; - // Implements VideoProtectionCallback. - virtual int ProtectionRequest( - const FecProtectionParams* delta_fec_params, - const FecProtectionParams* key_fec_params, - uint32_t* sent_video_rate_bps, - uint32_t* sent_nack_rate_bps, - uint32_t* sent_fec_rate_bps) OVERRIDE; - // Implements VideoSendStatisticsCallback. virtual int32_t SendStatistics(const uint32_t bit_rate, const uint32_t frame_rate) OVERRIDE; @@ -218,6 +210,8 @@ class ViEEncoder VideoProcessingModule& vpm_; rtc::scoped_ptr default_rtp_rtcp_; scoped_refptr send_payload_router_; + VCMProtectionCallback* vcm_protection_callback_; + rtc::scoped_ptr callback_cs_; rtc::scoped_ptr data_cs_; rtc::scoped_ptr bitrate_observer_; diff --git a/webrtc/video_engine/vie_rtp_rtcp_impl.cc b/webrtc/video_engine/vie_rtp_rtcp_impl.cc index bf27d8ab4..96307e157 100644 --- a/webrtc/video_engine/vie_rtp_rtcp_impl.cc +++ b/webrtc/video_engine/vie_rtp_rtcp_impl.cc @@ -382,7 +382,8 @@ int ViERTP_RTCPImpl::SetNACKStatus(const int video_channel, const bool enable) { shared_data_->SetLastError(kViERtpRtcpUnknownError); return -1; } - vie_encoder->UpdateProtectionMethod(enable); + vie_encoder->UpdateProtectionMethod(enable, + vie_channel->IsSendingFecEnabled()); return 0; } @@ -410,7 +411,7 @@ int ViERTP_RTCPImpl::SetFECStatus(const int video_channel, const bool enable, shared_data_->SetLastError(kViERtpRtcpUnknownError); return -1; } - vie_encoder->UpdateProtectionMethod(false); + vie_encoder->UpdateProtectionMethod(false, true); return 0; } @@ -443,7 +444,7 @@ int ViERTP_RTCPImpl::SetHybridNACKFECStatus( shared_data_->SetLastError(kViERtpRtcpUnknownError); return -1; } - vie_encoder->UpdateProtectionMethod(enable); + vie_encoder->UpdateProtectionMethod(enable, enable); return 0; }