[Adaptation] Move input state into VideoStreamAdapter

Bug: webrtc:11700
Change-Id: I81a060b914f91f6724f13a9b672234c9c4a65fae
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/177104
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Evan Shrubsole <eshr@google.com>
Cr-Commit-Position: refs/heads/master@{#31616}
This commit is contained in:
Evan Shrubsole 2020-07-02 14:42:09 +02:00 committed by Commit Bot
parent ec0af26ff8
commit 34b1a42de8
9 changed files with 474 additions and 448 deletions

View file

@ -68,13 +68,11 @@ ResourceAdaptationProcessor::MitigationResultAndLogMessage::
: result(result), message(std::move(message)) {}
ResourceAdaptationProcessor::ResourceAdaptationProcessor(
VideoStreamInputStateProvider* input_state_provider,
VideoStreamEncoderObserver* encoder_stats_observer,
VideoStreamAdapter* stream_adapter)
: resource_adaptation_queue_(nullptr),
resource_listener_delegate_(
new rtc::RefCountedObject<ResourceListenerDelegate>(this)),
input_state_provider_(input_state_provider),
encoder_stats_observer_(encoder_stats_observer),
resources_(),
degradation_preference_(DegradationPreference::DISABLED),
@ -279,15 +277,6 @@ void ResourceAdaptationProcessor::OnResourceUsageStateMeasured(
}
}
bool ResourceAdaptationProcessor::HasSufficientInputForAdaptation(
const VideoStreamInputState& input_state) const {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
return input_state.HasInputFrameSizeAndFramesPerSecond() &&
(effective_degradation_preference_ !=
DegradationPreference::MAINTAIN_RESOLUTION ||
input_state.frames_per_second() >= kMinFrameRateFps);
}
ResourceAdaptationProcessor::MitigationResultAndLogMessage
ResourceAdaptationProcessor::OnResourceUnderuse(
rtc::scoped_refptr<Resource> reason_resource) {
@ -300,15 +289,6 @@ ResourceAdaptationProcessor::OnResourceUnderuse(
MitigationResult::kDisabled,
"Not adapting up because DegradationPreference is disabled");
}
VideoStreamInputState input_state = input_state_provider_->InputState();
if (!HasSufficientInputForAdaptation(input_state)) {
processing_in_progress_ = false;
return MitigationResultAndLogMessage(
MitigationResult::kInsufficientInput,
"Not adapting up because input is insufficient");
}
// Update video input states and encoder settings for accurate adaptation.
stream_adapter_->SetInput(input_state);
// How can this stream be adapted up?
Adaptation adaptation = stream_adapter_->GetAdaptationUp();
if (adaptation.status() != Adaptation::Status::kValid) {
@ -331,9 +311,9 @@ ResourceAdaptationProcessor::OnResourceUnderuse(
FindMostLimitedResources();
for (const auto* constraint : adaptation_constraints_) {
if (!constraint->IsAdaptationUpAllowed(input_state, restrictions_before,
restrictions_after,
reason_resource)) {
if (!constraint->IsAdaptationUpAllowed(
adaptation.input_state(), restrictions_before, restrictions_after,
reason_resource)) {
processing_in_progress_ = false;
rtc::StringBuilder message;
message << "Not adapting up because constraint \"" << constraint->Name()
@ -375,7 +355,8 @@ ResourceAdaptationProcessor::OnResourceUnderuse(
stream_adapter_->ApplyAdaptation(adaptation, reason_resource);
for (auto* adaptation_listener : adaptation_listeners_) {
adaptation_listener->OnAdaptationApplied(
input_state, restrictions_before, restrictions_after, reason_resource);
adaptation.input_state(), restrictions_before, restrictions_after,
reason_resource);
}
processing_in_progress_ = false;
rtc::StringBuilder message;
@ -397,15 +378,6 @@ ResourceAdaptationProcessor::OnResourceOveruse(
MitigationResult::kDisabled,
"Not adapting down because DegradationPreference is disabled");
}
VideoStreamInputState input_state = input_state_provider_->InputState();
if (!HasSufficientInputForAdaptation(input_state)) {
processing_in_progress_ = false;
return MitigationResultAndLogMessage(
MitigationResult::kInsufficientInput,
"Not adapting down because input is insufficient");
}
// Update video input states and encoder settings for accurate adaptation.
stream_adapter_->SetInput(input_state);
// How can this stream be adapted up?
Adaptation adaptation = stream_adapter_->GetAdaptationDown();
if (adaptation.min_pixel_limit_reached()) {
@ -429,7 +401,8 @@ ResourceAdaptationProcessor::OnResourceOveruse(
stream_adapter_->ApplyAdaptation(adaptation, reason_resource);
for (auto* adaptation_listener : adaptation_listeners_) {
adaptation_listener->OnAdaptationApplied(
input_state, restrictions_before, restrictions_after, reason_resource);
adaptation.input_state(), restrictions_before, restrictions_after,
reason_resource);
}
processing_in_progress_ = false;
rtc::StringBuilder message;
@ -527,10 +500,9 @@ void ResourceAdaptationProcessor::
most_limited.adaptation_counters, most_limited.restrictions);
RTC_DCHECK_EQ(adapt_to.status(), Adaptation::Status::kValid);
stream_adapter_->ApplyAdaptation(adapt_to, nullptr);
auto input_state = input_state_provider_->InputState();
for (auto* adaptation_listener : adaptation_listeners_) {
adaptation_listener->OnAdaptationApplied(
input_state, removed_limitations.restrictions,
adapt_to.input_state(), removed_limitations.restrictions,
most_limited.restrictions, nullptr);
}

View file

@ -55,7 +55,6 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
public ResourceListener {
public:
ResourceAdaptationProcessor(
VideoStreamInputStateProvider* input_state_provider,
VideoStreamEncoderObserver* encoder_stats_observer,
VideoStreamAdapter* video_stream_adapter);
~ResourceAdaptationProcessor() override;
@ -105,9 +104,6 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
rtc::scoped_refptr<Resource> reason_resource) override;
private:
bool HasSufficientInputForAdaptation(
const VideoStreamInputState& input_state) const;
// If resource usage measurements happens off the adaptation task queue, this
// class takes care of posting the measurement for the processor to handle it
// on the adaptation task queue.
@ -131,7 +127,6 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
enum class MitigationResult {
kDisabled,
kInsufficientInput,
kNotMostLimitedResource,
kSharedMostLimitedResource,
kRejectedByAdapter,
@ -179,8 +174,6 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
TaskQueueBase* resource_adaptation_queue_;
rtc::scoped_refptr<ResourceListenerDelegate> resource_listener_delegate_;
// Input and output.
VideoStreamInputStateProvider* const input_state_provider_
RTC_GUARDED_BY(resource_adaptation_queue_);
VideoStreamEncoderObserver* const encoder_stats_observer_
RTC_GUARDED_BY(resource_adaptation_queue_);
std::vector<ResourceLimitationsListener*> resource_limitations_listeners_

View file

@ -92,9 +92,9 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
other_resource_(FakeResource::Create("OtherFakeResource")),
adaptation_constraint_("FakeAdaptationConstraint"),
adaptation_listener_(),
video_stream_adapter_(std::make_unique<VideoStreamAdapter>()),
video_stream_adapter_(
std::make_unique<VideoStreamAdapter>(&input_state_provider_)),
processor_(std::make_unique<ResourceAdaptationProcessor>(
&input_state_provider_,
/*encoder_stats_observer=*/&frame_rate_provider_,
video_stream_adapter_.get())) {
processor_->SetResourceAdaptationQueue(TaskQueueBase::Current());

View file

@ -100,6 +100,8 @@ const char* Adaptation::StatusToString(Adaptation::Status status) {
return "kLimitReached";
case Adaptation::Status::kAwaitingPreviousAdaptation:
return "kAwaitingPreviousAdaptation";
case Status::kInsufficientInput:
return "kInsufficientInput";
}
}
@ -113,35 +115,45 @@ Adaptation::Step::Step(VideoSourceRestrictions restrictions,
restrictions(restrictions),
counters(counters) {}
Adaptation::Adaptation(int validation_id, Step step)
Adaptation::Adaptation(int validation_id,
Step step,
VideoStreamInputState input_state)
: validation_id_(validation_id),
status_(Status::kValid),
step_(std::move(step)),
min_pixel_limit_reached_(false) {}
min_pixel_limit_reached_(false),
input_state_(input_state) {}
Adaptation::Adaptation(int validation_id,
Step step,
VideoStreamInputState input_state,
bool min_pixel_limit_reached)
: validation_id_(validation_id),
status_(Status::kValid),
step_(std::move(step)),
min_pixel_limit_reached_(min_pixel_limit_reached) {}
min_pixel_limit_reached_(min_pixel_limit_reached),
input_state_(input_state) {}
Adaptation::Adaptation(int validation_id, Status invalid_status)
Adaptation::Adaptation(int validation_id,
Status invalid_status,
VideoStreamInputState input_state)
: validation_id_(validation_id),
status_(invalid_status),
step_(absl::nullopt),
min_pixel_limit_reached_(false) {
min_pixel_limit_reached_(false),
input_state_(input_state) {
RTC_DCHECK_NE(status_, Status::kValid);
}
Adaptation::Adaptation(int validation_id,
Status invalid_status,
VideoStreamInputState input_state,
bool min_pixel_limit_reached)
: validation_id_(validation_id),
status_(invalid_status),
step_(absl::nullopt),
min_pixel_limit_reached_(min_pixel_limit_reached) {
min_pixel_limit_reached_(min_pixel_limit_reached),
input_state_(input_state) {
RTC_DCHECK_NE(status_, Status::kValid);
}
@ -157,6 +169,9 @@ const Adaptation::Step& Adaptation::step() const {
RTC_DCHECK_EQ(status_, Status::kValid);
return step_.value();
}
const VideoStreamInputState& Adaptation::input_state() const {
return input_state_;
}
// VideoSourceRestrictor is responsible for keeping track of current
// VideoSourceRestrictions.
@ -329,12 +344,13 @@ class VideoStreamAdapter::VideoSourceRestrictor {
VideoAdaptationCounters adaptations_;
};
VideoStreamAdapter::VideoStreamAdapter()
VideoStreamAdapter::VideoStreamAdapter(
VideoStreamInputStateProvider* input_state_provider)
: source_restrictor_(std::make_unique<VideoSourceRestrictor>()),
input_state_provider_(input_state_provider),
balanced_settings_(),
adaptation_validation_id_(0),
degradation_preference_(DegradationPreference::DISABLED),
input_state_(),
last_adaptation_request_(absl::nullopt),
last_video_source_restrictions_() {
sequence_checker_.Detach();
@ -399,29 +415,28 @@ void VideoStreamAdapter::SetDegradationPreference(
}
}
void VideoStreamAdapter::SetInput(VideoStreamInputState input_state) {
// Invalidate any previously returned Adaptation.
RTC_DCHECK_RUN_ON(&sequence_checker_);
++adaptation_validation_id_;
input_state_ = input_state;
source_restrictor_->set_min_pixels_per_frame(
input_state_.min_pixels_per_frame());
}
Adaptation VideoStreamAdapter::GetAdaptationUp() const {
Adaptation VideoStreamAdapter::GetAdaptationUp() {
RTC_DCHECK_RUN_ON(&sequence_checker_);
RTC_DCHECK_NE(degradation_preference_, DegradationPreference::DISABLED);
RTC_DCHECK(input_state_.HasInputFrameSizeAndFramesPerSecond());
VideoStreamInputState input_state = input_state_provider_->InputState();
++adaptation_validation_id_;
if (!HasSufficientInputForAdaptation(input_state)) {
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kInsufficientInput, input_state);
}
source_restrictor_->set_min_pixels_per_frame(
input_state.min_pixels_per_frame());
// Don't adapt if we're awaiting a previous adaptation to have an effect.
bool last_request_increased_resolution =
last_adaptation_request_ && last_adaptation_request_->step_type_ ==
Adaptation::StepType::kIncreaseResolution;
if (last_request_increased_resolution &&
degradation_preference_ == DegradationPreference::MAINTAIN_FRAMERATE &&
input_state_.frame_size_pixels().value() <=
input_state.frame_size_pixels().value() <=
last_adaptation_request_->input_pixel_count_) {
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kAwaitingPreviousAdaptation);
Adaptation::Status::kAwaitingPreviousAdaptation,
input_state);
}
// Maybe propose targets based on degradation preference.
@ -429,20 +444,21 @@ Adaptation VideoStreamAdapter::GetAdaptationUp() const {
case DegradationPreference::BALANCED: {
// Attempt to increase target frame rate.
int target_fps =
balanced_settings_.MaxFps(input_state_.video_codec_type(),
input_state_.frame_size_pixels().value());
balanced_settings_.MaxFps(input_state.video_codec_type(),
input_state.frame_size_pixels().value());
if (source_restrictor_->CanIncreaseFrameRateTo(target_fps)) {
return Adaptation(
adaptation_validation_id_,
Adaptation::Step(Adaptation::StepType::kIncreaseFrameRate,
target_fps));
target_fps),
input_state);
}
// Scale up resolution.
ABSL_FALLTHROUGH_INTENDED;
}
case DegradationPreference::MAINTAIN_FRAMERATE: {
// Attempt to increase pixel count.
int target_pixels = input_state_.frame_size_pixels().value();
int target_pixels = input_state.frame_size_pixels().value();
if (source_restrictor_->adaptation_counters().resolution_adaptations ==
1) {
RTC_LOG(LS_INFO) << "Removing resolution down-scaling setting.";
@ -451,16 +467,17 @@ Adaptation VideoStreamAdapter::GetAdaptationUp() const {
target_pixels = GetHigherResolutionThan(target_pixels);
if (!source_restrictor_->CanIncreaseResolutionTo(target_pixels)) {
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kLimitReached);
Adaptation::Status::kLimitReached, input_state);
}
return Adaptation(
adaptation_validation_id_,
Adaptation::Step(Adaptation::StepType::kIncreaseResolution,
target_pixels));
target_pixels),
input_state);
}
case DegradationPreference::MAINTAIN_RESOLUTION: {
// Scale up framerate.
int target_fps = input_state_.frames_per_second();
int target_fps = input_state.frames_per_second();
if (source_restrictor_->adaptation_counters().fps_adaptations == 1) {
RTC_LOG(LS_INFO) << "Removing framerate down-scaling setting.";
target_fps = std::numeric_limits<int>::max();
@ -468,24 +485,32 @@ Adaptation VideoStreamAdapter::GetAdaptationUp() const {
target_fps = GetHigherFrameRateThan(target_fps);
if (!source_restrictor_->CanIncreaseFrameRateTo(target_fps)) {
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kLimitReached);
Adaptation::Status::kLimitReached, input_state);
}
return Adaptation(
adaptation_validation_id_,
Adaptation::Step(Adaptation::StepType::kIncreaseFrameRate,
target_fps));
target_fps),
input_state);
}
case DegradationPreference::DISABLED:
RTC_NOTREACHED();
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kLimitReached);
Adaptation::Status::kLimitReached, input_state);
}
}
Adaptation VideoStreamAdapter::GetAdaptationDown() const {
Adaptation VideoStreamAdapter::GetAdaptationDown() {
RTC_DCHECK_RUN_ON(&sequence_checker_);
RTC_DCHECK_NE(degradation_preference_, DegradationPreference::DISABLED);
RTC_DCHECK(input_state_.HasInputFrameSizeAndFramesPerSecond());
VideoStreamInputState input_state = input_state_provider_->InputState();
++adaptation_validation_id_;
if (!HasSufficientInputForAdaptation(input_state)) {
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kInsufficientInput, input_state);
}
source_restrictor_->set_min_pixels_per_frame(
input_state.min_pixels_per_frame());
// Don't adapt if we're awaiting a previous adaptation to have an effect or
// if we switched degradation preference.
bool last_request_decreased_resolution =
@ -493,10 +518,11 @@ Adaptation VideoStreamAdapter::GetAdaptationDown() const {
Adaptation::StepType::kDecreaseResolution;
if (last_request_decreased_resolution &&
degradation_preference_ == DegradationPreference::MAINTAIN_FRAMERATE &&
input_state_.frame_size_pixels().value() >=
input_state.frame_size_pixels().value() >=
last_adaptation_request_->input_pixel_count_) {
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kAwaitingPreviousAdaptation);
Adaptation::Status::kAwaitingPreviousAdaptation,
input_state);
}
// Maybe propose targets based on degradation preference.
@ -504,13 +530,14 @@ Adaptation VideoStreamAdapter::GetAdaptationDown() const {
case DegradationPreference::BALANCED: {
// Try scale down framerate, if lower.
int target_fps =
balanced_settings_.MinFps(input_state_.video_codec_type(),
input_state_.frame_size_pixels().value());
balanced_settings_.MinFps(input_state.video_codec_type(),
input_state.frame_size_pixels().value());
if (source_restrictor_->CanDecreaseFrameRateTo(target_fps)) {
return Adaptation(
adaptation_validation_id_,
Adaptation::Step(Adaptation::StepType::kDecreaseFrameRate,
target_fps));
target_fps),
input_state);
}
// Scale down resolution.
ABSL_FALLTHROUGH_INTENDED;
@ -518,35 +545,36 @@ Adaptation VideoStreamAdapter::GetAdaptationDown() const {
case DegradationPreference::MAINTAIN_FRAMERATE: {
// Scale down resolution.
int target_pixels =
GetLowerResolutionThan(input_state_.frame_size_pixels().value());
GetLowerResolutionThan(input_state.frame_size_pixels().value());
bool min_pixel_limit_reached =
target_pixels < source_restrictor_->min_pixels_per_frame();
if (!source_restrictor_->CanDecreaseResolutionTo(target_pixels)) {
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kLimitReached,
Adaptation::Status::kLimitReached, input_state,
min_pixel_limit_reached);
}
return Adaptation(
adaptation_validation_id_,
Adaptation::Step(Adaptation::StepType::kDecreaseResolution,
target_pixels),
min_pixel_limit_reached);
input_state, min_pixel_limit_reached);
}
case DegradationPreference::MAINTAIN_RESOLUTION: {
int target_fps = GetLowerFrameRateThan(input_state_.frames_per_second());
int target_fps = GetLowerFrameRateThan(input_state.frames_per_second());
if (!source_restrictor_->CanDecreaseFrameRateTo(target_fps)) {
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kLimitReached);
Adaptation::Status::kLimitReached, input_state);
}
return Adaptation(
adaptation_validation_id_,
Adaptation::Step(Adaptation::StepType::kDecreaseFrameRate,
target_fps));
target_fps),
input_state);
}
case DegradationPreference::DISABLED:
RTC_NOTREACHED();
return Adaptation(adaptation_validation_id_,
Adaptation::Status::kLimitReached);
Adaptation::Status::kLimitReached, input_state);
}
}
@ -577,8 +605,8 @@ void VideoStreamAdapter::ApplyAdaptation(
// 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_state_.frame_size_pixels().value(),
input_state_.frames_per_second(), adaptation.step().type});
adaptation.input_state_.frame_size_pixels().value(),
adaptation.input_state_.frames_per_second(), adaptation.step().type});
// Adapt!
source_restrictor_->ApplyAdaptationStep(adaptation.step(),
degradation_preference_);
@ -587,11 +615,12 @@ void VideoStreamAdapter::ApplyAdaptation(
Adaptation VideoStreamAdapter::GetAdaptationTo(
const VideoAdaptationCounters& counters,
const VideoSourceRestrictions& restrictions) const {
const VideoSourceRestrictions& restrictions) {
// Adapts up/down from the current levels so counters are equal.
RTC_DCHECK_RUN_ON(&sequence_checker_);
VideoStreamInputState input_state = input_state_provider_->InputState();
return Adaptation(adaptation_validation_id_,
Adaptation::Step(restrictions, counters));
Adaptation::Step(restrictions, counters), input_state);
}
void VideoStreamAdapter::BroadcastVideoRestrictionsUpdate(
@ -611,4 +640,12 @@ void VideoStreamAdapter::BroadcastVideoRestrictionsUpdate(
last_filtered_restrictions_ = filtered;
}
bool VideoStreamAdapter::HasSufficientInputForAdaptation(
const VideoStreamInputState& input_state) const {
return input_state.HasInputFrameSizeAndFramesPerSecond() &&
(degradation_preference_ !=
DegradationPreference::MAINTAIN_RESOLUTION ||
input_state.frames_per_second() >= kMinFrameRateFps);
}
} // namespace webrtc

View file

@ -20,6 +20,7 @@
#include "api/video/video_adaptation_counters.h"
#include "call/adaptation/video_source_restrictions.h"
#include "call/adaptation/video_stream_input_state.h"
#include "call/adaptation/video_stream_input_state_provider.h"
#include "modules/video_coding/utility/quality_scaler.h"
#include "rtc_base/experiments/balanced_degradation_settings.h"
@ -67,6 +68,8 @@ class Adaptation final {
// adaptation has not yet been reflected in the input resolution or frame
// rate; adaptation is refused to avoid "double-adapting".
kAwaitingPreviousAdaptation,
// Not enough input.
kInsufficientInput,
};
static const char* StatusToString(Status status);
@ -77,6 +80,8 @@ class Adaptation final {
// Used for stats reporting.
bool min_pixel_limit_reached() const;
const VideoStreamInputState& input_state() const;
private:
// The adapter needs to know about step type and step target in order to
// construct and perform an Adaptation, which is a detail we do not want to
@ -107,12 +112,18 @@ class Adaptation final {
};
// Constructs with a valid adaptation Step. Status is kValid.
Adaptation(int validation_id, Step step);
Adaptation(int validation_id, Step step, bool min_pixel_limit_reached);
Adaptation(int validation_id, Step step, VideoStreamInputState input_state);
Adaptation(int validation_id,
Step step,
VideoStreamInputState input_state,
bool min_pixel_limit_reached);
// Constructor when adaptation is not valid. Status MUST NOT be kValid.
Adaptation(int validation_id, Status invalid_status);
Adaptation(int validation_id,
Status invalid_status,
VideoStreamInputState input_state);
Adaptation(int validation_id,
Status invalid_status,
VideoStreamInputState input_state,
bool min_pixel_limit_reached);
const Step& step() const; // Only callable if |status_| is kValid.
@ -124,6 +135,8 @@ class Adaptation final {
const Status status_;
const absl::optional<Step> step_; // Only present if |status_| is kValid.
const bool min_pixel_limit_reached_;
// Input state when adaptation was made.
const VideoStreamInputState input_state_;
};
// Owns the VideoSourceRestriction for a single stream and is responsible for
@ -134,7 +147,8 @@ class Adaptation final {
// 3. Modify the stream's restrictions in one of the valid ways.
class VideoStreamAdapter {
public:
VideoStreamAdapter();
explicit VideoStreamAdapter(
VideoStreamInputStateProvider* input_state_provider);
~VideoStreamAdapter();
VideoSourceRestrictions source_restrictions() const;
@ -150,15 +164,13 @@ class VideoStreamAdapter {
// restrictions! This is not defined in the spec and is unexpected, there is a
// tiny risk that people would discover and rely on this behavior.
void SetDegradationPreference(DegradationPreference degradation_preference);
// The adaptaiton logic depends on these inputs.
void SetInput(VideoStreamInputState input_state);
// Returns an adaptation that we are guaranteed to be able to apply, or a
// status code indicating the reason why we cannot adapt.
Adaptation GetAdaptationUp() const;
Adaptation GetAdaptationDown() const;
Adaptation GetAdaptationUp();
Adaptation GetAdaptationDown();
Adaptation GetAdaptationTo(const VideoAdaptationCounters& counters,
const VideoSourceRestrictions& restrictions) const;
const VideoSourceRestrictions& restrictions);
struct RestrictionsWithCounters {
VideoSourceRestrictions restrictions;
@ -192,6 +204,9 @@ class VideoStreamAdapter {
void BroadcastVideoRestrictionsUpdate(
const rtc::scoped_refptr<Resource>& resource);
bool HasSufficientInputForAdaptation(const VideoStreamInputState& input_state)
const RTC_RUN_ON(&sequence_checker_);
// The input frame rate and resolution at the time of an adaptation in the
// direction described by |mode_| (up or down).
// TODO(https://crbug.com/webrtc/11393): Can this be renamed? Can this be
@ -209,6 +224,9 @@ class VideoStreamAdapter {
// Owner and modifier of the VideoSourceRestriction of this stream adaptor.
const std::unique_ptr<VideoSourceRestrictor> source_restrictor_
RTC_GUARDED_BY(&sequence_checker_);
// Gets the input state which is the basis of all adaptations.
// Thread safe.
VideoStreamInputStateProvider* input_state_provider_;
// Decides the next adaptation target in DegradationPreference::BALANCED.
const BalancedDegradationSettings balanced_settings_;
// To guard against applying adaptations that have become invalidated, an
@ -219,7 +237,6 @@ class VideoStreamAdapter {
// https://w3c.github.io/mst-content-hint/#dom-rtcdegradationpreference
DegradationPreference degradation_preference_
RTC_GUARDED_BY(&sequence_checker_);
VideoStreamInputState input_state_ RTC_GUARDED_BY(&sequence_checker_);
// The input frame rate, resolution and adaptation direction of the last
// ApplyAdaptationTarget(). Used to avoid adapting twice if a recent
// adaptation has not had an effect on the input frame rate or resolution yet.

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,8 @@ VideoStreamInputStateProvider::VideoStreamInputStateProvider(
VideoStreamEncoderObserver* frame_rate_provider)
: frame_rate_provider_(frame_rate_provider) {}
VideoStreamInputStateProvider::~VideoStreamInputStateProvider() {}
void VideoStreamInputStateProvider::OnHasInputChanged(bool has_input) {
rtc::CritScope lock(&crit_);
input_state_.set_has_input(has_input);

View file

@ -22,12 +22,13 @@ class VideoStreamInputStateProvider {
public:
VideoStreamInputStateProvider(
VideoStreamEncoderObserver* frame_rate_provider);
virtual ~VideoStreamInputStateProvider();
void OnHasInputChanged(bool has_input);
void OnFrameSizeObserved(int frame_size_pixels);
void OnEncoderSettingsChanged(EncoderSettings encoder_settings);
VideoStreamInputState InputState();
virtual VideoStreamInputState InputState();
private:
mutable rtc::CriticalSection crit_;

View file

@ -256,10 +256,10 @@ VideoStreamEncoder::VideoStreamEncoder(
ParseAutomatincAnimationDetectionFieldTrial()),
encoder_switch_requested_(false),
input_state_provider_(encoder_stats_observer),
video_stream_adapter_(std::make_unique<VideoStreamAdapter>()),
video_stream_adapter_(
std::make_unique<VideoStreamAdapter>(&input_state_provider_)),
resource_adaptation_processor_(
std::make_unique<ResourceAdaptationProcessor>(
&input_state_provider_,
encoder_stats_observer,
video_stream_adapter_.get())),
adaptation_constraints_(),