diff options
author | Stefan Holmer <stefan@webrtc.org> | 2018-10-04 15:21:55 +0200 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2018-10-05 14:39:01 +0000 |
commit | 64be7fa7d8c1e2c897e70ef5d8de6dd5539ce6e8 (patch) | |
tree | 714eac5238d9d90fcdcdd5e2a1e4dd4299eb18b0 /call | |
parent | 8e87852cbe28f9417611fdf471b7735331b50c9c (diff) | |
download | webrtc-64be7fa7d8c1e2c897e70ef5d8de6dd5539ce6e8.tar.gz |
Move FecController to RtpVideoSender.
This also moves the packet feedback tracking to RtpVideoSender.
Bug: webrtc:9517
Change-Id: Ifb1ff85051730108a0b0d1dd30f6f8595ad2af6e
Reviewed-on: https://webrtc-review.googlesource.com/c/95920
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25019}
Diffstat (limited to 'call')
-rw-r--r-- | call/BUILD.gn | 3 | ||||
-rw-r--r-- | call/call.cc | 29 | ||||
-rw-r--r-- | call/call.h | 3 | ||||
-rw-r--r-- | call/degraded_call.cc | 5 | ||||
-rw-r--r-- | call/degraded_call.h | 6 | ||||
-rw-r--r-- | call/rtp_transport_controller_send.cc | 22 | ||||
-rw-r--r-- | call/rtp_transport_controller_send.h | 6 | ||||
-rw-r--r-- | call/rtp_transport_controller_send_interface.h | 9 | ||||
-rw-r--r-- | call/rtp_video_sender.cc | 200 | ||||
-rw-r--r-- | call/rtp_video_sender.h | 61 | ||||
-rw-r--r-- | call/rtp_video_sender_interface.h | 22 | ||||
-rw-r--r-- | call/rtp_video_sender_unittest.cc | 17 | ||||
-rw-r--r-- | call/test/mock_rtp_transport_controller_send.h | 7 |
13 files changed, 283 insertions, 107 deletions
diff --git a/call/BUILD.gn b/call/BUILD.gn index 7c1cb3f62b..611d9e8adb 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -65,6 +65,7 @@ rtc_source_set("rtp_interfaces") { ] deps = [ "../api:array_view", + "../api:fec_controller_api", "../api:libjingle_peerconnection_api", "../api/transport:bitrate_settings", "../logging:rtc_event_log_api", @@ -117,6 +118,7 @@ rtc_source_set("rtp_sender") { ":bitrate_configurator", ":rtp_interfaces", "..:webrtc_common", + "../api:fec_controller_api", "../api:transport_api", "../api/transport:network_control", "../api/video_codecs:video_codecs_api", @@ -341,6 +343,7 @@ if (rtc_include_tests) { "../modules/rtp_rtcp:rtp_rtcp_format", "../modules/utility:mock_process_thread", "../modules/video_coding:video_codec_interface", + "../modules/video_coding:video_coding", "../rtc_base:checks", "../rtc_base:rate_limiter", "../rtc_base:rtc_base_approved", diff --git a/call/call.cc b/call/call.cc index 1062baf49d..635874b2d6 100644 --- a/call/call.cc +++ b/call/call.cc @@ -221,8 +221,8 @@ class Call final : public webrtc::Call, void SignalChannelNetworkState(MediaType media, NetworkState state) override; - void OnTransportOverheadChanged(MediaType media, - int transport_overhead_per_packet) override; + void OnAudioTransportOverheadChanged( + int transport_overhead_per_packet) override; void OnSentPacket(const rtc::SentPacket& sent_packet) override; @@ -997,27 +997,10 @@ void Call::SignalChannelNetworkState(MediaType media, NetworkState state) { } } -void Call::OnTransportOverheadChanged(MediaType media, - int transport_overhead_per_packet) { - switch (media) { - case MediaType::AUDIO: { - ReadLockScoped read_lock(*send_crit_); - for (auto& kv : audio_send_ssrcs_) { - kv.second->SetTransportOverhead(transport_overhead_per_packet); - } - break; - } - case MediaType::VIDEO: { - ReadLockScoped read_lock(*send_crit_); - for (auto& kv : video_send_ssrcs_) { - kv.second->SetTransportOverhead(transport_overhead_per_packet); - } - break; - } - case MediaType::ANY: - case MediaType::DATA: - RTC_NOTREACHED(); - break; +void Call::OnAudioTransportOverheadChanged(int transport_overhead_per_packet) { + ReadLockScoped read_lock(*send_crit_); + for (auto& kv : audio_send_ssrcs_) { + kv.second->SetTransportOverhead(transport_overhead_per_packet); } } diff --git a/call/call.h b/call/call.h index d8b1b5777d..4167296d75 100644 --- a/call/call.h +++ b/call/call.h @@ -113,8 +113,7 @@ class Call { virtual void SignalChannelNetworkState(MediaType media, NetworkState state) = 0; - virtual void OnTransportOverheadChanged( - MediaType media, + virtual void OnAudioTransportOverheadChanged( int transport_overhead_per_packet) = 0; virtual void OnSentPacket(const rtc::SentPacket& sent_packet) = 0; diff --git a/call/degraded_call.cc b/call/degraded_call.cc index df9869729a..8181310e78 100644 --- a/call/degraded_call.cc +++ b/call/degraded_call.cc @@ -157,10 +157,9 @@ void DegradedCall::SignalChannelNetworkState(MediaType media, call_->SignalChannelNetworkState(media, state); } -void DegradedCall::OnTransportOverheadChanged( - MediaType media, +void DegradedCall::OnAudioTransportOverheadChanged( int transport_overhead_per_packet) { - call_->OnTransportOverheadChanged(media, transport_overhead_per_packet); + call_->OnAudioTransportOverheadChanged(transport_overhead_per_packet); } void DegradedCall::OnSentPacket(const rtc::SentPacket& sent_packet) { diff --git a/call/degraded_call.h b/call/degraded_call.h index 257ee0be25..3c0b80df86 100644 --- a/call/degraded_call.h +++ b/call/degraded_call.h @@ -70,10 +70,8 @@ class DegradedCall : public Call, private Transport, private PacketReceiver { bitrate_allocation_strategy) override; void SignalChannelNetworkState(MediaType media, NetworkState state) override; - - void OnTransportOverheadChanged(MediaType media, - int transport_overhead_per_packet) override; - + void OnAudioTransportOverheadChanged( + int transport_overhead_per_packet) override; void OnSentPacket(const rtc::SentPacket& sent_packet) override; protected: diff --git a/call/rtp_transport_controller_send.cc b/call/rtp_transport_controller_send.cc index 92d972911d..54aef21fd9 100644 --- a/call/rtp_transport_controller_send.cc +++ b/call/rtp_transport_controller_send.cc @@ -22,6 +22,7 @@ namespace webrtc { namespace { static const int64_t kRetransmitWindowSizeMs = 500; +static const size_t kMaxOverheadBytes = 500; const char kTaskQueueExperiment[] = "WebRTC-TaskQueueCongestionControl"; using TaskQueueController = webrtc::webrtc_cc::SendSideCongestionController; @@ -92,13 +93,15 @@ RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender( const RtcpConfig& rtcp_config, Transport* send_transport, const RtpSenderObservers& observers, - RtcEventLog* event_log) { + RtcEventLog* event_log, + std::unique_ptr<FecController> fec_controller) { video_rtp_senders_.push_back(absl::make_unique<RtpVideoSender>( ssrcs, suspended_ssrcs, states, rtp_config, rtcp_config, send_transport, observers, // TODO(holmer): Remove this circular dependency by injecting // the parts of RtpTransportControllerSendInterface that are really used. - this, event_log, &retransmission_rate_limiter_)); + this, event_log, &retransmission_rate_limiter_, + std::move(fec_controller))); return video_rtp_senders_.back().get(); } @@ -315,4 +318,19 @@ void RtpTransportControllerSend::SetAllocatedBitrateWithoutFeedback( send_side_cc_->SetAllocatedBitrateWithoutFeedback(bitrate_bps); } } + +void RtpTransportControllerSend::OnTransportOverheadChanged( + size_t transport_overhead_bytes_per_packet) { + if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) { + RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes; + return; + } + + // TODO(holmer): Call AudioRtpSenders when they have been moved to + // RtpTransportControllerSend. + for (auto& rtp_video_sender : video_rtp_senders_) { + rtp_video_sender->OnTransportOverheadChanged( + transport_overhead_bytes_per_packet); + } +} } // namespace webrtc diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h index 496a00ede5..6aaf29d6bc 100644 --- a/call/rtp_transport_controller_send.h +++ b/call/rtp_transport_controller_send.h @@ -55,7 +55,8 @@ class RtpTransportControllerSend final const RtcpConfig& rtcp_config, Transport* send_transport, const RtpSenderObservers& observers, - RtcEventLog* event_log) override; + RtcEventLog* event_log, + std::unique_ptr<FecController> fec_controller) override; void DestroyRtpVideoSender( RtpVideoSenderInterface* rtp_video_sender) override; @@ -102,6 +103,9 @@ class RtpTransportControllerSend final void SetAllocatedBitrateWithoutFeedback(uint32_t bitrate_bps) override; + void OnTransportOverheadChanged( + size_t transport_overhead_per_packet) override; + private: const Clock* const clock_; PacketRouter packet_router_; diff --git a/call/rtp_transport_controller_send_interface.h b/call/rtp_transport_controller_send_interface.h index 828fec40cf..5c51c54fe1 100644 --- a/call/rtp_transport_controller_send_interface.h +++ b/call/rtp_transport_controller_send_interface.h @@ -14,11 +14,13 @@ #include <stdint.h> #include <map> +#include <memory> #include <string> #include <vector> #include "absl/types/optional.h" #include "api/bitrate_constraints.h" +#include "api/fec_controller.h" #include "api/transport/bitrate_settings.h" #include "call/rtp_config.h" #include "logging/rtc_event_log/rtc_event_log.h" @@ -58,7 +60,6 @@ struct RtpSenderObservers { RtcpPacketTypeCounterObserver* rtcp_type_observer; SendSideDelayObserver* send_delay_observer; SendPacketObserver* send_packet_observer; - OverheadObserver* overhead_observer; }; // An RtpTransportController should own everything related to the RTP @@ -99,7 +100,8 @@ class RtpTransportControllerSendInterface { const RtcpConfig& rtcp_config, Transport* send_transport, const RtpSenderObservers& observers, - RtcEventLog* event_log) = 0; + RtcEventLog* event_log, + std::unique_ptr<FecController> fec_controller) = 0; virtual void DestroyRtpVideoSender( RtpVideoSenderInterface* rtp_video_sender) = 0; @@ -149,6 +151,9 @@ class RtpTransportControllerSendInterface { const BitrateSettings& preferences) = 0; virtual void SetAllocatedBitrateWithoutFeedback(uint32_t bitrate_bps) = 0; + + virtual void OnTransportOverheadChanged( + size_t transport_overhead_per_packet) = 0; }; } // namespace webrtc diff --git a/call/rtp_video_sender.cc b/call/rtp_video_sender.cc index 8a550e14f5..10d7e7daed 100644 --- a/call/rtp_video_sender.cc +++ b/call/rtp_video_sender.cc @@ -31,6 +31,12 @@ namespace webrtc { namespace { static const int kMinSendSidePacketHistorySize = 600; +// Assume an average video stream has around 3 packets per frame (1 mbps / 30 +// fps / 1400B) A sequence number set with size 5500 will be able to store +// packet sequence number for at least last 60 seconds. +static const int kSendSideSeqNumSetMaxSize = 5500; +// We don't do MTU discovery, so assume that we have the standard ethernet MTU. +static const size_t kPathMTU = 1500; std::vector<std::unique_ptr<RtpRtcp>> CreateRtpRtcpModules( const std::vector<uint32_t>& ssrcs, @@ -149,6 +155,21 @@ std::unique_ptr<FlexfecSender> MaybeCreateFlexfecSender( rtp.flexfec.protected_media_ssrcs[0], rtp.mid, rtp.extensions, RTPSender::FecExtensionSizes(), rtp_state, Clock::GetRealTimeClock()); } + +uint32_t CalculateOverheadRateBps(int packets_per_second, + size_t overhead_bytes_per_packet, + uint32_t max_overhead_bps) { + uint32_t overhead_bps = + static_cast<uint32_t>(8 * overhead_bytes_per_packet * packets_per_second); + return std::min(overhead_bps, max_overhead_bps); +} + +int CalculatePacketRate(uint32_t bitrate_bps, size_t packet_size_bytes) { + size_t packet_size_bits = 8 * packet_size_bytes; + // Ceil for int value of bitrate_bps / packet_size_bits. + return static_cast<int>((bitrate_bps + packet_size_bits - 1) / + packet_size_bits); +} } // namespace RtpVideoSender::RtpVideoSender( @@ -161,11 +182,15 @@ RtpVideoSender::RtpVideoSender( const RtpSenderObservers& observers, RtpTransportControllerSendInterface* transport, RtcEventLog* event_log, - RateLimiter* retransmission_limiter) - : active_(false), + RateLimiter* retransmission_limiter, + std::unique_ptr<FecController> fec_controller) + : send_side_bwe_with_overhead_( + webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), + active_(false), module_process_thread_(nullptr), suspended_ssrcs_(std::move(suspended_ssrcs)), flexfec_sender_(MaybeCreateFlexfecSender(rtp_config, suspended_ssrcs_)), + fec_controller_(std::move(fec_controller)), rtp_modules_( CreateRtpRtcpModules(ssrcs, rtp_config.flexfec.protected_media_ssrcs, @@ -183,10 +208,13 @@ RtpVideoSender::RtpVideoSender( observers.send_packet_observer, event_log, retransmission_limiter, - observers.overhead_observer, + this, transport->keepalive_config())), rtp_config_(rtp_config), - transport_(transport) { + transport_(transport), + transport_overhead_bytes_per_packet_(0), + overhead_bytes_per_packet_(0), + encoder_target_rate_bps_(0) { RTC_DCHECK_EQ(ssrcs.size(), rtp_modules_.size()); module_process_thread_checker_.DetachFromThread(); // SSRCs are assumed to be sorted in the same order as |rtp_modules|. @@ -246,12 +274,24 @@ RtpVideoSender::RtpVideoSender( rtp_rtcp->RegisterVideoSendPayload(rtp_config.payload_type, rtp_config.payload_name.c_str()); } + // Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic, + // so enable that logic if either of those FEC schemes are enabled. + fec_controller_->SetProtectionMethod(FecEnabled(), NackEnabled()); + + fec_controller_->SetProtectionCallback(this); + // Signal congestion controller this object is ready for OnPacket* callbacks. + if (fec_controller_->UseLossVectorMask()) { + transport_->RegisterPacketFeedbackObserver(this); + } } RtpVideoSender::~RtpVideoSender() { for (auto& rtp_rtcp : rtp_modules_) { transport_->packet_router()->RemoveSendRtpModule(rtp_rtcp.get()); } + if (fec_controller_->UseLossVectorMask()) { + transport_->DeRegisterPacketFeedbackObserver(this); + } } void RtpVideoSender::RegisterProcessThread( @@ -302,6 +342,8 @@ EncodedImageCallback::Result RtpVideoSender::OnEncodedImage( const EncodedImage& encoded_image, const CodecSpecificInfo* codec_specific_info, const RTPFragmentationHeader* fragmentation) { + fec_controller_->UpdateWithEncodedData(encoded_image._length, + encoded_image._frameType); rtc::CritScope lock(&crit_); RTC_DCHECK(!rtp_modules_.empty()); if (!active_) @@ -440,34 +482,6 @@ void RtpVideoSender::DeliverRtcp(const uint8_t* packet, size_t length) { rtp_rtcp->IncomingRtcpPacket(packet, length); } -void RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params, - const FecProtectionParams* key_params, - uint32_t* sent_video_rate_bps, - uint32_t* sent_nack_rate_bps, - uint32_t* sent_fec_rate_bps) { - *sent_video_rate_bps = 0; - *sent_nack_rate_bps = 0; - *sent_fec_rate_bps = 0; - for (auto& rtp_rtcp : rtp_modules_) { - uint32_t not_used = 0; - uint32_t module_video_rate = 0; - uint32_t module_fec_rate = 0; - uint32_t module_nack_rate = 0; - rtp_rtcp->SetFecParameters(*delta_params, *key_params); - rtp_rtcp->BitrateSent(¬_used, &module_video_rate, &module_fec_rate, - &module_nack_rate); - *sent_video_rate_bps += module_video_rate; - *sent_nack_rate_bps += module_nack_rate; - *sent_fec_rate_bps += module_fec_rate; - } -} - -void RtpVideoSender::SetMaxRtpPacketSize(size_t max_rtp_packet_size) { - for (auto& rtp_rtcp : rtp_modules_) { - rtp_rtcp->SetMaxRtpPacketSize(max_rtp_packet_size); - } -} - void RtpVideoSender::ConfigureSsrcs(const RtpConfig& rtp_config) { // Configure regular SSRCs. for (size_t i = 0; i < rtp_config.ssrcs.size(); ++i) { @@ -551,4 +565,126 @@ std::map<uint32_t, RtpPayloadState> RtpVideoSender::GetRtpPayloadStates() } return payload_states; } + +void RtpVideoSender::OnTransportOverheadChanged( + size_t transport_overhead_bytes_per_packet) { + rtc::CritScope lock(&crit_); + transport_overhead_bytes_per_packet_ = transport_overhead_bytes_per_packet; + + size_t max_rtp_packet_size = + std::min(rtp_config_.max_packet_size, + kPathMTU - transport_overhead_bytes_per_packet_); + for (auto& rtp_rtcp : rtp_modules_) { + rtp_rtcp->SetMaxRtpPacketSize(max_rtp_packet_size); + } +} + +void RtpVideoSender::OnOverheadChanged(size_t overhead_bytes_per_packet) { + rtc::CritScope lock(&crit_); + overhead_bytes_per_packet_ = overhead_bytes_per_packet; +} + +void RtpVideoSender::OnBitrateUpdated(uint32_t bitrate_bps, + uint8_t fraction_loss, + int64_t rtt, + int framerate) { + // Substract overhead from bitrate. + rtc::CritScope lock(&crit_); + uint32_t payload_bitrate_bps = bitrate_bps; + if (send_side_bwe_with_overhead_) { + payload_bitrate_bps -= CalculateOverheadRateBps( + CalculatePacketRate( + bitrate_bps, + rtp_config_.max_packet_size + transport_overhead_bytes_per_packet_), + overhead_bytes_per_packet_ + transport_overhead_bytes_per_packet_, + bitrate_bps); + } + + // Get the encoder target rate. It is the estimated network rate - + // protection overhead. + encoder_target_rate_bps_ = fec_controller_->UpdateFecRates( + payload_bitrate_bps, framerate, fraction_loss, loss_mask_vector_, rtt); + loss_mask_vector_.clear(); + + uint32_t encoder_overhead_rate_bps = + send_side_bwe_with_overhead_ + ? CalculateOverheadRateBps( + CalculatePacketRate(encoder_target_rate_bps_, + rtp_config_.max_packet_size + + transport_overhead_bytes_per_packet_ - + overhead_bytes_per_packet_), + overhead_bytes_per_packet_ + + transport_overhead_bytes_per_packet_, + bitrate_bps - encoder_target_rate_bps_) + : 0; + + // When the field trial "WebRTC-SendSideBwe-WithOverhead" is enabled + // protection_bitrate includes overhead. + protection_bitrate_bps_ = + bitrate_bps - (encoder_target_rate_bps_ + encoder_overhead_rate_bps); +} + +uint32_t RtpVideoSender::GetPayloadBitrateBps() const { + return encoder_target_rate_bps_; +} + +uint32_t RtpVideoSender::GetProtectionBitrateBps() const { + return protection_bitrate_bps_; +} + +int RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params, + const FecProtectionParams* key_params, + uint32_t* sent_video_rate_bps, + uint32_t* sent_nack_rate_bps, + uint32_t* sent_fec_rate_bps) { + *sent_video_rate_bps = 0; + *sent_nack_rate_bps = 0; + *sent_fec_rate_bps = 0; + for (auto& rtp_rtcp : rtp_modules_) { + uint32_t not_used = 0; + uint32_t module_video_rate = 0; + uint32_t module_fec_rate = 0; + uint32_t module_nack_rate = 0; + rtp_rtcp->SetFecParameters(*delta_params, *key_params); + rtp_rtcp->BitrateSent(¬_used, &module_video_rate, &module_fec_rate, + &module_nack_rate); + *sent_video_rate_bps += module_video_rate; + *sent_nack_rate_bps += module_nack_rate; + *sent_fec_rate_bps += module_fec_rate; + } + return 0; +} + +void RtpVideoSender::OnPacketAdded(uint32_t ssrc, uint16_t seq_num) { + const auto ssrcs = rtp_config_.ssrcs; + if (std::find(ssrcs.begin(), ssrcs.end(), ssrc) != ssrcs.end()) { + feedback_packet_seq_num_set_.insert(seq_num); + if (feedback_packet_seq_num_set_.size() > kSendSideSeqNumSetMaxSize) { + RTC_LOG(LS_WARNING) << "Feedback packet sequence number set exceed it's " + "max size', will get reset."; + feedback_packet_seq_num_set_.clear(); + } + } +} + +void RtpVideoSender::OnPacketFeedbackVector( + const std::vector<PacketFeedback>& packet_feedback_vector) { + rtc::CritScope lock(&crit_); + // Lost feedbacks are not considered to be lost packets. + for (const PacketFeedback& packet : packet_feedback_vector) { + auto it = feedback_packet_seq_num_set_.find(packet.sequence_number); + if (it != feedback_packet_seq_num_set_.end()) { + const bool lost = packet.arrival_time_ms == PacketFeedback::kNotReceived; + loss_mask_vector_.push_back(lost); + feedback_packet_seq_num_set_.erase(it); + } + } +} + +void RtpVideoSender::SetEncodingData(size_t width, + size_t height, + size_t num_temporal_layers) { + fec_controller_->SetEncodingData(width, height, num_temporal_layers, + rtp_config_.max_packet_size); +} } // namespace webrtc diff --git a/call/rtp_video_sender.h b/call/rtp_video_sender.h index 1735dc751a..db329be00b 100644 --- a/call/rtp_video_sender.h +++ b/call/rtp_video_sender.h @@ -13,9 +13,11 @@ #include <map> #include <memory> +#include <unordered_set> #include <vector> #include "api/call/transport.h" +#include "api/fec_controller.h" #include "api/video_codecs/video_encoder.h" #include "call/rtp_config.h" #include "call/rtp_payload_params.h" @@ -40,7 +42,10 @@ class RtpTransportControllerSendInterface; // RtpVideoSender routes outgoing data to the correct sending RTP module, based // on the simulcast layer in RTPVideoHeader. -class RtpVideoSender : public RtpVideoSenderInterface { +class RtpVideoSender : public RtpVideoSenderInterface, + public OverheadObserver, + public VCMProtectionCallback, + public PacketFeedbackObserver { public: // Rtp modules are assumed to be sorted in simulcast index order. RtpVideoSender( @@ -53,7 +58,8 @@ class RtpVideoSender : public RtpVideoSenderInterface { const RtpSenderObservers& observers, RtpTransportControllerSendInterface* transport, RtcEventLog* event_log, - RateLimiter* retransmission_limiter); // move inside RtpTransport + RateLimiter* retransmission_limiter, // move inside RtpTransport + std::unique_ptr<FecController> fec_controller); ~RtpVideoSender() override; // RegisterProcessThread register |module_process_thread| with those objects @@ -76,19 +82,14 @@ class RtpVideoSender : public RtpVideoSenderInterface { std::map<uint32_t, RtpState> GetRtpStates() const override; std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const override; - bool FecEnabled() const override; - - bool NackEnabled() const override; - void DeliverRtcp(const uint8_t* packet, size_t length) override; - void ProtectionRequest(const FecProtectionParams* delta_params, - const FecProtectionParams* key_params, - uint32_t* sent_video_rate_bps, - uint32_t* sent_nack_rate_bps, - uint32_t* sent_fec_rate_bps) override; - - void SetMaxRtpPacketSize(size_t max_rtp_packet_size) override; + // Implements webrtc::VCMProtectionCallback. + int ProtectionRequest(const FecProtectionParams* delta_params, + const FecProtectionParams* key_params, + uint32_t* sent_video_rate_bps, + uint32_t* sent_nack_rate_bps, + uint32_t* sent_fec_rate_bps) override; // Implements EncodedImageCallback. // Returns 0 if the packet was routed / sent, -1 otherwise. @@ -100,11 +101,36 @@ class RtpVideoSender : public RtpVideoSenderInterface { void OnBitrateAllocationUpdated( const VideoBitrateAllocation& bitrate) override; + void OnTransportOverheadChanged( + size_t transport_overhead_bytes_per_packet) override; + // Implements OverheadObserver. + void OnOverheadChanged(size_t overhead_bytes_per_packet) override; + void OnBitrateUpdated(uint32_t bitrate_bps, + uint8_t fraction_loss, + int64_t rtt, + int framerate) override; + uint32_t GetPayloadBitrateBps() const override; + uint32_t GetProtectionBitrateBps() const override; + void SetEncodingData(size_t width, + size_t height, + size_t num_temporal_layers) override; + + // From PacketFeedbackObserver. + void OnPacketAdded(uint32_t ssrc, uint16_t seq_num) override; + void OnPacketFeedbackVector( + const std::vector<PacketFeedback>& packet_feedback_vector) override; + private: void UpdateModuleSendingState() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_); void ConfigureProtection(const RtpConfig& rtp_config); void ConfigureSsrcs(const RtpConfig& rtp_config); + bool FecEnabled() const; + bool NackEnabled() const; + const bool send_side_bwe_with_overhead_; + + // TODO(holmer): Remove crit_ once RtpVideoSender runs on the + // transport task queue. rtc::CriticalSection crit_; bool active_ RTC_GUARDED_BY(crit_); @@ -113,6 +139,7 @@ class RtpVideoSender : public RtpVideoSenderInterface { std::map<uint32_t, RtpState> suspended_ssrcs_; std::unique_ptr<FlexfecSender> flexfec_sender_; + std::unique_ptr<FecController> fec_controller_; // Rtp modules are assumed to be sorted in simulcast index order. const std::vector<std::unique_ptr<RtpRtcp>> rtp_modules_; const RtpConfig rtp_config_; @@ -125,6 +152,14 @@ class RtpVideoSender : public RtpVideoSenderInterface { int64_t shared_frame_id_ = 0; std::vector<RtpPayloadParams> params_ RTC_GUARDED_BY(crit_); + size_t transport_overhead_bytes_per_packet_ RTC_GUARDED_BY(crit_); + size_t overhead_bytes_per_packet_ RTC_GUARDED_BY(crit_); + uint32_t protection_bitrate_bps_; + uint32_t encoder_target_rate_bps_; + + std::unordered_set<uint16_t> feedback_packet_seq_num_set_; + std::vector<bool> loss_mask_vector_ RTC_GUARDED_BY(crit_); + RTC_DISALLOW_COPY_AND_ASSIGN(RtpVideoSender); }; diff --git a/call/rtp_video_sender_interface.h b/call/rtp_video_sender_interface.h index c69f1bab02..ecaca9b256 100644 --- a/call/rtp_video_sender_interface.h +++ b/call/rtp_video_sender_interface.h @@ -40,21 +40,21 @@ class RtpVideoSenderInterface : public EncodedImageCallback { virtual std::map<uint32_t, RtpState> GetRtpStates() const = 0; virtual std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const = 0; - virtual bool FecEnabled() const = 0; - - virtual bool NackEnabled() const = 0; - virtual void DeliverRtcp(const uint8_t* packet, size_t length) = 0; - virtual void ProtectionRequest(const FecProtectionParams* delta_params, - const FecProtectionParams* key_params, - uint32_t* sent_video_rate_bps, - uint32_t* sent_nack_rate_bps, - uint32_t* sent_fec_rate_bps) = 0; - - virtual void SetMaxRtpPacketSize(size_t max_rtp_packet_size) = 0; virtual void OnBitrateAllocationUpdated( const VideoBitrateAllocation& bitrate) = 0; + virtual void OnBitrateUpdated(uint32_t bitrate_bps, + uint8_t fraction_loss, + int64_t rtt, + int framerate) = 0; + virtual void OnTransportOverheadChanged( + size_t transport_overhead_bytes_per_packet) = 0; + virtual uint32_t GetPayloadBitrateBps() const = 0; + virtual uint32_t GetProtectionBitrateBps() const = 0; + virtual void SetEncodingData(size_t width, + size_t height, + size_t num_temporal_layers) = 0; }; } // namespace webrtc #endif // CALL_RTP_VIDEO_SENDER_INTERFACE_H_ diff --git a/call/rtp_video_sender_unittest.cc b/call/rtp_video_sender_unittest.cc index 29fc2b6020..e91bfc4aeb 100644 --- a/call/rtp_video_sender_unittest.cc +++ b/call/rtp_video_sender_unittest.cc @@ -13,6 +13,7 @@ #include "call/rtp_transport_controller_send.h" #include "call/rtp_video_sender.h" +#include "modules/video_coding/fec_controller_default.h" #include "modules/video_coding/include/video_codec_interface.h" #include "rtc_base/rate_limiter.h" #include "test/field_trial.h" @@ -46,11 +47,6 @@ class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver { MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t)); }; -class MockOverheadObserver : public OverheadObserver { - public: - MOCK_METHOD1(OnOverheadChanged, void(size_t overhead_bytes_per_packet)); -}; - class MockCongestionObserver : public NetworkChangedObserver { public: MOCK_METHOD4(OnNetworkChanged, @@ -69,8 +65,7 @@ RtpSenderObservers CreateObservers( FrameCountObserver* frame_count_observer, RtcpPacketTypeCounterObserver* rtcp_type_observer, SendSideDelayObserver* send_delay_observer, - SendPacketObserver* send_packet_observer, - OverheadObserver* overhead_observer) { + SendPacketObserver* send_packet_observer) { RtpSenderObservers observers; observers.rtcp_rtt_stats = rtcp_rtt_stats; observers.intra_frame_callback = intra_frame_callback; @@ -81,7 +76,6 @@ RtpSenderObservers CreateObservers( observers.rtcp_type_observer = rtcp_type_observer; observers.send_delay_observer = send_delay_observer; observers.send_packet_observer = send_packet_observer; - observers.overhead_observer = overhead_observer; return observers; } @@ -111,9 +105,9 @@ class RtpVideoSenderTestFixture { config_.rtp, config_.rtcp, &transport_, CreateObservers(&call_stats_, &encoder_feedback_, &stats_proxy_, &stats_proxy_, &stats_proxy_, &stats_proxy_, - &stats_proxy_, &stats_proxy_, &send_delay_stats_, - &overhead_observer_), - &transport_controller_, &event_log_, &retransmission_rate_limiter_); + &stats_proxy_, &stats_proxy_, &send_delay_stats_), + &transport_controller_, &event_log_, &retransmission_rate_limiter_, + absl::make_unique<FecControllerDefault>(&clock_)); } RtpVideoSender* router() { return router_.get(); } @@ -121,7 +115,6 @@ class RtpVideoSenderTestFixture { private: NiceMock<MockTransport> transport_; NiceMock<MockCongestionObserver> congestion_observer_; - NiceMock<MockOverheadObserver> overhead_observer_; NiceMock<MockRtcpIntraFrameObserver> encoder_feedback_; SimulatedClock clock_; RtcEventLogNullImpl event_log_; diff --git a/call/test/mock_rtp_transport_controller_send.h b/call/test/mock_rtp_transport_controller_send.h index 828b030378..37587b2b76 100644 --- a/call/test/mock_rtp_transport_controller_send.h +++ b/call/test/mock_rtp_transport_controller_send.h @@ -12,6 +12,7 @@ #define CALL_TEST_MOCK_RTP_TRANSPORT_CONTROLLER_SEND_H_ #include <map> +#include <memory> #include <string> #include <vector> @@ -29,7 +30,7 @@ namespace webrtc { class MockRtpTransportControllerSend : public RtpTransportControllerSendInterface { public: - MOCK_METHOD8( + MOCK_METHOD9( CreateRtpVideoSender, RtpVideoSenderInterface*(const std::vector<uint32_t>&, std::map<uint32_t, RtpState>, @@ -38,7 +39,8 @@ class MockRtpTransportControllerSend const RtcpConfig&, Transport*, const RtpSenderObservers&, - RtcEventLog*)); + RtcEventLog*, + std::unique_ptr<FecController>)); MOCK_METHOD1(DestroyRtpVideoSender, void(RtpVideoSenderInterface*)); MOCK_METHOD0(GetWorkerQueue, rtc::TaskQueue*()); MOCK_METHOD0(packet_router, PacketRouter*()); @@ -65,6 +67,7 @@ class MockRtpTransportControllerSend MOCK_METHOD1(SetSdpBitrateParameters, void(const BitrateConstraints&)); MOCK_METHOD1(SetClientBitratePreferences, void(const BitrateSettings&)); MOCK_METHOD1(SetAllocatedBitrateWithoutFeedback, void(uint32_t)); + MOCK_METHOD1(OnTransportOverheadChanged, void(size_t)); }; } // namespace webrtc #endif // CALL_TEST_MOCK_RTP_TRANSPORT_CONTROLLER_SEND_H_ |