diff --git a/call/adaptation/resource_adaptation_module_interface.h b/call/adaptation/resource_adaptation_module_interface.h index bc64b8e26e..61380b91a6 100644 --- a/call/adaptation/resource_adaptation_module_interface.h +++ b/call/adaptation/resource_adaptation_module_interface.h @@ -11,6 +11,7 @@ #ifndef CALL_ADAPTATION_RESOURCE_ADAPTATION_MODULE_INTERFACE_H_ #define CALL_ADAPTATION_RESOURCE_ADAPTATION_MODULE_INTERFACE_H_ +#include "absl/types/optional.h" #include "api/rtp_parameters.h" #include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_config.h" @@ -84,6 +85,8 @@ class ResourceAdaptationModuleInterface { virtual void SetDegradationPreference( DegradationPreference degradation_preference) = 0; virtual void SetEncoderSettings(EncoderSettings encoder_settings) = 0; + virtual void SetEncoderTargetBitrate( + absl::optional target_bitrate_bps) = 0; // Removes all restrictions; the module will need to adapt all over again. // TODO(hbos): It's not clear why anybody should be able to tell the module to // reset like this; can we get rid of this method? diff --git a/video/overuse_frame_detector_resource_adaptation_module.cc b/video/overuse_frame_detector_resource_adaptation_module.cc index bd27eda3e1..1ba33e1e15 100644 --- a/video/overuse_frame_detector_resource_adaptation_module.cc +++ b/video/overuse_frame_detector_resource_adaptation_module.cc @@ -357,7 +357,7 @@ OveruseFrameDetectorResourceAdaptationModule:: overuse_detector_(std::move(overuse_detector)), overuse_detector_is_started_(false), target_frame_rate_(absl::nullopt), - encoder_start_bitrate_bps_(0), + target_bitrate_bps_(absl::nullopt), is_quality_scaler_enabled_(false), encoder_settings_(absl::nullopt), encoder_stats_observer_(encoder_stats_observer) { @@ -426,6 +426,11 @@ void OveruseFrameDetectorResourceAdaptationModule::SetEncoderSettings( MaybeUpdateTargetFrameRate(); } +void OveruseFrameDetectorResourceAdaptationModule::SetEncoderTargetBitrate( + absl::optional target_bitrate_bps) { + target_bitrate_bps_ = target_bitrate_bps; +} + void OveruseFrameDetectorResourceAdaptationModule:: ResetVideoSourceRestrictions() { last_adaptation_request_.reset(); @@ -472,11 +477,6 @@ void OveruseFrameDetectorResourceAdaptationModule::SetLastFramePixelCount( last_frame_pixel_count_ = last_frame_pixel_count; } -void OveruseFrameDetectorResourceAdaptationModule::SetEncoderStartBitrateBps( - uint32_t encoder_start_bitrate_bps) { - encoder_start_bitrate_bps_ = encoder_start_bitrate_bps; -} - void OveruseFrameDetectorResourceAdaptationModule::SetIsQualityScalerEnabled( bool is_quality_scaler_enabled) { is_quality_scaler_enabled_ = is_quality_scaler_enabled; @@ -516,7 +516,7 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) { if (reason == kQuality && !balanced_settings_.CanAdaptUp(GetVideoCodecTypeOrGeneric(), *last_frame_pixel_count_, - encoder_start_bitrate_bps_)) { + target_bitrate_bps_.value_or(0))) { return; } // Try scale up framerate, if higher. @@ -537,7 +537,7 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) { if (reason == kQuality && !balanced_settings_.CanAdaptUpResolution( GetVideoCodecTypeOrGeneric(), *last_frame_pixel_count_, - encoder_start_bitrate_bps_)) { + target_bitrate_bps_.value_or(0))) { return; } // Scale up resolution. @@ -548,7 +548,7 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) { // limits specified by encoder capabilities. if (reason == kQuality && !CanAdaptUpResolution(*last_frame_pixel_count_, - encoder_start_bitrate_bps_)) { + target_bitrate_bps_.value_or(0))) { return; } diff --git a/video/overuse_frame_detector_resource_adaptation_module.h b/video/overuse_frame_detector_resource_adaptation_module.h index efc2ec8364..f4080bd4c2 100644 --- a/video/overuse_frame_detector_resource_adaptation_module.h +++ b/video/overuse_frame_detector_resource_adaptation_module.h @@ -73,6 +73,8 @@ class OveruseFrameDetectorResourceAdaptationModule void SetDegradationPreference( DegradationPreference degradation_preference) override; void SetEncoderSettings(EncoderSettings encoder_settings) override; + void SetEncoderTargetBitrate( + absl::optional target_bitrate_bps) override; void ResetVideoSourceRestrictions() override; // Input to the OveruseFrameDetector, which are required for this module to @@ -92,7 +94,6 @@ class OveruseFrameDetectorResourceAdaptationModule // resource adaptation module. Unify code paths where possible. Do we really // need this many public methods? void SetLastFramePixelCount(absl::optional last_frame_pixel_count); - void SetEncoderStartBitrateBps(uint32_t encoder_start_bitrate_bps); // Inform the detector whether or not the quality scaler is enabled. This // helps GetActiveCounts() return absl::nullopt when appropriate. // TODO(hbos): This feels really hacky, can we report the right values without @@ -215,7 +216,7 @@ class OveruseFrameDetectorResourceAdaptationModule const std::unique_ptr overuse_detector_; bool overuse_detector_is_started_; absl::optional target_frame_rate_; - uint32_t encoder_start_bitrate_bps_; + absl::optional target_bitrate_bps_; bool is_quality_scaler_enabled_; absl::optional encoder_settings_; VideoStreamEncoderObserver* const encoder_stats_observer_; diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 65e81c1d7d..486143c5d8 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -279,7 +279,7 @@ VideoStreamEncoder::VideoStreamEncoder( pending_encoder_creation_(false), crop_width_(0), crop_height_(0), - encoder_start_bitrate_bps_(0), + encoder_target_bitrate_bps_(absl::nullopt), set_start_bitrate_bps_(0), set_start_bitrate_time_ms_(0), has_seen_first_bwe_drop_(false), @@ -405,9 +405,11 @@ void VideoStreamEncoder::SetSink(EncoderSink* sink, bool rotation_applied) { void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) { encoder_queue_.PostTask([this, start_bitrate_bps] { RTC_DCHECK_RUN_ON(&encoder_queue_); - encoder_start_bitrate_bps_ = start_bitrate_bps; - resource_adaptation_module_->SetEncoderStartBitrateBps( - encoder_start_bitrate_bps_); + encoder_target_bitrate_bps_ = + start_bitrate_bps != 0 ? absl::optional(start_bitrate_bps) + : absl::nullopt; + resource_adaptation_module_->SetEncoderTargetBitrate( + encoder_target_bitrate_bps_); set_start_bitrate_bps_ = start_bitrate_bps; set_start_bitrate_time_ms_ = clock_->TimeInMilliseconds(); }); @@ -619,8 +621,8 @@ void VideoStreamEncoder::ReconfigureEncoder() { } RTC_LOG(LS_INFO) << log_stream.str(); - codec.startBitrate = - std::max(encoder_start_bitrate_bps_ / 1000, codec.minBitrate); + codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000, + codec.minBitrate); codec.startBitrate = std::min(codec.startBitrate, codec.maxBitrate); codec.expect_encode_from_texture = last_frame_info_->is_texture; // Make sure the start bit rate is sane... @@ -1617,11 +1619,11 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate, // On significant changes to BWE at the start of the call, // enable frame drops to quickly react to jumps in available bandwidth. - if (encoder_start_bitrate_bps_ != 0 && + if (encoder_target_bitrate_bps_.has_value() && !has_seen_first_significant_bwe_change_ && quality_scaler_ && initial_framedrop_on_bwe_enabled_ && - abs_diff(target_bitrate.bps(), encoder_start_bitrate_bps_) >= - kFramedropThreshold * encoder_start_bitrate_bps_) { + abs_diff(target_bitrate.bps(), encoder_target_bitrate_bps_.value()) >= + kFramedropThreshold * encoder_target_bitrate_bps_.value()) { // Reset initial framedrop feature when first real BW estimate arrives. // TODO(kthelgason): Update BitrateAllocator to not call OnBitrateUpdated // without an actual BW estimate. @@ -1659,11 +1661,10 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate, link_allocation, target_bitrate, stable_target_bitrate}; SetEncoderRates(UpdateBitrateAllocationAndNotifyObserver(new_rate_settings)); - encoder_start_bitrate_bps_ = target_bitrate.bps() != 0 - ? target_bitrate.bps() - : encoder_start_bitrate_bps_; - resource_adaptation_module_->SetEncoderStartBitrateBps( - encoder_start_bitrate_bps_); + if (target_bitrate.bps() != 0) + encoder_target_bitrate_bps_ = target_bitrate.bps(); + resource_adaptation_module_->SetEncoderTargetBitrate( + encoder_target_bitrate_bps_); if (video_suspension_changed) { RTC_LOG(LS_INFO) << "Video suspend state changed to: " @@ -1681,7 +1682,7 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate, bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const { if (initial_framedrop_ >= kMaxInitialFramedrop || - encoder_start_bitrate_bps_ == 0) { + !encoder_target_bitrate_bps_.has_value()) { return false; } @@ -1690,13 +1691,13 @@ bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const { if (encoder_bitrate_limits.has_value()) { // Use bitrate limits provided by encoder. - return encoder_start_bitrate_bps_ < + return encoder_target_bitrate_bps_.value() < static_cast(encoder_bitrate_limits->min_start_bitrate_bps); } - if (encoder_start_bitrate_bps_ < 300000 /* qvga */) { + if (encoder_target_bitrate_bps_.value() < 300000 /* qvga */) { return pixel_count > 320 * 240; - } else if (encoder_start_bitrate_bps_ < 500000 /* vga */) { + } else if (encoder_target_bitrate_bps_.value() < 500000 /* vga */) { return pixel_count > 640 * 480; } return false; @@ -1713,7 +1714,8 @@ bool VideoStreamEncoder::TryQualityRampup(int64_t now_ms) { if (quality_rampup_experiment_.BwHigh(now_ms, bw_kbps)) { // Verify that encoder is at max bitrate and the QP is low. - if (encoder_start_bitrate_bps_ == send_codec_.maxBitrate * 1000 && + if (encoder_target_bitrate_bps_.value_or(0) == + send_codec_.maxBitrate * 1000 && quality_scaler_->QpFastFilterLow()) { return true; } diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h index bd76ee5f9c..5ac6db8028 100644 --- a/video/video_stream_encoder.h +++ b/video/video_stream_encoder.h @@ -251,7 +251,8 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, RTC_GUARDED_BY(&encoder_queue_); int crop_width_ RTC_GUARDED_BY(&encoder_queue_); int crop_height_ RTC_GUARDED_BY(&encoder_queue_); - uint32_t encoder_start_bitrate_bps_ RTC_GUARDED_BY(&encoder_queue_); + absl::optional encoder_target_bitrate_bps_ + RTC_GUARDED_BY(&encoder_queue_); int set_start_bitrate_bps_ RTC_GUARDED_BY(&encoder_queue_); int64_t set_start_bitrate_time_ms_ RTC_GUARDED_BY(&encoder_queue_); bool has_seen_first_bwe_drop_ RTC_GUARDED_BY(&encoder_queue_);