From 9b881abea95736a8aec8f1933d4c88aa452d88e9 Mon Sep 17 00:00:00 2001 From: Ying Wang Date: Fri, 7 Feb 2020 14:29:32 +0100 Subject: [PATCH] Enable congestion window pushback to reduce bitrate by only drop video frames. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With current congestion window pushback, when congestion window is filling up, it will reduce bitrate directly and encoder may reduce encode quality, resolution, or framerate to adapt to the allocated bitrate, the behavior is depending on the degradation preference. This change enable congestion window to only drop frames to reduce bitrate (when needed) instead of reduce general bitrate allocation. Bug: webrtc:11334 Change-Id: I9cf5c20a0858c4d07d006942abe72aa5e1f7cb38 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168059 Commit-Queue: Ying Wang Reviewed-by: Karl Wiberg Reviewed-by: Åsa Persson Cr-Commit-Position: refs/heads/master@{#30483} --- api/call/bitrate_allocation.h | 4 + api/transport/network_types.h | 1 + api/video/video_stream_encoder_interface.h | 3 +- api/video/video_stream_encoder_observer.h | 3 +- call/bitrate_allocator.cc | 1 + call/video_send_stream.h | 1 + ...ion_window_pushback_controller_unittest.cc | 12 + .../goog_cc/goog_cc_network_control.cc | 13 +- .../goog_cc_network_control_unittest.cc | 34 +++ rtc_base/experiments/rate_control_settings.cc | 7 +- rtc_base/experiments/rate_control_settings.h | 2 + video/send_statistics_proxy.cc | 7 +- video/test/mock_video_stream_encoder.h | 4 +- video/video_send_stream_impl.cc | 4 +- video/video_send_stream_impl_unittest.cc | 10 +- video/video_stream_encoder.cc | 79 ++++-- video/video_stream_encoder.h | 15 +- video/video_stream_encoder_unittest.cc | 233 ++++++++++-------- 18 files changed, 300 insertions(+), 133 deletions(-) diff --git a/api/call/bitrate_allocation.h b/api/call/bitrate_allocation.h index 24530c9755..13c7f74b3a 100644 --- a/api/call/bitrate_allocation.h +++ b/api/call/bitrate_allocation.h @@ -34,6 +34,10 @@ struct BitrateAllocationUpdate { TimeDelta round_trip_time = TimeDelta::PlusInfinity(); // |bwe_period| is deprecated, use |stable_target_bitrate| allocation instead. TimeDelta bwe_period = TimeDelta::PlusInfinity(); + // Congestion window pushback bitrate reduction fraction. Used in + // VideoStreamEncoder to reduce the bitrate by the given fraction + // by dropping frames. + double cwnd_reduce_ratio = 0; }; } // namespace webrtc diff --git a/api/transport/network_types.h b/api/transport/network_types.h index f658b34494..ec37a22e39 100644 --- a/api/transport/network_types.h +++ b/api/transport/network_types.h @@ -218,6 +218,7 @@ struct TargetTransferRate { NetworkEstimate network_estimate; DataRate target_rate = DataRate::Zero(); DataRate stable_target_rate = DataRate::Zero(); + double cwnd_reduce_ratio = 0; }; // Contains updates of network controller comand state. Using optionals to diff --git a/api/video/video_stream_encoder_interface.h b/api/video/video_stream_encoder_interface.h index d2a90bb00f..253fb04306 100644 --- a/api/video/video_stream_encoder_interface.h +++ b/api/video/video_stream_encoder_interface.h @@ -95,7 +95,8 @@ class VideoStreamEncoderInterface : public rtc::VideoSinkInterface { DataRate stable_target_bitrate, DataRate link_allocation, uint8_t fraction_lost, - int64_t round_trip_time_ms) = 0; + int64_t round_trip_time_ms, + double cwnd_reduce_ratio) = 0; // Register observer for the bitrate allocation between the temporal // and spatial layers. diff --git a/api/video/video_stream_encoder_observer.h b/api/video/video_stream_encoder_observer.h index 49531ae539..0d639f3c05 100644 --- a/api/video/video_stream_encoder_observer.h +++ b/api/video/video_stream_encoder_observer.h @@ -59,7 +59,8 @@ class VideoStreamEncoderObserver : public CpuOveruseMetricsObserver { kSource, kEncoderQueue, kEncoder, - kMediaOptimization + kMediaOptimization, + kCongestionWindow }; ~VideoStreamEncoderObserver() override = default; diff --git a/call/bitrate_allocator.cc b/call/bitrate_allocator.cc index 7d9e5cb651..6880422336 100644 --- a/call/bitrate_allocator.cc +++ b/call/bitrate_allocator.cc @@ -409,6 +409,7 @@ void BitrateAllocator::OnNetworkEstimateChanged(TargetTransferRate msg) { update.packet_loss_ratio = last_fraction_loss_ / 256.0; update.round_trip_time = TimeDelta::ms(last_rtt_); update.bwe_period = TimeDelta::ms(last_bwe_period_ms_); + update.cwnd_reduce_ratio = msg.cwnd_reduce_ratio; uint32_t protection_bitrate = config.observer->OnBitrateUpdated(update); if (allocated_bitrate == 0 && config.allocated_bitrate_bps > 0) { diff --git a/call/video_send_stream.h b/call/video_send_stream.h index 39abdfc808..85d8019747 100644 --- a/call/video_send_stream.h +++ b/call/video_send_stream.h @@ -81,6 +81,7 @@ class VideoSendStream { uint32_t frames_dropped_by_capturer = 0; uint32_t frames_dropped_by_encoder_queue = 0; uint32_t frames_dropped_by_rate_limiter = 0; + uint32_t frames_dropped_by_congestion_window = 0; uint32_t frames_dropped_by_encoder = 0; absl::optional qp_sum; // Bitrate the encoder is currently configured to use due to bandwidth diff --git a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller_unittest.cc b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller_unittest.cc index 426d9e182f..37b7233fbc 100644 --- a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller_unittest.cc +++ b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller_unittest.cc @@ -89,5 +89,17 @@ TEST_F(CongestionWindowPushbackControllerTest, PushbackOnInititialDataWindow) { EXPECT_GT(80000u, bitrate_bps); } +TEST_F(CongestionWindowPushbackControllerTest, PushbackDropFrame) { + test::ScopedFieldTrials trials("WebRTC-CongestionWindow/DropFrame:true/"); + cwnd_controller_.reset( + new CongestionWindowPushbackController(&field_trial_config_)); + cwnd_controller_->UpdateOutstandingData(1e8); // Large number + cwnd_controller_->SetDataWindow(DataSize::bytes(50000)); + + uint32_t bitrate_bps = 80000; + bitrate_bps = cwnd_controller_->UpdateTargetBitrate(bitrate_bps); + EXPECT_GT(80000u, bitrate_bps); +} + } // namespace test } // namespace webrtc diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc index 852c9574ad..fb3305e01d 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -600,6 +600,7 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged( BWE_TEST_LOGGING_PLOT(1, "Target_bitrate_kbps", at_time.ms(), loss_based_target_rate.kbps()); + double cwnd_reduce_ratio = 0.0; if (congestion_window_pushback_controller_) { int64_t pushback_rate = congestion_window_pushback_controller_->UpdateTargetBitrate( @@ -607,6 +608,11 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged( pushback_rate = std::max(bandwidth_estimation_->GetMinBitrate(), pushback_rate); pushback_target_rate = DataRate::bps(pushback_rate); + if (rate_control_settings_.UseCongestionWindowDropFrameOnly()) { + cwnd_reduce_ratio = static_cast(loss_based_target_rate.bps() - + pushback_target_rate.bps()) / + loss_based_target_rate.bps(); + } } if ((loss_based_target_rate != last_loss_based_target_rate_) || @@ -624,7 +630,12 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged( TargetTransferRate target_rate_msg; target_rate_msg.at_time = at_time; - target_rate_msg.target_rate = pushback_target_rate; + if (rate_control_settings_.UseCongestionWindowDropFrameOnly()) { + target_rate_msg.target_rate = loss_based_target_rate; + target_rate_msg.cwnd_reduce_ratio = cwnd_reduce_ratio; + } else { + target_rate_msg.target_rate = pushback_target_rate; + } if (loss_based_stable_rate_) { target_rate_msg.stable_target_rate = std::min(bandwidth_estimation_->GetEstimatedLinkCapacity(), diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc index 09aec436c1..3ce9a77841 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc @@ -289,6 +289,40 @@ TEST_F(GoogCcNetworkControllerTest, CongestionWindowPushbackOnNetworkDelay) { EXPECT_LT(client->target_rate().kbps(), 40); } +// Test congestion window pushback on network delay happens. +TEST_F(GoogCcNetworkControllerTest, + CongestionWindowPushbackDropFrameOnNetworkDelay) { + auto factory = CreateFeedbackOnlyFactory(); + ScopedFieldTrials trial( + "WebRTC-CongestionWindow/QueueSize:800,MinBitrate:30000,DropFrame:true/"); + Scenario s("googcc_unit/cwnd_on_delay", false); + auto send_net = + s.CreateMutableSimulationNode([=](NetworkSimulationConfig* c) { + c->bandwidth = DataRate::kbps(1000); + c->delay = TimeDelta::ms(100); + }); + auto ret_net = s.CreateSimulationNode( + [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(100); }); + CallClientConfig config; + config.transport.cc_factory = &factory; + // Start high so bandwidth drop has max effect. + config.transport.rates.start_rate = DataRate::kbps(300); + config.transport.rates.max_rate = DataRate::kbps(2000); + config.transport.rates.min_rate = DataRate::kbps(10); + + auto* client = CreateVideoSendingClient(&s, std::move(config), + {send_net->node()}, {ret_net}); + + s.RunFor(TimeDelta::seconds(10)); + send_net->PauseTransmissionUntil(s.Now() + TimeDelta::seconds(10)); + s.RunFor(TimeDelta::seconds(3)); + + // As the dropframe is set, after 3 seconds without feedback from any sent + // packets, we expect that the target rate is not reduced by congestion + // window. + EXPECT_GT(client->target_rate().kbps(), 300); +} + TEST_F(GoogCcNetworkControllerTest, OnNetworkRouteChanged) { NetworkControlUpdate update; DataRate new_bitrate = DataRate::bps(200000); diff --git a/rtc_base/experiments/rate_control_settings.cc b/rtc_base/experiments/rate_control_settings.cc index bf623bda86..ce77c9e631 100644 --- a/rtc_base/experiments/rate_control_settings.cc +++ b/rtc_base/experiments/rate_control_settings.cc @@ -63,7 +63,8 @@ constexpr char CongestionWindowConfig::kKey[]; std::unique_ptr CongestionWindowConfig::Parser() { return StructParametersParser::Create("QueueSize", &queue_size_ms, // "MinBitrate", &min_bitrate_bps, - "InitWin", &initial_data_window); + "InitWin", &initial_data_window, + "DropFrame", &drop_frame_only); } // static @@ -142,6 +143,10 @@ bool RateControlSettings::UseCongestionWindowPushback() const { congestion_window_config_.min_bitrate_bps; } +bool RateControlSettings::UseCongestionWindowDropFrameOnly() const { + return congestion_window_config_.drop_frame_only; +} + uint32_t RateControlSettings::CongestionWindowMinPushbackTargetBitrateBps() const { return congestion_window_config_.min_bitrate_bps.value_or( diff --git a/rtc_base/experiments/rate_control_settings.h b/rtc_base/experiments/rate_control_settings.h index 3f1d8dee70..6898bf6dd3 100644 --- a/rtc_base/experiments/rate_control_settings.h +++ b/rtc_base/experiments/rate_control_settings.h @@ -25,6 +25,7 @@ struct CongestionWindowConfig { absl::optional queue_size_ms; absl::optional min_bitrate_bps; absl::optional initial_data_window; + bool drop_frame_only = false; std::unique_ptr Parser(); static CongestionWindowConfig Parse(absl::string_view config); }; @@ -66,6 +67,7 @@ class RateControlSettings final { bool UseCongestionWindow() const; int64_t GetCongestionWindowAdditionalTimeMs() const; bool UseCongestionWindowPushback() const; + bool UseCongestionWindowDropFrameOnly() const; uint32_t CongestionWindowMinPushbackTargetBitrateBps() const; absl::optional CongestionWindowInitialDataWindow() const; diff --git a/video/send_statistics_proxy.cc b/video/send_statistics_proxy.cc index a4f17547bd..094baa3157 100644 --- a/video/send_statistics_proxy.cc +++ b/video/send_statistics_proxy.cc @@ -652,9 +652,11 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "DroppedFrames.Encoder", current_stats.frames_dropped_by_encoder); log_stream << uma_prefix_ << "DroppedFrames.Ratelimiter " - << current_stats.frames_dropped_by_rate_limiter; + << current_stats.frames_dropped_by_rate_limiter << "\n"; RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "DroppedFrames.Ratelimiter", current_stats.frames_dropped_by_rate_limiter); + log_stream << uma_prefix_ << "DroppedFrames.CongestionWindow " + << current_stats.frames_dropped_by_congestion_window; RTC_LOG(LS_INFO) << log_stream.str(); } @@ -1042,6 +1044,9 @@ void SendStatisticsProxy::OnFrameDropped(DropReason reason) { case DropReason::kMediaOptimization: ++stats_.frames_dropped_by_rate_limiter; break; + case DropReason::kCongestionWindow: + ++stats_.frames_dropped_by_congestion_window; + break; } } diff --git a/video/test/mock_video_stream_encoder.h b/video/test/mock_video_stream_encoder.h index 494419dffd..8e429681b8 100644 --- a/video/test/mock_video_stream_encoder.h +++ b/video/test/mock_video_stream_encoder.h @@ -24,8 +24,8 @@ class MockVideoStreamEncoder : public VideoStreamEncoderInterface { MOCK_METHOD1(SetStartBitrate, void(int)); MOCK_METHOD0(SendKeyFrame, void()); MOCK_METHOD1(OnLossNotification, void(const VideoEncoder::LossNotification&)); - MOCK_METHOD5(OnBitrateUpdated, - void(DataRate, DataRate, DataRate, uint8_t, int64_t)); + MOCK_METHOD6(OnBitrateUpdated, + void(DataRate, DataRate, DataRate, uint8_t, int64_t, double)); MOCK_METHOD1(OnFrame, void(const VideoFrame&)); MOCK_METHOD1(SetBitrateAllocationObserver, void(VideoBitrateAllocationObserver*)); diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc index 97f3bb7f4c..9ecb36ae92 100644 --- a/video/video_send_stream_impl.cc +++ b/video/video_send_stream_impl.cc @@ -387,7 +387,7 @@ void VideoSendStreamImpl::StopVideoSendStream() { bitrate_allocator_->RemoveObserver(this); check_encoder_activity_task_.Stop(); video_stream_encoder_->OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), - DataRate::Zero(), 0, 0); + DataRate::Zero(), 0, 0, 0); stats_proxy_->OnSetEncoderTargetRate(0); } @@ -646,7 +646,7 @@ uint32_t VideoSendStreamImpl::OnBitrateUpdated(BitrateAllocationUpdate update) { video_stream_encoder_->OnBitrateUpdated( encoder_target_rate, encoder_stable_target_rate, link_allocation, rtc::dchecked_cast(update.packet_loss_ratio * 256), - update.round_trip_time.ms()); + update.round_trip_time.ms(), update.cwnd_reduce_ratio); stats_proxy_->OnSetEncoderTargetRate(encoder_target_rate_bps_); return protection_bitrate_bps; } diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc index 1c44cc8dd4..06cad22cba 100644 --- a/video/video_send_stream_impl_unittest.cc +++ b/video/video_send_stream_impl_unittest.cc @@ -706,7 +706,7 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { EXPECT_CALL( video_stream_encoder_, OnBitrateUpdated(network_constrained_rate, network_constrained_rate, - network_constrained_rate, 0, _)); + network_constrained_rate, 0, _, 0)); static_cast(vss_impl.get()) ->OnBitrateUpdated(update); @@ -723,7 +723,7 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { .WillOnce(Return(rate_with_headroom.bps())); EXPECT_CALL(video_stream_encoder_, OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, - rate_with_headroom, 0, _)); + rate_with_headroom, 0, _, 0)); static_cast(vss_impl.get()) ->OnBitrateUpdated(update); @@ -740,7 +740,7 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { rate_with_headroom - DataRate::bps(protection_bitrate_bps); EXPECT_CALL(video_stream_encoder_, OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, - headroom_minus_protection, 0, _)); + headroom_minus_protection, 0, _, 0)); static_cast(vss_impl.get()) ->OnBitrateUpdated(update); @@ -753,14 +753,14 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { .WillOnce(Return(rate_with_headroom.bps())); EXPECT_CALL(video_stream_encoder_, OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, - qvga_max_bitrate, 0, _)); + qvga_max_bitrate, 0, _, 0)); static_cast(vss_impl.get()) ->OnBitrateUpdated(update); // Set rates to zero on stop. EXPECT_CALL(video_stream_encoder_, OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), - DataRate::Zero(), 0, 0)); + DataRate::Zero(), 0, 0, 0)); vss_impl->Stop(); }, RTC_FROM_HERE); diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 1ae4856b73..4079ab5f73 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -273,7 +273,8 @@ VideoStreamEncoder::VideoStreamEncoder( clock_->TimeInMilliseconds()), last_frame_log_ms_(clock_->TimeInMilliseconds()), captured_frame_count_(0), - dropped_frame_count_(0), + dropped_frame_cwnd_pushback_count_(0), + dropped_frame_encoder_block_count_(0), pending_frame_post_time_us_(0), accumulated_update_rect_{0, 0, 0, 0}, accumulated_update_rect_is_valid_(true), @@ -285,6 +286,7 @@ VideoStreamEncoder::VideoStreamEncoder( force_disable_frame_dropper_(false), input_framerate_(kFrameRateAvergingWindowSizeMs, 1000), pending_frame_drops_(0), + cwnd_frame_counter_(0), next_frame_types_(1, VideoFrameType::kVideoFrameDelta), frame_encode_metadata_writer_(this), experiment_groups_(GetExperimentGroups()), @@ -823,26 +825,40 @@ void VideoStreamEncoder::OnFrame(const VideoFrame& video_frame) { posted_frames_waiting_for_encode_.fetch_sub(1); RTC_DCHECK_GT(posted_frames_waiting_for_encode, 0); CheckForAnimatedContent(incoming_frame, post_time_us); - if (posted_frames_waiting_for_encode == 1) { + bool cwnd_frame_drop = + cwnd_frame_drop_interval_ && + (cwnd_frame_counter_++ % cwnd_frame_drop_interval_.value() == 0); + if (posted_frames_waiting_for_encode == 1 && !cwnd_frame_drop) { MaybeEncodeVideoFrame(incoming_frame, post_time_us); } else { - // There is a newer frame in flight. Do not encode this frame. - RTC_LOG(LS_VERBOSE) - << "Incoming frame dropped due to that the encoder is blocked."; - ++dropped_frame_count_; - encoder_stats_observer_->OnFrameDropped( - VideoStreamEncoderObserver::DropReason::kEncoderQueue); + if (cwnd_frame_drop) { + // Frame drop by congestion window pusback. Do not encode this + // frame. + ++dropped_frame_cwnd_pushback_count_; + encoder_stats_observer_->OnFrameDropped( + VideoStreamEncoderObserver::DropReason::kCongestionWindow); + } else { + // There is a newer frame in flight. Do not encode this frame. + RTC_LOG(LS_VERBOSE) + << "Incoming frame dropped due to that the encoder is blocked."; + ++dropped_frame_encoder_block_count_; + encoder_stats_observer_->OnFrameDropped( + VideoStreamEncoderObserver::DropReason::kEncoderQueue); + } accumulated_update_rect_.Union(incoming_frame.update_rect()); accumulated_update_rect_is_valid_ &= incoming_frame.has_update_rect(); } if (log_stats) { RTC_LOG(LS_INFO) << "Number of frames: captured " << captured_frame_count_ + << ", dropped (due to congestion window pushback) " + << dropped_frame_cwnd_pushback_count_ << ", dropped (due to encoder blocked) " - << dropped_frame_count_ << ", interval_ms " - << kFrameLogIntervalMs; + << dropped_frame_encoder_block_count_ + << ", interval_ms " << kFrameLogIntervalMs; captured_frame_count_ = 0; - dropped_frame_count_ = 0; + dropped_frame_cwnd_pushback_count_ = 0; + dropped_frame_encoder_block_count_ = 0; } }); } @@ -1484,18 +1500,49 @@ void VideoStreamEncoder::OnDroppedFrame(DropReason reason) { }); } +DataRate VideoStreamEncoder::UpdateTargetBitrate(DataRate target_bitrate, + double cwnd_reduce_ratio) { + RTC_DCHECK_RUN_ON(&encoder_queue_); + DataRate updated_target_bitrate = target_bitrate; + + // Drop frames when congestion window pushback ratio is larger than 1 + // percent and target bitrate is larger than codec min bitrate. + // When target_bitrate is 0 means codec is paused, skip frame dropping. + if (cwnd_reduce_ratio > 0.01 && target_bitrate.bps() > 0 && + target_bitrate.bps() > send_codec_.minBitrate * 1000) { + int reduce_bitrate_bps = std::min( + static_cast(target_bitrate.bps() * cwnd_reduce_ratio), + static_cast(target_bitrate.bps() - send_codec_.minBitrate * 1000)); + if (reduce_bitrate_bps > 0) { + // At maximum the congestion window can drop 1/2 frames. + cwnd_frame_drop_interval_ = std::max( + 2, static_cast(target_bitrate.bps() / reduce_bitrate_bps)); + // Reduce target bitrate accordingly. + updated_target_bitrate = + target_bitrate - (target_bitrate / cwnd_frame_drop_interval_.value()); + return updated_target_bitrate; + } + } + cwnd_frame_drop_interval_.reset(); + return updated_target_bitrate; +} + void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate, DataRate stable_target_bitrate, DataRate link_allocation, uint8_t fraction_lost, - int64_t round_trip_time_ms) { + int64_t round_trip_time_ms, + double cwnd_reduce_ratio) { RTC_DCHECK_GE(link_allocation, target_bitrate); if (!encoder_queue_.IsCurrent()) { encoder_queue_.PostTask([this, target_bitrate, stable_target_bitrate, - link_allocation, fraction_lost, - round_trip_time_ms] { - OnBitrateUpdated(target_bitrate, stable_target_bitrate, link_allocation, - fraction_lost, round_trip_time_ms); + link_allocation, fraction_lost, round_trip_time_ms, + cwnd_reduce_ratio] { + DataRate updated_target_bitrate = + UpdateTargetBitrate(target_bitrate, cwnd_reduce_ratio); + OnBitrateUpdated(updated_target_bitrate, stable_target_bitrate, + link_allocation, fraction_lost, round_trip_time_ms, + cwnd_reduce_ratio); }); return; } diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h index fee106703c..0390d7fdf0 100644 --- a/video/video_stream_encoder.h +++ b/video/video_stream_encoder.h @@ -110,7 +110,11 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, DataRate stable_target_bitrate, DataRate target_headroom, uint8_t fraction_lost, - int64_t round_trip_time_ms) override; + int64_t round_trip_time_ms, + double cwnd_reduce_ratio) override; + + DataRate UpdateTargetBitrate(DataRate target_bitrate, + double cwnd_reduce_ratio); protected: // Used for testing. For example the |ScalingObserverInterface| methods must @@ -269,7 +273,8 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, int64_t last_frame_log_ms_ RTC_GUARDED_BY(incoming_frame_race_checker_); int captured_frame_count_ RTC_GUARDED_BY(&encoder_queue_); - int dropped_frame_count_ RTC_GUARDED_BY(&encoder_queue_); + int dropped_frame_cwnd_pushback_count_ RTC_GUARDED_BY(&encoder_queue_); + int dropped_frame_encoder_block_count_ RTC_GUARDED_BY(&encoder_queue_); absl::optional pending_frame_ RTC_GUARDED_BY(&encoder_queue_); int64_t pending_frame_post_time_us_ RTC_GUARDED_BY(&encoder_queue_); @@ -317,6 +322,12 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // the worker thread. std::atomic pending_frame_drops_; + // Congestion window frame drop ratio (drop 1 in every + // cwnd_frame_drop_interval_ frames). + absl::optional cwnd_frame_drop_interval_ RTC_GUARDED_BY(&encoder_queue_); + // Frame counter for congestion window frame drop. + int cwnd_frame_counter_ RTC_GUARDED_BY(&encoder_queue_); + std::unique_ptr bitrate_adjuster_ RTC_GUARDED_BY(&encoder_queue_); diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc index 472027b478..d7cf579dba 100644 --- a/video/video_stream_encoder_unittest.cc +++ b/video/video_stream_encoder_unittest.cc @@ -547,7 +547,7 @@ class VideoStreamEncoderTest : public ::testing::Test { .Times(1); video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame( CreateFrame(1, codec_width_, codec_height_)); @@ -1157,7 +1157,7 @@ class VideoStreamEncoderTest : public ::testing::Test { TEST_F(VideoStreamEncoderTest, EncodeOneFrame) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); rtc::Event frame_destroyed_event; video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event)); WaitForEncodedFrame(1); @@ -1177,7 +1177,7 @@ TEST_F(VideoStreamEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // The pending frame should be received. WaitForEncodedFrame(2); @@ -1190,12 +1190,12 @@ TEST_F(VideoStreamEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) { TEST_F(VideoStreamEncoderTest, DropsFramesWhenRateSetToZero) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr)); WaitForEncodedFrame(1); video_stream_encoder_->OnBitrateUpdated(DataRate::bps(0), DataRate::bps(0), - DataRate::bps(0), 0, 0); + DataRate::bps(0), 0, 0, 0); // The encoder will cache up to one frame for a short duration. Adding two // frames means that the first frame will be dropped and the second frame will // be sent when the encoder is resumed. @@ -1204,7 +1204,7 @@ TEST_F(VideoStreamEncoderTest, DropsFramesWhenRateSetToZero) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); WaitForEncodedFrame(3); video_source_.IncomingCapturedFrame(CreateFrame(4, nullptr)); WaitForEncodedFrame(4); @@ -1214,7 +1214,7 @@ TEST_F(VideoStreamEncoderTest, DropsFramesWhenRateSetToZero) { TEST_F(VideoStreamEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr)); WaitForEncodedFrame(1); @@ -1229,7 +1229,7 @@ TEST_F(VideoStreamEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) { TEST_F(VideoStreamEncoderTest, DropsFrameAfterStop) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr)); WaitForEncodedFrame(1); @@ -1244,7 +1244,7 @@ TEST_F(VideoStreamEncoderTest, DropsFrameAfterStop) { TEST_F(VideoStreamEncoderTest, DropsPendingFramesOnSlowEncode) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); fake_encoder_.BlockNextEncode(); video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr)); @@ -1262,7 +1262,7 @@ TEST_F(VideoStreamEncoderTest, DropsPendingFramesOnSlowEncode) { TEST_F(VideoStreamEncoderTest, DropFrameWithFailedI420Conversion) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); rtc::Event frame_destroyed_event; video_source_.IncomingCapturedFrame( @@ -1283,7 +1283,7 @@ TEST_F(VideoStreamEncoderTest, DropFrameWithFailedI420ConversionWithCrop) { // Capture a frame at codec_width_/codec_height_. video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr)); WaitForEncodedFrame(1); // The encoder will have been configured once. @@ -1301,11 +1301,34 @@ TEST_F(VideoStreamEncoderTest, DropFrameWithFailedI420ConversionWithCrop) { video_stream_encoder_->Stop(); } +TEST_F(VideoStreamEncoderTest, DropsFramesWhenCongestionWindowPushbackSet) { + video_stream_encoder_->OnBitrateUpdated( + DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), + DataRate::bps(kTargetBitrateBps), 0, 0, 0); + video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr)); + WaitForEncodedFrame(1); + + video_stream_encoder_->OnBitrateUpdated( + DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), + DataRate::bps(kTargetBitrateBps), 0, 0, 0.5); + // The congestion window pushback is set to 0.5, which will drop 1/2 of + // frames. Adding two frames means that the first frame will be dropped and + // the second frame will be sent to the encoder. + video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr)); + video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr)); + WaitForEncodedFrame(3); + video_source_.IncomingCapturedFrame(CreateFrame(4, nullptr)); + video_source_.IncomingCapturedFrame(CreateFrame(5, nullptr)); + WaitForEncodedFrame(5); + EXPECT_EQ(2u, stats_proxy_->GetStats().frames_dropped_by_congestion_window); + video_stream_encoder_->Stop(); +} + TEST_F(VideoStreamEncoderTest, ConfigureEncoderTriggersOnEncoderConfigurationChanged) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); EXPECT_EQ(0, sink_.number_of_reconfigurations()); // Capture a frame and wait for it to synchronize with the encoder thread. @@ -1333,7 +1356,7 @@ TEST_F(VideoStreamEncoderTest, TEST_F(VideoStreamEncoderTest, FrameResolutionChangeReconfigureEncoder) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Capture a frame and wait for it to synchronize with the encoder thread. video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr)); @@ -1360,7 +1383,7 @@ TEST_F(VideoStreamEncoderTest, EncoderInstanceDestroyedBeforeAnotherInstanceCreated) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Capture a frame and wait for it to synchronize with the encoder thread. video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr)); @@ -1383,7 +1406,7 @@ TEST_F(VideoStreamEncoderTest, TEST_F(VideoStreamEncoderTest, BitrateLimitsChangeReconfigureRateAllocator) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); VideoEncoderConfig video_encoder_config; test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config); @@ -1429,7 +1452,7 @@ TEST_F(VideoStreamEncoderTest, IntersectionOfEncoderAndAppBitrateLimitsUsedWhenBothProvided) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const uint32_t kMinEncBitrateKbps = 100; const uint32_t kMaxEncBitrateKbps = 1000; @@ -1476,7 +1499,7 @@ TEST_F(VideoStreamEncoderTest, EncoderAndAppLimitsDontIntersectEncoderLimitsIgnored) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const uint32_t kMinAppBitrateKbps = 100; const uint32_t kMaxAppBitrateKbps = 200; @@ -1511,7 +1534,7 @@ TEST_F(VideoStreamEncoderTest, EncoderRecommendedMaxAndMinBitratesUsedForGivenResolution) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const VideoEncoder::ResolutionBitrateLimits encoder_bitrate_limits_270p( 480 * 270, 34 * 1000, 12 * 1000, 1234 * 1000); @@ -1580,7 +1603,7 @@ TEST_F(VideoStreamEncoderTest, TEST_F(VideoStreamEncoderTest, EncoderRecommendedMaxBitrateCapsTargetBitrate) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); VideoEncoderConfig video_encoder_config; test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config); @@ -1645,7 +1668,7 @@ TEST_F(VideoStreamEncoderTest, SinkWantsResolutionAlignment) { fake_encoder_.SetRequestedResolutionAlignment(kRequestedResolutionAlignment); video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // On the 1st frame, we should have initialized the encoder and // asked for its resolution requirements. @@ -1678,7 +1701,7 @@ TEST_F(VideoStreamEncoderTest, TestCpuDowngrades_BalancedMode) { // Enable BALANCED preference, no initial limitation. video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_stream_encoder_->SetSource(&video_source_, webrtc::DegradationPreference::BALANCED); VerifyNoLimitation(video_source_.sink_wants()); @@ -1763,7 +1786,7 @@ TEST_F(VideoStreamEncoderTest, TestCpuDowngrades_BalancedMode) { TEST_F(VideoStreamEncoderTest, SinkWantsStoredByDegradationPreference) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); VerifyNoLimitation(video_source_.sink_wants()); const int kFrameWidth = 1280; @@ -1876,7 +1899,7 @@ TEST_F(VideoStreamEncoderTest, SinkWantsStoredByDegradationPreference) { TEST_F(VideoStreamEncoderTest, StatsTracksQualityAdaptationStats) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const int kWidth = 1280; const int kHeight = 720; @@ -1911,7 +1934,7 @@ TEST_F(VideoStreamEncoderTest, StatsTracksQualityAdaptationStats) { TEST_F(VideoStreamEncoderTest, StatsTracksCpuAdaptationStats) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const int kWidth = 1280; const int kHeight = 720; @@ -1946,7 +1969,7 @@ TEST_F(VideoStreamEncoderTest, StatsTracksCpuAdaptationStats) { TEST_F(VideoStreamEncoderTest, SwitchingSourceKeepsCpuAdaptation) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const int kWidth = 1280; const int kHeight = 720; @@ -2016,7 +2039,7 @@ TEST_F(VideoStreamEncoderTest, SwitchingSourceKeepsCpuAdaptation) { TEST_F(VideoStreamEncoderTest, SwitchingSourceKeepsQualityAdaptation) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const int kWidth = 1280; const int kHeight = 720; @@ -2078,7 +2101,7 @@ TEST_F(VideoStreamEncoderTest, QualityAdaptationStatsAreResetWhenScalerIsDisabled) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const int kWidth = 1280; const int kHeight = 720; @@ -2135,7 +2158,7 @@ TEST_F(VideoStreamEncoderTest, StatsTracksCpuAdaptationStatsWhenSwitchingSource) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const int kWidth = 1280; const int kHeight = 720; @@ -2273,7 +2296,7 @@ TEST_F(VideoStreamEncoderTest, const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Expect no scaling to begin with. VerifyNoLimitation(video_source_.sink_wants()); @@ -2323,7 +2346,7 @@ TEST_F(VideoStreamEncoderTest, const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable MAINTAIN_FRAMERATE preference, no initial limitation. test::FrameForwarder source; @@ -2357,7 +2380,7 @@ TEST_F(VideoStreamEncoderTest, SkipsSameOrLargerAdaptDownRequest_BalancedMode) { const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable BALANCED preference, no initial limitation. test::FrameForwarder source; @@ -2399,7 +2422,7 @@ TEST_F(VideoStreamEncoderTest, const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable MAINTAIN_FRAMERATE preference, no initial limitation. test::FrameForwarder source; @@ -2427,7 +2450,7 @@ TEST_F(VideoStreamEncoderTest, const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable MAINTAIN_RESOLUTION preference, no initial limitation. test::FrameForwarder source; @@ -2454,7 +2477,7 @@ TEST_F(VideoStreamEncoderTest, NoChangeForInitialNormalUsage_BalancedMode) { const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable BALANCED preference, no initial limitation. test::FrameForwarder source; @@ -2483,7 +2506,7 @@ TEST_F(VideoStreamEncoderTest, NoChangeForInitialNormalUsage_DisabledMode) { const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable DISABLED preference, no initial limitation. test::FrameForwarder source; @@ -2513,7 +2536,7 @@ TEST_F(VideoStreamEncoderTest, const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable MAINTAIN_FRAMERATE preference, no initial limitation. AdaptingFrameForwarder source; @@ -2552,7 +2575,7 @@ TEST_F(VideoStreamEncoderTest, const int kInputFps = 30; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); VideoSendStream::Stats stats = stats_proxy_->GetStats(); stats.input_frame_rate = kInputFps; @@ -2599,7 +2622,7 @@ TEST_F(VideoStreamEncoderTest, DoesNotScaleBelowSetResolutionLimit) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable adapter, expected input resolutions when downscaling: // 1280x720 -> 960x540 -> 640x360 -> 480x270 -> 320x180 (kMinPixelsPerFrame) @@ -2636,7 +2659,7 @@ TEST_F(VideoStreamEncoderTest, const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable MAINTAIN_FRAMERATE preference, no initial limitation. AdaptingFrameForwarder source; @@ -2696,7 +2719,7 @@ TEST_F(VideoStreamEncoderTest, const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable BALANCED preference, no initial limitation. AdaptingFrameForwarder source; @@ -2757,7 +2780,7 @@ TEST_F(VideoStreamEncoderTest, AdaptUpIfBwEstimateIsHigherThanMinBitrate) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), - DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), 0, 0); + DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), 0, 0, 0); // Enable MAINTAIN_FRAMERATE preference, no initial limitation. AdaptingFrameForwarder source; @@ -2774,7 +2797,7 @@ TEST_F(VideoStreamEncoderTest, AdaptUpIfBwEstimateIsHigherThanMinBitrate) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), - DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), 0, 0); + DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), 0, 0, 0); video_stream_encoder_->TriggerQualityLow(); // Insert 720p frame. It should be downscaled and encoded. @@ -2791,7 +2814,7 @@ TEST_F(VideoStreamEncoderTest, AdaptUpIfBwEstimateIsHigherThanMinBitrate) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), - DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), 0, 0); + DataRate::bps(kEncoderBitrateLimits720p.min_start_bitrate_bps), 0, 0, 0); // Trigger adapt up. Higher resolution should be requested. video_stream_encoder_->TriggerQualityHigh(); @@ -2808,7 +2831,7 @@ TEST_F(VideoStreamEncoderTest, DropFirstFramesIfBwEstimateIsTooLow) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), - DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), 0, 0); + DataRate::bps(kEncoderBitrateLimits540p.min_start_bitrate_bps), 0, 0, 0); // Enable MAINTAIN_FRAMERATE preference, no initial limitation. AdaptingFrameForwarder source; @@ -2844,9 +2867,9 @@ class BalancedDegradationTest : public VideoStreamEncoderTest { } void OnBitrateUpdated(int bitrate_bps) { - video_stream_encoder_->OnBitrateUpdated(DataRate::bps(bitrate_bps), - DataRate::bps(bitrate_bps), - DataRate::bps(bitrate_bps), 0, 0); + video_stream_encoder_->OnBitrateUpdated( + DataRate::bps(bitrate_bps), DataRate::bps(bitrate_bps), + DataRate::bps(bitrate_bps), 0, 0, 0); } void InsertFrame() { @@ -3132,7 +3155,7 @@ TEST_F(VideoStreamEncoderTest, const int kHeight = 720; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable MAINTAIN_FRAMERATE preference, no initial limitation. AdaptingFrameForwarder source; @@ -3271,7 +3294,7 @@ TEST_F(VideoStreamEncoderTest, CpuLimitedHistogramIsReported) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) { video_source_.IncomingCapturedFrame(CreateFrame(i, kWidth, kHeight)); @@ -3299,7 +3322,7 @@ TEST_F(VideoStreamEncoderTest, CpuLimitedHistogramIsNotReportedForDisabledDegradation) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const int kWidth = 640; const int kHeight = 360; @@ -3333,7 +3356,7 @@ TEST_F(VideoStreamEncoderTest, CallsBitrateObserver) { .Times(1); video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kLowTargetBitrateBps), DataRate::bps(kLowTargetBitrateBps), - DataRate::bps(kLowTargetBitrateBps), 0, 0); + DataRate::bps(kLowTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame( CreateFrame(rtc::TimeMillis(), codec_width_, codec_height_)); @@ -3441,7 +3464,7 @@ TEST_F(VideoStreamEncoderTest, OveruseDetectorUpdatedOnReconfigureAndAdaption) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); test::FrameForwarder source; video_stream_encoder_->SetSource( &source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION); @@ -3503,7 +3526,7 @@ TEST_F(VideoStreamEncoderTest, video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); test::FrameForwarder source; video_stream_encoder_->SetSource( &source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION); @@ -3568,7 +3591,7 @@ TEST_F(VideoStreamEncoderTest, video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); test::FrameForwarder source; video_stream_encoder_->SetSource( &source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION); @@ -3616,7 +3639,7 @@ TEST_F(VideoStreamEncoderTest, DropsFramesAndScalesWhenBitrateIsTooLow) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTooLowBitrateForFrameSizeBps), DataRate::bps(kTooLowBitrateForFrameSizeBps), - DataRate::bps(kTooLowBitrateForFrameSizeBps), 0, 0); + DataRate::bps(kTooLowBitrateForFrameSizeBps), 0, 0, 0); const int kWidth = 640; const int kHeight = 360; @@ -3648,7 +3671,7 @@ TEST_F(VideoStreamEncoderTest, video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTooLowBitrateForFrameSizeBps), DataRate::bps(kTooLowBitrateForFrameSizeBps), - DataRate::bps(kTooLowBitrateForFrameSizeBps), 0, 0); + DataRate::bps(kTooLowBitrateForFrameSizeBps), 0, 0, 0); const int kWidth = 640; const int kHeight = 360; @@ -3674,7 +3697,7 @@ TEST_F(VideoStreamEncoderTest, const int kHeight = 360; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kLowTargetBitrateBps), DataRate::bps(kLowTargetBitrateBps), - DataRate::bps(kLowTargetBitrateBps), 0, 0); + DataRate::bps(kLowTargetBitrateBps), 0, 0, 0); // Set degradation preference. video_stream_encoder_->SetSource( @@ -3700,7 +3723,7 @@ TEST_F(VideoStreamEncoderTest, InitialFrameDropOffWhenEncoderDisabledScaling) { kMaxPayloadLength); video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kLowTargetBitrateBps), DataRate::bps(kLowTargetBitrateBps), - DataRate::bps(kLowTargetBitrateBps), 0, 0); + DataRate::bps(kLowTargetBitrateBps), 0, 0, 0); // Force quality scaler reconfiguration by resetting the source. video_stream_encoder_->SetSource(&video_source_, @@ -3727,7 +3750,7 @@ TEST_F(VideoStreamEncoderTest, InitialFrameDropActivatesWhenBweDrops) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight)); // Frame should not be dropped. WaitForEncodedFrame(1); @@ -3735,7 +3758,7 @@ TEST_F(VideoStreamEncoderTest, InitialFrameDropActivatesWhenBweDrops) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kNotTooLowBitrateForFrameSizeBps), DataRate::bps(kNotTooLowBitrateForFrameSizeBps), - DataRate::bps(kNotTooLowBitrateForFrameSizeBps), 0, 0); + DataRate::bps(kNotTooLowBitrateForFrameSizeBps), 0, 0, 0); video_source_.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight)); // Frame should not be dropped. WaitForEncodedFrame(2); @@ -3743,7 +3766,7 @@ TEST_F(VideoStreamEncoderTest, InitialFrameDropActivatesWhenBweDrops) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTooLowBitrateForFrameSizeBps), DataRate::bps(kTooLowBitrateForFrameSizeBps), - DataRate::bps(kTooLowBitrateForFrameSizeBps), 0, 0); + DataRate::bps(kTooLowBitrateForFrameSizeBps), 0, 0, 0); video_source_.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight)); // Expect to drop this frame, the wait should time out. ExpectDroppedFrame(); @@ -3771,9 +3794,9 @@ TEST_F(VideoStreamEncoderTest, RampsUpInQualityWhenBwIsHigh) { // Start at low bitrate. const int kLowBitrateBps = 200000; - video_stream_encoder_->OnBitrateUpdated(DataRate::bps(kLowBitrateBps), - DataRate::bps(kLowBitrateBps), - DataRate::bps(kLowBitrateBps), 0, 0); + video_stream_encoder_->OnBitrateUpdated( + DataRate::bps(kLowBitrateBps), DataRate::bps(kLowBitrateBps), + DataRate::bps(kLowBitrateBps), 0, 0, 0); // Expect first frame to be dropped and resolution to be limited. const int kWidth = 1280; @@ -3788,7 +3811,7 @@ TEST_F(VideoStreamEncoderTest, RampsUpInQualityWhenBwIsHigh) { video_stream_encoder_->OnBitrateUpdated(DataRate::bps(config.max_bitrate_bps), DataRate::bps(config.max_bitrate_bps), DataRate::bps(config.max_bitrate_bps), - 0, 0); + 0, 0, 0); // Insert frames and advance |min_duration_ms|. for (size_t i = 1; i <= 10; i++) { @@ -3822,7 +3845,7 @@ TEST_F(VideoStreamEncoderTest, const int kTooSmallHeight = 10; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable MAINTAIN_FRAMERATE preference, no initial limitation. test::FrameForwarder source; @@ -3849,7 +3872,7 @@ TEST_F(VideoStreamEncoderTest, const int kFpsLimit = 7; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable BALANCED preference, no initial limitation. test::FrameForwarder source; @@ -3884,7 +3907,7 @@ TEST_F(VideoStreamEncoderTest, FailingInitEncodeDoesntCauseCrash) { fake_encoder_.ForceInitEncodeFailure(true); video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); ResetEncoder("VP8", 2, 1, 1, false); const int kFrameWidth = 1280; const int kFrameHeight = 720; @@ -3899,7 +3922,7 @@ TEST_F(VideoStreamEncoderTest, AdaptsResolutionOnOveruse_MaintainFramerateMode) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); const int kFrameWidth = 1280; const int kFrameHeight = 720; @@ -3934,7 +3957,7 @@ TEST_F(VideoStreamEncoderTest, video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_stream_encoder_->SetSource( &video_source_, webrtc::DegradationPreference::MAINTAIN_RESOLUTION); video_source_.set_adaptation_enabled(true); @@ -4037,7 +4060,7 @@ TEST_F(VideoStreamEncoderTest, DoesntAdaptDownPastMinFramerate) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_stream_encoder_->SetSource( &video_source_, webrtc::DegradationPreference::MAINTAIN_RESOLUTION); video_source_.set_adaptation_enabled(true); @@ -4077,7 +4100,7 @@ TEST_F(VideoStreamEncoderTest, int64_t timestamp_ms = kFrameIntervalMs; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable BALANCED preference, no initial limitation. AdaptingFrameForwarder source; @@ -4259,7 +4282,7 @@ TEST_F(VideoStreamEncoderTest, AdaptWithTwoReasonsAndDifferentOrder_Framerate) { int64_t timestamp_ms = kFrameIntervalMs; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable BALANCED preference, no initial limitation. AdaptingFrameForwarder source; @@ -4374,7 +4397,7 @@ TEST_F(VideoStreamEncoderTest, int64_t timestamp_ms = kFrameIntervalMs; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Enable BALANCED preference, no initial limitation. AdaptingFrameForwarder source; @@ -4464,7 +4487,7 @@ TEST_F(VideoStreamEncoderTest, AcceptsFullHdAdaptedDownSimulcastFrames) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Trigger reconfigure encoder (without resetting the entire instance). VideoEncoderConfig video_encoder_config; video_encoder_config.codec_type = kVideoCodecVP8; @@ -4499,7 +4522,7 @@ TEST_F(VideoStreamEncoderTest, PeriodicallyUpdatesChannelParameters) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec; max_framerate_ = kLowFps; @@ -4515,7 +4538,7 @@ TEST_F(VideoStreamEncoderTest, PeriodicallyUpdatesChannelParameters) { // Make sure encoder is updated with new target. video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame( CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight)); WaitForEncodedFrame(timestamp_ms); @@ -4554,7 +4577,7 @@ TEST_F(VideoStreamEncoderTest, DoesNotUpdateBitrateAllocationWhenSuspended) { video_stream_encoder_->SetBitrateAllocationObserver(&bitrate_observer); video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_stream_encoder_->WaitUntilTaskQueueIsIdle(); // Insert a first video frame, causes another bitrate update. @@ -4566,7 +4589,7 @@ TEST_F(VideoStreamEncoderTest, DoesNotUpdateBitrateAllocationWhenSuspended) { // Next, simulate video suspension due to pacer queue overrun. video_stream_encoder_->OnBitrateUpdated(DataRate::bps(0), DataRate::bps(0), - DataRate::bps(0), 0, 1); + DataRate::bps(0), 0, 1, 0); // Skip ahead until a new periodic parameter update should have occured. timestamp_ms += kProcessIntervalMs; @@ -4588,7 +4611,7 @@ TEST_F(VideoStreamEncoderTest, const CpuOveruseOptions default_options; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame( CreateFrame(1, kFrameWidth, kFrameHeight)); WaitForEncodedFrame(1); @@ -4612,7 +4635,7 @@ TEST_F(VideoStreamEncoderTest, video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_source_.IncomingCapturedFrame( CreateFrame(1, kFrameWidth, kFrameHeight)); WaitForEncodedFrame(1); @@ -4634,7 +4657,7 @@ TEST_F(VideoStreamEncoderTest, DropsFramesWhenEncoderOvershoots) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec; max_framerate_ = kFps; @@ -4671,7 +4694,7 @@ TEST_F(VideoStreamEncoderTest, DropsFramesWhenEncoderOvershoots) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps + 1000), DataRate::bps(kTargetBitrateBps + 1000), - DataRate::bps(kTargetBitrateBps + 1000), 0, 0); + DataRate::bps(kTargetBitrateBps + 1000), 0, 0, 0); num_dropped = 0; for (int i = 0; i < kNumFramesInRun; ++i) { video_source_.IncomingCapturedFrame( @@ -4685,7 +4708,7 @@ TEST_F(VideoStreamEncoderTest, DropsFramesWhenEncoderOvershoots) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Target framerate should be still be near the expected target, despite // the frame drops. @@ -4709,7 +4732,7 @@ TEST_F(VideoStreamEncoderTest, ConfiguresCorrectFrameRate) { max_framerate_ = kActualInputFps; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Insert 3 seconds of video, with an input fps lower than configured max. for (int i = 0; i < kActualInputFps * 3; ++i) { @@ -4729,7 +4752,7 @@ TEST_F(VideoStreamEncoderTest, AccumulatesUpdateRectOnDroppedFrames) { VideoFrame::UpdateRect rect; video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); fake_encoder_.BlockNextEncode(); video_source_.IncomingCapturedFrame( @@ -4774,7 +4797,7 @@ TEST_F(VideoStreamEncoderTest, AccumulatesUpdateRectOnDroppedFrames) { TEST_F(VideoStreamEncoderTest, SetsFrameTypes) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // First frame is always keyframe. video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr)); @@ -4807,7 +4830,7 @@ TEST_F(VideoStreamEncoderTest, SetsFrameTypesSimulcast) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kSimulcastTargetBitrateBps), DataRate::bps(kSimulcastTargetBitrateBps), - DataRate::bps(kSimulcastTargetBitrateBps), 0, 0); + DataRate::bps(kSimulcastTargetBitrateBps), 0, 0, 0); // Wait for all three layers before triggering event. sink_.SetNumExpectedLayers(3); @@ -4849,7 +4872,7 @@ TEST_F(VideoStreamEncoderTest, RequestKeyframeInternalSource) { ResetEncoder("VP8", 1, 1, 1, false); video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Call encoder directly, simulating internal source where encoded frame // callback in VideoStreamEncoder is called despite no OnFrame(). @@ -4887,7 +4910,7 @@ TEST_F(VideoStreamEncoderTest, AdjustsTimestampInternalSource) { ResetEncoder("VP8", 1, 1, 1, false); video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); int64_t timestamp = 1; EncodedImage image; @@ -4979,7 +5002,7 @@ TEST_F(VideoStreamEncoderTest, CopiesVideoFrameMetadataAfterDownscale) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_stream_encoder_->WaitUntilTaskQueueIsIdle(); // Insert a first video frame. It should be dropped because of downscale in @@ -5022,7 +5045,8 @@ TEST_F(VideoStreamEncoderTest, BandwidthAllocationLowerBound) { /*stable_target_bitrate=*/DataRate::kbps(300), /*link_allocation=*/DataRate::kbps(300), /*fraction_lost=*/0, - /*rtt_ms=*/0); + /*rtt_ms=*/0, + /*cwnd_reduce_ratio=*/0); // Insert a first video frame so that encoder gets configured. int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec; @@ -5040,7 +5064,8 @@ TEST_F(VideoStreamEncoderTest, BandwidthAllocationLowerBound) { /*stable_target_bitrate=*/target_rate, /*link_allocation=*/target_rate, /*fraction_lost=*/0, - /*rtt_ms=*/0); + /*rtt_ms=*/0, + /*cwnd_reduce_ratio=*/0); video_stream_encoder_->WaitUntilTaskQueueIsIdle(); // Target bitrate and bandwidth allocation should both be capped at min_rate. @@ -5056,7 +5081,7 @@ TEST_F(VideoStreamEncoderTest, BandwidthAllocationLowerBound) { TEST_F(VideoStreamEncoderTest, EncoderRatesPropagatedOnReconfigure) { video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); // Capture a frame and wait for it to synchronize with the encoder thread. int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec; video_source_.IncomingCapturedFrame(CreateFrame(timestamp_ms, nullptr)); @@ -5130,7 +5155,8 @@ TEST_F(VideoStreamEncoderTest, BitrateEncoderSwitch) { /*stable_target_bitrate=*/DataRate::kbps(kDontCare), /*link_allocation=*/DataRate::kbps(kDontCare), /*fraction_lost=*/0, - /*rtt_ms=*/0); + /*rtt_ms=*/0, + /*cwnd_reduce_ratio=*/0); video_stream_encoder_->Stop(); } @@ -5161,7 +5187,8 @@ TEST_F(VideoStreamEncoderTest, ResolutionEncoderSwitch) { /*stable_target_bitrate=*/DataRate::kbps(kSufficientBitrateToNotDrop), /*link_allocation=*/DataRate::kbps(kSufficientBitrateToNotDrop), /*fraction_lost=*/0, - /*rtt_ms=*/0); + /*rtt_ms=*/0, + /*cwnd_reduce_ratio=*/0); // Send one frame to trigger ReconfigureEncoder. video_source_.IncomingCapturedFrame(CreateFrame(1, kHighRes, kHighRes)); @@ -5191,7 +5218,8 @@ TEST_F(VideoStreamEncoderTest, /*stable_target_bitrate=*/rate, /*link_allocation=*/rate, /*fraction_lost=*/0, - /*rtt_ms=*/0); + /*rtt_ms=*/0, + /*cwnd_reduce_ratio=*/0); // Insert a first video frame so that encoder gets configured. int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec; @@ -5208,7 +5236,8 @@ TEST_F(VideoStreamEncoderTest, /*stable_target_bitrate=*/new_stable_rate, /*link_allocation=*/rate, /*fraction_lost=*/0, - /*rtt_ms=*/0); + /*rtt_ms=*/0, + /*cwnd_reduce_ratio=*/0); video_stream_encoder_->WaitUntilTaskQueueIsIdle(); EXPECT_EQ(2, fake_encoder_.GetNumSetRates()); video_stream_encoder_->Stop(); @@ -5226,7 +5255,8 @@ TEST_F(VideoStreamEncoderTest, /*stable_target_bitrate=*/rate, /*link_allocation=*/rate, /*fraction_lost=*/0, - /*rtt_ms=*/0); + /*rtt_ms=*/0, + /*cwnd_reduce_ratio=*/0); // Insert a first video frame so that encoder gets configured. int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec; @@ -5244,7 +5274,8 @@ TEST_F(VideoStreamEncoderTest, /*stable_target_bitrate=*/new_stable_rate, /*link_allocation=*/rate, /*fraction_lost=*/0, - /*rtt_ms=*/0); + /*rtt_ms=*/0, + /*cwnd_reduce_ratio=*/0); video_stream_encoder_->WaitUntilTaskQueueIsIdle(); EXPECT_EQ(1, fake_encoder_.GetNumSetRates()); video_stream_encoder_->Stop(); @@ -5267,7 +5298,7 @@ TEST_F(VideoStreamEncoderTest, AutomaticAnimationDetection) { // BALANCED degradation preference is required for this feature. video_stream_encoder_->OnBitrateUpdated( DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), - DataRate::bps(kTargetBitrateBps), 0, 0); + DataRate::bps(kTargetBitrateBps), 0, 0, 0); video_stream_encoder_->SetSource(&video_source_, webrtc::DegradationPreference::BALANCED); VerifyNoLimitation(video_source_.sink_wants());