webrtc/call/rtp_bitrate_configurator_unittest.cc
Sebastian Jansson df023aa6b4 Extracted bitrate configuration from call class.
This separates the bitrate configuration logic from other call specific
logic, creating a greater separation of concern and simplifying testing.
The old call tests are kept but can be removed in the future reducing
the dependencies on rtp transport control interface and congestion
control in the system, which will simplify future refactoring.

This also prepares for moving the bitrate configuration responsibility
to the rtp transport controller in a later CL.

Bug: webrtc:8415
Change-Id: I97126e89f30b63fc9b5d98a0bed1c29f18a6ed44
Reviewed-on: https://webrtc-review.googlesource.com/54401
Reviewed-by: Zach Stein <zstein@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22124}
2018-02-21 12:33:02 +00:00

299 lines
10 KiB
C++

/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <memory>
#include "call/rtp_bitrate_configurator.h"
#include "test/gtest.h"
namespace webrtc {
using rtc::nullopt;
class RtpBitrateConfiguratorTest : public testing::Test {
public:
RtpBitrateConfiguratorTest()
: configurator_(new RtpBitrateConfigurator(BitrateConstraints())) {}
std::unique_ptr<RtpBitrateConfigurator> configurator_;
void UpdateConfigMatches(BitrateConstraints bitrate_config,
rtc::Optional<int> min_bitrate_bps,
rtc::Optional<int> start_bitrate_bps,
rtc::Optional<int> max_bitrate_bps) {
rtc::Optional<BitrateConstraints> result =
configurator_->UpdateWithSdpParameters(bitrate_config);
EXPECT_TRUE(result.has_value());
if (start_bitrate_bps.has_value())
EXPECT_EQ(result->start_bitrate_bps, start_bitrate_bps);
if (min_bitrate_bps.has_value())
EXPECT_EQ(result->min_bitrate_bps, min_bitrate_bps);
if (max_bitrate_bps.has_value())
EXPECT_EQ(result->max_bitrate_bps, max_bitrate_bps);
}
void UpdateMaskMatches(BitrateConstraintsMask bitrate_mask,
rtc::Optional<int> min_bitrate_bps,
rtc::Optional<int> start_bitrate_bps,
rtc::Optional<int> max_bitrate_bps) {
rtc::Optional<BitrateConstraints> result =
configurator_->UpdateWithClientPreferences(bitrate_mask);
EXPECT_TRUE(result.has_value());
if (start_bitrate_bps.has_value())
EXPECT_EQ(result->start_bitrate_bps, start_bitrate_bps);
if (min_bitrate_bps.has_value())
EXPECT_EQ(result->min_bitrate_bps, min_bitrate_bps);
if (max_bitrate_bps.has_value())
EXPECT_EQ(result->max_bitrate_bps, max_bitrate_bps);
}
};
TEST_F(RtpBitrateConfiguratorTest, NewConfigWithValidConfigReturnsNewConfig) {
BitrateConstraints bitrate_config;
bitrate_config.min_bitrate_bps = 1;
bitrate_config.start_bitrate_bps = 2;
bitrate_config.max_bitrate_bps = 3;
UpdateConfigMatches(bitrate_config, 1, 2, 3);
}
TEST_F(RtpBitrateConfiguratorTest, NewConfigWithDifferentMinReturnsNewConfig) {
BitrateConstraints bitrate_config;
bitrate_config.min_bitrate_bps = 10;
bitrate_config.start_bitrate_bps = 20;
bitrate_config.max_bitrate_bps = 30;
configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
bitrate_config.min_bitrate_bps = 11;
UpdateConfigMatches(bitrate_config, 11, -1, 30);
}
TEST_F(RtpBitrateConfiguratorTest,
NewConfigWithDifferentStartReturnsNewConfig) {
BitrateConstraints bitrate_config;
bitrate_config.min_bitrate_bps = 10;
bitrate_config.start_bitrate_bps = 20;
bitrate_config.max_bitrate_bps = 30;
configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
bitrate_config.start_bitrate_bps = 21;
UpdateConfigMatches(bitrate_config, 10, 21, 30);
}
TEST_F(RtpBitrateConfiguratorTest, NewConfigWithDifferentMaxReturnsNewConfig) {
BitrateConstraints bitrate_config;
bitrate_config.min_bitrate_bps = 10;
bitrate_config.start_bitrate_bps = 20;
bitrate_config.max_bitrate_bps = 30;
configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
bitrate_config.max_bitrate_bps = 31;
UpdateConfigMatches(bitrate_config, 10, -1, 31);
}
TEST_F(RtpBitrateConfiguratorTest, NewConfigWithSameConfigElidesSecondCall) {
BitrateConstraints bitrate_config;
bitrate_config.min_bitrate_bps = 1;
bitrate_config.start_bitrate_bps = 2;
bitrate_config.max_bitrate_bps = 3;
UpdateConfigMatches(bitrate_config, 1, 2, 3);
EXPECT_FALSE(
configurator_->UpdateWithSdpParameters(bitrate_config).has_value());
}
TEST_F(RtpBitrateConfiguratorTest,
NewConfigWithSameMinMaxAndNegativeStartElidesSecondCall) {
BitrateConstraints bitrate_config;
bitrate_config.min_bitrate_bps = 1;
bitrate_config.start_bitrate_bps = 2;
bitrate_config.max_bitrate_bps = 3;
UpdateConfigMatches(bitrate_config, 1, 2, 3);
bitrate_config.start_bitrate_bps = -1;
EXPECT_FALSE(
configurator_->UpdateWithSdpParameters(bitrate_config).has_value());
}
TEST_F(RtpBitrateConfiguratorTest, BiggerMaskMinUsed) {
BitrateConstraintsMask mask;
mask.min_bitrate_bps = 1234;
UpdateMaskMatches(mask, *mask.min_bitrate_bps, nullopt, nullopt);
}
TEST_F(RtpBitrateConfiguratorTest, BiggerConfigMinUsed) {
BitrateConstraintsMask mask;
mask.min_bitrate_bps = 1000;
UpdateMaskMatches(mask, 1000, nullopt, nullopt);
BitrateConstraints config;
config.min_bitrate_bps = 1234;
UpdateConfigMatches(config, 1234, nullopt, nullopt);
}
// The last call to set start should be used.
TEST_F(RtpBitrateConfiguratorTest, LatestStartMaskPreferred) {
BitrateConstraintsMask mask;
mask.start_bitrate_bps = 1300;
UpdateMaskMatches(mask, nullopt, *mask.start_bitrate_bps, nullopt);
BitrateConstraints bitrate_config;
bitrate_config.start_bitrate_bps = 1200;
UpdateConfigMatches(bitrate_config, nullopt, bitrate_config.start_bitrate_bps,
nullopt);
}
TEST_F(RtpBitrateConfiguratorTest, SmallerMaskMaxUsed) {
BitrateConstraints bitrate_config;
bitrate_config.max_bitrate_bps = bitrate_config.start_bitrate_bps + 2000;
configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
BitrateConstraintsMask mask;
mask.max_bitrate_bps = bitrate_config.start_bitrate_bps + 1000;
UpdateMaskMatches(mask, nullopt, nullopt, *mask.max_bitrate_bps);
}
TEST_F(RtpBitrateConfiguratorTest, SmallerConfigMaxUsed) {
BitrateConstraints bitrate_config;
bitrate_config.max_bitrate_bps = bitrate_config.start_bitrate_bps + 1000;
configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
BitrateConstraintsMask mask;
mask.max_bitrate_bps = bitrate_config.start_bitrate_bps + 2000;
// Expect no return because nothing changes
EXPECT_FALSE(configurator_->UpdateWithClientPreferences(mask).has_value());
}
TEST_F(RtpBitrateConfiguratorTest, MaskStartLessThanConfigMinClamped) {
BitrateConstraints bitrate_config;
bitrate_config.min_bitrate_bps = 2000;
configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
BitrateConstraintsMask mask;
mask.start_bitrate_bps = 1000;
UpdateMaskMatches(mask, 2000, 2000, nullopt);
}
TEST_F(RtpBitrateConfiguratorTest, MaskStartGreaterThanConfigMaxClamped) {
BitrateConstraints bitrate_config;
bitrate_config.start_bitrate_bps = 2000;
configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
BitrateConstraintsMask mask;
mask.max_bitrate_bps = 1000;
UpdateMaskMatches(mask, nullopt, -1, 1000);
}
TEST_F(RtpBitrateConfiguratorTest, MaskMinGreaterThanConfigMaxClamped) {
BitrateConstraints bitrate_config;
bitrate_config.min_bitrate_bps = 2000;
configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
BitrateConstraintsMask mask;
mask.max_bitrate_bps = 1000;
UpdateMaskMatches(mask, 1000, nullopt, 1000);
}
TEST_F(RtpBitrateConfiguratorTest, SettingMaskStartForcesUpdate) {
BitrateConstraintsMask mask;
mask.start_bitrate_bps = 1000;
// Config should be returned twice with the same params since
// start_bitrate_bps is set.
UpdateMaskMatches(mask, nullopt, 1000, nullopt);
UpdateMaskMatches(mask, nullopt, 1000, nullopt);
}
TEST_F(RtpBitrateConfiguratorTest, NewConfigWithNoChangesDoesNotCallNewConfig) {
BitrateConstraints config1;
config1.min_bitrate_bps = 0;
config1.start_bitrate_bps = 1000;
config1.max_bitrate_bps = -1;
BitrateConstraints config2;
config2.min_bitrate_bps = 0;
config2.start_bitrate_bps = -1;
config2.max_bitrate_bps = -1;
// The second call should not return anything because it doesn't
// change any values.
UpdateConfigMatches(config1, 0, 1000, -1);
EXPECT_FALSE(configurator_->UpdateWithSdpParameters(config2).has_value());
}
// If config changes the max, but not the effective max,
// new config shouldn't be returned, to avoid unnecessary encoder
// reconfigurations.
TEST_F(RtpBitrateConfiguratorTest,
NewConfigNotReturnedWhenEffectiveMaxUnchanged) {
BitrateConstraints config;
config.min_bitrate_bps = 0;
config.start_bitrate_bps = -1;
config.max_bitrate_bps = 2000;
UpdateConfigMatches(config, nullopt, nullopt, 2000);
// Reduce effective max to 1000 with the mask.
BitrateConstraintsMask mask;
mask.max_bitrate_bps = 1000;
UpdateMaskMatches(mask, nullopt, nullopt, 1000);
// This leaves the effective max unchanged, so new config shouldn't be
// returned again.
config.max_bitrate_bps = 1000;
EXPECT_FALSE(configurator_->UpdateWithSdpParameters(config).has_value());
}
// When the "start bitrate" mask is removed, new config shouldn't be returned
// again, since nothing's changing.
TEST_F(RtpBitrateConfiguratorTest, NewConfigNotReturnedWhenStartMaskRemoved) {
BitrateConstraintsMask mask;
mask.start_bitrate_bps = 1000;
UpdateMaskMatches(mask, 0, 1000, -1);
mask.start_bitrate_bps.reset();
EXPECT_FALSE(configurator_->UpdateWithClientPreferences(mask).has_value());
}
// Test that if a new config is returned after BitrateConstraintsMask applies a
// "start" value, the new config won't return that start value a
// second time.
TEST_F(RtpBitrateConfiguratorTest, NewConfigAfterBitrateConfigMaskWithStart) {
BitrateConstraintsMask mask;
mask.start_bitrate_bps = 1000;
UpdateMaskMatches(mask, 0, 1000, -1);
BitrateConstraints config;
config.min_bitrate_bps = 0;
config.start_bitrate_bps = -1;
config.max_bitrate_bps = 5000;
// The start value isn't changing, so new config should be returned with
// -1.
UpdateConfigMatches(config, 0, -1, 5000);
}
TEST_F(RtpBitrateConfiguratorTest,
NewConfigNotReturnedWhenClampedMinUnchanged) {
BitrateConstraints bitrate_config;
bitrate_config.start_bitrate_bps = 500;
bitrate_config.max_bitrate_bps = 1000;
configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
// Set min to 2000; it is clamped to the max (1000).
BitrateConstraintsMask mask;
mask.min_bitrate_bps = 2000;
UpdateMaskMatches(mask, 1000, -1, 1000);
// Set min to 3000; the clamped value stays the same so nothing happens.
mask.min_bitrate_bps = 3000;
EXPECT_FALSE(configurator_->UpdateWithClientPreferences(mask).has_value());
}
} // namespace webrtc