[Overuse] Make EffectiveDegradationPreference() private.
The EffectiveDegradationPreference() exposed an "implementation detail" of the VideoStreamAdapter - how degradation preference may be modified. By changing the return value of ApplyAdaptationTarget() this dependency could be removed. We still have a TODO to get rid of the ResourceListenerResponse enum, but that is QualityScaler related work. This CL does the following: - Module's GetAdaptUpTarget/GetAdaptDownTarget/ApplyAdaptationTarget methods are removed in favor if invoking the VideoStreamAdapter's version of these methods directly. - Removing the EffectiveDegradationPreference() usage in OveruseFrameDetectorResourceAdaptationModule meant moving that usage to VideoStreamAdapter. - MinPixelsPerFrame() is moved to VideoStreamAdapter; this is "can adapt?" logic, i.e. the adapter's responsibility. Bug: webrtc:11393 Change-Id: I75091ce97093bfa48a6d883492de30ed4b004492 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/169859 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@{#30714}
This commit is contained in:
parent
01ab084f47
commit
8d9f750580
@ -25,6 +25,13 @@ namespace {
|
||||
|
||||
const int kMinFramerateFps = 2;
|
||||
|
||||
int MinPixelsPerFrame(const absl::optional<EncoderSettings>& encoder_settings) {
|
||||
return encoder_settings.has_value()
|
||||
? encoder_settings->encoder_info()
|
||||
.scaling_settings.min_pixels_per_frame
|
||||
: kDefaultMinPixelsPerFrame;
|
||||
}
|
||||
|
||||
// Generate suggested higher and lower frame rates and resolutions, to be
|
||||
// applied to the VideoSourceRestrictor. These are used in "maintain-resolution"
|
||||
// and "maintain-framerate". The "balanced" degradation preference also makes
|
||||
@ -263,21 +270,6 @@ VideoStreamAdapter::SetDegradationPreference(
|
||||
: SetDegradationPreferenceResult::kRestrictionsNotCleared;
|
||||
}
|
||||
|
||||
DegradationPreference VideoStreamAdapter::EffectiveDegradationPreference(
|
||||
VideoInputMode input_mode) const {
|
||||
// Balanced mode for screenshare works via automatic animation detection:
|
||||
// Resolution is capped for fullscreen animated content.
|
||||
// Adapatation is done only via framerate downgrade.
|
||||
// Thus effective degradation preference is MAINTAIN_RESOLUTION.
|
||||
// TODO(hbos): Don't do this. This is not what "balanced" means. If the
|
||||
// application wants to maintain resolution it should set that degradation
|
||||
// preference rather than depend on non-standard behaviors.
|
||||
return (input_mode == VideoInputMode::kScreenshareVideo &&
|
||||
degradation_preference_ == DegradationPreference::BALANCED)
|
||||
? DegradationPreference::MAINTAIN_RESOLUTION
|
||||
: degradation_preference_;
|
||||
}
|
||||
|
||||
absl::optional<VideoStreamAdapter::AdaptationTarget>
|
||||
VideoStreamAdapter::GetAdaptUpTarget(
|
||||
const absl::optional<EncoderSettings>& encoder_settings,
|
||||
@ -376,8 +368,8 @@ VideoStreamAdapter::GetAdaptDownTarget(
|
||||
VideoInputMode input_mode,
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
int min_pixels_per_frame,
|
||||
VideoStreamEncoderObserver* encoder_stats_observer) const {
|
||||
const int min_pixels_per_frame = MinPixelsPerFrame(encoder_settings);
|
||||
// Preconditions for being able to adapt down:
|
||||
if (input_mode == VideoInputMode::kNoVideo)
|
||||
return absl::nullopt;
|
||||
@ -451,24 +443,27 @@ VideoStreamAdapter::GetAdaptDownTarget(
|
||||
}
|
||||
}
|
||||
|
||||
void VideoStreamAdapter::ApplyAdaptationTarget(const AdaptationTarget& target,
|
||||
VideoInputMode input_mode,
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
int min_pixels_per_frame) {
|
||||
ResourceListenerResponse VideoStreamAdapter::ApplyAdaptationTarget(
|
||||
const AdaptationTarget& target,
|
||||
const absl::optional<EncoderSettings>& encoder_settings,
|
||||
VideoInputMode input_mode,
|
||||
int input_pixels,
|
||||
int input_fps) {
|
||||
const int min_pixels_per_frame = MinPixelsPerFrame(encoder_settings);
|
||||
// Remember the input pixels and fps of this adaptation. Used to avoid
|
||||
// adapting again before this adaptation has had an effect.
|
||||
last_adaptation_request_.emplace(AdaptationRequest{
|
||||
input_pixels, input_fps,
|
||||
AdaptationRequest::GetModeFromAdaptationAction(target.action)});
|
||||
// Adapt!
|
||||
switch (target.action) {
|
||||
case AdaptationAction::kIncreaseResolution:
|
||||
source_restrictor_->IncreaseResolutionTo(target.value);
|
||||
return;
|
||||
break;
|
||||
case AdaptationAction::kDecreaseResolution:
|
||||
source_restrictor_->DecreaseResolutionTo(target.value,
|
||||
min_pixels_per_frame);
|
||||
return;
|
||||
break;
|
||||
case AdaptationAction::kIncreaseFrameRate:
|
||||
source_restrictor_->IncreaseFrameRateTo(target.value);
|
||||
// TODO(https://crbug.com/webrtc/11222): Don't adapt in two steps.
|
||||
@ -483,11 +478,42 @@ void VideoStreamAdapter::ApplyAdaptationTarget(const AdaptationTarget& target,
|
||||
source_restrictor_->IncreaseFrameRateTo(
|
||||
std::numeric_limits<int>::max());
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case AdaptationAction::kDecreaseFrameRate:
|
||||
source_restrictor_->DecreaseFrameRateTo(target.value);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
// In BALANCED, if requested FPS is higher or close to input FPS to the target
|
||||
// we tell the QualityScaler to increase its frequency.
|
||||
// TODO(hbos): Don't have QualityScaler-specific logic here. If the
|
||||
// QualityScaler wants to add special logic depending on what effects
|
||||
// adaptation had, it should listen to changes to the VideoSourceRestrictions
|
||||
// instead.
|
||||
if (EffectiveDegradationPreference(input_mode) ==
|
||||
DegradationPreference::BALANCED &&
|
||||
target.action ==
|
||||
VideoStreamAdapter::AdaptationAction::kDecreaseFrameRate) {
|
||||
absl::optional<int> min_diff = balanced_settings_.MinFpsDiff(input_pixels);
|
||||
if (min_diff && input_fps > 0) {
|
||||
int fps_diff = input_fps - target.value;
|
||||
if (fps_diff < min_diff.value()) {
|
||||
return ResourceListenerResponse::kQualityScalerShouldIncreaseFrequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ResourceListenerResponse::kNothing;
|
||||
}
|
||||
|
||||
DegradationPreference VideoStreamAdapter::EffectiveDegradationPreference(
|
||||
VideoInputMode input_mode) const {
|
||||
// Balanced mode for screenshare works via automatic animation detection:
|
||||
// Resolution is capped for fullscreen animated content.
|
||||
// Adapatation is done only via framerate downgrade.
|
||||
// Thus effective degradation preference is MAINTAIN_RESOLUTION.
|
||||
return (input_mode == VideoInputMode::kScreenshareVideo &&
|
||||
degradation_preference_ == DegradationPreference::BALANCED)
|
||||
? DegradationPreference::MAINTAIN_RESOLUTION
|
||||
: degradation_preference_;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "api/rtp_parameters.h"
|
||||
#include "api/video/video_stream_encoder_observer.h"
|
||||
#include "call/adaptation/encoder_settings.h"
|
||||
#include "call/adaptation/resource.h"
|
||||
#include "call/adaptation/video_source_restrictions.h"
|
||||
#include "modules/video_coding/utility/quality_scaler.h"
|
||||
#include "rtc_base/experiments/balanced_degradation_settings.h"
|
||||
@ -85,11 +86,6 @@ class VideoStreamAdapter {
|
||||
// tiny risk that people would discover and rely on this behavior.
|
||||
SetDegradationPreferenceResult SetDegradationPreference(
|
||||
DegradationPreference degradation_preference);
|
||||
// TODO(hbos): This is only used in one place externally by
|
||||
// OveruseFrameDetectorResourceAdaptationModule - can we get rid of that
|
||||
// usage? This is exposing an implementation detail.
|
||||
DegradationPreference EffectiveDegradationPreference(
|
||||
VideoInputMode input_mode) const;
|
||||
|
||||
// Returns a target that we are guaranteed to be able to adapt to, or null if
|
||||
// adaptation is not desired or not possible.
|
||||
@ -108,14 +104,15 @@ class VideoStreamAdapter {
|
||||
VideoInputMode input_mode,
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
int min_pixels_per_frame,
|
||||
VideoStreamEncoderObserver* encoder_stats_observer) const;
|
||||
// Applies the |target| to |source_restrictor_|.
|
||||
void ApplyAdaptationTarget(const AdaptationTarget& target,
|
||||
VideoInputMode input_mode,
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
int min_pixels_per_frame);
|
||||
// TODO(hbos): Delete ResourceListenerResponse!
|
||||
ResourceListenerResponse ApplyAdaptationTarget(
|
||||
const AdaptationTarget& target,
|
||||
const absl::optional<EncoderSettings>& encoder_settings,
|
||||
VideoInputMode input_mode,
|
||||
int input_pixels,
|
||||
int input_fps);
|
||||
|
||||
private:
|
||||
class VideoSourceRestrictor;
|
||||
@ -137,6 +134,13 @@ class VideoStreamAdapter {
|
||||
static Mode GetModeFromAdaptationAction(AdaptationAction action);
|
||||
};
|
||||
|
||||
// Reinterprets "balanced + screenshare" as "maintain-resolution".
|
||||
// TODO(hbos): Don't do this. This is not what "balanced" means. If the
|
||||
// application wants to maintain resolution it should set that degradation
|
||||
// preference rather than depend on non-standard behaviors.
|
||||
DegradationPreference EffectiveDegradationPreference(
|
||||
VideoInputMode input_mode) const;
|
||||
|
||||
// Owner and modifier of the VideoSourceRestriction of this stream adaptor.
|
||||
const std::unique_ptr<VideoSourceRestrictor> source_restrictor_;
|
||||
// Decides the next adaptation target in DegradationPreference::BALANCED.
|
||||
|
||||
@ -443,11 +443,8 @@ OveruseFrameDetectorResourceAdaptationModule::OnResourceUsageStateMeasured(
|
||||
}
|
||||
}
|
||||
|
||||
absl::optional<VideoStreamAdapter::AdaptationTarget>
|
||||
OveruseFrameDetectorResourceAdaptationModule::GetAdaptUpTarget(
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
AdaptationObserverInterface::AdaptReason reason) const {
|
||||
void OveruseFrameDetectorResourceAdaptationModule::OnResourceUnderuse(
|
||||
AdaptationObserverInterface::AdaptReason reason) {
|
||||
// We can't adapt up if we're already at the highest setting.
|
||||
// Note that this only includes counts relevant to the current degradation
|
||||
// preference. e.g. we previously adapted resolution, now prefer adpating fps,
|
||||
@ -464,45 +461,21 @@ OveruseFrameDetectorResourceAdaptationModule::GetAdaptUpTarget(
|
||||
.Total();
|
||||
RTC_DCHECK_GE(num_downgrades, 0);
|
||||
if (num_downgrades == 0)
|
||||
return absl::nullopt;
|
||||
return stream_adapter_->GetAdaptUpTarget(
|
||||
encoder_settings_, encoder_target_bitrate_bps_, GetVideoInputMode(),
|
||||
input_pixels, input_fps, reason);
|
||||
}
|
||||
|
||||
absl::optional<VideoStreamAdapter::AdaptationTarget>
|
||||
OveruseFrameDetectorResourceAdaptationModule::GetAdaptDownTarget(
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
int min_pixels_per_frame) const {
|
||||
return stream_adapter_->GetAdaptDownTarget(
|
||||
encoder_settings_, GetVideoInputMode(), input_pixels, input_fps,
|
||||
min_pixels_per_frame, encoder_stats_observer_);
|
||||
}
|
||||
|
||||
void OveruseFrameDetectorResourceAdaptationModule::ApplyAdaptationTarget(
|
||||
const VideoStreamAdapter::AdaptationTarget& target,
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
int min_pixels_per_frame) {
|
||||
stream_adapter_->ApplyAdaptationTarget(target, GetVideoInputMode(),
|
||||
input_pixels, input_fps,
|
||||
min_pixels_per_frame);
|
||||
}
|
||||
|
||||
void OveruseFrameDetectorResourceAdaptationModule::OnResourceUnderuse(
|
||||
AdaptationObserverInterface::AdaptReason reason) {
|
||||
int input_pixels = LastInputFrameSizeOrDefault();
|
||||
int input_fps = encoder_stats_observer_->GetInputFrameRate();
|
||||
int min_pixels_per_frame = MinPixelsPerFrame();
|
||||
return;
|
||||
// Current video input states used by VideoStreamAdapter.
|
||||
const VideoStreamAdapter::VideoInputMode input_mode = GetVideoInputMode();
|
||||
const int input_pixels = LastInputFrameSizeOrDefault();
|
||||
const int input_fps = encoder_stats_observer_->GetInputFrameRate();
|
||||
// Should we adapt, if so to what target?
|
||||
absl::optional<VideoStreamAdapter::AdaptationTarget> target =
|
||||
GetAdaptUpTarget(input_pixels, input_fps, reason);
|
||||
stream_adapter_->GetAdaptUpTarget(encoder_settings_,
|
||||
encoder_target_bitrate_bps_, input_mode,
|
||||
input_pixels, input_fps, reason);
|
||||
if (!target.has_value())
|
||||
return;
|
||||
// Apply target.
|
||||
ApplyAdaptationTarget(target.value(), input_pixels, input_fps,
|
||||
min_pixels_per_frame);
|
||||
stream_adapter_->ApplyAdaptationTarget(target.value(), encoder_settings_,
|
||||
input_mode, input_pixels, input_fps);
|
||||
// Update VideoSourceRestrictions based on adaptation. This also informs the
|
||||
// |adaptation_listener_|.
|
||||
MaybeUpdateVideoSourceRestrictions();
|
||||
@ -516,39 +489,27 @@ OveruseFrameDetectorResourceAdaptationModule::OnResourceOveruse(
|
||||
AdaptationObserverInterface::AdaptReason reason) {
|
||||
if (!has_input_video_)
|
||||
return ResourceListenerResponse::kQualityScalerShouldIncreaseFrequency;
|
||||
int input_pixels = LastInputFrameSizeOrDefault();
|
||||
int input_fps = encoder_stats_observer_->GetInputFrameRate();
|
||||
int min_pixels_per_frame = MinPixelsPerFrame();
|
||||
// Current video input states used by VideoStreamAdapter.
|
||||
const VideoStreamAdapter::VideoInputMode input_mode = GetVideoInputMode();
|
||||
const int input_pixels = LastInputFrameSizeOrDefault();
|
||||
const int input_fps = encoder_stats_observer_->GetInputFrameRate();
|
||||
// Should we adapt, if so to what target?
|
||||
absl::optional<VideoStreamAdapter::AdaptationTarget> target =
|
||||
GetAdaptDownTarget(input_pixels, input_fps, min_pixels_per_frame);
|
||||
stream_adapter_->GetAdaptDownTarget(encoder_settings_, input_mode,
|
||||
input_pixels, input_fps,
|
||||
encoder_stats_observer_);
|
||||
if (!target.has_value())
|
||||
return ResourceListenerResponse::kNothing;
|
||||
// Apply target.
|
||||
ApplyAdaptationTarget(target.value(), input_pixels, input_fps,
|
||||
min_pixels_per_frame);
|
||||
ResourceListenerResponse response = stream_adapter_->ApplyAdaptationTarget(
|
||||
target.value(), encoder_settings_, input_mode, input_pixels, input_fps);
|
||||
// Update VideoSourceRestrictions based on adaptation. This also informs the
|
||||
// |adaptation_listener_|.
|
||||
MaybeUpdateVideoSourceRestrictions();
|
||||
// Stats and logging.
|
||||
UpdateAdaptationStats(reason);
|
||||
RTC_LOG(INFO) << ActiveCountsToString();
|
||||
// In BALANCED, if requested FPS is higher or close to input FPS to the target
|
||||
// we tell the QualityScaler to increase its frequency.
|
||||
if (stream_adapter_->EffectiveDegradationPreference(GetVideoInputMode()) ==
|
||||
DegradationPreference::BALANCED &&
|
||||
target->action ==
|
||||
VideoStreamAdapter::AdaptationAction::kDecreaseFrameRate) {
|
||||
absl::optional<int> min_diff =
|
||||
stream_adapter_->balanced_settings().MinFpsDiff(input_pixels);
|
||||
if (min_diff && input_fps > 0) {
|
||||
int fps_diff = input_fps - target->value;
|
||||
if (fps_diff < min_diff.value()) {
|
||||
return ResourceListenerResponse::kQualityScalerShouldIncreaseFrequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ResourceListenerResponse::kNothing;
|
||||
return response;
|
||||
}
|
||||
|
||||
// TODO(pbos): Lower these thresholds (to closer to 100%) when we handle
|
||||
@ -587,13 +548,6 @@ int OveruseFrameDetectorResourceAdaptationModule::LastInputFrameSizeOrDefault()
|
||||
VideoStreamEncoder::kDefaultLastFrameInfoHeight);
|
||||
}
|
||||
|
||||
int OveruseFrameDetectorResourceAdaptationModule::MinPixelsPerFrame() const {
|
||||
return encoder_settings_.has_value()
|
||||
? encoder_settings_->encoder_info()
|
||||
.scaling_settings.min_pixels_per_frame
|
||||
: kDefaultMinPixelsPerFrame;
|
||||
}
|
||||
|
||||
void OveruseFrameDetectorResourceAdaptationModule::
|
||||
MaybeUpdateVideoSourceRestrictions() {
|
||||
VideoSourceRestrictions new_restrictions = ApplyDegradationPreference(
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
#include "api/video_codecs/video_encoder_config.h"
|
||||
#include "call/adaptation/resource.h"
|
||||
#include "call/adaptation/resource_adaptation_module_interface.h"
|
||||
#include "rtc_base/experiments/balanced_degradation_settings.h"
|
||||
#include "rtc_base/experiments/quality_rampup_experiment.h"
|
||||
#include "rtc_base/experiments/quality_scaler_settings.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
@ -132,22 +131,6 @@ class OveruseFrameDetectorResourceAdaptationModule
|
||||
|
||||
enum class State { kStopped, kStarted };
|
||||
|
||||
// Returns a target that we are guaranteed to be able to adapt to, or null if
|
||||
// adaptation is not desired or not possible.
|
||||
absl::optional<VideoStreamAdapter::AdaptationTarget> GetAdaptUpTarget(
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
AdaptationObserverInterface::AdaptReason reason) const;
|
||||
absl::optional<VideoStreamAdapter::AdaptationTarget> GetAdaptDownTarget(
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
int min_pixels_per_frame) const;
|
||||
// Applies the |target| to |source_restrictor_|.
|
||||
void ApplyAdaptationTarget(const VideoStreamAdapter::AdaptationTarget& target,
|
||||
int input_pixels,
|
||||
int input_fps,
|
||||
int min_pixels_per_frame);
|
||||
|
||||
// Performs the adaptation by getting the next target, applying it and
|
||||
// informing listeners of the new VideoSourceRestriction and adapt counters.
|
||||
void OnResourceUnderuse(AdaptationObserverInterface::AdaptReason reason);
|
||||
@ -156,7 +139,6 @@ class OveruseFrameDetectorResourceAdaptationModule
|
||||
|
||||
CpuOveruseOptions GetCpuOveruseOptions() const;
|
||||
int LastInputFrameSizeOrDefault() const;
|
||||
int MinPixelsPerFrame() const;
|
||||
VideoStreamEncoderObserver::AdaptationSteps GetActiveCounts(
|
||||
AdaptationObserverInterface::AdaptReason reason);
|
||||
VideoStreamAdapter::VideoInputMode GetVideoInputMode() const;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user