Update simulcast bitrate calculations for non-standard resolutions.
* Increase 540p bitrate to 1.2mbps from 0.9mpbs. 960x540 bitrate was by far smallest in terms of bits per pixel. This change brings it closer to other resolutions. * Interpolate max/target/min bitrates for non-standard resolutions based on number of pixels. Bug: webrtc:10965 Change-Id: If0aa56bb4c614ca09ee39d3a2b700aab2ffa1a2c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/152828 Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29195}
This commit is contained in:
parent
1b6a30ddcc
commit
73ceed58f8
@ -74,7 +74,7 @@ struct SimulcastFormat {
|
||||
const SimulcastFormat kSimulcastFormats[] = {
|
||||
{1920, 1080, 3, 5000, 4000, 800},
|
||||
{1280, 720, 3, 2500, 2500, 600},
|
||||
{960, 540, 3, 900, 900, 450},
|
||||
{960, 540, 3, 1200, 1200, 350},
|
||||
{640, 360, 2, 700, 500, 150},
|
||||
{480, 270, 2, 450, 350, 150},
|
||||
{320, 180, 1, 200, 150, 30},
|
||||
@ -143,19 +143,46 @@ int NormalizeSimulcastSize(int size, size_t simulcast_layers) {
|
||||
return ((size >> base2_exponent) << base2_exponent);
|
||||
}
|
||||
|
||||
SimulcastFormat InterpolateSimulcastFormat(int width, int height) {
|
||||
const int index = FindSimulcastFormatIndex(width, height);
|
||||
if (index == 0)
|
||||
return kSimulcastFormats[index];
|
||||
const int total_pixels_up =
|
||||
kSimulcastFormats[index - 1].width * kSimulcastFormats[index - 1].height;
|
||||
const int total_pixels_down =
|
||||
kSimulcastFormats[index].width * kSimulcastFormats[index].height;
|
||||
const int total_pixels = width * height;
|
||||
const float rate = (total_pixels_up - total_pixels) /
|
||||
static_cast<float>(total_pixels_up - total_pixels_down);
|
||||
SimulcastFormat res;
|
||||
res.width = width;
|
||||
res.height = height;
|
||||
res.max_layers = kSimulcastFormats[index].max_layers;
|
||||
res.max_bitrate_kbps =
|
||||
kSimulcastFormats[index - 1].max_bitrate_kbps * (1.0 - rate) +
|
||||
kSimulcastFormats[index].max_bitrate_kbps * rate;
|
||||
res.target_bitrate_kbps =
|
||||
kSimulcastFormats[index - 1].target_bitrate_kbps * (1.0 - rate) +
|
||||
kSimulcastFormats[index].target_bitrate_kbps * rate;
|
||||
res.min_bitrate_kbps =
|
||||
kSimulcastFormats[index - 1].min_bitrate_kbps * (1.0 - rate) +
|
||||
kSimulcastFormats[index].min_bitrate_kbps * rate;
|
||||
return res;
|
||||
}
|
||||
|
||||
int FindSimulcastMaxBitrateBps(int width, int height) {
|
||||
const int format_index = FindSimulcastFormatIndex(width, height);
|
||||
return kSimulcastFormats[format_index].max_bitrate_kbps * 1000;
|
||||
const SimulcastFormat format = InterpolateSimulcastFormat(width, height);
|
||||
return format.max_bitrate_kbps * 1000;
|
||||
}
|
||||
|
||||
int FindSimulcastTargetBitrateBps(int width, int height) {
|
||||
const int format_index = FindSimulcastFormatIndex(width, height);
|
||||
return kSimulcastFormats[format_index].target_bitrate_kbps * 1000;
|
||||
const SimulcastFormat format = InterpolateSimulcastFormat(width, height);
|
||||
return format.target_bitrate_kbps * 1000;
|
||||
}
|
||||
|
||||
int FindSimulcastMinBitrateBps(int width, int height) {
|
||||
const int format_index = FindSimulcastFormatIndex(width, height);
|
||||
return kSimulcastFormats[format_index].min_bitrate_kbps * 1000;
|
||||
const SimulcastFormat format = InterpolateSimulcastFormat(width, height);
|
||||
return format.min_bitrate_kbps * 1000;
|
||||
}
|
||||
|
||||
void BoostMaxSimulcastLayer(int max_bitrate_bps,
|
||||
|
||||
@ -262,7 +262,7 @@ TEST(SimulcastTest, GetConfigForScreenshareSimulcastWithLimitedMaxLayers) {
|
||||
TEST(SimulcastTest, SimulcastScreenshareMaxBitrateAdjustedForResolution) {
|
||||
constexpr int kScreenshareHighStreamMinBitrateBps = 600000;
|
||||
constexpr int kScreenshareHighStreamMaxBitrateBps = 1250000;
|
||||
constexpr int kMaxBitrate960_540 = 900000;
|
||||
constexpr int kMaxBitrate960_540 = 1200000;
|
||||
|
||||
// Normal case, max bitrate not limited by resolution.
|
||||
const size_t kMaxLayers = 2;
|
||||
@ -291,4 +291,40 @@ TEST(SimulcastTest, SimulcastScreenshareMaxBitrateAdjustedForResolution) {
|
||||
EXPECT_GE(streams[1].max_bitrate_bps, streams[1].min_bitrate_bps);
|
||||
}
|
||||
|
||||
TEST(SimulcastTest, AveragesBitratesForNonStandardResolution) {
|
||||
const size_t kMaxLayers = 3;
|
||||
std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
|
||||
kMaxLayers, 900, 800, kBitratePriority, kQpMax, !kScreenshare);
|
||||
|
||||
EXPECT_EQ(kMaxLayers, streams.size());
|
||||
EXPECT_EQ(900u, streams[2].width);
|
||||
EXPECT_EQ(800u, streams[2].height);
|
||||
EXPECT_EQ(1850000, streams[2].max_bitrate_bps);
|
||||
EXPECT_EQ(1850000, streams[2].target_bitrate_bps);
|
||||
EXPECT_EQ(475000, streams[2].min_bitrate_bps);
|
||||
}
|
||||
|
||||
TEST(SimulcastTest, BitratesForCloseToStandardResolution) {
|
||||
const size_t kMaxLayers = 3;
|
||||
// Resolution very close to 720p in number of pixels
|
||||
const size_t kWidth = 1280;
|
||||
const size_t kHeight = 716;
|
||||
const std::vector<VideoStream> kExpectedNear = GetSimulcastBitrates720p();
|
||||
|
||||
std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
|
||||
kMaxLayers, kWidth, kHeight, kBitratePriority, kQpMax, !kScreenshare);
|
||||
|
||||
EXPECT_EQ(kMaxLayers, streams.size());
|
||||
EXPECT_EQ(kWidth, streams[2].width);
|
||||
EXPECT_EQ(kHeight, streams[2].height);
|
||||
for (size_t i = 0; i < streams.size(); ++i) {
|
||||
EXPECT_NEAR(kExpectedNear[i].max_bitrate_bps, streams[i].max_bitrate_bps,
|
||||
20000);
|
||||
EXPECT_NEAR(kExpectedNear[i].target_bitrate_bps,
|
||||
streams[i].target_bitrate_bps, 20000);
|
||||
EXPECT_NEAR(kExpectedNear[i].min_bitrate_bps, streams[i].min_bitrate_bps,
|
||||
20000);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user