diff options
author | Erik Språng <sprang@webrtc.org> | 2022-05-05 10:52:20 +0200 |
---|---|---|
committer | WebRTC LUCI CQ <webrtc-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-05-05 10:10:20 +0000 |
commit | 45361f78ed18c350b3edcaef19ae4c7cf167e95b (patch) | |
tree | c14c51cd315adeee9b6269456c4bf294d69fae12 /media | |
parent | 658dfb74e563295b7ed4961d06c68afbd566ef8d (diff) | |
download | webrtc-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.cc | 34 | ||||
-rw-r--r-- | media/engine/webrtc_video_engine_unittest.cc | 36 |
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(); |