Fix for video protection_bitrate in BWE with overhead.
BUG=webrtc:6876, webrtc:6638, webrtc:6886 Review-Url: https://codereview.webrtc.org/2571463002 Cr-Commit-Position: refs/heads/master@{#16305}
This commit is contained in:
parent
04bd836ca1
commit
192132ef04
@ -289,6 +289,24 @@ int CalculateMaxPadBitrateBps(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) {
|
||||
if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe-WithOverhead") !=
|
||||
"Enabled")
|
||||
return 0;
|
||||
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
|
||||
|
||||
namespace internal {
|
||||
@ -1203,36 +1221,35 @@ uint32_t VideoSendStreamImpl::OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
RTC_DCHECK(payload_router_.IsActive())
|
||||
<< "VideoSendStream::Start has not been called.";
|
||||
|
||||
if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe-WithOverhead") ==
|
||||
"Enabled") {
|
||||
// Subtract total overhead (transport + rtp) from bitrate.
|
||||
size_t rtp_overhead;
|
||||
{
|
||||
rtc::CritScope lock(&overhead_bytes_per_packet_crit_);
|
||||
rtp_overhead = overhead_bytes_per_packet_;
|
||||
}
|
||||
RTC_CHECK_GE(rtp_overhead, 0);
|
||||
RTC_DCHECK_LT(rtp_overhead, config_->rtp.max_packet_size);
|
||||
if (rtp_overhead >= config_->rtp.max_packet_size) {
|
||||
LOG(LS_WARNING) << "RTP overhead (" << rtp_overhead << " bytes)"
|
||||
<< "exceeds maximum packet size ("
|
||||
<< config_->rtp.max_packet_size << " bytes)";
|
||||
|
||||
bitrate_bps = 0;
|
||||
} else {
|
||||
bitrate_bps =
|
||||
static_cast<uint32_t>(static_cast<uint64_t>(bitrate_bps) *
|
||||
(config_->rtp.max_packet_size - rtp_overhead) /
|
||||
(config_->rtp.max_packet_size +
|
||||
transport_overhead_bytes_per_packet_));
|
||||
}
|
||||
}
|
||||
// Substract overhead from bitrate.
|
||||
rtc::CritScope lock(&overhead_bytes_per_packet_crit_);
|
||||
uint32_t payload_bitrate_bps =
|
||||
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_ = protection_bitrate_calculator_.SetTargetRates(
|
||||
bitrate_bps, stats_proxy_->GetSendFrameRate(), fraction_loss, rtt);
|
||||
uint32_t protection_bitrate = bitrate_bps - encoder_target_rate_bps_;
|
||||
payload_bitrate_bps, stats_proxy_->GetSendFrameRate(), fraction_loss,
|
||||
rtt);
|
||||
|
||||
uint32_t encoder_overhead_rate_bps = 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_);
|
||||
|
||||
// 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);
|
||||
|
||||
encoder_target_rate_bps_ =
|
||||
std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps_);
|
||||
|
||||
@ -3169,16 +3169,10 @@ TEST_F(VideoSendStreamTest,
|
||||
TestRequestSourceRotateVideo(true);
|
||||
}
|
||||
|
||||
// Flaky on Win32 Release: http://crbug.com/webrtc/6886
|
||||
#if defined(WEBRTC_WIN)
|
||||
#define MAYBE_RemoveOverheadFromBandwidth DISABLED_RemoveOverheadFromBandwidth
|
||||
#else
|
||||
#define MAYBE_RemoveOverheadFromBandwidth RemoveOverheadFromBandwidth
|
||||
#endif
|
||||
// This test verifies that overhead is removed from the bandwidth estimate by
|
||||
// testing that the maximum possible target payload rate is smaller than the
|
||||
// maximum bandwidth estimate by the overhead rate.
|
||||
TEST_F(VideoSendStreamTest, MAYBE_RemoveOverheadFromBandwidth) {
|
||||
TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
|
||||
test::ScopedFieldTrials override_field_trials(
|
||||
"WebRTC-SendSideBwe-WithOverhead/Enabled/");
|
||||
class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
|
||||
@ -3188,13 +3182,19 @@ TEST_F(VideoSendStreamTest, MAYBE_RemoveOverheadFromBandwidth) {
|
||||
: EndToEndTest(test::CallTest::kDefaultTimeoutMs),
|
||||
FakeEncoder(Clock::GetRealTimeClock()),
|
||||
call_(nullptr),
|
||||
max_bitrate_kbps_(0) {}
|
||||
max_bitrate_bps_(0),
|
||||
first_packet_sent_(false),
|
||||
bitrate_changed_event_(false, false) {}
|
||||
|
||||
int32_t SetRateAllocation(const BitrateAllocation& bitrate,
|
||||
uint32_t frameRate) override {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (max_bitrate_kbps_ < bitrate.get_sum_kbps())
|
||||
max_bitrate_kbps_ = bitrate.get_sum_kbps();
|
||||
// Wait for the first sent packet so that videosendstream knows
|
||||
// rtp_overhead.
|
||||
if (first_packet_sent_) {
|
||||
max_bitrate_bps_ = bitrate.get_sum_bps();
|
||||
bitrate_changed_event_.Set();
|
||||
}
|
||||
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
|
||||
}
|
||||
|
||||
@ -3211,29 +3211,39 @@ TEST_F(VideoSendStreamTest, MAYBE_RemoveOverheadFromBandwidth) {
|
||||
EXPECT_FALSE(send_config->rtp.extensions.empty());
|
||||
}
|
||||
|
||||
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
||||
rtc::CritScope lock(&crit_);
|
||||
first_packet_sent_ = true;
|
||||
return SEND_PACKET;
|
||||
}
|
||||
|
||||
void PerformTest() override {
|
||||
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 20);
|
||||
Call::Config::BitrateConfig bitrate_config;
|
||||
constexpr int kStartBitrateBps = 50000;
|
||||
constexpr int kStartBitrateBps = 60000;
|
||||
constexpr int kMaxBitrateBps = 60000;
|
||||
constexpr int kMinBitrateBps = 10000;
|
||||
bitrate_config.start_bitrate_bps = kStartBitrateBps;
|
||||
bitrate_config.max_bitrate_bps = kMaxBitrateBps;
|
||||
bitrate_config.min_bitrate_bps = kMinBitrateBps;
|
||||
call_->SetBitrateConfig(bitrate_config);
|
||||
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 20);
|
||||
|
||||
// At a bitrate of 60kbps with a packet size of 1200B video and an
|
||||
// overhead of 40B per packet video produces 2kbps overhead.
|
||||
// So with a BWE should reach 58kbps but not 60kbps.
|
||||
Wait();
|
||||
// overhead of 40B per packet video produces 2240bps overhead.
|
||||
// So the encoder BW should be set to 57760bps.
|
||||
bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
|
||||
{
|
||||
rtc::CritScope lock(&crit_);
|
||||
EXPECT_EQ(58u, max_bitrate_kbps_);
|
||||
EXPECT_LE(57760u, max_bitrate_bps_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Call* call_;
|
||||
rtc::CriticalSection crit_;
|
||||
uint32_t max_bitrate_kbps_ GUARDED_BY(&crit_);
|
||||
uint32_t max_bitrate_bps_ GUARDED_BY(&crit_);
|
||||
bool first_packet_sent_ GUARDED_BY(&crit_);
|
||||
rtc::Event bitrate_changed_event_;
|
||||
} test;
|
||||
|
||||
RunBaseTest(&test);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user