aboutsummaryrefslogtreecommitdiff
path: root/media
diff options
context:
space:
mode:
authorErik Språng <sprang@webrtc.org>2022-05-05 10:52:20 +0200
committerWebRTC LUCI CQ <webrtc-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-05-05 10:10:20 +0000
commit45361f78ed18c350b3edcaef19ae4c7cf167e95b (patch)
treec14c51cd315adeee9b6269456c4bf294d69fae12 /media
parent658dfb74e563295b7ed4961d06c68afbd566ef8d (diff)
downloadwebrtc-45361f78ed18c350b3edcaef19ae4c7cf167e95b.tar.gz
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}
Diffstat (limited to 'media')
-rw-r--r--media/engine/webrtc_video_engine.cc34
-rw-r--r--media/engine/webrtc_video_engine_unittest.cc36
2 files changed, 56 insertions, 14 deletions
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index e29d1ea66e..82caab9292 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -343,24 +343,30 @@ bool IsCodecDisabledForSimulcast(const std::string& codec_name,
return false;
}
-// The selected thresholds for QVGA and VGA corresponded to a QP around 10.
-// The change in QP declined above the selected bitrates.
+// Calculates some reasonable max bitrate thresholds based on resolution.
static int GetMaxDefaultVideoBitrateKbps(int width,
int height,
bool is_screenshare) {
- int max_bitrate;
- if (width * height <= 320 * 240) {
- max_bitrate = 600;
- } else if (width * height <= 640 * 480) {
- max_bitrate = 1700;
- } else if (width * height <= 960 * 540) {
- max_bitrate = 2000;
- } else {
- max_bitrate = 2500;
- }
+ double pixel_count = width * height;
+ // This expression uses a rectangular hyperbola plus a small exponential
+ // correction function, with parameters selected so the curve fits well to
+ // values expected for common resolutions.
+ //
+ // Some examples:
+ // 320x240 => 600
+ // 640x480 => 1600
+ // 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)
- max_bitrate = std::max(max_bitrate, 1200);
- return max_bitrate;
+ max_bitrate_kbps = std::max(max_bitrate_kbps, 1200);
+ return max_bitrate_kbps;
}
// Returns its smallest positive argument. If neither argument is positive,
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index 377ea232c4..e32d005f61 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -7068,6 +7068,42 @@ TEST_F(WebRtcVideoChannelTest,
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) {
FakeVideoSendStream* stream = AddSendStream();