In EncoderStreamFactory pass field trials as required parameter

Instead of passing it as optional parameter during construction, pass field trials as required parameters on use.
Test that create the EncoderStreamFactory might not have an easy access to the actual field trials, but prod code has appropriate field trials when uses the factory.

This way EncoderStreamFactory doesn't need to depend on global field trial string through FieldTrialBaseConfig class.

Bug: webrtc:10335
Change-Id: I8f7030e41579ff2c5dd362c491a4e1624b23e690
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/347700
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42098}
This commit is contained in:
Danil Chapovalov 2024-04-17 12:11:29 +02:00 committed by WebRTC LUCI CQ
parent 039288c284
commit 44ab20021d
19 changed files with 87 additions and 86 deletions

View file

@ -795,6 +795,7 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
private:
std::vector<VideoStream> CreateEncoderStreams(
const FieldTrialsView& /*field_trials*/,
int frame_width,
int frame_height,
const webrtc::VideoEncoderConfig& encoder_config) override {

View file

@ -133,6 +133,7 @@ class RampUpTester::VideoStreamFactory
private:
std::vector<VideoStream> CreateEncoderStreams(
const FieldTrialsView& /*field_trials*/,
int frame_width,
int frame_height,
const VideoEncoderConfig& encoder_config) override {

View file

@ -251,20 +251,18 @@ void FakeVideoSendStream::OnFrame(const webrtc::VideoFrame& frame) {
// Note: only tests set their own EncoderStreamFactory...
video_streams_ =
encoder_config_.video_stream_factory->CreateEncoderStreams(
frame.width(), frame.height(), encoder_config_);
env_.field_trials(), frame.width(), frame.height(),
encoder_config_);
} else {
webrtc::VideoEncoder::EncoderInfo encoder_info;
rtc::scoped_refptr<
webrtc::VideoEncoderConfig::VideoStreamFactoryInterface>
factory = rtc::make_ref_counted<cricket::EncoderStreamFactory>(
encoder_config_.video_format.name, encoder_config_.max_qp,
encoder_config_.content_type ==
webrtc::VideoEncoderConfig::ContentType::kScreen,
encoder_config_.legacy_conference_mode, encoder_info,
absl::nullopt, &env_.field_trials());
auto factory = rtc::make_ref_counted<cricket::EncoderStreamFactory>(
encoder_config_.video_format.name, encoder_config_.max_qp,
encoder_config_.content_type ==
webrtc::VideoEncoderConfig::ContentType::kScreen,
encoder_config_.legacy_conference_mode, encoder_info);
video_streams_ = factory->CreateEncoderStreams(
frame.width(), frame.height(), encoder_config_);
env_.field_trials(), frame.width(), frame.height(), encoder_config_);
}
}
last_frame_ = frame;
@ -297,17 +295,16 @@ void FakeVideoSendStream::ReconfigureVideoEncoder(
if (config.video_stream_factory) {
// Note: only tests set their own EncoderStreamFactory...
video_streams_ = config.video_stream_factory->CreateEncoderStreams(
width, height, config);
env_.field_trials(), width, height, config);
} else {
webrtc::VideoEncoder::EncoderInfo encoder_info;
rtc::scoped_refptr<webrtc::VideoEncoderConfig::VideoStreamFactoryInterface>
factory = rtc::make_ref_counted<cricket::EncoderStreamFactory>(
config.video_format.name, config.max_qp,
config.content_type ==
webrtc::VideoEncoderConfig::ContentType::kScreen,
config.legacy_conference_mode, encoder_info);
auto factory = rtc::make_ref_counted<cricket::EncoderStreamFactory>(
config.video_format.name, config.max_qp,
config.content_type == webrtc::VideoEncoderConfig::ContentType::kScreen,
config.legacy_conference_mode, encoder_info);
video_streams_ = factory->CreateEncoderStreams(width, height, config);
video_streams_ = factory->CreateEncoderStreams(env_.field_trials(), width,
height, config);
}
if (config.encoder_specific_settings != nullptr) {

View file

@ -106,6 +106,7 @@ std::vector<VideoStream> CreateVideoStreams(
DefaultVideoStreamFactory::DefaultVideoStreamFactory() {}
std::vector<VideoStream> DefaultVideoStreamFactory::CreateEncoderStreams(
const FieldTrialsView& /*field_trials*/,
int frame_width,
int frame_height,
const webrtc::VideoEncoderConfig& encoder_config) {

View file

@ -35,6 +35,7 @@ class DefaultVideoStreamFactory
private:
std::vector<VideoStream> CreateEncoderStreams(
const FieldTrialsView& field_trials,
int frame_width,
int frame_height,
const webrtc::VideoEncoderConfig& encoder_config) override;

View file

@ -19,7 +19,6 @@ rtc_library("streams_config") {
deps = [
":encoder_config",
"../../api:field_trials_view",
"../../api/transport:field_trial_based_config",
"../../api/units:data_rate",
"../../api/video:video_codec_constants",
"../../api/video_codecs:video_codecs_api",
@ -50,6 +49,7 @@ rtc_library("encoder_config") {
]
deps = [
"../../api:field_trials_view",
"../../api:scoped_refptr",
"../../api/video:resolution",
"../../api/video_codecs:scalability_mode",

View file

@ -17,6 +17,7 @@
#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
#include "api/field_trials_view.h"
#include "api/video/video_codec_constants.h"
#include "media/base/media_constants.h"
#include "media/base/video_adapter.h"
@ -29,6 +30,8 @@
namespace cricket {
namespace {
using ::webrtc::FieldTrialsView;
const int kMinLayerSize = 16;
int ScaleDownResolution(int resolution,
@ -99,35 +102,23 @@ static int GetMaxDefaultVideoBitrateKbps(int width,
// TODO(bugs.webrtc.org/8785): Consider removing max_qp as member of
// EncoderStreamFactory and instead set this value individually for each stream
// in the VideoEncoderConfig.simulcast_layers.
EncoderStreamFactory::EncoderStreamFactory(std::string codec_name,
int max_qp,
bool is_screenshare,
bool conference_mode)
: codec_name_(codec_name),
max_qp_(max_qp),
is_screenshare_(is_screenshare),
conference_mode_(conference_mode),
trials_(fallback_trials_),
encoder_info_requested_resolution_alignment_(1) {}
EncoderStreamFactory::EncoderStreamFactory(
std::string codec_name,
int max_qp,
bool is_screenshare,
bool conference_mode,
const webrtc::VideoEncoder::EncoderInfo& encoder_info,
absl::optional<webrtc::VideoSourceRestrictions> restrictions,
const webrtc::FieldTrialsView* trials)
absl::optional<webrtc::VideoSourceRestrictions> restrictions)
: codec_name_(codec_name),
max_qp_(max_qp),
is_screenshare_(is_screenshare),
conference_mode_(conference_mode),
trials_(trials ? *trials : fallback_trials_),
encoder_info_requested_resolution_alignment_(
encoder_info.requested_resolution_alignment),
restrictions_(restrictions) {}
std::vector<webrtc::VideoStream> EncoderStreamFactory::CreateEncoderStreams(
const FieldTrialsView& trials,
int frame_width,
int frame_height,
const webrtc::VideoEncoderConfig& encoder_config) {
@ -136,7 +127,7 @@ std::vector<webrtc::VideoStream> EncoderStreamFactory::CreateEncoderStreams(
encoder_config.number_of_streams);
const absl::optional<webrtc::DataRate> experimental_min_bitrate =
GetExperimentalMinVideoBitrate(trials_, encoder_config.codec_type);
GetExperimentalMinVideoBitrate(trials, encoder_config.codec_type);
bool is_simulcast = (encoder_config.number_of_streams > 1);
// If scalability mode was specified, don't treat {active,inactive,inactive}
@ -159,7 +150,8 @@ std::vector<webrtc::VideoStream> EncoderStreamFactory::CreateEncoderStreams(
absl::EqualsIgnoreCase(codec_name_, kH264CodecName)) &&
is_screenshare_ && conference_mode_)) {
return CreateSimulcastOrConferenceModeScreenshareStreams(
frame_width, frame_height, encoder_config, experimental_min_bitrate);
trials, frame_width, frame_height, encoder_config,
experimental_min_bitrate);
}
return CreateDefaultVideoStreams(frame_width, frame_height, encoder_config,
@ -307,6 +299,7 @@ EncoderStreamFactory::CreateDefaultVideoStreams(
std::vector<webrtc::VideoStream>
EncoderStreamFactory::CreateSimulcastOrConferenceModeScreenshareStreams(
const FieldTrialsView& trials,
int width,
int height,
const webrtc::VideoEncoderConfig& encoder_config,
@ -320,7 +313,7 @@ EncoderStreamFactory::CreateSimulcastOrConferenceModeScreenshareStreams(
encoder_config.number_of_streams, width, height,
encoder_config.bitrate_priority, max_qp_,
is_screenshare_ && conference_mode_,
temporal_layers_supported, trials_,
temporal_layers_supported, trials,
encoder_config.codec_type);
// Allow an experiment to override the minimum bitrate for the lowest
// spatial layer. The experiment's configuration has the lowest priority.
@ -340,18 +333,18 @@ EncoderStreamFactory::CreateSimulcastOrConferenceModeScreenshareStreams(
default_scale_factors_used = IsScaleFactorsPowerOfTwo(encoder_config);
}
const bool norm_size_configured =
webrtc::NormalizeSimulcastSizeExperiment::GetBase2Exponent(trials_)
webrtc::NormalizeSimulcastSizeExperiment::GetBase2Exponent(trials)
.has_value();
const int normalized_width =
(default_scale_factors_used || norm_size_configured) &&
(width >= kMinLayerSize)
? NormalizeSimulcastSize(trials_, width,
? NormalizeSimulcastSize(trials, width,
encoder_config.number_of_streams)
: width;
const int normalized_height =
(default_scale_factors_used || norm_size_configured) &&
(height >= kMinLayerSize)
? NormalizeSimulcastSize(trials_, height,
? NormalizeSimulcastSize(trials, height,
encoder_config.number_of_streams)
: height;
for (size_t i = 0; i < layers.size(); ++i) {

View file

@ -13,7 +13,7 @@
#include <string>
#include <vector>
#include "api/transport/field_trial_based_config.h"
#include "api/field_trials_view.h"
#include "api/units/data_rate.h"
#include "api/video_codecs/video_encoder.h"
#include "call/adaptation/video_source_restrictions.h"
@ -24,22 +24,16 @@ namespace cricket {
class EncoderStreamFactory
: public webrtc::VideoEncoderConfig::VideoStreamFactoryInterface {
public:
// Note: this constructor is used by testcase in downstream.
EncoderStreamFactory(std::string codec_name,
int max_qp,
bool is_screenshare,
bool conference_mode);
EncoderStreamFactory(std::string codec_name,
int max_qp,
bool is_screenshare,
bool conference_mode,
const webrtc::VideoEncoder::EncoderInfo& encoder_info,
absl::optional<webrtc::VideoSourceRestrictions>
restrictions = absl::nullopt,
const webrtc::FieldTrialsView* trials = nullptr);
restrictions = absl::nullopt);
std::vector<webrtc::VideoStream> CreateEncoderStreams(
const webrtc::FieldTrialsView& trials,
int width,
int height,
const webrtc::VideoEncoderConfig& encoder_config) override;
@ -53,6 +47,7 @@ class EncoderStreamFactory
std::vector<webrtc::VideoStream>
CreateSimulcastOrConferenceModeScreenshareStreams(
const webrtc::FieldTrialsView& trials,
int width,
int height,
const webrtc::VideoEncoderConfig& encoder_config,
@ -69,8 +64,6 @@ class EncoderStreamFactory
// Allows a screenshare specific configuration, which enables temporal
// layering and various settings.
const bool conference_mode_;
const webrtc::FieldTrialBasedConfig fallback_trials_;
const webrtc::FieldTrialsView& trials_;
const int encoder_info_requested_resolution_alignment_;
const absl::optional<webrtc::VideoSourceRestrictions> restrictions_;
};

View file

@ -11,15 +11,17 @@
#include "video/config/encoder_stream_factory.h"
#include "call/adaptation/video_source_restrictions.h"
#include "test/explicit_key_value_config.h"
#include "test/gtest.h"
namespace webrtc {
using cricket::EncoderStreamFactory;
constexpr int kMaxQp = 48;
namespace {
using ::cricket::EncoderStreamFactory;
using test::ExplicitKeyValueConfig;
constexpr int kMaxQp = 48;
std::vector<Resolution> GetStreamResolutions(
const std::vector<VideoStream>& streams) {
std::vector<Resolution> res;
@ -41,6 +43,7 @@ VideoStream LayerWithRequestedResolution(Resolution res) {
} // namespace
TEST(EncoderStreamFactory, SinglecastRequestedResolution) {
ExplicitKeyValueConfig field_trials("");
VideoEncoder::EncoderInfo encoder_info;
auto factory = rtc::make_ref_counted<EncoderStreamFactory>(
"VP8", kMaxQp,
@ -50,7 +53,8 @@ TEST(EncoderStreamFactory, SinglecastRequestedResolution) {
encoder_config.number_of_streams = 1;
encoder_config.simulcast_layers.push_back(
LayerWithRequestedResolution({.width = 640, .height = 360}));
auto streams = factory->CreateEncoderStreams(1280, 720, encoder_config);
auto streams =
factory->CreateEncoderStreams(field_trials, 1280, 720, encoder_config);
EXPECT_EQ(streams[0].requested_resolution,
(Resolution{.width = 640, .height = 360}));
EXPECT_EQ(GetStreamResolutions(streams), (std::vector<Resolution>{
@ -59,6 +63,7 @@ TEST(EncoderStreamFactory, SinglecastRequestedResolution) {
}
TEST(EncoderStreamFactory, SinglecastRequestedResolutionWithAdaptation) {
ExplicitKeyValueConfig field_trials("");
VideoSourceRestrictions restrictions(
/* max_pixels_per_frame= */ (320 * 320),
/* target_pixels_per_frame= */ absl::nullopt,
@ -72,7 +77,8 @@ TEST(EncoderStreamFactory, SinglecastRequestedResolutionWithAdaptation) {
encoder_config.number_of_streams = 1;
encoder_config.simulcast_layers.push_back(
LayerWithRequestedResolution({.width = 640, .height = 360}));
auto streams = factory->CreateEncoderStreams(1280, 720, encoder_config);
auto streams =
factory->CreateEncoderStreams(field_trials, 1280, 720, encoder_config);
EXPECT_EQ(streams[0].requested_resolution,
(Resolution{.width = 640, .height = 360}));
EXPECT_EQ(GetStreamResolutions(streams), (std::vector<Resolution>{

View file

@ -17,6 +17,7 @@
#include <vector>
#include "absl/types/optional.h"
#include "api/field_trials_view.h"
#include "api/scoped_refptr.h"
#include "api/video/resolution.h"
#include "api/video_codecs/scalability_mode.h"
@ -145,6 +146,7 @@ class VideoEncoderConfig {
// The size of the vector may not be larger than
// `encoder_config.number_of_streams`.
virtual std::vector<VideoStream> CreateEncoderStreams(
const FieldTrialsView& field_trials,
int frame_width,
int frame_height,
const VideoEncoderConfig& encoder_config) = 0;

View file

@ -142,6 +142,7 @@ void RtpRtcpEndToEndTest::TestRtpStatePreservation(
private:
std::vector<VideoStream> CreateEncoderStreams(
const FieldTrialsView& /*field_trials*/,
int frame_width,
int frame_height,
const VideoEncoderConfig& encoder_config) override {

View file

@ -362,15 +362,16 @@ void Loopback() {
std::vector<std::string> SL_descriptors;
SL_descriptors.push_back(SL0());
SL_descriptors.push_back(SL1());
VideoQualityTest::FillScalabilitySettings(
VideoQualityTest fixture(nullptr);
fixture.FillScalabilitySettings(
&params, 0, stream_descriptors, NumStreams(), SelectedStream(),
NumSpatialLayers(), SelectedSL(), InterLayerPred(), SL_descriptors);
auto fixture = std::make_unique<VideoQualityTest>(nullptr);
if (DurationSecs()) {
fixture->RunWithAnalyzer(params);
fixture.RunWithAnalyzer(params);
} else {
fixture->RunWithRenderers(params);
fixture.RunWithRenderers(params);
}
}

View file

@ -664,13 +664,15 @@ void Loopback() {
params.ss[screenshare_idx].infer_streams = true;
}
VideoQualityTest fixture(nullptr);
std::vector<std::string> stream_descriptors;
stream_descriptors.push_back(ScreenshareStream0());
stream_descriptors.push_back(ScreenshareStream1());
std::vector<std::string> SL_descriptors;
SL_descriptors.push_back(ScreenshareSL0());
SL_descriptors.push_back(ScreenshareSL1());
VideoQualityTest::FillScalabilitySettings(
fixture.FillScalabilitySettings(
&params, screenshare_idx, stream_descriptors, ScreenshareNumStreams(),
ScreenshareSelectedStream(), ScreenshareNumSpatialLayers(),
ScreenshareSelectedSL(), ScreenshareInterLayerPred(), SL_descriptors);
@ -681,16 +683,15 @@ void Loopback() {
SL_descriptors.clear();
SL_descriptors.push_back(VideoSL0());
SL_descriptors.push_back(VideoSL1());
VideoQualityTest::FillScalabilitySettings(
&params, camera_idx, stream_descriptors, VideoNumStreams(),
VideoSelectedStream(), VideoNumSpatialLayers(), VideoSelectedSL(),
VideoInterLayerPred(), SL_descriptors);
fixture.FillScalabilitySettings(&params, camera_idx, stream_descriptors,
VideoNumStreams(), VideoSelectedStream(),
VideoNumSpatialLayers(), VideoSelectedSL(),
VideoInterLayerPred(), SL_descriptors);
auto fixture = std::make_unique<VideoQualityTest>(nullptr);
if (DurationSecs()) {
fixture->RunWithAnalyzer(params);
fixture.RunWithAnalyzer(params);
} else {
fixture->RunWithRenderers(params);
fixture.RunWithRenderers(params);
}
}
} // namespace webrtc

View file

@ -418,15 +418,16 @@ void Loopback() {
SL_descriptors.push_back(SL0());
SL_descriptors.push_back(SL1());
SL_descriptors.push_back(SL2());
VideoQualityTest::FillScalabilitySettings(
VideoQualityTest fixture(nullptr);
fixture.FillScalabilitySettings(
&params, 0, stream_descriptors, NumStreams(), SelectedStream(),
NumSpatialLayers(), SelectedSL(), InterLayerPred(), SL_descriptors);
auto fixture = std::make_unique<VideoQualityTest>(nullptr);
if (DurationSecs()) {
fixture->RunWithAnalyzer(params);
fixture.RunWithAnalyzer(params);
} else {
fixture->RunWithRenderers(params);
fixture.RunWithRenderers(params);
}
}

View file

@ -106,6 +106,7 @@ class VideoStreamFactory
private:
std::vector<VideoStream> CreateEncoderStreams(
const FieldTrialsView& /*field_trials*/,
int frame_width,
int frame_height,
const VideoEncoderConfig& encoder_config) override {
@ -591,7 +592,6 @@ VideoStream VideoQualityTest::DefaultThumbnailStream() {
return stream;
}
// Static.
void VideoQualityTest::FillScalabilitySettings(
Params* params,
size_t video_idx,
@ -624,8 +624,8 @@ void VideoQualityTest::FillScalabilitySettings(
params->screenshare[video_idx].enabled, true, encoder_info);
params->ss[video_idx].streams =
encoder_config.video_stream_factory->CreateEncoderStreams(
params->video[video_idx].width, params->video[video_idx].height,
encoder_config);
env().field_trials(), params->video[video_idx].width,
params->video[video_idx].height, encoder_config);
} else {
// Read VideoStream and SpatialLayer elements from a list of comma separated
// lists. To use a default value for an element, use -1 or leave empty.

View file

@ -49,7 +49,7 @@ class VideoQualityTest : public test::CallTest,
return payload_type_map_;
}
static void FillScalabilitySettings(
void FillScalabilitySettings(
Params* params,
size_t video_idx,
const std::vector<std::string>& stream_descriptors,

View file

@ -2606,6 +2606,7 @@ TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
private:
std::vector<VideoStream> CreateEncoderStreams(
const FieldTrialsView& /*field_trials*/,
int frame_width,
int frame_height,
const VideoEncoderConfig& encoder_config) override {

View file

@ -1018,19 +1018,19 @@ void VideoStreamEncoder::ReconfigureEncoder() {
if (encoder_config_.video_stream_factory) {
// Note: only tests set their own EncoderStreamFactory...
streams = encoder_config_.video_stream_factory->CreateEncoderStreams(
last_frame_info_->width, last_frame_info_->height, encoder_config_);
env_.field_trials(), last_frame_info_->width, last_frame_info_->height,
encoder_config_);
} else {
rtc::scoped_refptr<VideoEncoderConfig::VideoStreamFactoryInterface>
factory = rtc::make_ref_counted<cricket::EncoderStreamFactory>(
encoder_config_.video_format.name, encoder_config_.max_qp,
encoder_config_.content_type ==
webrtc::VideoEncoderConfig::ContentType::kScreen,
encoder_config_.legacy_conference_mode, encoder_->GetEncoderInfo(),
MergeRestrictions({latest_restrictions_, animate_restrictions_}),
&env_.field_trials());
auto factory = rtc::make_ref_counted<cricket::EncoderStreamFactory>(
encoder_config_.video_format.name, encoder_config_.max_qp,
encoder_config_.content_type ==
webrtc::VideoEncoderConfig::ContentType::kScreen,
encoder_config_.legacy_conference_mode, encoder_->GetEncoderInfo(),
MergeRestrictions({latest_restrictions_, animate_restrictions_}));
streams = factory->CreateEncoderStreams(
last_frame_info_->width, last_frame_info_->height, encoder_config_);
env_.field_trials(), last_frame_info_->width, last_frame_info_->height,
encoder_config_);
}
// TODO(webrtc:14451) : Move AlignmentAdjuster into EncoderStreamFactory

View file

@ -516,6 +516,7 @@ class CroppingVideoStreamFactory
private:
std::vector<VideoStream> CreateEncoderStreams(
const FieldTrialsView& /*field_trials*/,
int frame_width,
int frame_height,
const VideoEncoderConfig& encoder_config) override {