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());