diff --git a/video/BUILD.gn b/video/BUILD.gn index fdd12cf2a7..3012f35f97 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -849,6 +849,7 @@ if (rtc_include_tests) { "../api:fec_controller_api", "../api:field_trials_view", "../api:frame_generator_api", + "../api:location", "../api:make_ref_counted", "../api:mock_fec_controller_override", "../api:mock_frame_decryptor", @@ -856,12 +857,15 @@ if (rtc_include_tests) { "../api:mock_video_codec_factory", "../api:mock_video_decoder", "../api:mock_video_encoder", + "../api:rtc_error_matchers", "../api:rtp_headers", "../api:rtp_parameters", "../api:scoped_refptr", "../api:sequence_checker", "../api:simulated_network_api", "../api:time_controller", + "../api:video_track_source_constraints", + "../api/adaptation:resource_adaptation_api", "../api/crypto:options", "../api/environment", "../api/environment:environment_factory", @@ -882,15 +886,18 @@ if (rtc_include_tests) { "../api/video:builtin_video_bitrate_allocator_factory", "../api/video:encoded_image", "../api/video:recordable_encoded_frame", + "../api/video:render_resolution", "../api/video:resolution", "../api/video:video_adaptation", "../api/video:video_bitrate_allocation", "../api/video:video_bitrate_allocator", "../api/video:video_bitrate_allocator_factory", + "../api/video:video_codec_constants", "../api/video:video_frame", "../api/video:video_frame_type", "../api/video:video_layers_allocation", "../api/video:video_rtp_headers", + "../api/video:video_stream_encoder", "../api/video/test:video_frame_matchers", "../api/video_codecs:scalability_mode", "../api/video_codecs:video_codecs_api", @@ -958,6 +965,7 @@ if (rtc_include_tests) { "../rtc_base/containers:flat_map", "../rtc_base/experiments:alr_experiment", "../rtc_base/experiments:encoder_info_settings", + "../rtc_base/experiments:rate_control_settings", "../rtc_base/synchronization:mutex", "../system_wrappers", "../system_wrappers:metrics", @@ -978,13 +986,16 @@ if (rtc_include_tests) { "../test:test_support", "../test:video_test_common", "../test:video_test_constants", + "../test:wait_until", "../test/network:simulated_network", "../test/time_controller", + "adaptation:video_adaptation", "config:encoder_config", "config:streams_config", "config:video_config_tests", "corruption_detection:corruption_detection_tests", "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/container:inlined_vector", "//third_party/abseil-cpp/absl/functional:any_invocable", "//third_party/abseil-cpp/absl/memory", "//third_party/abseil-cpp/absl/strings", diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc index dc977f2e67..c26934ae14 100644 --- a/video/video_stream_encoder_unittest.cc +++ b/video/video_stream_encoder_unittest.cc @@ -10,64 +10,96 @@ #include "video/video_stream_encoder.h" #include +#include #include +#include #include #include #include -#include +#include #include +#include -#include "absl/memory/memory.h" +#include "absl/algorithm/container.h" +#include "absl/container/inlined_vector.h" +#include "absl/functional/any_invocable.h" #include "absl/types/variant.h" +#include "api/adaptation/resource.h" +#include "api/array_view.h" #include "api/environment/environment.h" #include "api/environment/environment_factory.h" #include "api/field_trials_view.h" +#include "api/location.h" +#include "api/make_ref_counted.h" #include "api/rtp_parameters.h" -#include "api/task_queue/default_task_queue_factory.h" +#include "api/scoped_refptr.h" +#include "api/sequence_checker.h" #include "api/task_queue/task_queue_base.h" #include "api/task_queue/task_queue_factory.h" #include "api/test/mock_fec_controller_override.h" #include "api/test/mock_video_encoder.h" #include "api/test/mock_video_encoder_factory.h" +#include "api/test/rtc_error_matchers.h" +#include "api/test/time_controller.h" #include "api/units/data_rate.h" #include "api/units/time_delta.h" +#include "api/units/timestamp.h" #include "api/video/builtin_video_bitrate_allocator_factory.h" #include "api/video/encoded_image.h" #include "api/video/i420_buffer.h" #include "api/video/nv12_buffer.h" +#include "api/video/render_resolution.h" #include "api/video/resolution.h" +#include "api/video/video_adaptation_counters.h" #include "api/video/video_adaptation_reason.h" #include "api/video/video_bitrate_allocation.h" +#include "api/video/video_bitrate_allocator.h" +#include "api/video/video_bitrate_allocator_factory.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/video_layers_allocation.h" +#include "api/video/video_rotation.h" +#include "api/video/video_sink_interface.h" #include "api/video/video_source_interface.h" +#include "api/video/video_stream_encoder_settings.h" +#include "api/video_codecs/scalability_mode.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_codec.h" #include "api/video_codecs/video_encoder.h" -#include "api/video_codecs/vp8_temporal_layers.h" +#include "api/video_codecs/vp8_frame_buffer_controller.h" #include "api/video_codecs/vp8_temporal_layers_factory.h" +#include "api/video_track_source_constraints.h" #include "call/adaptation/test/fake_adaptation_constraint.h" #include "call/adaptation/test/fake_resource.h" +#include "call/adaptation/video_source_restrictions.h" +#include "call/adaptation/video_stream_adapter.h" +#include "call/video_send_stream.h" #include "common_video/frame_instrumentation_data.h" #include "common_video/h264/h264_common.h" -#include "common_video/include/video_frame_buffer.h" #include "media/base/video_adapter.h" #include "media/engine/webrtc_video_engine.h" #include "modules/video_coding/codecs/av1/libaom_av1_encoder.h" #include "modules/video_coding/codecs/h264/include/h264.h" #include "modules/video_coding/codecs/vp8/include/vp8.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/svc_config.h" #include "modules/video_coding/include/video_codec_interface.h" -#include "modules/video_coding/utility/quality_scaler.h" +#include "modules/video_coding/include/video_error_codes.h" #include "modules/video_coding/utility/simulcast_rate_allocator.h" #include "modules/video_coding/utility/vp8_constants.h" +#include "rtc_base/checks.h" #include "rtc_base/event.h" #include "rtc_base/experiments/encoder_info_settings.h" -#include "rtc_base/gunit.h" +#include "rtc_base/experiments/rate_control_settings.h" #include "rtc_base/logging.h" #include "rtc_base/ref_counted_object.h" +#include "rtc_base/strings/string_builder.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" +#include "rtc_base/time_utils.h" #include "system_wrappers/include/metrics.h" #include "test/encoder_settings.h" #include "test/fake_encoder.h" @@ -79,11 +111,14 @@ #include "test/time_controller/simulated_time_controller.h" #include "test/video_encoder_nullable_proxy_factory.h" #include "test/video_encoder_proxy_factory.h" -#include "video/config/encoder_stream_factory.h" +#include "test/wait_until.h" +#include "video/adaptation/overuse_frame_detector.h" #include "video/config/video_encoder_config.h" #include "video/encoder_bitrate_adjuster.h" #include "video/frame_cadence_adapter.h" #include "video/send_statistics_proxy.h" +#include "video/video_stream_encoder_interface.h" +#include "video/video_stream_encoder_observer.h" namespace webrtc { @@ -94,6 +129,7 @@ using ::testing::Field; using ::testing::Ge; using ::testing::Gt; using ::testing::Invoke; +using ::testing::IsTrue; using ::testing::Le; using ::testing::Lt; using ::testing::Matcher; @@ -4480,7 +4516,9 @@ TEST_F(VideoStreamEncoderTest, DropFirstFramesIfBwEstimateIsTooLow) { int64_t timestamp_ms = kFrameIntervalMs; source.IncomingCapturedFrame(CreateFrame(timestamp_ms, 1280, 720)); ExpectDroppedFrame(); - EXPECT_TRUE_WAIT(source.sink_wants().max_pixel_count < 1280 * 720, 5000); + EXPECT_THAT(WaitUntil([&] { return source.sink_wants().max_pixel_count; }, + Lt(1280 * 720)), + IsRtcOk()); // Insert 720p frame. It should be downscaled and encoded. timestamp_ms += kFrameIntervalMs; @@ -5847,8 +5885,10 @@ TEST_F(VideoStreamEncoderTest, DropsFramesAndScalesWhenBitrateIsTooLow) { ExpectDroppedFrame(); // Expect the sink_wants to specify a scaled frame. - EXPECT_TRUE_WAIT( - video_source_.sink_wants().max_pixel_count < kWidth * kHeight, 5000); + EXPECT_THAT( + WaitUntil([&] { return video_source_.sink_wants().max_pixel_count; }, + Lt(kWidth * kHeight)), + IsRtcOk()); int last_pixel_count = video_source_.sink_wants().max_pixel_count; @@ -5859,8 +5899,10 @@ TEST_F(VideoStreamEncoderTest, DropsFramesAndScalesWhenBitrateIsTooLow) { // Expect to drop this frame, the wait should time out. ExpectDroppedFrame(); - EXPECT_TRUE_WAIT( - video_source_.sink_wants().max_pixel_count < last_pixel_count, 5000); + EXPECT_THAT( + WaitUntil([&] { return video_source_.sink_wants().max_pixel_count; }, + Lt(last_pixel_count)), + IsRtcOk()); video_stream_encoder_->Stop(); } @@ -5970,8 +6012,10 @@ TEST_F(VideoStreamEncoderTest, InitialFrameDropActivatesWhenBweDrops) { ExpectDroppedFrame(); // Expect the sink_wants to specify a scaled frame. - EXPECT_TRUE_WAIT( - video_source_.sink_wants().max_pixel_count < kWidth * kHeight, 5000); + EXPECT_THAT( + WaitUntil([&] { return video_source_.sink_wants().max_pixel_count; }, + Lt(kWidth * kHeight)), + IsRtcOk()); video_stream_encoder_->Stop(); } @@ -6104,8 +6148,10 @@ TEST_F(VideoStreamEncoderTest, InitialFrameDropActivatesWhenLayersChange) { ExpectDroppedFrame(); // Expect the sink_wants to specify a scaled frame. - EXPECT_TRUE_WAIT( - video_source_.sink_wants().max_pixel_count < kWidth * kHeight, 5000); + EXPECT_THAT( + WaitUntil([&] { return video_source_.sink_wants().max_pixel_count; }, + Lt(kWidth * kHeight)), + IsRtcOk()); video_stream_encoder_->Stop(); } @@ -6167,8 +6213,10 @@ TEST_F(VideoStreamEncoderTest, InitialFrameDropActivatesWhenSVCLayersChange) { ExpectDroppedFrame(); // Expect the sink_wants to specify a scaled frame. - EXPECT_TRUE_WAIT( - video_source_.sink_wants().max_pixel_count < kWidth * kHeight, 5000); + EXPECT_THAT( + WaitUntil([&] { return video_source_.sink_wants().max_pixel_count; }, + Lt(kWidth * kHeight)), + IsRtcOk()); video_stream_encoder_->Stop(); } @@ -6515,8 +6563,10 @@ TEST_P(VideoStreamEncoderInitialFrameDropperTest, ExpectDroppedFrame(); // Expect the sink_wants to specify a scaled frame. - EXPECT_TRUE_WAIT( - video_source_.sink_wants().max_pixel_count < kWidth * kHeight, 5000); + EXPECT_THAT( + WaitUntil([&] { return video_source_.sink_wants().max_pixel_count; }, + Lt(kWidth * kHeight)), + IsRtcOk()); video_stream_encoder_->Stop(); } @@ -6560,8 +6610,9 @@ TEST_P(VideoStreamEncoderInitialFrameDropperTest, video_stream_encoder_->TriggerQualityLow(); // Adaptation has an effect. - EXPECT_TRUE_WAIT(source.sink_wants().max_pixel_count < kWidth * kHeight, - 5000); + EXPECT_THAT(WaitUntil([&] { return source.sink_wants().max_pixel_count; }, + Lt(kWidth * kHeight)), + IsRtcOk()); // Frame isn't dropped as initial frame dropper is disabled. source.IncomingCapturedFrame( @@ -6574,8 +6625,9 @@ TEST_P(VideoStreamEncoderInitialFrameDropperTest, video_stream_encoder_->TriggerQualityHigh(); // Adaptation has an effect. - EXPECT_TRUE_WAIT(source.sink_wants().max_pixel_count > kWidth * kHeight, - 5000); + EXPECT_THAT(WaitUntil([&] { return source.sink_wants().max_pixel_count; }, + Gt(kWidth * kHeight)), + IsRtcOk()); source.IncomingCapturedFrame( CreateFrame(timestamp, captureWidth, captureHeight)); @@ -6615,8 +6667,10 @@ TEST_P(VideoStreamEncoderInitialFrameDropperTest, ExpectDroppedFrame(); // Expect sink_wants to specify a scaled frame. - EXPECT_TRUE_WAIT(video_source_.sink_wants().max_pixel_count < 640 * 360, - 5000); + EXPECT_THAT( + WaitUntil([&] { return video_source_.sink_wants().max_pixel_count; }, + Lt(640 * 360)), + IsRtcOk()); video_stream_encoder_->Stop(); } @@ -6679,8 +6733,11 @@ TEST_F(VideoStreamEncoderTest, // for the first time. // TODO(eshr): We should avoid these waits by using threads with simulated // time. - EXPECT_TRUE_WAIT(stats_proxy_->GetStats().bw_limited_resolution, - 2000 * 2.5 * 2); + EXPECT_THAT( + WaitUntil([&] { return stats_proxy_->GetStats().bw_limited_resolution; }, + IsTrue(), + {.timeout = webrtc::TimeDelta::Millis(2000 * 2.5 * 2)}), + IsRtcOk()); timestamp_ms += kFrameIntervalMs; source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight)); WaitForEncodedFrame(timestamp_ms); @@ -8855,7 +8912,7 @@ TEST_F(VideoStreamEncoderTest, } TEST_F(VideoStreamEncoderTest, NormalComplexityWithMoreThanTwoCores) { - ResetEncoder("VP9", /*num_stream=*/1, /*num_temporal_layers=*/1, + ResetEncoder("VP9", /*num_streams=*/1, /*num_temporal_layers=*/1, /*num_spatial_layers=*/1, /*screenshare=*/false, kDefaultFramerate, /*allocation_callback_type=*/ @@ -8878,7 +8935,7 @@ TEST_F(VideoStreamEncoderTest, webrtc::test::ScopedKeyValueConfig field_trials( field_trials_, "WebRTC-VP9-LowTierOptimizations/Disabled/"); - ResetEncoder("VP9", /*num_stream=*/1, /*num_temporal_layers=*/1, + ResetEncoder("VP9", /*num_streams=*/1, /*num_temporal_layers=*/1, /*num_spatial_layers=*/1, /*screenshare=*/false, kDefaultFramerate, /*allocation_callback_type=*/ @@ -8897,7 +8954,7 @@ TEST_F(VideoStreamEncoderTest, } TEST_F(VideoStreamEncoderTest, LowComplexityWithTwoCores) { - ResetEncoder("VP9", /*num_stream=*/1, /*num_temporal_layers=*/1, + ResetEncoder("VP9", /*num_streams=*/1, /*num_temporal_layers=*/1, /*num_spatial_layers=*/1, /*screenshare=*/false, kDefaultFramerate, /*allocation_callback_type=*/