Calculate video stream max bitrate using expression.

This replaces the ealier table-based caps.
Apart from the VGA cap (now 1600kbps instead of 1700kbps), or if using
"in between" resolutions, the caps are unchanged - but now cover high
resolutions better.

Bug: webrtc:14017
Change-Id: I8649b528495d6c917e38ea8cb1a272df6c464c03
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/260940
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36776}
This commit is contained in:
Erik Språng 2022-05-05 10:52:20 +02:00 committed by WebRTC LUCI CQ
parent 658dfb74e5
commit 45361f78ed
2 changed files with 56 additions and 14 deletions

View File

@ -343,24 +343,30 @@ bool IsCodecDisabledForSimulcast(const std::string& codec_name,
return false; return false;
} }
// The selected thresholds for QVGA and VGA corresponded to a QP around 10. // Calculates some reasonable max bitrate thresholds based on resolution.
// The change in QP declined above the selected bitrates.
static int GetMaxDefaultVideoBitrateKbps(int width, static int GetMaxDefaultVideoBitrateKbps(int width,
int height, int height,
bool is_screenshare) { bool is_screenshare) {
int max_bitrate; double pixel_count = width * height;
if (width * height <= 320 * 240) { // This expression uses a rectangular hyperbola plus a small exponential
max_bitrate = 600; // correction function, with parameters selected so the curve fits well to
} else if (width * height <= 640 * 480) { // values expected for common resolutions.
max_bitrate = 1700; //
} else if (width * height <= 960 * 540) { // Some examples:
max_bitrate = 2000; // 320x240 => 600
} else { // 640x480 => 1600
max_bitrate = 2500; // 960x540 => 2000
} // 1280x720 => 2500
// 1920x1080 => 3300
double max_kbps = (3000 * pixel_count) / (310000 + pixel_count) +
0.0003 * std::pow(pixel_count, 1.005);
// Round to nearest 100kbps.
int max_bitrate_kbps =
100 * std::max(1, static_cast<int>(std::round(max_kbps / 100)));
if (is_screenshare) if (is_screenshare)
max_bitrate = std::max(max_bitrate, 1200); max_bitrate_kbps = std::max(max_bitrate_kbps, 1200);
return max_bitrate; return max_bitrate_kbps;
} }
// Returns its smallest positive argument. If neither argument is positive, // Returns its smallest positive argument. If neither argument is positive,

View File

@ -7068,6 +7068,42 @@ TEST_F(WebRtcVideoChannelTest,
stream->GetVideoStreams()[0].max_bitrate_bps); stream->GetVideoStreams()[0].max_bitrate_bps);
} }
TEST_F(WebRtcVideoChannelTest, SetsCorrectMaxBitrateForCommonResolutions) {
FakeVideoSendStream* stream = AddSendStream();
webrtc::test::FrameForwarder frame_forwarder;
VideoOptions options;
EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
channel_->SetSend(true);
auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
ASSERT_TRUE(result.ok());
struct ResolutionBitratePairing {
int width;
int height;
int bitrate_kbps;
};
std::vector<ResolutionBitratePairing> resolutions = {
{.width = 320, .height = 240, .bitrate_kbps = 600},
{.width = 640, .height = 480, .bitrate_kbps = 1600},
{.width = 960, .height = 540, .bitrate_kbps = 2000},
{.width = 1280, .height = 720, .bitrate_kbps = 2500},
{.width = 1920, .height = 1080, .bitrate_kbps = 3300},
{.width = 3840, .height = 2190, .bitrate_kbps = 5600}};
for (const ResolutionBitratePairing& resolution : resolutions) {
FakeFrameSource frame_source(resolution.width, resolution.height,
rtc::kNumMicrosecsPerSec / 30);
frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
ASSERT_EQ(1UL, stream->GetVideoStreams().size());
EXPECT_EQ(resolution.bitrate_kbps * 1000,
stream->GetVideoStreams()[0].max_bitrate_bps);
}
EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}
TEST_F(WebRtcVideoChannelTest, SetMaxFramerateOneStream) { TEST_F(WebRtcVideoChannelTest, SetMaxFramerateOneStream) {
FakeVideoSendStream* stream = AddSendStream(); FakeVideoSendStream* stream = AddSendStream();