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}
This commit is contained in:
Stefan Holmer 2018-10-04 15:21:55 +02:00 committed by Commit Bot
parent 8e87852cbe
commit 64be7fa7d8
25 changed files with 375 additions and 391 deletions

View File

@ -138,7 +138,7 @@ class NoBandwidthDropAfterDtx : public AudioBweTest {
void PerformTest() override {
stats_poller_.PostDelayedTask(
std::unique_ptr<rtc::QueuedTask>(new StatsPollTask(sender_call_)), 100);
sender_call_->OnTransportOverheadChanged(webrtc::MediaType::AUDIO, 0);
sender_call_->OnAudioTransportOverheadChanged(0);
AudioBweTest::PerformTest();
}

View File

@ -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",

View File

@ -221,7 +221,7 @@ class Call final : public webrtc::Call,
void SignalChannelNetworkState(MediaType media, NetworkState state) override;
void OnTransportOverheadChanged(MediaType media,
void OnAudioTransportOverheadChanged(
int transport_overhead_per_packet) override;
void OnSentPacket(const rtc::SentPacket& sent_packet) override;
@ -997,28 +997,11 @@ void Call::SignalChannelNetworkState(MediaType media, NetworkState state) {
}
}
void Call::OnTransportOverheadChanged(MediaType media,
int transport_overhead_per_packet) {
switch (media) {
case MediaType::AUDIO: {
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);
}
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::UpdateAggregateNetworkState() {

View File

@ -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;

View File

@ -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) {

View File

@ -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,
void OnAudioTransportOverheadChanged(
int transport_overhead_per_packet) override;
void OnSentPacket(const rtc::SentPacket& sent_packet) override;
protected:

View File

@ -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

View File

@ -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_;

View File

@ -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

View File

@ -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(&not_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(&not_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

View File

@ -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,20 +82,15 @@ 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,
// 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;
void SetMaxRtpPacketSize(size_t max_rtp_packet_size) override;
// Implements EncodedImageCallback.
// Returns 0 if the packet was routed / sent, -1 otherwise.
EncodedImageCallback::Result OnEncodedImage(
@ -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);
};

View File

@ -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_

View File

@ -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_;

View File

@ -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_

View File

@ -390,9 +390,7 @@ FakeCall::FakeCall()
: audio_network_state_(webrtc::kNetworkUp),
video_network_state_(webrtc::kNetworkUp),
num_created_send_streams_(0),
num_created_receive_streams_(0),
audio_transport_overhead_(0),
video_transport_overhead_(0) {}
num_created_receive_streams_(0) {}
FakeCall::~FakeCall() {
EXPECT_EQ(0u, video_send_streams_.size());
@ -635,21 +633,8 @@ void FakeCall::SignalChannelNetworkState(webrtc::MediaType media,
}
}
void FakeCall::OnTransportOverheadChanged(webrtc::MediaType media,
int transport_overhead_per_packet) {
switch (media) {
case webrtc::MediaType::AUDIO:
audio_transport_overhead_ = transport_overhead_per_packet;
break;
case webrtc::MediaType::VIDEO:
video_transport_overhead_ = transport_overhead_per_packet;
break;
case webrtc::MediaType::DATA:
case webrtc::MediaType::ANY:
ADD_FAILURE()
<< "SignalChannelNetworkState called with unknown parameter.";
}
}
void FakeCall::OnAudioTransportOverheadChanged(
int transport_overhead_per_packet) {}
void FakeCall::OnSentPacket(const rtc::SentPacket& sent_packet) {
last_sent_packet_ = sent_packet;

View File

@ -317,7 +317,7 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver {
void SignalChannelNetworkState(webrtc::MediaType media,
webrtc::NetworkState state) override;
void OnTransportOverheadChanged(webrtc::MediaType media,
void OnAudioTransportOverheadChanged(
int transport_overhead_per_packet) override;
void OnSentPacket(const rtc::SentPacket& sent_packet) override;
@ -338,9 +338,6 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver {
int num_created_send_streams_;
int num_created_receive_streams_;
int audio_transport_overhead_;
int video_transport_overhead_;
};
} // namespace cricket

View File

@ -1408,7 +1408,7 @@ void WebRtcVideoChannel::OnNetworkRouteChanged(
const rtc::NetworkRoute& network_route) {
call_->GetTransportControllerSend()->OnNetworkRouteChanged(transport_name,
network_route);
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
call_->GetTransportControllerSend()->OnTransportOverheadChanged(
network_route.packet_overhead);
}

View File

@ -2059,8 +2059,7 @@ void WebRtcVoiceMediaChannel::OnNetworkRouteChanged(
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
call_->GetTransportControllerSend()->OnNetworkRouteChanged(transport_name,
network_route);
call_->OnTransportOverheadChanged(webrtc::MediaType::AUDIO,
network_route.packet_overhead);
call_->OnAudioTransportOverheadChanged(network_route.packet_overhead);
}
bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) {

View File

@ -75,8 +75,8 @@ SendAudioStream::SendAudioStream(
}
send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
if (field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
sender->call_->OnTransportOverheadChanged(
MediaType::AUDIO, config.stream.packet_overhead.bytes());
sender->call_->OnAudioTransportOverheadChanged(
config.stream.packet_overhead.bytes());
}
}

View File

@ -197,15 +197,6 @@ void VideoSendStream::StopPermanentlyAndGetRtpStates(
thread_sync_event_.Wait(rtc::Event::kForever);
}
void VideoSendStream::SetTransportOverhead(
size_t transport_overhead_per_packet) {
RTC_DCHECK_RUN_ON(&thread_checker_);
VideoSendStreamImpl* send_stream = send_stream_.get();
worker_queue_->PostTask([send_stream, transport_overhead_per_packet] {
send_stream->SetTransportOverhead(transport_overhead_per_packet);
});
}
bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
// Called on a network thread.
return send_stream_->DeliverRtcp(packet, length);

View File

@ -88,8 +88,6 @@ class VideoSendStream : public webrtc::VideoSendStream {
void StopPermanentlyAndGetRtpStates(RtpStateMap* rtp_state_map,
RtpPayloadStateMap* payload_state_map);
void SetTransportOverhead(size_t transport_overhead_per_packet);
private:
friend class test::VideoSendStreamPeer;

View File

@ -28,19 +28,12 @@
namespace webrtc {
namespace internal {
namespace {
// 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;
// Max positive size difference to treat allocations as "similar".
static constexpr int kMaxVbaSizeDifferencePercent = 10;
// Max time we will throttle similar video bitrate allocations.
static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
// We don't do MTU discovery, so assume that we have the standard ethernet MTU.
const size_t kPathMTU = 1500;
bool TransportSeqNumExtensionConfigured(const VideoSendStream::Config& config) {
const std::vector<RtpExtension>& extensions = config.rtp.extensions;
return std::find_if(
@ -118,26 +111,10 @@ int CalculateMaxPadBitrateBps(const std::vector<VideoStream>& streams,
return pad_up_to_bitrate_bps;
}
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);
}
RtpSenderObservers CreateObservers(CallStats* call_stats,
EncoderRtcpFeedback* encoder_feedback,
SendStatisticsProxy* stats_proxy,
SendDelayStats* send_delay_stats,
OverheadObserver* overhead_observer) {
SendDelayStats* send_delay_stats) {
RtpSenderObservers observers;
observers.rtcp_rtt_stats = call_stats;
observers.intra_frame_callback = encoder_feedback;
@ -148,7 +125,6 @@ RtpSenderObservers CreateObservers(CallStats* call_stats,
observers.rtcp_type_observer = stats_proxy;
observers.send_delay_observer = stats_proxy;
observers.send_packet_observer = send_delay_stats;
observers.overhead_observer = overhead_observer;
return observers;
}
@ -243,13 +219,10 @@ VideoSendStreamImpl::VideoSendStreamImpl(
std::map<uint32_t, RtpPayloadState> suspended_payload_states,
VideoEncoderConfig::ContentType content_type,
std::unique_ptr<FecController> fec_controller)
: send_side_bwe_with_overhead_(
webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
has_alr_probing_(config->periodic_alr_bandwidth_probing ||
: has_alr_probing_(config->periodic_alr_bandwidth_probing ||
GetAlrSettings(content_type)),
stats_proxy_(stats_proxy),
config_(config),
fec_controller_(std::move(fec_controller)),
worker_queue_(worker_queue),
check_encoder_activity_task_(nullptr),
call_stats_(call_stats),
@ -275,12 +248,10 @@ VideoSendStreamImpl::VideoSendStreamImpl(
CreateObservers(call_stats,
&encoder_feedback_,
stats_proxy_,
send_delay_stats,
this),
event_log)),
weak_ptr_factory_(this),
overhead_bytes_per_packet_(0),
transport_overhead_bytes_per_packet_(0) {
send_delay_stats),
event_log,
std::move(fec_controller))),
weak_ptr_factory_(this) {
RTC_DCHECK_RUN_ON(worker_queue_);
RTC_LOG(LS_INFO) << "VideoSendStreamInternal: " << config_->ToString();
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
@ -332,17 +303,6 @@ VideoSendStreamImpl::VideoSendStreamImpl(
transport->EnablePeriodicAlrProbing(true);
}
// 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(rtp_video_sender_->FecEnabled(),
rtp_video_sender_->NackEnabled());
fec_controller_->SetProtectionCallback(this);
// Signal congestion controller this object is ready for OnPacket* callbacks.
if (fec_controller_->UseLossVectorMask()) {
transport_->RegisterPacketFeedbackObserver(this);
}
RTC_DCHECK_GE(config_->rtp.payload_type, 0);
RTC_DCHECK_LE(config_->rtp.payload_type, 127);
@ -368,9 +328,6 @@ VideoSendStreamImpl::~VideoSendStreamImpl() {
RTC_DCHECK(!rtp_video_sender_->IsActive())
<< "VideoSendStreamImpl::Stop not called";
RTC_LOG(LS_INFO) << "~VideoSendStreamInternal: " << config_->ToString();
if (fec_controller_->UseLossVectorMask()) {
transport_->DeRegisterPacketFeedbackObserver(this);
}
transport_->DestroyRtpVideoSender(rtp_video_sender_);
}
@ -582,9 +539,9 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged(
const size_t num_temporal_layers =
streams.back().num_temporal_layers.value_or(1);
fec_controller_->SetEncodingData(streams[0].width, streams[0].height,
num_temporal_layers,
config_->rtp.max_packet_size);
rtp_video_sender_->SetEncodingData(streams[0].width, streams[0].height,
num_temporal_layers);
if (rtp_video_sender_->IsActive()) {
// The send stream is started already. Update the allocator with new bitrate
@ -623,8 +580,6 @@ EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage(
check_encoder_activity_task_->UpdateEncoderActivity();
}
fec_controller_->UpdateWithEncodedData(encoded_image._length,
encoded_image._frameType);
EncodedImageCallback::Result result = rtp_video_sender_->OnEncodedImage(
encoded_image, codec_specific_info, fragmentation);
@ -666,125 +621,16 @@ uint32_t VideoSendStreamImpl::OnBitrateUpdated(uint32_t bitrate_bps,
RTC_DCHECK(rtp_video_sender_->IsActive())
<< "VideoSendStream::Start has not been called.";
// Substract overhead from bitrate.
rtc::CritScope lock(&overhead_bytes_per_packet_crit_);
uint32_t payload_bitrate_bps = bitrate_bps;
if (send_side_bwe_with_overhead_) {
payload_bitrate_bps -= CalculateOverheadRateBps(
CalculatePacketRate(bitrate_bps,
config_->rtp.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, stats_proxy_->GetSendFrameRate(), 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_,
config_->rtp.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.
uint32_t protection_bitrate =
bitrate_bps - (encoder_target_rate_bps_ + encoder_overhead_rate_bps);
rtp_video_sender_->OnBitrateUpdated(bitrate_bps, fraction_loss, rtt,
stats_proxy_->GetSendFrameRate());
encoder_target_rate_bps_ = rtp_video_sender_->GetPayloadBitrateBps();
encoder_target_rate_bps_ =
std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps_);
video_stream_encoder_->OnBitrateUpdated(encoder_target_rate_bps_,
fraction_loss, rtt);
stats_proxy_->OnSetEncoderTargetRate(encoder_target_rate_bps_);
return protection_bitrate;
return rtp_video_sender_->GetProtectionBitrateBps();
}
int VideoSendStreamImpl::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) {
RTC_DCHECK_RUN_ON(worker_queue_);
rtp_video_sender_->ProtectionRequest(delta_params, key_params,
sent_video_rate_bps, sent_nack_rate_bps,
sent_fec_rate_bps);
return 0;
}
void VideoSendStreamImpl::OnOverheadChanged(size_t overhead_bytes_per_packet) {
rtc::CritScope lock(&overhead_bytes_per_packet_crit_);
overhead_bytes_per_packet_ = overhead_bytes_per_packet;
}
void VideoSendStreamImpl::SetTransportOverhead(
size_t transport_overhead_bytes_per_packet) {
if (transport_overhead_bytes_per_packet >= static_cast<int>(kPathMTU)) {
RTC_LOG(LS_ERROR) << "Transport overhead exceeds size of ethernet frame";
return;
}
transport_overhead_bytes_per_packet_ = transport_overhead_bytes_per_packet;
size_t rtp_packet_size =
std::min(config_->rtp.max_packet_size,
kPathMTU - transport_overhead_bytes_per_packet_);
rtp_video_sender_->SetMaxRtpPacketSize(rtp_packet_size);
}
void VideoSendStreamImpl::OnPacketAdded(uint32_t ssrc, uint16_t seq_num) {
if (!worker_queue_->IsCurrent()) {
auto ptr = weak_ptr_;
worker_queue_->PostTask([=] {
if (!ptr.get())
return;
ptr->OnPacketAdded(ssrc, seq_num);
});
return;
}
const auto ssrcs = config_->rtp.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 VideoSendStreamImpl::OnPacketFeedbackVector(
const std::vector<PacketFeedback>& packet_feedback_vector) {
if (!worker_queue_->IsCurrent()) {
auto ptr = weak_ptr_;
worker_queue_->PostTask([=] {
if (!ptr.get())
return;
ptr->OnPacketFeedbackVector(packet_feedback_vector);
});
return;
}
// 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);
}
}
}
} // namespace internal
} // namespace webrtc

View File

@ -12,7 +12,6 @@
#include <map>
#include <memory>
#include <unordered_set>
#include <vector>
#include "api/video/video_bitrate_allocator.h"
@ -39,11 +38,8 @@ namespace internal {
// An encoder may deliver frames through the EncodedImageCallback on an
// arbitrary thread.
class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
public webrtc::OverheadObserver,
public webrtc::VCMProtectionCallback,
public VideoStreamEncoderInterface::EncoderSink,
public VideoBitrateAllocationObserver,
public webrtc::PacketFeedbackObserver {
public VideoBitrateAllocationObserver {
public:
VideoSendStreamImpl(
SendStatisticsProxy* stats_proxy,
@ -81,15 +77,8 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
std::map<uint32_t, RtpPayloadState> GetRtpPayloadStates() const;
void SetTransportOverhead(size_t transport_overhead_per_packet);
absl::optional<float> configured_pacing_factor_;
// From PacketFeedbackObserver.
void OnPacketAdded(uint32_t ssrc, uint16_t seq_num) override;
void OnPacketFeedbackVector(
const std::vector<PacketFeedback>& packet_feedback_vector) override;
private:
class CheckEncoderActivityTask;
@ -99,16 +88,6 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
int64_t rtt,
int64_t probing_interval_ms) 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 OverheadObserver.
void OnOverheadChanged(size_t overhead_bytes_per_packet) override;
void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
int min_transmit_bitrate_bps) override;
@ -135,13 +114,11 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
void SignalEncoderTimedOut();
void SignalEncoderActive();
const bool send_side_bwe_with_overhead_;
const bool has_alr_probing_;
SendStatisticsProxy* const stats_proxy_;
const VideoSendStream::Config* const config_;
std::unique_ptr<FecController> fec_controller_;
rtc::TaskQueue* const worker_queue_;
rtc::CriticalSection encoder_activity_crit_sect_;
@ -175,14 +152,6 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
// invalidated before any other members are destroyed.
rtc::WeakPtrFactory<VideoSendStreamImpl> weak_ptr_factory_;
rtc::CriticalSection overhead_bytes_per_packet_crit_;
size_t overhead_bytes_per_packet_
RTC_GUARDED_BY(overhead_bytes_per_packet_crit_);
size_t transport_overhead_bytes_per_packet_;
std::unordered_set<uint16_t> feedback_packet_seq_num_set_;
std::vector<bool> loss_mask_vector_;
// Context for the most recent and last sent video bitrate allocation. Used to
// throttle sending of similar bitrate allocations.
struct VbaSendContext {

View File

@ -45,7 +45,7 @@ std::string GetAlrProbingExperimentString() {
AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
"/1.0,2875,80,40,-60,3/";
}
class MockPayloadRouter : public RtpVideoSenderInterface {
class MockRtpVideoSender : public RtpVideoSenderInterface {
public:
MOCK_METHOD1(RegisterProcessThread, void(ProcessThread*));
MOCK_METHOD0(DeRegisterProcessThread, void());
@ -56,21 +56,18 @@ class MockPayloadRouter : public RtpVideoSenderInterface {
MOCK_CONST_METHOD0(GetRtpStates, std::map<uint32_t, RtpState>());
MOCK_CONST_METHOD0(GetRtpPayloadStates,
std::map<uint32_t, RtpPayloadState>());
MOCK_CONST_METHOD0(FecEnabled, bool());
MOCK_CONST_METHOD0(NackEnabled, bool());
MOCK_METHOD2(DeliverRtcp, void(const uint8_t*, size_t));
MOCK_METHOD5(ProtectionRequest,
void(const FecProtectionParams*,
const FecProtectionParams*,
uint32_t*,
uint32_t*,
uint32_t*));
MOCK_METHOD1(SetMaxRtpPacketSize, void(size_t));
MOCK_METHOD1(OnBitrateAllocationUpdated, void(const VideoBitrateAllocation&));
MOCK_METHOD3(OnEncodedImage,
EncodedImageCallback::Result(const EncodedImage&,
const CodecSpecificInfo*,
const RTPFragmentationHeader*));
MOCK_METHOD1(OnTransportOverheadChanged, void(size_t));
MOCK_METHOD1(OnOverheadChanged, void(size_t));
MOCK_METHOD4(OnBitrateUpdated, void(uint32_t, uint8_t, int64_t, int));
MOCK_CONST_METHOD0(GetPayloadBitrateBps, uint32_t());
MOCK_CONST_METHOD0(GetProtectionBitrateBps, uint32_t());
MOCK_METHOD3(SetEncodingData, void(size_t, size_t, size_t));
};
} // namespace
@ -94,14 +91,14 @@ class VideoSendStreamImplTest : public ::testing::Test {
EXPECT_CALL(transport_controller_, packet_router())
.WillRepeatedly(Return(&packet_router_));
EXPECT_CALL(transport_controller_,
CreateRtpVideoSender(_, _, _, _, _, _, _, _))
.WillRepeatedly(Return(&payload_router_));
EXPECT_CALL(payload_router_, SetActive(_))
CreateRtpVideoSender(_, _, _, _, _, _, _, _, _))
.WillRepeatedly(Return(&rtp_video_sender_));
EXPECT_CALL(rtp_video_sender_, SetActive(_))
.WillRepeatedly(testing::Invoke(
[&](bool active) { payload_router_active_ = active; }));
EXPECT_CALL(payload_router_, IsActive())
[&](bool active) { rtp_video_sender_active_ = active; }));
EXPECT_CALL(rtp_video_sender_, IsActive())
.WillRepeatedly(
testing::Invoke([&]() { return payload_router_active_; }));
testing::Invoke([&]() { return rtp_video_sender_active_; }));
}
~VideoSendStreamImplTest() {}
@ -127,9 +124,9 @@ class VideoSendStreamImplTest : public ::testing::Test {
NiceMock<MockRtpTransportControllerSend> transport_controller_;
NiceMock<MockBitrateAllocator> bitrate_allocator_;
NiceMock<MockVideoStreamEncoder> video_stream_encoder_;
NiceMock<MockPayloadRouter> payload_router_;
NiceMock<MockRtpVideoSender> rtp_video_sender_;
bool payload_router_active_ = false;
bool rtp_video_sender_active_ = false;
SimulatedClock clock_;
RtcEventLogNullImpl event_log_;
VideoSendStream::Config config_;
@ -361,19 +358,26 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
alloc.SetBitrate(1, 1, 40000);
// Encoder starts out paused, don't forward allocation.
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
observer->OnBitrateAllocationUpdated(alloc);
// Unpause encoder, allocation should be passed through.
const uint32_t kBitrateBps = 100000;
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
.Times(1)
.WillOnce(Return(kBitrateBps));
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(100000, 0, 0, 0);
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
->OnBitrateUpdated(kBitrateBps, 0, 0, 0);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
observer->OnBitrateAllocationUpdated(alloc);
// Pause encoder again, and block allocations.
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
.Times(1)
.WillOnce(Return(0));
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(0, 0, 0, 0);
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0);
observer->OnBitrateAllocationUpdated(alloc);
vss_impl->Stop();
@ -387,8 +391,12 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
VideoEncoderConfig::ContentType::kScreen);
vss_impl->Start();
// Unpause encoder, to allows allocations to be passed through.
const uint32_t kBitrateBps = 100000;
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
.Times(1)
.WillOnce(Return(kBitrateBps));
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(100000, 0, 0, 0);
->OnBitrateUpdated(kBitrateBps, 0, 0, 0);
VideoBitrateAllocationObserver* const observer =
static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
@ -400,7 +408,7 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
alloc.SetBitrate(1, 1, 40000);
// Initial value.
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
observer->OnBitrateAllocationUpdated(alloc);
VideoBitrateAllocation updated_alloc = alloc;
@ -410,19 +418,19 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
// Too small increase, don't forward.
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(_)).Times(0);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0);
observer->OnBitrateAllocationUpdated(updated_alloc);
// Large enough increase, do forward.
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(updated_alloc))
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
.Times(1);
observer->OnBitrateAllocationUpdated(updated_alloc);
// This is now a decrease compared to last forward allocation, forward
// immediately.
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(updated_alloc))
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
.Times(1);
observer->OnBitrateAllocationUpdated(updated_alloc);
@ -437,8 +445,12 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
VideoEncoderConfig::ContentType::kScreen);
vss_impl->Start();
// Unpause encoder, to allows allocations to be passed through.
const uint32_t kBitrateBps = 100000;
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
.Times(1)
.WillOnce(Return(kBitrateBps));
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(100000, 0, 0, 0);
->OnBitrateUpdated(kBitrateBps, 0, 0, 0);
VideoBitrateAllocationObserver* const observer =
static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
@ -450,7 +462,7 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
alloc.SetBitrate(1, 1, 40000);
// Initial value.
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1);
observer->OnBitrateAllocationUpdated(alloc);
// Move some bitrate from one layer to a new one, but keep sum the same.
@ -459,7 +471,7 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
updated_alloc.SetBitrate(2, 0, 10000);
updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(updated_alloc))
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc))
.Times(1);
observer->OnBitrateAllocationUpdated(updated_alloc);
@ -476,9 +488,13 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kScreen);
vss_impl->Start();
const uint32_t kBitrateBps = 100000;
// Unpause encoder, to allows allocations to be passed through.
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
.Times(1)
.WillRepeatedly(Return(kBitrateBps));
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(100000, 0, 0, 0);
->OnBitrateUpdated(kBitrateBps, 0, 0, 0);
VideoBitrateAllocationObserver* const observer =
static_cast<VideoBitrateAllocationObserver*>(vss_impl.get());
@ -491,7 +507,7 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
EncodedImage encoded_image;
CodecSpecificInfo codec_specific;
EXPECT_CALL(payload_router_, OnEncodedImage(_, _, _))
EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
.WillRepeatedly(Return(
EncodedImageCallback::Result(EncodedImageCallback::Result::OK)));
@ -500,13 +516,15 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
{
// Initial value.
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(1);
observer->OnBitrateAllocationUpdated(alloc);
}
{
// Sending same allocation again, this one should be throttled.
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(0);
observer->OnBitrateAllocationUpdated(alloc);
}
@ -514,19 +532,22 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
{
// Sending similar allocation again after timeout, should forward.
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(1);
observer->OnBitrateAllocationUpdated(alloc);
}
{
// Sending similar allocation again without timeout, throttle.
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(0);
observer->OnBitrateAllocationUpdated(alloc);
}
{
// Send encoded image, should be a noop.
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(0);
static_cast<EncodedImageCallback*>(vss_impl.get())
->OnEncodedImage(encoded_image, &codec_specific, nullptr);
}
@ -535,7 +556,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
// Advance time and send encoded image, this should wake up and send
// cached bitrate allocation.
fake_clock.AdvanceTimeMicros(kMaxVbaThrottleTimeMs * 1000);
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(1);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(1);
static_cast<EncodedImageCallback*>(vss_impl.get())
->OnEncodedImage(encoded_image, &codec_specific, nullptr);
}
@ -544,7 +566,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
// Advance time and send encoded image, there should be no cached
// allocation to send.
fake_clock.AdvanceTimeMicros(kMaxVbaThrottleTimeMs * 1000);
EXPECT_CALL(payload_router_, OnBitrateAllocationUpdated(alloc)).Times(0);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(0);
static_cast<EncodedImageCallback*>(vss_impl.get())
->OnEncodedImage(encoded_image, &codec_specific, nullptr);
}

View File

@ -1734,7 +1734,7 @@ TEST_P(VideoSendStreamTest, ChangingTransportOverhead) {
void PerformTest() override {
task_queue_->SendTask([this]() {
transport_overhead_ = 100;
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
call_->GetTransportControllerSend()->OnTransportOverheadChanged(
transport_overhead_);
});
@ -1747,7 +1747,7 @@ TEST_P(VideoSendStreamTest, ChangingTransportOverhead) {
task_queue_->SendTask([this]() {
transport_overhead_ = 500;
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
call_->GetTransportControllerSend()->OnTransportOverheadChanged(
transport_overhead_);
});
@ -3725,7 +3725,7 @@ TEST_P(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
task_queue_->SendTask([this, &bitrate_config]() {
call_->GetTransportControllerSend()->SetSdpBitrateParameters(
bitrate_config);
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
call_->GetTransportControllerSend()->OnTransportOverheadChanged(40);
});
// At a bitrate of 60kbps with a packet size of 1200B video and an