From 52ea2c3d2a9c35f5744d0d3eadbae75d8506eb0f Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Tue, 17 Sep 2024 14:58:25 +0200 Subject: [PATCH] Propagate FieldTrialsView to query WebRTC-StableTargetRate field trial MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:42220378 Change-Id: Ie2a2c3eccc36c98f09176eb6f4c5f06ded9f516f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/362701 Reviewed-by: Rasmus Brandt Commit-Queue: Danil Chapovalov Reviewed-by: Erik Språng Cr-Commit-Position: refs/heads/main@{#43036} --- ...builtin_video_bitrate_allocator_factory.cc | 2 +- modules/video_coding/BUILD.gn | 14 +++- .../codecs/vp9/libvpx_vp9_encoder.cc | 47 +++++++++--- .../codecs/vp9/libvpx_vp9_encoder.h | 18 ++++- modules/video_coding/svc/BUILD.gn | 17 ++++- .../video_coding/svc/svc_rate_allocator.cc | 17 ++++- modules/video_coding/svc/svc_rate_allocator.h | 7 +- .../svc/svc_rate_allocator_unittest.cc | 75 +++++++++++++------ .../utility/simulcast_rate_allocator.cc | 12 ++- rtc_base/experiments/BUILD.gn | 1 - .../stable_target_rate_experiment.cc | 25 ++----- .../stable_target_rate_experiment.h | 9 +-- .../stable_target_rate_experiment_unittest.cc | 24 +++--- test/fuzzers/BUILD.gn | 8 ++ test/fuzzers/vp9_encoder_references_fuzzer.cc | 20 ++++- 15 files changed, 203 insertions(+), 93 deletions(-) diff --git a/api/video/builtin_video_bitrate_allocator_factory.cc b/api/video/builtin_video_bitrate_allocator_factory.cc index e7ccada9d3..7b95c2aab9 100644 --- a/api/video/builtin_video_bitrate_allocator_factory.cc +++ b/api/video/builtin_video_bitrate_allocator_factory.cc @@ -38,7 +38,7 @@ class BuiltinVideoBitrateAllocatorFactory if ((codec.codecType == kVideoCodecAV1 || codec.codecType == kVideoCodecVP9) && codec.numberOfSimulcastStreams <= 1) { - return std::make_unique(codec); + return std::make_unique(codec, env.field_trials()); } return std::make_unique(env, codec); } diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 396255b135..0aba776cc2 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -408,6 +408,7 @@ rtc_library("video_coding_utility") { "../../api:scoped_refptr", "../../api:sequence_checker", "../../api/environment", + "../../api/units:data_rate", "../../api/units:time_delta", "../../api/video:encoded_frame", "../../api/video:encoded_image", @@ -654,17 +655,25 @@ rtc_library("webrtc_vp9") { ] deps = [ + ":codec_globals_headers", ":video_codec_interface", ":video_coding_utility", ":webrtc_libvpx_interface", - ":webrtc_vp9_helpers", + "../../api:array_view", "../../api:fec_controller_api", "../../api:field_trials_view", "../../api:refcountedbase", "../../api:scoped_refptr", "../../api/environment", + "../../api/transport/rtp:dependency_descriptor", + "../../api/video:encoded_image", + "../../api/video:render_resolution", + "../../api/video:video_bitrate_allocation", + "../../api/video:video_bitrate_allocator", + "../../api/video:video_codec_constants", "../../api/video:video_frame", "../../api/video:video_frame_i010", + "../../api/video:video_frame_type", "../../api/video:video_rtp_headers", "../../api/video_codecs:scalability_mode", "../../api/video_codecs:video_codecs_api", @@ -673,8 +682,8 @@ rtc_library("webrtc_vp9") { "../../rtc_base:checks", "../../rtc_base:event_tracer", "../../rtc_base:logging", + "../../rtc_base:safe_conversions", "../../rtc_base:stringutils", - "../../rtc_base:timeutils", "../../rtc_base/containers:flat_map", "../../rtc_base/experiments:encoder_info_settings", "../../rtc_base/experiments:field_trial_parser", @@ -689,7 +698,6 @@ rtc_library("webrtc_vp9") { "//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/base:nullability", "//third_party/abseil-cpp/absl/container:inlined_vector", - "//third_party/abseil-cpp/absl/memory", "//third_party/abseil-cpp/absl/strings", "//third_party/libyuv", ] diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc index 96d23c6c17..c2a17c59d4 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc @@ -14,39 +14,63 @@ #ifdef RTC_ENABLE_VP9 #include -#include +#include +#include +#include +#include #include #include #include #include "absl/algorithm/container.h" -#include "absl/memory/memory.h" -#include "absl/strings/match.h" -#include "api/video/color_space.h" +#include "absl/container/inlined_vector.h" +#include "api/array_view.h" +#include "api/environment/environment.h" +#include "api/fec_controller_override.h" +#include "api/field_trials_view.h" +#include "api/scoped_refptr.h" +#include "api/transport/rtp/dependency_descriptor.h" +#include "api/video/encoded_image.h" #include "api/video/i010_buffer.h" +#include "api/video/render_resolution.h" +#include "api/video/video_bitrate_allocation.h" +#include "api/video/video_bitrate_allocator.h" +#include "api/video/video_codec_constants.h" +#include "api/video/video_codec_type.h" +#include "api/video/video_frame.h" +#include "api/video/video_frame_buffer.h" +#include "api/video/video_frame_type.h" #include "api/video_codecs/scalability_mode.h" -#include "common_video/include/video_frame_buffer.h" -#include "common_video/libyuv/include/webrtc_libyuv.h" +#include "api/video_codecs/video_codec.h" +#include "api/video_codecs/video_encoder.h" +#include "api/video_codecs/vp9_profile.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "modules/video_coding/codecs/interface/common_constants.h" +#include "modules/video_coding/codecs/interface/libvpx_interface.h" +#include "modules/video_coding/codecs/vp9/include/vp9.h" +#include "modules/video_coding/codecs/vp9/include/vp9_globals.h" #include "modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h" +#include "modules/video_coding/include/video_codec_interface.h" +#include "modules/video_coding/include/video_error_codes.h" #include "modules/video_coding/svc/create_scalability_structure.h" #include "modules/video_coding/svc/scalability_mode_util.h" #include "modules/video_coding/svc/scalable_video_controller.h" #include "modules/video_coding/svc/scalable_video_controller_no_layering.h" #include "modules/video_coding/svc/svc_rate_allocator.h" +#include "modules/video_coding/utility/framerate_controller_deprecated.h" #include "modules/video_coding/utility/simulcast_utility.h" -#include "modules/video_coding/utility/vp9_uncompressed_header_parser.h" #include "rtc_base/checks.h" +#include "rtc_base/containers/flat_map.h" #include "rtc_base/experiments/field_trial_list.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/rate_control_settings.h" #include "rtc_base/logging.h" +#include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/strings/string_builder.h" -#include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" -#include "third_party/libyuv/include/libyuv/convert.h" #include "vpx/vp8cx.h" #include "vpx/vpx_encoder.h" +#include "vpx/vpx_image.h" #if (defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64)) && \ (defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)) @@ -229,7 +253,8 @@ void LibvpxVp9Encoder::EncoderOutputCodedPacketCallback(vpx_codec_cx_pkt* pkt, LibvpxVp9Encoder::LibvpxVp9Encoder(const Environment& env, Vp9EncoderSettings settings, std::unique_ptr interface) - : libvpx_(std::move(interface)), + : env_(env), + libvpx_(std::move(interface)), encoded_image_(), encoded_complete_callback_(nullptr), profile_(settings.profile), @@ -793,7 +818,7 @@ int LibvpxVp9Encoder::InitAndSetControlSettings() { RTC_DCHECK_EQ(performance_flags_by_spatial_index_.size(), static_cast(num_spatial_layers_)); - SvcRateAllocator init_allocator(codec_); + SvcRateAllocator init_allocator(codec_, env_.field_trials()); current_bitrate_allocation_ = init_allocator.Allocate(VideoBitrateAllocationParameters( codec_.startBitrate * 1000, codec_.maxFramerate)); diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h index f08d452346..0073380520 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h @@ -15,6 +15,8 @@ #ifdef RTC_ENABLE_VP9 #include +#include +#include #include #include #include @@ -22,20 +24,29 @@ #include "api/environment/environment.h" #include "api/fec_controller_override.h" #include "api/field_trials_view.h" +#include "api/scoped_refptr.h" +#include "api/video/encoded_image.h" +#include "api/video/video_bitrate_allocation.h" +#include "api/video/video_frame.h" +#include "api/video/video_frame_buffer.h" +#include "api/video/video_frame_type.h" #include "api/video_codecs/scalability_mode.h" +#include "api/video_codecs/video_codec.h" #include "api/video_codecs/video_encoder.h" #include "api/video_codecs/vp9_profile.h" -#include "common_video/include/video_frame_buffer_pool.h" #include "modules/video_coding/codecs/interface/libvpx_interface.h" #include "modules/video_coding/codecs/vp9/include/vp9.h" -#include "modules/video_coding/codecs/vp9/svc_config.h" -#include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h" +#include "modules/video_coding/codecs/vp9/include/vp9_globals.h" +#include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/svc/scalable_video_controller.h" #include "modules/video_coding/svc/simulcast_to_svc_converter.h" #include "modules/video_coding/utility/framerate_controller_deprecated.h" #include "rtc_base/containers/flat_map.h" #include "rtc_base/experiments/encoder_info_settings.h" #include "vpx/vp8cx.h" +#include "vpx/vpx_codec.h" +#include "vpx/vpx_encoder.h" +#include "vpx/vpx_image.h" namespace webrtc { @@ -120,6 +131,7 @@ class LibvpxVp9Encoder : public VideoEncoder { rtc::scoped_refptr PrepareBufferForProfile0( rtc::scoped_refptr buffer); + const Environment env_; const std::unique_ptr libvpx_; EncodedImage encoded_image_; CodecSpecificInfo codec_specific_; diff --git a/modules/video_coding/svc/BUILD.gn b/modules/video_coding/svc/BUILD.gn index 0246b10590..f306dea59a 100644 --- a/modules/video_coding/svc/BUILD.gn +++ b/modules/video_coding/svc/BUILD.gn @@ -70,9 +70,15 @@ rtc_source_set("svc_rate_allocator") { ] deps = [ ":scalability_structures", + ":scalable_video_controller", + "../../../api:field_trials_view", + "../../../api/transport:field_trial_based_config", + "../../../api/units:data_rate", "../../../api/video:video_bitrate_allocation", "../../../api/video:video_bitrate_allocator", "../../../api/video:video_codec_constants", + "../../../api/video:video_frame", + "../../../api/video_codecs:scalability_mode", "../../../api/video_codecs:video_codecs_api", "../../../rtc_base:checks", "../../../rtc_base/experiments:stable_target_rate_experiment", @@ -134,11 +140,18 @@ if (rtc_include_tests) { deps = [ ":svc_rate_allocator", "..:webrtc_vp9_helpers", + "../../../api/units:data_rate", + "../../../api/video:video_bitrate_allocation", + "../../../api/video:video_bitrate_allocator", + "../../../api/video:video_codec_constants", "../../../api/video:video_frame", - "../../../modules/video_coding/codecs/av1:av1_svc_config", + "../../../api/video_codecs:scalability_mode", + "../../../api/video_codecs:video_codecs_api", "../../../rtc_base:checks", - "../../../test:field_trial", + "../../../test:explicit_key_value_config", "../../../test:test_support", + "../codecs/av1:av1_svc_config", + "//third_party/abseil-cpp/absl/container:inlined_vector", ] } diff --git a/modules/video_coding/svc/svc_rate_allocator.cc b/modules/video_coding/svc/svc_rate_allocator.cc index e637408a38..06fd1d928e 100644 --- a/modules/video_coding/svc/svc_rate_allocator.cc +++ b/modules/video_coding/svc/svc_rate_allocator.cc @@ -14,10 +14,21 @@ #include #include #include +#include #include #include "absl/container/inlined_vector.h" +#include "api/field_trials_view.h" +#include "api/transport/field_trial_based_config.h" +#include "api/units/data_rate.h" +#include "api/video/video_bitrate_allocation.h" +#include "api/video/video_bitrate_allocator.h" +#include "api/video/video_codec_constants.h" +#include "api/video/video_codec_type.h" +#include "api/video_codecs/scalability_mode.h" +#include "api/video_codecs/video_codec.h" #include "modules/video_coding/svc/create_scalability_structure.h" +#include "modules/video_coding/svc/scalable_video_controller.h" #include "rtc_base/checks.h" namespace webrtc { @@ -236,9 +247,13 @@ SvcRateAllocator::NumLayers SvcRateAllocator::GetNumLayers( } SvcRateAllocator::SvcRateAllocator(const VideoCodec& codec) + : SvcRateAllocator(codec, FieldTrialBasedConfig()) {} + +SvcRateAllocator::SvcRateAllocator(const VideoCodec& codec, + const FieldTrialsView& field_trials) : codec_(codec), num_layers_(GetNumLayers(codec)), - experiment_settings_(StableTargetRateExperiment::ParseFromFieldTrials()), + experiment_settings_(field_trials), cumulative_layer_start_bitrates_(GetLayerStartBitrates(codec)), last_active_layer_count_(0) { RTC_DCHECK_GT(num_layers_.spatial, 0); diff --git a/modules/video_coding/svc/svc_rate_allocator.h b/modules/video_coding/svc/svc_rate_allocator.h index f64d92bd38..afd71ce1d8 100644 --- a/modules/video_coding/svc/svc_rate_allocator.h +++ b/modules/video_coding/svc/svc_rate_allocator.h @@ -12,11 +12,12 @@ #define MODULES_VIDEO_CODING_SVC_SVC_RATE_ALLOCATOR_H_ #include -#include #include #include "absl/container/inlined_vector.h" +#include "api/field_trials_view.h" +#include "api/units/data_rate.h" #include "api/video/video_bitrate_allocation.h" #include "api/video/video_bitrate_allocator.h" #include "api/video/video_codec_constants.h" @@ -27,7 +28,9 @@ namespace webrtc { class SvcRateAllocator : public VideoBitrateAllocator { public: - explicit SvcRateAllocator(const VideoCodec& codec); + [[deprecated]] explicit SvcRateAllocator(const VideoCodec& codec); + SvcRateAllocator(const VideoCodec& codec, + const FieldTrialsView& field_trials); VideoBitrateAllocation Allocate( VideoBitrateAllocationParameters parameters) override; diff --git a/modules/video_coding/svc/svc_rate_allocator_unittest.cc b/modules/video_coding/svc/svc_rate_allocator_unittest.cc index 9aa6c5dbe9..09a769a0ec 100644 --- a/modules/video_coding/svc/svc_rate_allocator_unittest.cc +++ b/modules/video_coding/svc/svc_rate_allocator_unittest.cc @@ -11,13 +11,23 @@ #include "modules/video_coding/svc/svc_rate_allocator.h" #include +#include +#include #include +#include "absl/container/inlined_vector.h" +#include "api/units/data_rate.h" +#include "api/video/video_bitrate_allocation.h" +#include "api/video/video_bitrate_allocator.h" +#include "api/video/video_codec_constants.h" #include "api/video/video_codec_type.h" +#include "api/video_codecs/scalability_mode.h" +#include "api/video_codecs/spatial_layer.h" +#include "api/video_codecs/video_codec.h" #include "modules/video_coding/codecs/av1/av1_svc_config.h" #include "modules/video_coding/codecs/vp9/svc_config.h" #include "rtc_base/checks.h" -#include "test/field_trial.h" +#include "test/explicit_key_value_config.h" #include "test/gtest.h" namespace webrtc { @@ -76,7 +86,8 @@ static VideoCodec Configure(VideoCodecType codecType, TEST(SvcRateAllocatorTest, SingleLayerFor320x180Input) { VideoCodec codec = Configure(kVideoCodecVP9, 320, 180, 3, 3, false); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate(VideoBitrateAllocationParameters(1000 * 1000, 30)); @@ -87,7 +98,8 @@ TEST(SvcRateAllocatorTest, SingleLayerFor320x180Input) { TEST(SvcRateAllocatorTest, TwoLayersFor640x360Input) { VideoCodec codec = Configure(kVideoCodecVP9, 640, 360, 3, 3, false); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate(VideoBitrateAllocationParameters(1000 * 1000, 30)); @@ -99,7 +111,8 @@ TEST(SvcRateAllocatorTest, TwoLayersFor640x360Input) { TEST(SvcRateAllocatorTest, ThreeLayersFor1280x720Input) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 3, false); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate(VideoBitrateAllocationParameters(1000 * 1000, 30)); @@ -112,7 +125,8 @@ TEST(SvcRateAllocatorTest, ThreeLayersFor1280x720Input) { TEST(SvcRateAllocatorTest, BaseLayerNonZeroBitrateEvenIfTotalIfLessThanMinimum) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 3, false); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); const SpatialLayer* layers = codec.spatialLayers; @@ -126,7 +140,8 @@ TEST(SvcRateAllocatorTest, TEST(SvcRateAllocatorTest, Disable640x360Layer) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 3, false); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); const SpatialLayer* layers = codec.spatialLayers; @@ -143,7 +158,8 @@ TEST(SvcRateAllocatorTest, Disable640x360Layer) { TEST(SvcRateAllocatorTest, Disable1280x720Layer) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 3, false); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); const SpatialLayer* layers = codec.spatialLayers; @@ -161,7 +177,8 @@ TEST(SvcRateAllocatorTest, Disable1280x720Layer) { TEST(SvcRateAllocatorTest, BitrateIsCapped) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 3, false); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); const SpatialLayer* layers = codec.spatialLayers; @@ -178,7 +195,8 @@ TEST(SvcRateAllocatorTest, BitrateIsCapped) { TEST(SvcRateAllocatorTest, MinBitrateToGetQualityLayer) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 1, true); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); const SpatialLayer* layers = codec.spatialLayers; @@ -196,6 +214,7 @@ TEST(SvcRateAllocatorTest, MinBitrateToGetQualityLayer) { } TEST(SvcRateAllocatorTest, DeactivateHigherLayers) { + ExplicitKeyValueConfig field_trials(""); for (int deactivated_idx = 2; deactivated_idx >= 0; --deactivated_idx) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 1, false); EXPECT_LE(codec.VP9()->numberOfSpatialLayers, 3U); @@ -203,7 +222,7 @@ TEST(SvcRateAllocatorTest, DeactivateHigherLayers) { for (int i = deactivated_idx; i < 3; ++i) codec.spatialLayers[i].active = false; - SvcRateAllocator allocator = SvcRateAllocator(codec); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate( VideoBitrateAllocationParameters(10 * 1000 * 1000, 30)); @@ -221,6 +240,7 @@ TEST(SvcRateAllocatorTest, DeactivateHigherLayers) { } TEST(SvcRateAllocatorTest, DeactivateLowerLayers) { + ExplicitKeyValueConfig field_trials(""); for (int deactivated_idx = 0; deactivated_idx < 3; ++deactivated_idx) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 1, false); EXPECT_LE(codec.VP9()->numberOfSpatialLayers, 3U); @@ -228,7 +248,7 @@ TEST(SvcRateAllocatorTest, DeactivateLowerLayers) { for (int i = deactivated_idx; i >= 0; --i) codec.spatialLayers[i].active = false; - SvcRateAllocator allocator = SvcRateAllocator(codec); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate( VideoBitrateAllocationParameters(10 * 1000 * 1000, 30)); @@ -248,7 +268,8 @@ TEST(SvcRateAllocatorTest, DeactivateLowerLayers) { TEST(SvcRateAllocatorTest, SignalsBwLimited) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 1, false); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); // Rough estimate calculated by hand. uint32_t min_to_enable_all = 900000; @@ -310,8 +331,9 @@ TEST(SvcRateAllocatorTest, SupportsAv1) { codec.spatialLayers[2].minBitrate = 193; codec.spatialLayers[2].targetBitrate = 305; codec.spatialLayers[2].maxBitrate = 418; + ExplicitKeyValueConfig field_trials(""); - SvcRateAllocator allocator(codec); + SvcRateAllocator allocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate(VideoBitrateAllocationParameters(1'000'000, 30)); @@ -339,8 +361,9 @@ TEST(SvcRateAllocatorTest, SupportsAv1WithSkippedLayer) { codec.spatialLayers[2].minBitrate = 193; codec.spatialLayers[2].targetBitrate = 305; codec.spatialLayers[2].maxBitrate = 418; + ExplicitKeyValueConfig field_trials(""); - SvcRateAllocator allocator(codec); + SvcRateAllocator allocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate(VideoBitrateAllocationParameters(1'000'000, 30)); @@ -368,8 +391,9 @@ TEST(SvcRateAllocatorTest, UsesScalabilityModeToGetNumberOfLayers) { codec.spatialLayers[2].minBitrate = 193; codec.spatialLayers[2].targetBitrate = 305; codec.spatialLayers[2].maxBitrate = 418; + ExplicitKeyValueConfig field_trials(""); - SvcRateAllocator allocator(codec); + SvcRateAllocator allocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate(VideoBitrateAllocationParameters(1'000'000, 30)); @@ -386,7 +410,9 @@ TEST(SvcRateAllocatorTest, UsesScalabilityModeToGetNumberOfLayers) { TEST(SvcRateAllocatorTest, CapsAllocationToMaxBitrate) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 3, false); codec.maxBitrate = 70; // Cap the overall max bitrate to 70kbps. - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); // Allocate 3Mbps which should be enough for all layers. VideoBitrateAllocation allocation = @@ -423,7 +449,8 @@ TEST_P(SvcRateAllocatorTestParametrizedContentType, MaxBitrate) { TEST_P(SvcRateAllocatorTestParametrizedContentType, PaddingBitrate) { VideoCodec codec = Configure(kVideoCodecVP9, 1280, 720, 3, 1, is_screen_sharing_); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); DataRate padding_bitrate = SvcRateAllocator::GetPaddingBitrate(codec); @@ -467,7 +494,7 @@ TEST_P(SvcRateAllocatorTestParametrizedContentType, PaddingBitrate) { } TEST_P(SvcRateAllocatorTestParametrizedContentType, StableBitrate) { - ScopedFieldTrials field_trial( + ExplicitKeyValueConfig field_trials( "WebRTC-StableTargetRate/enabled:true,video_hysteresis_factor:1.0," "screenshare_hysteresis_factor:1.0/"); @@ -486,7 +513,7 @@ TEST_P(SvcRateAllocatorTestParametrizedContentType, StableBitrate) { : DataRate::KilobitsPerSec(codec.spatialLayers[0].maxBitrate + codec.spatialLayers[1].maxBitrate); - SvcRateAllocator allocator = SvcRateAllocator(codec); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); // Two layers, stable and target equal. auto allocation = allocator.Allocate(VideoBitrateAllocationParameters( @@ -532,10 +559,10 @@ TEST_P(SvcRateAllocatorTestParametrizedContentType, const DataRate min_rate_two_layers = start_rates[1]; const DataRate min_rate_three_layers = start_rates[2]; - ScopedFieldTrials field_trial( + ExplicitKeyValueConfig field_trials( "WebRTC-StableTargetRate/enabled:true,video_hysteresis_factor:1.1," "screenshare_hysteresis_factor:1.1/"); - SvcRateAllocator allocator = SvcRateAllocator(codec); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); // Always use max bitrate as target, verify only stable is used for layer // count selection. const DataRate max_bitrate = allocator.GetMaxBitrate(codec); @@ -618,7 +645,8 @@ TEST_P(SvcRateAllocatorTestParametrizedContentType, TEST_P(SvcRateAllocatorTestParametrizedContentType, TwoTemporalLayersAv1) { VideoCodec codec = Configure(kVideoCodecAV1, 1280, 720, 1, 2, is_screen_sharing_); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate(VideoBitrateAllocationParameters( /*total_bitrate_bps=*/1024'000, /*framerate=*/30)); @@ -632,7 +660,8 @@ TEST_P(SvcRateAllocatorTestParametrizedContentType, TwoTemporalLayersAv1) { TEST_P(SvcRateAllocatorTestParametrizedContentType, ThreeTemporalLayersAv1) { VideoCodec codec = Configure(kVideoCodecAV1, 1280, 720, 1, 3, is_screen_sharing_); - SvcRateAllocator allocator = SvcRateAllocator(codec); + ExplicitKeyValueConfig field_trials(""); + SvcRateAllocator allocator = SvcRateAllocator(codec, field_trials); VideoBitrateAllocation allocation = allocator.Allocate(VideoBitrateAllocationParameters( /*total_bitrate_bps=*/1024'000, /*framerate=*/30)); diff --git a/modules/video_coding/utility/simulcast_rate_allocator.cc b/modules/video_coding/utility/simulcast_rate_allocator.cc index 89522e6ca3..dd054030f1 100644 --- a/modules/video_coding/utility/simulcast_rate_allocator.cc +++ b/modules/video_coding/utility/simulcast_rate_allocator.cc @@ -13,14 +13,19 @@ #include #include -#include #include #include -#include #include #include #include "api/environment/environment.h" +#include "api/units/data_rate.h" +#include "api/video/video_bitrate_allocation.h" +#include "api/video/video_bitrate_allocator.h" +#include "api/video/video_codec_constants.h" +#include "api/video/video_codec_type.h" +#include "api/video_codecs/simulcast_stream.h" +#include "api/video_codecs/video_codec.h" #include "rtc_base/checks.h" #include "rtc_base/experiments/rate_control_settings.h" @@ -61,8 +66,7 @@ float SimulcastRateAllocator::GetTemporalRateAllocation( SimulcastRateAllocator::SimulcastRateAllocator(const Environment& env, const VideoCodec& codec) : codec_(codec), - stable_rate_settings_(StableTargetRateExperiment::ParseFromKeyValueConfig( - &env.field_trials())), + stable_rate_settings_(env.field_trials()), rate_control_settings_(env.field_trials()), legacy_conference_mode_(false) {} diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn index 8b21a61b56..c5fce0469c 100644 --- a/rtc_base/experiments/BUILD.gn +++ b/rtc_base/experiments/BUILD.gn @@ -145,7 +145,6 @@ rtc_library("stable_target_rate_experiment") { deps = [ ":field_trial_parser", "../../api:field_trials_view", - "../../api/transport:field_trial_based_config", ] } diff --git a/rtc_base/experiments/stable_target_rate_experiment.cc b/rtc_base/experiments/stable_target_rate_experiment.cc index fa04fa35b4..d554b5d355 100644 --- a/rtc_base/experiments/stable_target_rate_experiment.cc +++ b/rtc_base/experiments/stable_target_rate_experiment.cc @@ -10,7 +10,8 @@ #include "rtc_base/experiments/stable_target_rate_experiment.h" -#include "api/transport/field_trial_based_config.h" +#include "api/field_trials_view.h" +#include "rtc_base/experiments/field_trial_parser.h" namespace webrtc { namespace { @@ -18,17 +19,15 @@ constexpr char kFieldTrialName[] = "WebRTC-StableTargetRate"; } // namespace StableTargetRateExperiment::StableTargetRateExperiment( - const FieldTrialsView* const key_value_config, - double default_video_hysteresis, - double default_screenshare_hysteresis) + const FieldTrialsView& key_value_config) : enabled_("enabled", false), video_hysteresis_factor_("video_hysteresis_factor", - default_video_hysteresis), + /*default_value=*/1.2), screenshare_hysteresis_factor_("screenshare_hysteresis_factor", - default_screenshare_hysteresis) { + /*default_value=*/1.35) { ParseFieldTrial( {&enabled_, &video_hysteresis_factor_, &screenshare_hysteresis_factor_}, - key_value_config->Lookup(kFieldTrialName)); + key_value_config.Lookup(kFieldTrialName)); } StableTargetRateExperiment::StableTargetRateExperiment( @@ -36,18 +35,6 @@ StableTargetRateExperiment::StableTargetRateExperiment( StableTargetRateExperiment::StableTargetRateExperiment( StableTargetRateExperiment&&) = default; -StableTargetRateExperiment StableTargetRateExperiment::ParseFromFieldTrials() { - FieldTrialBasedConfig config; - return ParseFromKeyValueConfig(&config); -} - -StableTargetRateExperiment StableTargetRateExperiment::ParseFromKeyValueConfig( - const FieldTrialsView* const key_value_config) { - return StableTargetRateExperiment(key_value_config, - /*default_video_hysteresis=*/1.2, - /*default_screenshare_hysteresis=*/1.35); -} - bool StableTargetRateExperiment::IsEnabled() const { return enabled_.Get(); } diff --git a/rtc_base/experiments/stable_target_rate_experiment.h b/rtc_base/experiments/stable_target_rate_experiment.h index be0f9da129..ced3eb8b81 100644 --- a/rtc_base/experiments/stable_target_rate_experiment.h +++ b/rtc_base/experiments/stable_target_rate_experiment.h @@ -18,22 +18,15 @@ namespace webrtc { class StableTargetRateExperiment { public: + explicit StableTargetRateExperiment(const FieldTrialsView& field_trials); StableTargetRateExperiment(const StableTargetRateExperiment&); StableTargetRateExperiment(StableTargetRateExperiment&&); - static StableTargetRateExperiment ParseFromFieldTrials(); - static StableTargetRateExperiment ParseFromKeyValueConfig( - const FieldTrialsView* const key_value_config); bool IsEnabled() const; double GetVideoHysteresisFactor() const; double GetScreenshareHysteresisFactor() const; private: - explicit StableTargetRateExperiment( - const FieldTrialsView* const key_value_config, - double default_video_hysteresis, - double default_screenshare_hysteresis); - FieldTrialParameter enabled_; FieldTrialParameter video_hysteresis_factor_; FieldTrialParameter screenshare_hysteresis_factor_; diff --git a/rtc_base/experiments/stable_target_rate_experiment_unittest.cc b/rtc_base/experiments/stable_target_rate_experiment_unittest.cc index 854398e910..f4b63c30b6 100644 --- a/rtc_base/experiments/stable_target_rate_experiment_unittest.cc +++ b/rtc_base/experiments/stable_target_rate_experiment_unittest.cc @@ -10,46 +10,45 @@ #include "rtc_base/experiments/stable_target_rate_experiment.h" -#include "test/field_trial.h" +#include "test/explicit_key_value_config.h" #include "test/gtest.h" namespace webrtc { +using test::ExplicitKeyValueConfig; + TEST(StableBweExperimentTest, Default) { - StableTargetRateExperiment config = - StableTargetRateExperiment::ParseFromFieldTrials(); + ExplicitKeyValueConfig field_trials(""); + StableTargetRateExperiment config(field_trials); EXPECT_FALSE(config.IsEnabled()); EXPECT_EQ(config.GetVideoHysteresisFactor(), 1.2); EXPECT_EQ(config.GetScreenshareHysteresisFactor(), 1.35); } TEST(StableBweExperimentTest, EnabledNoHysteresis) { - webrtc::test::ScopedFieldTrials field_trials( - "WebRTC-StableTargetRate/enabled:true/"); + ExplicitKeyValueConfig field_trials("WebRTC-StableTargetRate/enabled:true/"); - StableTargetRateExperiment config = - StableTargetRateExperiment::ParseFromFieldTrials(); + StableTargetRateExperiment config(field_trials); EXPECT_TRUE(config.IsEnabled()); EXPECT_EQ(config.GetVideoHysteresisFactor(), 1.2); EXPECT_EQ(config.GetScreenshareHysteresisFactor(), 1.35); } TEST(StableBweExperimentTest, EnabledWithHysteresis) { - webrtc::test::ScopedFieldTrials field_trials( + ExplicitKeyValueConfig field_trials( "WebRTC-StableTargetRate/" "enabled:true," "video_hysteresis_factor:1.1," "screenshare_hysteresis_factor:1.2/"); - StableTargetRateExperiment config = - StableTargetRateExperiment::ParseFromFieldTrials(); + StableTargetRateExperiment config(field_trials); EXPECT_TRUE(config.IsEnabled()); EXPECT_EQ(config.GetVideoHysteresisFactor(), 1.1); EXPECT_EQ(config.GetScreenshareHysteresisFactor(), 1.2); } TEST(StableBweExperimentTest, HysteresisOverrideVideoRateHystersis) { - webrtc::test::ScopedFieldTrials field_trials( + ExplicitKeyValueConfig field_trials( "WebRTC-StableTargetRate/" "enabled:true," "video_hysteresis_factor:1.1," @@ -57,8 +56,7 @@ TEST(StableBweExperimentTest, HysteresisOverrideVideoRateHystersis) { "WebRTC-VideoRateControl/video_hysteresis:1.3," "screenshare_hysteresis:1.4/"); - StableTargetRateExperiment config = - StableTargetRateExperiment::ParseFromFieldTrials(); + StableTargetRateExperiment config(field_trials); EXPECT_TRUE(config.IsEnabled()); EXPECT_EQ(config.GetVideoHysteresisFactor(), 1.1); EXPECT_EQ(config.GetScreenshareHysteresisFactor(), 1.2); diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn index 09faca4cc2..e692bdbed8 100644 --- a/test/fuzzers/BUILD.gn +++ b/test/fuzzers/BUILD.gn @@ -719,16 +719,24 @@ if (rtc_build_libvpx) { "../../api:array_view", "../../api:field_trials_view", "../../api/environment:environment_factory", + "../../api/video:encoded_image", + "../../api/video:video_bitrate_allocation", "../../api/video:video_frame", + "../../api/video:video_frame_type", "../../api/video_codecs:video_codecs_api", + "../../common_video/generic_frame_descriptor", "../../media:media_constants", + "../../modules/video_coding:codec_globals_headers", "../../modules/video_coding:frame_dependencies_calculator", + "../../modules/video_coding:video_codec_interface", "../../modules/video_coding:webrtc_libvpx_interface", "../../modules/video_coding:webrtc_vp9", + "../../rtc_base:checks", "../../rtc_base:safe_compare", "//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/base:core_headers", "//third_party/abseil-cpp/absl/container:inlined_vector", + "//third_party/abseil-cpp/absl/strings:string_view", rtc_libvpx_dir, ] seed_corpus = "corpora/vp9-encoder-references-corpus" diff --git a/test/fuzzers/vp9_encoder_references_fuzzer.cc b/test/fuzzers/vp9_encoder_references_fuzzer.cc index 739e3ff225..cf80ccfe94 100644 --- a/test/fuzzers/vp9_encoder_references_fuzzer.cc +++ b/test/fuzzers/vp9_encoder_references_fuzzer.cc @@ -10,20 +10,36 @@ #include +#include +#include +#include +#include + #include "absl/algorithm/container.h" #include "absl/base/macros.h" #include "absl/container/inlined_vector.h" +#include "absl/strings/string_view.h" #include "api/array_view.h" #include "api/environment/environment_factory.h" #include "api/field_trials_view.h" +#include "api/video/encoded_image.h" +#include "api/video/i420_buffer.h" +#include "api/video/video_bitrate_allocation.h" +#include "api/video/video_codec_type.h" #include "api/video/video_frame.h" +#include "api/video/video_frame_type.h" +#include "api/video_codecs/spatial_layer.h" #include "api/video_codecs/video_codec.h" #include "api/video_codecs/video_encoder.h" -#include "media/base/media_constants.h" +#include "common_video/generic_frame_descriptor/generic_frame_info.h" +#include "modules/video_coding/codecs/interface/common_constants.h" #include "modules/video_coding/codecs/interface/libvpx_interface.h" +#include "modules/video_coding/codecs/vp9/include/vp9_globals.h" #include "modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h" #include "modules/video_coding/frame_dependencies_calculator.h" -#include "rtc_base/numerics/safe_compare.h" +#include "modules/video_coding/include/video_codec_interface.h" +#include "modules/video_coding/include/video_error_codes.h" +#include "rtc_base/checks.h" #include "test/fuzzers/fuzz_data_helper.h" // Fuzzer simulates various svc configurations and libvpx encoder dropping