[Overuse] Setting the target bitrate through the interface.

The poorly named SetEncoderStartBitrate() is renamed
SetEncoderTargetBitrate() and added to the abstract resource adaptation
module interface.

The so-called "start bitrate" was updated to match the target bitrate,
so this was only ever a "start bitrate" until we had any estimates. The
variable is renamed in VideoStreamEncoder as well, and usage of optional
types are introduced to avoid magical values in a few places in the
existing code.

Bug: webrtc:11222
Change-Id: Idde92f68f34616aa3c34ab77a791fdbe7ea7af26
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/166880
Reviewed-by: Evan Shrubsole <eshr@google.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30347}
This commit is contained in:
Henrik Boström 2020-01-21 17:45:35 +01:00 committed by Commit Bot
parent ee558dcca8
commit ede69c0fbe
5 changed files with 38 additions and 31 deletions

View File

@ -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<uint32_t> 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?

View File

@ -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<uint32_t> 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;
}

View File

@ -73,6 +73,8 @@ class OveruseFrameDetectorResourceAdaptationModule
void SetDegradationPreference(
DegradationPreference degradation_preference) override;
void SetEncoderSettings(EncoderSettings encoder_settings) override;
void SetEncoderTargetBitrate(
absl::optional<uint32_t> 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<int> 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<OveruseFrameDetector> overuse_detector_;
bool overuse_detector_is_started_;
absl::optional<double> target_frame_rate_;
uint32_t encoder_start_bitrate_bps_;
absl::optional<uint32_t> target_bitrate_bps_;
bool is_quality_scaler_enabled_;
absl::optional<EncoderSettings> encoder_settings_;
VideoStreamEncoderObserver* const encoder_stats_observer_;

View File

@ -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<uint32_t>(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<uint32_t>(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;
}

View File

@ -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<uint32_t> 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_);