diff --git a/media/BUILD.gn b/media/BUILD.gn index bf585acaa3..ab2f8f2c9c 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -292,6 +292,7 @@ rtc_static_library("rtc_audio_video") { "../rtc_base:rtc_task_queue", "../rtc_base:stringutils", "../rtc_base/experiments:audio_allocation_settings", + "../rtc_base/experiments:experimental_screenshare_settings", "../rtc_base/experiments:field_trial_parser", "../rtc_base/experiments:normalize_simulcast_size_experiment", "../rtc_base/system:rtc_export", diff --git a/media/engine/simulcast.cc b/media/engine/simulcast.cc index afcd162f12..5b62e52dbc 100644 --- a/media/engine/simulcast.cc +++ b/media/engine/simulcast.cc @@ -23,6 +23,7 @@ #include "modules/video_coding/utility/simulcast_rate_allocator.h" #include "rtc_base/arraysize.h" #include "rtc_base/checks.h" +#include "rtc_base/experiments/experimental_screenshare_settings.h" #include "rtc_base/experiments/normalize_simulcast_size_experiment.h" #include "rtc_base/logging.h" #include "system_wrappers/include/field_trial.h" @@ -315,6 +316,13 @@ std::vector GetScreenshareLayers( // more normal layout, with the regular 3 temporal layer pattern and no fps // restrictions. The base simulcast layer will still use legacy setup. if (num_simulcast_layers == kMaxScreenshareSimulcastLayers) { + auto experimental_settings = + webrtc::ExperimentalScreenshareSettings::ParseFromFieldTrials(); + if (temporal_layers_supported && + experimental_settings.BaseLayerMaxBitrate().has_value()) { + layers[0].max_bitrate_bps = *experimental_settings.BaseLayerMaxBitrate(); + } + // Add optional upper simulcast layer. const int num_temporal_layers = DefaultNumberOfTemporalLayers(1, true); int max_bitrate_bps; @@ -330,7 +338,8 @@ std::vector GetScreenshareLayers( webrtc::field_trial::IsEnabled( kUseBaseHeavyVP8TL3RateAllocationFieldTrial)) { // Experimental temporal layer mode used, use increased max bitrate. - max_bitrate_bps = kScreenshareHighStreamMaxBitrateBps; + max_bitrate_bps = experimental_settings.TopLayerMaxBitrate().value_or( + kScreenshareHighStreamMaxBitrateBps); using_boosted_bitrate = true; } else { // Keep current bitrates with default 3tl/8 frame settings. diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 1e3aadf106..33c893d9f4 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -260,6 +260,7 @@ rtc_source_set("video_coding_utility") { "../../rtc_base:rtc_base_approved", "../../rtc_base:rtc_numerics", "../../rtc_base:rtc_task_queue", + "../../rtc_base/experiments:experimental_screenshare_settings", "../../rtc_base/experiments:quality_scaler_settings", "../../rtc_base/experiments:quality_scaling_experiment", "../../rtc_base/experiments:rate_control_settings", @@ -384,6 +385,7 @@ rtc_static_library("webrtc_vp8") { "../../rtc_base:rtc_base_approved", "../../rtc_base:rtc_numerics", "../../rtc_base/experiments:cpu_speed_experiment", + "../../rtc_base/experiments:experimental_screenshare_settings", "../../rtc_base/experiments:field_trial_parser", "../../rtc_base/experiments:rate_control_settings", "../../system_wrappers:field_trial", diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index 892d6ffe53..dcda30db71 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -35,6 +35,7 @@ #include "modules/video_coding/utility/simulcast_rate_allocator.h" #include "modules/video_coding/utility/simulcast_utility.h" #include "rtc_base/checks.h" +#include "rtc_base/experiments/experimental_screenshare_settings.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/field_trial_units.h" #include "rtc_base/logging.h" @@ -280,6 +281,8 @@ LibvpxVp8Encoder::LibvpxVp8Encoder( : libvpx_(std::move(interface)), experimental_cpu_speed_config_arm_(CpuSpeedExperiment::GetConfigs()), rate_control_settings_(RateControlSettings::ParseFromFieldTrials()), + screenshare_max_qp_( + ExperimentalScreenshareSettings::ParseFromFieldTrials().MaxQp()), encoded_complete_callback_(nullptr), inited_(false), timestamp_(0), @@ -584,6 +587,9 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, qp_max_ = std::max(rate_control_settings_.LibvpxVp8QpMax().value(), static_cast(vpx_configs_[0].rc_min_quantizer)); } + if (codec_.mode == VideoCodecMode::kScreensharing && screenshare_max_qp_) { + qp_max_ = *screenshare_max_qp_; + } vpx_configs_[0].rc_max_quantizer = qp_max_; vpx_configs_[0].rc_undershoot_pct = 100; vpx_configs_[0].rc_overshoot_pct = 15; diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h index bfe174b41b..675d386456 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h @@ -103,6 +103,7 @@ class LibvpxVp8Encoder : public VideoEncoder { const absl::optional> experimental_cpu_speed_config_arm_; const RateControlSettings rate_control_settings_; + const absl::optional screenshare_max_qp_; EncodedImageCallback* encoded_complete_callback_; VideoCodec codec_; diff --git a/modules/video_coding/utility/simulcast_utility.cc b/modules/video_coding/utility/simulcast_utility.cc index ee2ea51451..3c3e235896 100644 --- a/modules/video_coding/utility/simulcast_utility.cc +++ b/modules/video_coding/utility/simulcast_utility.cc @@ -14,6 +14,7 @@ #include #include "rtc_base/checks.h" +#include "rtc_base/experiments/experimental_screenshare_settings.h" namespace webrtc { @@ -88,6 +89,15 @@ bool SimulcastUtility::IsConferenceModeScreenshare(const VideoCodec& codec) { NumberOfTemporalLayers(codec, 0) != 2) { return false; } + + if (codec.numberOfSimulcastStreams > 0 && + ExperimentalScreenshareSettings::ParseFromFieldTrials() + .DefaultTlInBaseLayer() + .value_or(false)) { + // Don't use ScreenshareLayers for base layer, regardless of flags. + return false; + } + // Fixed default bitrates for legacy screenshare layers mode. return (codec.numberOfSimulcastStreams == 0 && codec.maxBitrate == 1000) || (codec.numberOfSimulcastStreams >= 1 && diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn index 849e740ce6..daffb22a2f 100644 --- a/rtc_base/experiments/BUILD.gn +++ b/rtc_base/experiments/BUILD.gn @@ -179,6 +179,19 @@ rtc_static_library("keyframe_interval_settings_experiment") { ] } +rtc_static_library("experimental_screenshare_settings") { + sources = [ + "experimental_screenshare_settings.cc", + "experimental_screenshare_settings.h", + ] + deps = [ + ":field_trial_parser", + "../../api/transport:field_trial_based_config", + "../../api/transport:webrtc_key_value_config", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + if (rtc_include_tests) { rtc_source_set("experiments_unittests") { testonly = true diff --git a/rtc_base/experiments/experimental_screenshare_settings.cc b/rtc_base/experiments/experimental_screenshare_settings.cc new file mode 100644 index 0000000000..ac5840a5ed --- /dev/null +++ b/rtc_base/experiments/experimental_screenshare_settings.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019 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 "rtc_base/experiments/experimental_screenshare_settings.h" + +#include "api/transport/field_trial_based_config.h" + +namespace webrtc { + +namespace { +constexpr char kFieldTrialName[] = "WebRTC-ExperimentalScreenshareSettings"; +} // namespace + +ExperimentalScreenshareSettings::ExperimentalScreenshareSettings( + const WebRtcKeyValueConfig* key_value_config) + : max_qp_("max_qp"), + default_tl_in_base_layer_("default_tl_in_base_layer"), + base_layer_max_bitrate_("base_layer_max_bitrate"), + top_layer_max_bitrate("top_layer_max_bitrate") { + ParseFieldTrial({&max_qp_, &default_tl_in_base_layer_, + &base_layer_max_bitrate_, &top_layer_max_bitrate}, + key_value_config->Lookup(kFieldTrialName)); +} + +ExperimentalScreenshareSettings +ExperimentalScreenshareSettings::ParseFromFieldTrials() { + FieldTrialBasedConfig field_trial_config; + return ExperimentalScreenshareSettings(&field_trial_config); +} + +absl::optional ExperimentalScreenshareSettings::MaxQp() const { + return max_qp_.GetOptional(); +} + +absl::optional ExperimentalScreenshareSettings::DefaultTlInBaseLayer() + const { + return default_tl_in_base_layer_.GetOptional(); +} + +absl::optional ExperimentalScreenshareSettings::BaseLayerMaxBitrate() + const { + return base_layer_max_bitrate_.GetOptional(); +} + +absl::optional ExperimentalScreenshareSettings::TopLayerMaxBitrate() + const { + return top_layer_max_bitrate.GetOptional(); +} + +} // namespace webrtc diff --git a/rtc_base/experiments/experimental_screenshare_settings.h b/rtc_base/experiments/experimental_screenshare_settings.h new file mode 100644 index 0000000000..8887a3e3c3 --- /dev/null +++ b/rtc_base/experiments/experimental_screenshare_settings.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef RTC_BASE_EXPERIMENTS_EXPERIMENTAL_SCREENSHARE_SETTINGS_H_ +#define RTC_BASE_EXPERIMENTS_EXPERIMENTAL_SCREENSHARE_SETTINGS_H_ + +#include "absl/types/optional.h" +#include "api/transport/webrtc_key_value_config.h" +#include "rtc_base/experiments/field_trial_parser.h" + +namespace webrtc { + +class ExperimentalScreenshareSettings { + public: + static ExperimentalScreenshareSettings ParseFromFieldTrials(); + explicit ExperimentalScreenshareSettings( + const WebRtcKeyValueConfig* key_value_config); + + absl::optional MaxQp() const; + absl::optional DefaultTlInBaseLayer() const; + absl::optional BaseLayerMaxBitrate() const; + absl::optional TopLayerMaxBitrate() const; + + private: + FieldTrialOptional max_qp_; + FieldTrialOptional default_tl_in_base_layer_; + FieldTrialOptional base_layer_max_bitrate_; + FieldTrialOptional top_layer_max_bitrate; +}; + +} // namespace webrtc + +#endif // RTC_BASE_EXPERIMENTS_EXPERIMENTAL_SCREENSHARE_SETTINGS_H_