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:
michaelt 2017-01-26 09:05:27 -08:00 committed by Commit bot
parent 04bd836ca1
commit 192132ef04
2 changed files with 70 additions and 43 deletions

View File

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

View File

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