diff --git a/media/BUILD.gn b/media/BUILD.gn index 3042ac2a86..94c85e9e6c 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -219,6 +219,7 @@ rtc_static_library("rtc_internal_video_codecs") { "../system_wrappers", "../system_wrappers:field_trial_api", "../system_wrappers:metrics_api", + "//third_party/abseil-cpp/absl/types:optional", "//third_party/libyuv", ] } diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc index d58a7a7d2a..4ab83a0940 100644 --- a/media/engine/simulcast_encoder_adapter.cc +++ b/media/engine/simulcast_encoder_adapter.cc @@ -11,6 +11,8 @@ #include "media/engine/simulcast_encoder_adapter.h" #include +#include +#include #include "api/video/i420_buffer.h" #include "api/video/video_bitrate_allocation.h" @@ -19,6 +21,7 @@ #include "modules/video_coding/utility/simulcast_rate_allocator.h" #include "rtc_base/checks.h" #include "system_wrappers/include/clock.h" +#include "system_wrappers/include/field_trial.h" #include "third_party/libyuv/include/libyuv/scale.h" namespace { @@ -28,6 +31,17 @@ const unsigned int kDefaultMaxQp = 56; // Max qp for lowest spatial resolution when doing simulcast. const unsigned int kLowestResMaxQp = 45; +absl::optional GetScreenshareBoostedQpValue() { + std::string experiment_group = + webrtc::field_trial::FindFullName("WebRTC-BoostedScreenshareQp"); + unsigned int qp; + if (sscanf(experiment_group.c_str(), "%u", &qp) != 1) + return absl::nullopt; + qp = std::min(qp, 63u); + qp = std::max(qp, 1u); + return qp; +} + uint32_t SumStreamMaxBitrate(int streams, const webrtc::VideoCodec& codec) { uint32_t bitrate_sum = 0; for (int i = 0; i < streams; ++i) { @@ -113,7 +127,8 @@ SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory, factory_(factory), video_format_(format), encoded_complete_callback_(nullptr), - implementation_name_("SimulcastEncoderAdapter") { + implementation_name_("SimulcastEncoderAdapter"), + experimental_boosted_screenshare_qp_(GetScreenshareBoostedQpValue()) { RTC_DCHECK(factory_); // The adapter is typically created on the worker thread, but operated on @@ -463,9 +478,15 @@ void SimulcastEncoderAdapter::PopulateStreamCodec( stream_codec->qpMax = inst.simulcastStream[stream_index].qpMax; // Settings that are based on stream/resolution. const bool lowest_resolution_stream = (stream_index == 0); - if (lowest_resolution_stream && inst.mode != VideoCodecMode::kScreensharing) { + if (lowest_resolution_stream) { // Settings for lowest spatial resolutions. - stream_codec->qpMax = kLowestResMaxQp; + if (inst.mode == VideoCodecMode::kScreensharing) { + if (experimental_boosted_screenshare_qp_) { + stream_codec->qpMax = *experimental_boosted_screenshare_qp_; + } + } else { + stream_codec->qpMax = kLowestResMaxQp; + } } if (inst.codecType == webrtc::kVideoCodecVP8) { stream_codec->VP8()->numberOfTemporalLayers = diff --git a/media/engine/simulcast_encoder_adapter.h b/media/engine/simulcast_encoder_adapter.h index af830d7ab8..52643aa79b 100644 --- a/media/engine/simulcast_encoder_adapter.h +++ b/media/engine/simulcast_encoder_adapter.h @@ -18,6 +18,7 @@ #include #include +#include "absl/types/optional.h" #include "media/engine/webrtcvideoencoderfactory.h" #include "modules/video_coding/include/video_codec_interface.h" #include "rtc_base/atomicops.h" @@ -87,11 +88,11 @@ class SimulcastEncoderAdapter : public VideoEncoder { }; // Populate the codec settings for each simulcast stream. - static void PopulateStreamCodec(const webrtc::VideoCodec& inst, - int stream_index, - uint32_t start_bitrate_kbps, - bool highest_resolution_stream, - webrtc::VideoCodec* stream_codec); + void PopulateStreamCodec(const webrtc::VideoCodec& inst, + int stream_index, + uint32_t start_bitrate_kbps, + bool highest_resolution_stream, + webrtc::VideoCodec* stream_codec); bool Initialized() const; @@ -111,6 +112,8 @@ class SimulcastEncoderAdapter : public VideoEncoder { // Store encoders in between calls to Release and InitEncode, so they don't // have to be recreated. Remaining encoders are destroyed by the destructor. std::stack> stored_encoders_; + + const absl::optional experimental_boosted_screenshare_qp_; }; } // namespace webrtc