[Adaptation] Move IsAdaptationUpAllowed/OnAdaptationApplied out of API.

IsAdaptationUpAllowed is moved from Resource to AdaptationConstraint.
OnAdaptationApplied is moved from Resource to AdaptationListener.

In a future CL, Resource will be moved to api/, but
AdaptationConstraint and AdaptationListener will stay in call/.

The processor, encode stream and manager are updated to keep track of
both resources, constraints and listeners. Fakes and tests are updated.
After this CL, the manager's inner classes that prevent adaptation
implement AdaptationConstraint instead of Resource.

Bug: webrtc:11525
Change-Id: Ie9cd5b1ba7d8e161951e131ab8f6bd9d5cf765bf
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176368
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Evan Shrubsole <eshr@google.com>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31409}
This commit is contained in:
Henrik Boström 2020-06-02 13:02:36 +02:00 committed by Commit Bot
parent a0cf1eabb7
commit 0f0aa9c7a8
27 changed files with 775 additions and 497 deletions

View File

@ -10,6 +10,10 @@ import("../../webrtc.gni")
rtc_library("resource_adaptation") {
sources = [
"adaptation_constraint.cc",
"adaptation_constraint.h",
"adaptation_listener.cc",
"adaptation_listener.h",
"encoder_settings.cc",
"encoder_settings.h",
"resource.cc",
@ -80,6 +84,10 @@ if (rtc_include_tests) {
testonly = true
sources = [
"test/fake_adaptation_constraint.cc",
"test/fake_adaptation_constraint.h",
"test/fake_adaptation_listener.cc",
"test/fake_adaptation_listener.h",
"test/fake_frame_rate_provider.cc",
"test/fake_frame_rate_provider.h",
"test/fake_resource.cc",

View File

@ -0,0 +1,17 @@
/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "call/adaptation/adaptation_constraint.h"
namespace webrtc {
AdaptationConstraint::~AdaptationConstraint() {}
} // namespace webrtc

View File

@ -0,0 +1,43 @@
/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef CALL_ADAPTATION_ADAPTATION_CONSTRAINT_H_
#define CALL_ADAPTATION_ADAPTATION_CONSTRAINT_H_
#include <string>
#include "api/scoped_refptr.h"
#include "call/adaptation/resource.h"
#include "call/adaptation/video_source_restrictions.h"
#include "call/adaptation/video_stream_input_state.h"
namespace webrtc {
// Adaptation constraints have the ability to prevent applying a proposed
// adaptation (expressed as restrictions before/after adaptation).
class AdaptationConstraint {
public:
virtual ~AdaptationConstraint();
virtual std::string Name() const = 0;
// TODO(https://crbug.com/webrtc/11172): When we have multi-stream adaptation
// support, this interface needs to indicate which stream the adaptation
// applies to.
virtual bool IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const = 0;
};
} // namespace webrtc
#endif // CALL_ADAPTATION_ADAPTATION_CONSTRAINT_H_

View File

@ -0,0 +1,17 @@
/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "call/adaptation/adaptation_listener.h"
namespace webrtc {
AdaptationListener::~AdaptationListener() {}
} // namespace webrtc

View File

@ -0,0 +1,41 @@
/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef CALL_ADAPTATION_ADAPTATION_LISTENER_H_
#define CALL_ADAPTATION_ADAPTATION_LISTENER_H_
#include "api/scoped_refptr.h"
#include "call/adaptation/resource.h"
#include "call/adaptation/video_source_restrictions.h"
#include "call/adaptation/video_stream_input_state.h"
namespace webrtc {
// TODO(hbos): Can this be consolidated with
// ResourceAdaptationProcessorListener::OnVideoSourceRestrictionsUpdated()? Both
// listen to adaptations being applied, but on different layers with different
// arguments.
class AdaptationListener {
public:
virtual ~AdaptationListener();
// TODO(https://crbug.com/webrtc/11172): When we have multi-stream adaptation
// support, this interface needs to indicate which stream the adaptation
// applies to.
virtual void OnAdaptationApplied(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) = 0;
};
} // namespace webrtc
#endif // CALL_ADAPTATION_ADAPTATION_LISTENER_H_

View File

@ -48,8 +48,8 @@ class ResourceListener {
// kOveruse or kUnderuse when resource usage is high or low enough that we
// should perform some sort of mitigation to fulfil the resource's constraints.
//
// All methods defined in this interface, except RegisterAdaptationTaskQueue(),
// MUST be invoked on the resource adaptation task queue.
// All methods defined in this interface, except SetResourceListener(), MUST be
// invoked on the resource adaptation task queue.
//
// Usage measurements may be performed on an implementation-specific task queue.
// The Resource is reference counted to prevent use-after-free when posting
@ -61,21 +61,9 @@ class Resource : public rtc::RefCountInterface {
// Destruction may happen on any task queue.
~Resource() override;
// Provides a pointer to the adaptation task queue. After this call, all
// methods defined in this interface, including
// UnregisterAdaptationTaskQueue() MUST be invoked on the adaptation task
// queue. Registering the adaptation task queue may, however, happen off the
// adaptation task queue.
virtual void RegisterAdaptationTaskQueue(
TaskQueueBase* resource_adaptation_queue) = 0;
// Signals that the adaptation task queue is no longer safe to use. No
// assumptions must be made as to whether or not tasks in-flight will run.
virtual void UnregisterAdaptationTaskQueue() = 0;
// The listeners MUST be informed any time UsageState() changes.
virtual void SetResourceListener(ResourceListener* listener) = 0;
virtual std::string Name() const = 0;
// The listener MUST be informed any time UsageState() changes.
virtual void SetResourceListener(ResourceListener* listener) = 0;
// Within a single task running on the adaptation task queue, UsageState()
// MUST return the same value every time it is called.
// TODO(https://crbug.com/webrtc/11618): Remove the UsageState() getter in
@ -86,20 +74,6 @@ class Resource : public rtc::RefCountInterface {
// Invalidates current usage measurements, i.e. in response to the system load
// changing. Example: an adaptation was just applied.
virtual void ClearUsageState() = 0;
// This method allows the Resource to reject a proposed adaptation in the "up"
// direction if it predicts this would cause overuse of this resource.
virtual bool IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const = 0;
virtual void OnAdaptationApplied(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) = 0;
};
} // namespace webrtc

View File

@ -49,12 +49,18 @@ ResourceAdaptationProcessor::ResourceAdaptationProcessor(
ResourceAdaptationProcessor::~ResourceAdaptationProcessor() {
RTC_DCHECK_RUN_ON(&sequence_checker_);
RTC_DCHECK(!is_resource_adaptation_enabled_);
RTC_DCHECK(adaptation_listeners_.empty())
<< "There are listener(s) depending on a ResourceAdaptationProcessor "
<< "being destroyed.";
RTC_DCHECK(restrictions_listeners_.empty())
<< "There are restrictions listener(s) depending on a "
<< "ResourceAdaptationProcessor being destroyed.";
RTC_DCHECK(resources_.empty())
<< "There are resource(s) attached to a ResourceAdaptationProcessor "
<< "being destroyed.";
RTC_DCHECK(adaptation_constraints_.empty())
<< "There are constaint(s) attached to a ResourceAdaptationProcessor "
<< "being destroyed.";
RTC_DCHECK(adaptation_listeners_.empty())
<< "There are listener(s) attached to a ResourceAdaptationProcessor "
<< "being destroyed.";
}
void ResourceAdaptationProcessor::InitializeOnResourceAdaptationQueue() {
@ -95,22 +101,22 @@ void ResourceAdaptationProcessor::StopResourceAdaptation() {
is_resource_adaptation_enabled_ = false;
}
void ResourceAdaptationProcessor::AddAdaptationListener(
ResourceAdaptationProcessorListener* adaptation_listener) {
void ResourceAdaptationProcessor::AddRestrictionsListener(
VideoSourceRestrictionsListener* restrictions_listener) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
RTC_DCHECK(std::find(adaptation_listeners_.begin(),
adaptation_listeners_.end(),
adaptation_listener) == adaptation_listeners_.end());
adaptation_listeners_.push_back(adaptation_listener);
RTC_DCHECK(std::find(restrictions_listeners_.begin(),
restrictions_listeners_.end(),
restrictions_listener) == restrictions_listeners_.end());
restrictions_listeners_.push_back(restrictions_listener);
}
void ResourceAdaptationProcessor::RemoveAdaptationListener(
ResourceAdaptationProcessorListener* adaptation_listener) {
void ResourceAdaptationProcessor::RemoveRestrictionsListener(
VideoSourceRestrictionsListener* restrictions_listener) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
auto it = std::find(adaptation_listeners_.begin(),
adaptation_listeners_.end(), adaptation_listener);
RTC_DCHECK(it != adaptation_listeners_.end());
adaptation_listeners_.erase(it);
auto it = std::find(restrictions_listeners_.begin(),
restrictions_listeners_.end(), restrictions_listener);
RTC_DCHECK(it != restrictions_listeners_.end());
restrictions_listeners_.erase(it);
}
void ResourceAdaptationProcessor::AddResource(
@ -136,6 +142,42 @@ void ResourceAdaptationProcessor::RemoveResource(
resources_.erase(it);
}
void ResourceAdaptationProcessor::AddAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
RTC_DCHECK(std::find(adaptation_constraints_.begin(),
adaptation_constraints_.end(),
adaptation_constraint) == adaptation_constraints_.end());
adaptation_constraints_.push_back(adaptation_constraint);
}
void ResourceAdaptationProcessor::RemoveAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
auto it = std::find(adaptation_constraints_.begin(),
adaptation_constraints_.end(), adaptation_constraint);
RTC_DCHECK(it != adaptation_constraints_.end());
adaptation_constraints_.erase(it);
}
void ResourceAdaptationProcessor::AddAdaptationListener(
AdaptationListener* adaptation_listener) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
RTC_DCHECK(std::find(adaptation_listeners_.begin(),
adaptation_listeners_.end(),
adaptation_listener) == adaptation_listeners_.end());
adaptation_listeners_.push_back(adaptation_listener);
}
void ResourceAdaptationProcessor::RemoveAdaptationListener(
AdaptationListener* adaptation_listener) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
auto it = std::find(adaptation_listeners_.begin(),
adaptation_listeners_.end(), adaptation_listener);
RTC_DCHECK(it != adaptation_listeners_.end());
adaptation_listeners_.erase(it);
}
void ResourceAdaptationProcessor::SetDegradationPreference(
DegradationPreference degradation_preference) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
@ -181,8 +223,8 @@ void ResourceAdaptationProcessor::MaybeUpdateVideoSourceRestrictions(
effective_degradation_preference_)
<< "): " << new_source_restrictions.ToString();
last_reported_source_restrictions_ = std::move(new_source_restrictions);
for (auto* adaptation_listener : adaptation_listeners_) {
adaptation_listener->OnVideoSourceRestrictionsUpdated(
for (auto* restrictions_listener : restrictions_listeners_) {
restrictions_listener->OnVideoSourceRestrictionsUpdated(
last_reported_source_restrictions_,
stream_adapter_->adaptation_counters(), reason);
}
@ -284,25 +326,26 @@ ResourceAdaptationProcessor::OnResourceUnderuse(
stream_adapter_->source_restrictions();
VideoSourceRestrictions restrictions_after =
stream_adapter_->PeekNextRestrictions(adaptation);
for (const auto& resource : resources_) {
if (!resource->IsAdaptationUpAllowed(input_state, restrictions_before,
restrictions_after, reason_resource)) {
for (const auto* constraint : adaptation_constraints_) {
if (!constraint->IsAdaptationUpAllowed(input_state, restrictions_before,
restrictions_after,
reason_resource)) {
processing_in_progress_ = false;
rtc::StringBuilder message;
message << "Not adapting up because resource \"" << resource->Name()
message << "Not adapting up because constraint \"" << constraint->Name()
<< "\" disallowed it";
return MitigationResultAndLogMessage(
MitigationResult::kRejectedByResource, message.Release());
MitigationResult::kRejectedByConstraint, message.Release());
}
}
// Apply adaptation.
stream_adapter_->ApplyAdaptation(adaptation);
for (const auto& resource : resources_) {
resource->OnAdaptationApplied(input_state, restrictions_before,
restrictions_after, reason_resource);
for (auto* adaptation_listener : adaptation_listeners_) {
adaptation_listener->OnAdaptationApplied(
input_state, restrictions_before, restrictions_after, reason_resource);
}
// Update VideoSourceRestrictions based on adaptation. This also informs the
// |adaptation_listeners_|.
// |restrictions_listeners_|.
MaybeUpdateVideoSourceRestrictions(reason_resource);
processing_in_progress_ = false;
rtc::StringBuilder message;
@ -359,12 +402,12 @@ ResourceAdaptationProcessor::OnResourceOveruse(
VideoSourceRestrictions restrictions_after =
stream_adapter_->PeekNextRestrictions(adaptation);
stream_adapter_->ApplyAdaptation(adaptation);
for (const auto& resource : resources_) {
resource->OnAdaptationApplied(input_state, restrictions_before,
restrictions_after, reason_resource);
for (auto* adaptation_listener : adaptation_listeners_) {
adaptation_listener->OnAdaptationApplied(
input_state, restrictions_before, restrictions_after, reason_resource);
}
// Update VideoSourceRestrictions based on adaptation. This also informs the
// |adaptation_listeners_|.
// |restrictions_listeners_|.
MaybeUpdateVideoSourceRestrictions(reason_resource);
processing_in_progress_ = false;
rtc::StringBuilder message;

View File

@ -21,6 +21,8 @@
#include "api/scoped_refptr.h"
#include "api/video/video_frame.h"
#include "api/video/video_stream_encoder_observer.h"
#include "call/adaptation/adaptation_constraint.h"
#include "call/adaptation/adaptation_listener.h"
#include "call/adaptation/resource.h"
#include "call/adaptation/resource_adaptation_processor_interface.h"
#include "call/adaptation/video_source_restrictions.h"
@ -63,12 +65,19 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
void StartResourceAdaptation() override;
void StopResourceAdaptation() override;
void AddAdaptationListener(
ResourceAdaptationProcessorListener* adaptation_listener) override;
void RemoveAdaptationListener(
ResourceAdaptationProcessorListener* adaptation_listener) override;
void AddRestrictionsListener(
VideoSourceRestrictionsListener* restrictions_listener) override;
void RemoveRestrictionsListener(
VideoSourceRestrictionsListener* restrictions_listener) override;
void AddResource(rtc::scoped_refptr<Resource> resource) override;
void RemoveResource(rtc::scoped_refptr<Resource> resource) override;
void AddAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) override;
void RemoveAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) override;
void AddAdaptationListener(AdaptationListener* adaptation_listener) override;
void RemoveAdaptationListener(
AdaptationListener* adaptation_listener) override;
void SetDegradationPreference(
DegradationPreference degradation_preference) override;
@ -95,7 +104,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
kInsufficientInput,
kRejectedByAdaptationCounts,
kRejectedByAdapter,
kRejectedByResource,
kRejectedByConstraint,
kAdaptationApplied,
};
@ -139,10 +148,14 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
RTC_GUARDED_BY(sequence_checker_);
VideoStreamEncoderObserver* const encoder_stats_observer_
RTC_GUARDED_BY(sequence_checker_);
std::vector<ResourceAdaptationProcessorListener*> adaptation_listeners_
std::vector<VideoSourceRestrictionsListener*> restrictions_listeners_
RTC_GUARDED_BY(sequence_checker_);
std::vector<rtc::scoped_refptr<Resource>> resources_
RTC_GUARDED_BY(sequence_checker_);
std::vector<AdaptationConstraint*> adaptation_constraints_
RTC_GUARDED_BY(sequence_checker_);
std::vector<AdaptationListener*> adaptation_listeners_
RTC_GUARDED_BY(sequence_checker_);
// Purely used for statistics, does not ensure mapped resources stay alive.
std::map<const Resource*, int> adaptations_counts_by_resource_
RTC_GUARDED_BY(sequence_checker_);

View File

@ -12,7 +12,7 @@
namespace webrtc {
ResourceAdaptationProcessorListener::~ResourceAdaptationProcessorListener() {}
VideoSourceRestrictionsListener::~VideoSourceRestrictionsListener() {}
ResourceAdaptationProcessorInterface::~ResourceAdaptationProcessorInterface() {}

View File

@ -16,6 +16,8 @@
#include "api/scoped_refptr.h"
#include "api/video/video_adaptation_counters.h"
#include "api/video/video_frame.h"
#include "call/adaptation/adaptation_constraint.h"
#include "call/adaptation/adaptation_listener.h"
#include "call/adaptation/encoder_settings.h"
#include "call/adaptation/resource.h"
#include "call/adaptation/video_source_restrictions.h"
@ -25,9 +27,9 @@ namespace webrtc {
// The listener is responsible for carrying out the reconfiguration of the video
// source such that the VideoSourceRestrictions are fulfilled.
class ResourceAdaptationProcessorListener {
class VideoSourceRestrictionsListener {
public:
virtual ~ResourceAdaptationProcessorListener();
virtual ~VideoSourceRestrictionsListener();
// The |restrictions| are filtered by degradation preference but not the
// |adaptation_counters|, which are currently only reported for legacy stats
@ -63,12 +65,20 @@ class ResourceAdaptationProcessorInterface {
// over time.
virtual void StartResourceAdaptation() = 0;
virtual void StopResourceAdaptation() = 0;
virtual void AddAdaptationListener(
ResourceAdaptationProcessorListener* adaptation_listener) = 0;
virtual void RemoveAdaptationListener(
ResourceAdaptationProcessorListener* adaptation_listener) = 0;
virtual void AddRestrictionsListener(
VideoSourceRestrictionsListener* restrictions_listener) = 0;
virtual void RemoveRestrictionsListener(
VideoSourceRestrictionsListener* restrictions_listener) = 0;
virtual void AddResource(rtc::scoped_refptr<Resource> resource) = 0;
virtual void RemoveResource(rtc::scoped_refptr<Resource> resource) = 0;
virtual void AddAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) = 0;
virtual void RemoveAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) = 0;
virtual void AddAdaptationListener(
AdaptationListener* adaptation_listener) = 0;
virtual void RemoveAdaptationListener(
AdaptationListener* adaptation_listener) = 0;
virtual void SetDegradationPreference(
DegradationPreference degradation_preference) = 0;

View File

@ -14,6 +14,8 @@
#include "api/video/video_adaptation_counters.h"
#include "call/adaptation/resource.h"
#include "call/adaptation/resource_adaptation_processor_interface.h"
#include "call/adaptation/test/fake_adaptation_constraint.h"
#include "call/adaptation/test/fake_adaptation_listener.h"
#include "call/adaptation/test/fake_frame_rate_provider.h"
#include "call/adaptation/test/fake_resource.h"
#include "call/adaptation/video_source_restrictions.h"
@ -29,15 +31,15 @@ namespace {
const int kDefaultFrameRate = 30;
const int kDefaultFrameSize = 1280 * 720;
class ResourceAdaptationProcessorListenerForTesting
: public ResourceAdaptationProcessorListener {
class VideoSourceRestrictionsListenerForTesting
: public VideoSourceRestrictionsListener {
public:
ResourceAdaptationProcessorListenerForTesting()
VideoSourceRestrictionsListenerForTesting()
: restrictions_updated_count_(0),
restrictions_(),
adaptation_counters_(),
reason_(nullptr) {}
~ResourceAdaptationProcessorListenerForTesting() override {}
~VideoSourceRestrictionsListenerForTesting() override {}
size_t restrictions_updated_count() const {
return restrictions_updated_count_;
@ -48,7 +50,7 @@ class ResourceAdaptationProcessorListenerForTesting
}
rtc::scoped_refptr<Resource> reason() const { return reason_; }
// ResourceAdaptationProcessorListener implementation.
// VideoSourceRestrictionsListener implementation.
void OnVideoSourceRestrictionsUpdated(
VideoSourceRestrictions restrictions,
const VideoAdaptationCounters& adaptation_counters,
@ -74,18 +76,19 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
input_state_provider_(&frame_rate_provider_),
resource_(FakeResource::Create("FakeResource")),
other_resource_(FakeResource::Create("OtherFakeResource")),
adaptation_constraint_("FakeAdaptationConstraint"),
adaptation_listener_(),
processor_(std::make_unique<ResourceAdaptationProcessor>(
&input_state_provider_,
/*encoder_stats_observer=*/&frame_rate_provider_)) {
resource_->RegisterAdaptationTaskQueue(resource_adaptation_queue_.Get());
other_resource_->RegisterAdaptationTaskQueue(
resource_adaptation_queue_.Get());
rtc::Event event;
resource_adaptation_queue_.PostTask([this, &event] {
processor_->InitializeOnResourceAdaptationQueue();
processor_->AddAdaptationListener(&processor_listener_);
processor_->AddRestrictionsListener(&restrictions_listener_);
processor_->AddResource(resource_);
processor_->AddResource(other_resource_);
processor_->AddAdaptationConstraint(&adaptation_constraint_);
processor_->AddAdaptationListener(&adaptation_listener_);
event.Set();
});
event.Wait(rtc::Event::kForever);
@ -94,9 +97,11 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
rtc::Event event;
resource_adaptation_queue_.PostTask([this, &event] {
processor_->StopResourceAdaptation();
processor_->RemoveRestrictionsListener(&restrictions_listener_);
processor_->RemoveResource(resource_);
processor_->RemoveResource(other_resource_);
processor_->RemoveAdaptationListener(&processor_listener_);
processor_->RemoveAdaptationConstraint(&adaptation_constraint_);
processor_->RemoveAdaptationListener(&adaptation_listener_);
processor_.reset();
event.Set();
});
@ -123,8 +128,10 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
VideoStreamInputStateProvider input_state_provider_;
rtc::scoped_refptr<FakeResource> resource_;
rtc::scoped_refptr<FakeResource> other_resource_;
FakeAdaptationConstraint adaptation_constraint_;
FakeAdaptationListener adaptation_listener_;
std::unique_ptr<ResourceAdaptationProcessor> processor_;
ResourceAdaptationProcessorListenerForTesting processor_listener_;
VideoSourceRestrictionsListenerForTesting restrictions_listener_;
};
} // namespace
@ -139,8 +146,8 @@ TEST_F(ResourceAdaptationProcessorTest, DisabledByDefault) {
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
processor_->StartResourceAdaptation();
// Adaptation does not happen when disabled.
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
},
RTC_FROM_HERE);
}
@ -154,12 +161,12 @@ TEST_F(ResourceAdaptationProcessorTest, InsufficientInput) {
// Adaptation does not happen if input is insufficient.
// When frame size is missing (OnFrameSizeObserved not called yet).
input_state_provider_.OnHasInputChanged(true);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
// When "has input" is missing.
SetInputStates(false, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
// Note: frame rate cannot be missing, if unset it is 0.
},
RTC_FROM_HERE);
@ -177,9 +184,9 @@ TEST_F(ResourceAdaptationProcessorTest,
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
EXPECT_TRUE(processor_listener_.restrictions()
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
EXPECT_TRUE(restrictions_listener_.restrictions()
.max_pixels_per_frame()
.has_value());
},
@ -194,10 +201,10 @@ TEST_F(ResourceAdaptationProcessorTest,
DegradationPreference::MAINTAIN_RESOLUTION);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
EXPECT_TRUE(
processor_listener_.restrictions().max_frame_rate().has_value());
restrictions_listener_.restrictions().max_frame_rate().has_value());
},
RTC_FROM_HERE);
}
@ -214,15 +221,15 @@ TEST_F(ResourceAdaptationProcessorTest,
// BalancedDegradationSettings, VideoStreamAdapter and default input
// states. This test requires it to be achieved within 4 adaptations.
for (size_t i = 0; i < 4; ++i) {
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(i + 1, processor_listener_.restrictions_updated_count());
RestrictSource(processor_listener_.restrictions());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(i + 1, restrictions_listener_.restrictions_updated_count());
RestrictSource(restrictions_listener_.restrictions());
}
EXPECT_TRUE(processor_listener_.restrictions()
EXPECT_TRUE(restrictions_listener_.restrictions()
.max_pixels_per_frame()
.has_value());
EXPECT_TRUE(
processor_listener_.restrictions().max_frame_rate().has_value());
restrictions_listener_.restrictions().max_frame_rate().has_value());
},
RTC_FROM_HERE);
}
@ -234,12 +241,12 @@ TEST_F(ResourceAdaptationProcessorTest, AwaitingPreviousAdaptation) {
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
// If we don't restrict the source then adaptation will not happen again
// due to "awaiting previous adaptation". This prevents "double-adapt".
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
},
RTC_FROM_HERE);
}
@ -251,8 +258,8 @@ TEST_F(ResourceAdaptationProcessorTest, CannotAdaptUpWhenUnrestricted) {
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kUnderuse);
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kUnderuse);
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
},
RTC_FROM_HERE);
}
@ -264,13 +271,13 @@ TEST_F(ResourceAdaptationProcessorTest, UnderuseTakesUsBackToUnrestricted) {
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
RestrictSource(processor_listener_.restrictions());
resource_->set_usage_state(ResourceUsageState::kUnderuse);
EXPECT_EQ(2u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
RestrictSource(restrictions_listener_.restrictions());
resource_->SetUsageState(ResourceUsageState::kUnderuse);
EXPECT_EQ(2u, restrictions_listener_.restrictions_updated_count());
EXPECT_EQ(VideoSourceRestrictions(),
processor_listener_.restrictions());
restrictions_listener_.restrictions());
},
RTC_FROM_HERE);
}
@ -283,13 +290,13 @@ TEST_F(ResourceAdaptationProcessorTest, ResourcesCanPreventAdaptingUp) {
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
// Adapt down so that we can adapt up.
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
RestrictSource(processor_listener_.restrictions());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
RestrictSource(restrictions_listener_.restrictions());
// Adapting up is prevented.
resource_->set_is_adaptation_up_allowed(false);
resource_->set_usage_state(ResourceUsageState::kUnderuse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
adaptation_constraint_.set_is_adaptation_up_allowed(false);
resource_->SetUsageState(ResourceUsageState::kUnderuse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
},
RTC_FROM_HERE);
}
@ -302,13 +309,13 @@ TEST_F(ResourceAdaptationProcessorTest,
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
RestrictSource(processor_listener_.restrictions());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
RestrictSource(restrictions_listener_.restrictions());
// Other resource signals under-use
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
},
RTC_FROM_HERE);
}
@ -321,19 +328,19 @@ TEST_F(ResourceAdaptationProcessorTest,
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
processor_->ResetVideoSourceRestrictions();
EXPECT_EQ(0, processor_listener_.adaptation_counters().Total());
other_resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
other_resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
RestrictSource(restrictions_listener_.restrictions());
// resource_ did not overuse after we reset the restrictions, so adapt
// up should be disallowed.
resource_->set_usage_state(ResourceUsageState::kUnderuse);
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
resource_->SetUsageState(ResourceUsageState::kUnderuse);
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
},
RTC_FROM_HERE);
}
@ -346,30 +353,30 @@ TEST_F(ResourceAdaptationProcessorTest,
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
other_resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(2, processor_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
other_resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(3, processor_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
RestrictSource(restrictions_listener_.restrictions());
other_resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
RestrictSource(restrictions_listener_.restrictions());
other_resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(3, restrictions_listener_.adaptation_counters().Total());
RestrictSource(restrictions_listener_.restrictions());
resource_->set_usage_state(ResourceUsageState::kUnderuse);
EXPECT_EQ(2, processor_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
resource_->SetUsageState(ResourceUsageState::kUnderuse);
EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
RestrictSource(restrictions_listener_.restrictions());
// Does not trigger adaptation since resource has no adaptations left.
resource_->set_usage_state(ResourceUsageState::kUnderuse);
EXPECT_EQ(2, processor_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
resource_->SetUsageState(ResourceUsageState::kUnderuse);
EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
RestrictSource(restrictions_listener_.restrictions());
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
EXPECT_EQ(0, processor_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
RestrictSource(restrictions_listener_.restrictions());
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
RestrictSource(restrictions_listener_.restrictions());
},
RTC_FROM_HERE);
}
@ -381,8 +388,8 @@ TEST_F(ResourceAdaptationProcessorTest, AdaptingTriggersOnAdaptationApplied) {
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, resource_->num_adaptations_applied());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, adaptation_listener_.num_adaptations_applied());
},
RTC_FROM_HERE);
}
@ -394,8 +401,8 @@ TEST_F(ResourceAdaptationProcessorTest, AdaptingClearsResourceUsageState) {
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
EXPECT_FALSE(resource_->UsageState().has_value());
},
RTC_FROM_HERE);
@ -407,8 +414,8 @@ TEST_F(ResourceAdaptationProcessorTest,
[this] {
processor_->SetDegradationPreference(DegradationPreference::DISABLED);
processor_->StartResourceAdaptation();
resource_->set_usage_state(ResourceUsageState::kOveruse);
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
resource_->SetUsageState(ResourceUsageState::kOveruse);
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
EXPECT_FALSE(resource_->UsageState().has_value());
},
RTC_FROM_HERE);
@ -422,20 +429,20 @@ TEST_F(ResourceAdaptationProcessorTest,
DegradationPreference::MAINTAIN_FRAMERATE);
processor_->StartResourceAdaptation();
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
// Does not trigger adapataion because there's no restriction.
EXPECT_EQ(0, processor_listener_.adaptation_counters().Total());
EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
resource_->set_usage_state(ResourceUsageState::kOveruse);
RestrictSource(restrictions_listener_.restrictions());
resource_->SetUsageState(ResourceUsageState::kOveruse);
// Adapts down even if other resource asked for adapting up.
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
RestrictSource(restrictions_listener_.restrictions());
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
// Doesn't adapt up because adaptation is due to another resource.
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
RestrictSource(processor_listener_.restrictions());
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
RestrictSource(restrictions_listener_.restrictions());
},
RTC_FROM_HERE);
}

View File

@ -14,8 +14,6 @@
#include "api/scoped_refptr.h"
#include "call/adaptation/test/fake_resource.h"
#include "rtc_base/event.h"
#include "rtc_base/task_queue_for_test.h"
#include "test/gmock.h"
#include "test/gtest.h"
@ -34,22 +32,13 @@ class MockResourceListener : public ResourceListener {
class ResourceTest : public ::testing::Test {
public:
ResourceTest()
: resource_adaptation_queue_("ResourceAdaptationQueue"),
fake_resource_(FakeResource::Create("FakeResource")) {
fake_resource_->RegisterAdaptationTaskQueue(
resource_adaptation_queue_.Get());
}
ResourceTest() : fake_resource_(FakeResource::Create("FakeResource")) {}
protected:
const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
TaskQueueForTest resource_adaptation_queue_;
rtc::scoped_refptr<FakeResource> fake_resource_;
};
TEST_F(ResourceTest, RegisteringListenerReceivesCallbacks) {
resource_adaptation_queue_.SendTask(
[this] {
StrictMock<MockResourceListener> resource_listener;
fake_resource_->SetResourceListener(&resource_listener);
EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
@ -57,23 +46,16 @@ TEST_F(ResourceTest, RegisteringListenerReceivesCallbacks) {
.WillOnce([](rtc::scoped_refptr<Resource> resource) {
EXPECT_EQ(ResourceUsageState::kOveruse, resource->UsageState());
});
fake_resource_->set_usage_state(ResourceUsageState::kOveruse);
fake_resource_->SetUsageState(ResourceUsageState::kOveruse);
fake_resource_->SetResourceListener(nullptr);
},
RTC_FROM_HERE);
}
TEST_F(ResourceTest, UnregisteringListenerStopsCallbacks) {
resource_adaptation_queue_.SendTask(
[this] {
StrictMock<MockResourceListener> resource_listener;
fake_resource_->SetResourceListener(&resource_listener);
fake_resource_->SetResourceListener(nullptr);
EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
.Times(0);
fake_resource_->set_usage_state(ResourceUsageState::kOveruse);
},
RTC_FROM_HERE);
EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_)).Times(0);
fake_resource_->SetUsageState(ResourceUsageState::kOveruse);
}
} // namespace webrtc

View File

@ -0,0 +1,39 @@
/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "call/adaptation/test/fake_adaptation_constraint.h"
#include <utility>
namespace webrtc {
FakeAdaptationConstraint::FakeAdaptationConstraint(std::string name)
: name_(std::move(name)), is_adaptation_up_allowed_(true) {}
FakeAdaptationConstraint::~FakeAdaptationConstraint() {}
void FakeAdaptationConstraint::set_is_adaptation_up_allowed(
bool is_adaptation_up_allowed) {
is_adaptation_up_allowed_ = is_adaptation_up_allowed;
}
std::string FakeAdaptationConstraint::Name() const {
return name_;
}
bool FakeAdaptationConstraint::IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const {
return is_adaptation_up_allowed_;
}
} // namespace webrtc

View File

@ -0,0 +1,42 @@
/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef CALL_ADAPTATION_TEST_FAKE_ADAPTATION_CONSTRAINT_H_
#define CALL_ADAPTATION_TEST_FAKE_ADAPTATION_CONSTRAINT_H_
#include <string>
#include "call/adaptation/adaptation_constraint.h"
namespace webrtc {
class FakeAdaptationConstraint : public AdaptationConstraint {
public:
explicit FakeAdaptationConstraint(std::string name);
~FakeAdaptationConstraint() override;
void set_is_adaptation_up_allowed(bool is_adaptation_up_allowed);
// AdaptationConstraint implementation.
std::string Name() const override;
bool IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const override;
private:
const std::string name_;
bool is_adaptation_up_allowed_;
};
} // namespace webrtc
#endif // CALL_ADAPTATION_TEST_FAKE_ADAPTATION_CONSTRAINT_H_

View File

@ -0,0 +1,32 @@
/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "call/adaptation/test/fake_adaptation_listener.h"
namespace webrtc {
FakeAdaptationListener::FakeAdaptationListener()
: num_adaptations_applied_(0) {}
FakeAdaptationListener::~FakeAdaptationListener() {}
size_t FakeAdaptationListener::num_adaptations_applied() const {
return num_adaptations_applied_;
}
void FakeAdaptationListener::OnAdaptationApplied(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) {
++num_adaptations_applied_;
}
} // namespace webrtc

View File

@ -0,0 +1,38 @@
/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef CALL_ADAPTATION_TEST_FAKE_ADAPTATION_LISTENER_H_
#define CALL_ADAPTATION_TEST_FAKE_ADAPTATION_LISTENER_H_
#include "call/adaptation/adaptation_listener.h"
namespace webrtc {
class FakeAdaptationListener : public AdaptationListener {
public:
FakeAdaptationListener();
~FakeAdaptationListener() override;
size_t num_adaptations_applied() const;
// AdaptationListener implementation.
void OnAdaptationApplied(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) override;
private:
size_t num_adaptations_applied_;
};
} // namespace webrtc
#endif // CALL_ADAPTATION_TEST_FAKE_ADAPTATION_LISTENER_H_

View File

@ -14,7 +14,6 @@
#include <utility>
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/task_utils/to_queued_task.h"
namespace webrtc {
@ -25,91 +24,33 @@ rtc::scoped_refptr<FakeResource> FakeResource::Create(std::string name) {
FakeResource::FakeResource(std::string name)
: Resource(),
lock_(),
name_(std::move(name)),
resource_adaptation_queue_(nullptr),
is_adaptation_up_allowed_(true),
num_adaptations_applied_(0),
usage_state_(absl::nullopt),
listener_(nullptr) {}
listener_(nullptr),
usage_state_(absl::nullopt) {}
FakeResource::~FakeResource() {}
void FakeResource::set_usage_state(ResourceUsageState usage_state) {
if (!resource_adaptation_queue_->IsCurrent()) {
resource_adaptation_queue_->PostTask(ToQueuedTask(
[this_ref = rtc::scoped_refptr<FakeResource>(this), usage_state] {
this_ref->set_usage_state(usage_state);
}));
return;
}
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
void FakeResource::SetUsageState(ResourceUsageState usage_state) {
usage_state_ = usage_state;
if (listener_) {
listener_->OnResourceUsageStateMeasured(this);
}
}
void FakeResource::set_is_adaptation_up_allowed(bool is_adaptation_up_allowed) {
rtc::CritScope crit(&lock_);
is_adaptation_up_allowed_ = is_adaptation_up_allowed;
}
size_t FakeResource::num_adaptations_applied() const {
rtc::CritScope crit(&lock_);
return num_adaptations_applied_;
}
void FakeResource::RegisterAdaptationTaskQueue(
TaskQueueBase* resource_adaptation_queue) {
RTC_DCHECK(!resource_adaptation_queue_);
RTC_DCHECK(resource_adaptation_queue);
resource_adaptation_queue_ = resource_adaptation_queue;
}
void FakeResource::UnregisterAdaptationTaskQueue() {
RTC_DCHECK(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
resource_adaptation_queue_ = nullptr;
}
void FakeResource::SetResourceListener(ResourceListener* listener) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
listener_ = listener;
}
std::string FakeResource::Name() const {
return name_;
}
void FakeResource::SetResourceListener(ResourceListener* listener) {
listener_ = listener;
}
absl::optional<ResourceUsageState> FakeResource::UsageState() const {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
return usage_state_;
}
void FakeResource::ClearUsageState() {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
usage_state_ = absl::nullopt;
}
bool FakeResource::IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
rtc::CritScope crit(&lock_);
return is_adaptation_up_allowed_;
}
void FakeResource::OnAdaptationApplied(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
rtc::CritScope crit(&lock_);
++num_adaptations_applied_;
}
} // namespace webrtc

View File

@ -16,10 +16,7 @@
#include "absl/types/optional.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/task_queue_base.h"
#include "call/adaptation/resource.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/synchronization/sequence_checker.h"
namespace webrtc {
@ -31,38 +28,18 @@ class FakeResource : public Resource {
explicit FakeResource(std::string name);
~FakeResource() override;
void set_usage_state(ResourceUsageState usage_state);
void set_is_adaptation_up_allowed(bool is_adaptation_up_allowed);
size_t num_adaptations_applied() const;
void SetUsageState(ResourceUsageState usage_state);
// Resource implementation.
void RegisterAdaptationTaskQueue(
TaskQueueBase* resource_adaptation_queue) override;
void UnregisterAdaptationTaskQueue() override;
void SetResourceListener(ResourceListener* listener) override;
std::string Name() const override;
void SetResourceListener(ResourceListener* listener) override;
absl::optional<ResourceUsageState> UsageState() const override;
void ClearUsageState() override;
bool IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const override;
void OnAdaptationApplied(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) override;
private:
rtc::CriticalSection lock_;
const std::string name_;
TaskQueueBase* resource_adaptation_queue_;
bool is_adaptation_up_allowed_ RTC_GUARDED_BY(lock_);
size_t num_adaptations_applied_ RTC_GUARDED_BY(lock_);
absl::optional<ResourceUsageState> usage_state_
RTC_GUARDED_BY(resource_adaptation_queue_);
ResourceListener* listener_ RTC_GUARDED_BY(resource_adaptation_queue_);
ResourceListener* listener_;
absl::optional<ResourceUsageState> usage_state_;
};
} // namespace webrtc

View File

@ -17,7 +17,6 @@
#include "absl/types/optional.h"
#include "api/scoped_refptr.h"
#include "api/video/video_adaptation_reason.h"
#include "call/adaptation/resource.h"
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/task_queue.h"
#include "video/adaptation/overuse_frame_detector.h"

View File

@ -19,7 +19,7 @@
#include "api/scoped_refptr.h"
#include "api/video/video_adaptation_reason.h"
#include "api/video_codecs/video_encoder.h"
#include "call/adaptation/resource.h"
#include "call/adaptation/adaptation_listener.h"
#include "call/adaptation/resource_adaptation_processor_interface.h"
#include "modules/video_coding/utility/quality_scaler.h"
#include "rtc_base/critical_section.h"
@ -31,6 +31,7 @@ namespace webrtc {
// Handles interaction with the QualityScaler.
class QualityScalerResource : public VideoStreamEncoderResource,
public AdaptationListener,
public QualityScalerQpUsageHandlerInterface {
public:
static rtc::scoped_refptr<QualityScalerResource> Create();
@ -60,7 +61,7 @@ class QualityScalerResource : public VideoStreamEncoderResource,
rtc::scoped_refptr<QualityScalerQpUsageHandlerCallbackInterface> callback)
override;
// VideoStreamEncoderResource implementation.
// AdaptationListener implementation.
void OnAdaptationApplied(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,

View File

@ -75,20 +75,6 @@ void VideoStreamEncoderResource::ClearUsageState() {
usage_state_ = absl::nullopt;
}
bool VideoStreamEncoderResource::IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const {
return true;
}
void VideoStreamEncoderResource::OnAdaptationApplied(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) {}
void VideoStreamEncoderResource::OnResourceUsageStateMeasured(
ResourceUsageState usage_state) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue());

View File

@ -16,6 +16,8 @@
#include "absl/types/optional.h"
#include "api/task_queue/task_queue_base.h"
#include "call/adaptation/adaptation_constraint.h"
#include "call/adaptation/adaptation_listener.h"
#include "call/adaptation/resource.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/synchronization/sequence_checker.h"
@ -30,24 +32,20 @@ class VideoStreamEncoderResource : public Resource {
void RegisterEncoderTaskQueue(TaskQueueBase* encoder_queue);
// Resource implementation.
void RegisterAdaptationTaskQueue(
TaskQueueBase* resource_adaptation_queue) override;
void UnregisterAdaptationTaskQueue() override;
void SetResourceListener(ResourceListener* listener) override;
std::string Name() const override;
void SetResourceListener(ResourceListener* listener) override;
absl::optional<ResourceUsageState> UsageState() const override;
void ClearUsageState() override;
// Default implementations, may be overriden again by child classes.
bool IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const override;
void OnAdaptationApplied(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) override;
// Provides a pointer to the adaptation task queue. After this call, all
// methods defined in this interface, including
// UnregisterAdaptationTaskQueue() MUST be invoked on the adaptation task
// queue. Registering the adaptation task queue may, however, happen off the
// adaptation task queue.
void RegisterAdaptationTaskQueue(TaskQueueBase* resource_adaptation_queue);
// Signals that the adaptation task queue is no longer safe to use. No
// assumptions must be made as to whether or not tasks in-flight will run.
void UnregisterAdaptationTaskQueue();
protected:
explicit VideoStreamEncoderResource(std::string name);

View File

@ -139,26 +139,30 @@ class VideoStreamEncoderResourceManager::InitialFrameDropper {
int initial_framedrop_;
};
VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
PreventAdaptUpDueToActiveCounts(VideoStreamEncoderResourceManager* manager)
: rtc::RefCountedObject<VideoStreamEncoderResource>(
"PreventAdaptUpDueToActiveCounts"),
manager_(manager),
VideoStreamEncoderResourceManager::ActiveCountsConstraint::
ActiveCountsConstraint(VideoStreamEncoderResourceManager* manager)
: manager_(manager),
resource_adaptation_queue_(nullptr),
adaptation_processor_(nullptr) {}
void VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
void VideoStreamEncoderResourceManager::ActiveCountsConstraint::
SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue) {
resource_adaptation_queue_ = resource_adaptation_queue;
}
void VideoStreamEncoderResourceManager::ActiveCountsConstraint::
SetAdaptationProcessor(
ResourceAdaptationProcessorInterface* adaptation_processor) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
adaptation_processor_ = adaptation_processor;
}
bool VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
bool VideoStreamEncoderResourceManager::ActiveCountsConstraint::
IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const {
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK(adaptation_processor_);
VideoAdaptationReason reason =
manager_->GetReasonFromResource(reason_resource);
@ -185,52 +189,47 @@ bool VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
}
}
VideoStreamEncoderResourceManager::
PreventIncreaseResolutionDueToBitrateResource::
PreventIncreaseResolutionDueToBitrateResource(
VideoStreamEncoderResourceManager::BitrateConstraint::BitrateConstraint(
VideoStreamEncoderResourceManager* manager)
: rtc::RefCountedObject<VideoStreamEncoderResource>(
"PreventIncreaseResolutionDueToBitrateResource"),
manager_(manager),
: manager_(manager),
resource_adaptation_queue_(nullptr),
encoder_settings_(absl::nullopt),
encoder_target_bitrate_bps_(absl::nullopt) {}
void VideoStreamEncoderResourceManager::
PreventIncreaseResolutionDueToBitrateResource::OnEncoderSettingsUpdated(
absl::optional<EncoderSettings> encoder_settings) {
RTC_DCHECK_RUN_ON(encoder_queue());
MaybePostTaskToResourceAdaptationQueue(
[this_ref =
rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>(
this),
encoder_settings] {
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
this_ref->encoder_settings_ = std::move(encoder_settings);
});
void VideoStreamEncoderResourceManager::BitrateConstraint::SetAdaptationQueue(
TaskQueueBase* resource_adaptation_queue) {
resource_adaptation_queue_ = resource_adaptation_queue;
}
void VideoStreamEncoderResourceManager::
PreventIncreaseResolutionDueToBitrateResource::
void VideoStreamEncoderResourceManager::BitrateConstraint::
OnEncoderSettingsUpdated(absl::optional<EncoderSettings> encoder_settings) {
RTC_DCHECK_RUN_ON(manager_->encoder_queue_);
resource_adaptation_queue_->PostTask(
ToQueuedTask([this_ref = rtc::scoped_refptr<BitrateConstraint>(this),
encoder_settings] {
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
this_ref->encoder_settings_ = std::move(encoder_settings);
}));
}
void VideoStreamEncoderResourceManager::BitrateConstraint::
OnEncoderTargetBitrateUpdated(
absl::optional<uint32_t> encoder_target_bitrate_bps) {
RTC_DCHECK_RUN_ON(encoder_queue());
MaybePostTaskToResourceAdaptationQueue(
[this_ref =
rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>(
this),
RTC_DCHECK_RUN_ON(manager_->encoder_queue_);
resource_adaptation_queue_->PostTask(
ToQueuedTask([this_ref = rtc::scoped_refptr<BitrateConstraint>(this),
encoder_target_bitrate_bps] {
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
});
}));
}
bool VideoStreamEncoderResourceManager::
PreventIncreaseResolutionDueToBitrateResource::IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
bool VideoStreamEncoderResourceManager::BitrateConstraint::
IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const {
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
VideoAdaptationReason reason =
manager_->GetReasonFromResource(reason_resource);
// If increasing resolution due to kQuality, make sure bitrate limits are not
@ -259,39 +258,43 @@ bool VideoStreamEncoderResourceManager::
return true;
}
VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
PreventAdaptUpInBalancedResource(VideoStreamEncoderResourceManager* manager)
: rtc::RefCountedObject<VideoStreamEncoderResource>(
"PreventAdaptUpInBalancedResource"),
manager_(manager),
VideoStreamEncoderResourceManager::BalancedConstraint::BalancedConstraint(
VideoStreamEncoderResourceManager* manager)
: manager_(manager),
resource_adaptation_queue_(nullptr),
adaptation_processor_(nullptr),
encoder_target_bitrate_bps_(absl::nullopt) {}
void VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
void VideoStreamEncoderResourceManager::BalancedConstraint::SetAdaptationQueue(
TaskQueueBase* resource_adaptation_queue) {
resource_adaptation_queue_ = resource_adaptation_queue;
}
void VideoStreamEncoderResourceManager::BalancedConstraint::
SetAdaptationProcessor(
ResourceAdaptationProcessorInterface* adaptation_processor) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
adaptation_processor_ = adaptation_processor;
}
void VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
void VideoStreamEncoderResourceManager::BalancedConstraint::
OnEncoderTargetBitrateUpdated(
absl::optional<uint32_t> encoder_target_bitrate_bps) {
RTC_DCHECK_RUN_ON(encoder_queue());
MaybePostTaskToResourceAdaptationQueue(
[this_ref = rtc::scoped_refptr<PreventAdaptUpInBalancedResource>(this),
RTC_DCHECK_RUN_ON(manager_->encoder_queue_);
resource_adaptation_queue_->PostTask(
ToQueuedTask([this_ref = rtc::scoped_refptr<BalancedConstraint>(this),
encoder_target_bitrate_bps] {
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
});
}));
}
bool VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
bool VideoStreamEncoderResourceManager::BalancedConstraint::
IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after,
rtc::scoped_refptr<Resource> reason_resource) const {
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK(adaptation_processor_);
VideoAdaptationReason reason =
manager_->GetReasonFromResource(reason_resource);
@ -325,12 +328,10 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager(
Clock* clock,
bool experiment_cpu_load_estimator,
std::unique_ptr<OveruseFrameDetector> overuse_detector)
: prevent_adapt_up_due_to_active_counts_(
new PreventAdaptUpDueToActiveCounts(this)),
prevent_increase_resolution_due_to_bitrate_resource_(
new PreventIncreaseResolutionDueToBitrateResource(this)),
prevent_adapt_up_in_balanced_resource_(
new PreventAdaptUpInBalancedResource(this)),
: active_counts_constraint_(
new rtc::RefCountedObject<ActiveCountsConstraint>(this)),
bitrate_constraint_(new rtc::RefCountedObject<BitrateConstraint>(this)),
balanced_constraint_(new rtc::RefCountedObject<BalancedConstraint>(this)),
encode_usage_resource_(
EncodeUsageResource::Create(std::move(overuse_detector))),
quality_scaler_resource_(QualityScalerResource::Create()),
@ -352,12 +353,6 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager(
encoder_settings_(absl::nullopt),
active_counts_() {
RTC_DCHECK(encoder_stats_observer_);
MapResourceToReason(prevent_adapt_up_due_to_active_counts_,
VideoAdaptationReason::kQuality);
MapResourceToReason(prevent_increase_resolution_due_to_bitrate_resource_,
VideoAdaptationReason::kQuality);
MapResourceToReason(prevent_adapt_up_in_balanced_resource_,
VideoAdaptationReason::kQuality);
MapResourceToReason(encode_usage_resource_, VideoAdaptationReason::kCpu);
MapResourceToReason(quality_scaler_resource_,
VideoAdaptationReason::kQuality);
@ -374,18 +369,10 @@ void VideoStreamEncoderResourceManager::Initialize(
RTC_DCHECK(resource_adaptation_queue);
encoder_queue_ = encoder_queue;
resource_adaptation_queue_ = resource_adaptation_queue;
prevent_adapt_up_due_to_active_counts_->RegisterEncoderTaskQueue(
encoder_queue_->Get());
prevent_adapt_up_due_to_active_counts_->RegisterAdaptationTaskQueue(
resource_adaptation_queue_->Get());
prevent_increase_resolution_due_to_bitrate_resource_
->RegisterEncoderTaskQueue(encoder_queue_->Get());
prevent_increase_resolution_due_to_bitrate_resource_
->RegisterAdaptationTaskQueue(resource_adaptation_queue_->Get());
prevent_adapt_up_in_balanced_resource_->RegisterEncoderTaskQueue(
encoder_queue_->Get());
prevent_adapt_up_in_balanced_resource_->RegisterAdaptationTaskQueue(
active_counts_constraint_->SetAdaptationQueue(
resource_adaptation_queue_->Get());
bitrate_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
balanced_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
encode_usage_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
encode_usage_resource_->RegisterAdaptationTaskQueue(
resource_adaptation_queue_->Get());
@ -398,10 +385,8 @@ void VideoStreamEncoderResourceManager::SetAdaptationProcessor(
ResourceAdaptationProcessorInterface* adaptation_processor) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
adaptation_processor_ = adaptation_processor;
prevent_adapt_up_due_to_active_counts_->SetAdaptationProcessor(
adaptation_processor);
prevent_adapt_up_in_balanced_resource_->SetAdaptationProcessor(
adaptation_processor);
active_counts_constraint_->SetAdaptationProcessor(adaptation_processor);
balanced_constraint_->SetAdaptationProcessor(adaptation_processor);
quality_scaler_resource_->SetAdaptationProcessor(adaptation_processor);
}
@ -454,6 +439,16 @@ VideoStreamEncoderResourceManager::MappedResources() const {
return resources;
}
std::vector<AdaptationConstraint*>
VideoStreamEncoderResourceManager::AdaptationConstraints() const {
return {active_counts_constraint_, bitrate_constraint_, balanced_constraint_};
}
std::vector<AdaptationListener*>
VideoStreamEncoderResourceManager::AdaptationListeners() const {
return {quality_scaler_resource_};
}
rtc::scoped_refptr<QualityScalerResource>
VideoStreamEncoderResourceManager::quality_scaler_resource_for_testing() {
rtc::CritScope crit(&resource_lock_);
@ -464,8 +459,7 @@ void VideoStreamEncoderResourceManager::SetEncoderSettings(
EncoderSettings encoder_settings) {
RTC_DCHECK_RUN_ON(encoder_queue_);
encoder_settings_ = std::move(encoder_settings);
prevent_increase_resolution_due_to_bitrate_resource_
->OnEncoderSettingsUpdated(encoder_settings_);
bitrate_constraint_->OnEncoderSettingsUpdated(encoder_settings_);
quality_rampup_experiment_.SetMaxBitrate(
LastInputFrameSizeOrDefault(),
@ -478,9 +472,9 @@ void VideoStreamEncoderResourceManager::SetStartBitrate(
RTC_DCHECK_RUN_ON(encoder_queue_);
if (!start_bitrate.IsZero()) {
encoder_target_bitrate_bps_ = start_bitrate.bps();
prevent_increase_resolution_due_to_bitrate_resource_
->OnEncoderTargetBitrateUpdated(encoder_target_bitrate_bps_);
prevent_adapt_up_in_balanced_resource_->OnEncoderTargetBitrateUpdated(
bitrate_constraint_->OnEncoderTargetBitrateUpdated(
encoder_target_bitrate_bps_);
balanced_constraint_->OnEncoderTargetBitrateUpdated(
encoder_target_bitrate_bps_);
}
initial_frame_dropper_->SetStartBitrate(start_bitrate,
@ -492,9 +486,9 @@ void VideoStreamEncoderResourceManager::SetTargetBitrate(
RTC_DCHECK_RUN_ON(encoder_queue_);
if (!target_bitrate.IsZero()) {
encoder_target_bitrate_bps_ = target_bitrate.bps();
prevent_increase_resolution_due_to_bitrate_resource_
->OnEncoderTargetBitrateUpdated(encoder_target_bitrate_bps_);
prevent_adapt_up_in_balanced_resource_->OnEncoderTargetBitrateUpdated(
bitrate_constraint_->OnEncoderTargetBitrateUpdated(
encoder_target_bitrate_bps_);
balanced_constraint_->OnEncoderTargetBitrateUpdated(
encoder_target_bitrate_bps_);
}
initial_frame_dropper_->SetTargetBitrate(target_bitrate,

View File

@ -22,6 +22,7 @@
#include "absl/types/optional.h"
#include "api/rtp_parameters.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/task_queue_base.h"
#include "api/video/video_adaptation_counters.h"
#include "api/video/video_adaptation_reason.h"
#include "api/video/video_frame.h"
@ -37,6 +38,7 @@
#include "rtc_base/critical_section.h"
#include "rtc_base/experiments/quality_rampup_experiment.h"
#include "rtc_base/experiments/quality_scaler_settings.h"
#include "rtc_base/ref_count.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/task_queue.h"
#include "system_wrappers/include/clock.h"
@ -62,7 +64,7 @@ extern const int kDefaultInputPixelsHeight;
// The manager is also involved with various mitigations not part of the
// ResourceAdaptationProcessor code such as the inital frame dropping.
class VideoStreamEncoderResourceManager
: public ResourceAdaptationProcessorListener {
: public VideoSourceRestrictionsListener {
public:
VideoStreamEncoderResourceManager(
VideoStreamInputStateProvider* input_state_provider,
@ -117,13 +119,15 @@ class VideoStreamEncoderResourceManager
void MapResourceToReason(rtc::scoped_refptr<Resource> resource,
VideoAdaptationReason reason);
std::vector<rtc::scoped_refptr<Resource>> MappedResources() const;
std::vector<AdaptationConstraint*> AdaptationConstraints() const;
std::vector<AdaptationListener*> AdaptationListeners() const;
rtc::scoped_refptr<QualityScalerResource>
quality_scaler_resource_for_testing();
// If true, the VideoStreamEncoder should eexecute its logic to maybe drop
// frames baseed on size and bitrate.
bool DropInitialFrames() const;
// ResourceAdaptationProcessorListener implementation.
// VideoSourceRestrictionsListener implementation.
// Updates |video_source_restrictions_| and |active_counts_|.
void OnVideoSourceRestrictionsUpdated(
VideoSourceRestrictions restrictions,
@ -173,22 +177,22 @@ class VideoStreamEncoderResourceManager
void ResetActiveCounts();
std::string ActiveCountsToString() const;
// TODO(hbos): Consider moving all of the manager's resources into separate
// files for testability.
// TODO(hbos): Add tests for manager's constraints.
// Does not trigger adaptations, only prevents adapting up based on
// |active_counts_|.
class PreventAdaptUpDueToActiveCounts final
: public rtc::RefCountedObject<VideoStreamEncoderResource> {
class ActiveCountsConstraint : public rtc::RefCountInterface,
public AdaptationConstraint {
public:
explicit PreventAdaptUpDueToActiveCounts(
VideoStreamEncoderResourceManager* manager);
~PreventAdaptUpDueToActiveCounts() override = default;
explicit ActiveCountsConstraint(VideoStreamEncoderResourceManager* manager);
~ActiveCountsConstraint() override = default;
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
void SetAdaptationProcessor(
ResourceAdaptationProcessorInterface* adaptation_processor);
// Resource overrides.
// AdaptationConstraint implementation.
std::string Name() const override { return "ActiveCountsConstraint"; }
bool IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
@ -199,24 +203,26 @@ class VideoStreamEncoderResourceManager
// The |manager_| must be alive as long as this resource is added to the
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
VideoStreamEncoderResourceManager* const manager_;
TaskQueueBase* resource_adaptation_queue_;
ResourceAdaptationProcessorInterface* adaptation_processor_
RTC_GUARDED_BY(resource_adaptation_queue());
RTC_GUARDED_BY(resource_adaptation_queue_);
};
// Does not trigger adaptations, only prevents adapting up resolution.
class PreventIncreaseResolutionDueToBitrateResource final
: public rtc::RefCountedObject<VideoStreamEncoderResource> {
class BitrateConstraint : public rtc::RefCountInterface,
public AdaptationConstraint {
public:
explicit PreventIncreaseResolutionDueToBitrateResource(
VideoStreamEncoderResourceManager* manager);
~PreventIncreaseResolutionDueToBitrateResource() override = default;
explicit BitrateConstraint(VideoStreamEncoderResourceManager* manager);
~BitrateConstraint() override = default;
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
void OnEncoderSettingsUpdated(
absl::optional<EncoderSettings> encoder_settings);
void OnEncoderTargetBitrateUpdated(
absl::optional<uint32_t> encoder_target_bitrate_bps);
// Resource overrides.
// AdaptationConstraint implementation.
std::string Name() const override { return "BitrateConstraint"; }
bool IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
@ -227,26 +233,28 @@ class VideoStreamEncoderResourceManager
// The |manager_| must be alive as long as this resource is added to the
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
VideoStreamEncoderResourceManager* const manager_;
TaskQueueBase* resource_adaptation_queue_;
absl::optional<EncoderSettings> encoder_settings_
RTC_GUARDED_BY(resource_adaptation_queue());
RTC_GUARDED_BY(resource_adaptation_queue_);
absl::optional<uint32_t> encoder_target_bitrate_bps_
RTC_GUARDED_BY(resource_adaptation_queue());
RTC_GUARDED_BY(resource_adaptation_queue_);
};
// Does not trigger adaptations, only prevents adapting up in BALANCED.
class PreventAdaptUpInBalancedResource final
: public rtc::RefCountedObject<VideoStreamEncoderResource> {
class BalancedConstraint : public rtc::RefCountInterface,
public AdaptationConstraint {
public:
explicit PreventAdaptUpInBalancedResource(
VideoStreamEncoderResourceManager* manager);
~PreventAdaptUpInBalancedResource() override = default;
explicit BalancedConstraint(VideoStreamEncoderResourceManager* manager);
~BalancedConstraint() override = default;
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
void SetAdaptationProcessor(
ResourceAdaptationProcessorInterface* adaptation_processor);
void OnEncoderTargetBitrateUpdated(
absl::optional<uint32_t> encoder_target_bitrate_bps);
// Resource overrides.
// AdaptationConstraint implementation.
std::string Name() const override { return "BalancedConstraint"; }
bool IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
@ -257,18 +265,16 @@ class VideoStreamEncoderResourceManager
// The |manager_| must be alive as long as this resource is added to the
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
VideoStreamEncoderResourceManager* const manager_;
TaskQueueBase* resource_adaptation_queue_;
ResourceAdaptationProcessorInterface* adaptation_processor_
RTC_GUARDED_BY(resource_adaptation_queue());
RTC_GUARDED_BY(resource_adaptation_queue_);
absl::optional<uint32_t> encoder_target_bitrate_bps_
RTC_GUARDED_BY(resource_adaptation_queue());
RTC_GUARDED_BY(resource_adaptation_queue_);
};
const rtc::scoped_refptr<PreventAdaptUpDueToActiveCounts>
prevent_adapt_up_due_to_active_counts_;
const rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>
prevent_increase_resolution_due_to_bitrate_resource_;
const rtc::scoped_refptr<PreventAdaptUpInBalancedResource>
prevent_adapt_up_in_balanced_resource_;
const rtc::scoped_refptr<ActiveCountsConstraint> active_counts_constraint_;
const rtc::scoped_refptr<BitrateConstraint> bitrate_constraint_;
const rtc::scoped_refptr<BalancedConstraint> balanced_constraint_;
const rtc::scoped_refptr<EncodeUsageResource> encode_usage_resource_;
const rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource_;
@ -321,7 +327,7 @@ class VideoStreamEncoderResourceManager
// TODO(https://crbug.com/webrtc/11542): When we have an adaptation queue,
// guard the activec counts by it instead. The |encoder_stats_observer_| is
// thread-safe anyway, and active counts are used by
// PreventAdaptUpDueToActiveCounts to make decisions.
// ActiveCountsConstraint to make decisions.
std::unordered_map<VideoAdaptationReason, VideoAdaptationCounters>
active_counts_ RTC_GUARDED_BY(resource_adaptation_queue_);
};

View File

@ -260,6 +260,8 @@ VideoStreamEncoder::VideoStreamEncoder(
std::make_unique<ResourceAdaptationProcessor>(
&input_state_provider_,
encoder_stats_observer)),
adaptation_constraints_(),
adaptation_listeners_(),
stream_resource_manager_(&input_state_provider_,
encoder_stats_observer,
clock_,
@ -285,12 +287,22 @@ VideoStreamEncoder::VideoStreamEncoder(
resource_adaptation_processor_->InitializeOnResourceAdaptationQueue();
stream_resource_manager_.SetAdaptationProcessor(
resource_adaptation_processor_.get());
resource_adaptation_processor_->AddAdaptationListener(
resource_adaptation_processor_->AddRestrictionsListener(
&stream_resource_manager_);
resource_adaptation_processor_->AddAdaptationListener(this);
resource_adaptation_processor_->AddRestrictionsListener(this);
// Add the stream resource manager's resources to the processor.
for (Resource* resource : stream_resource_manager_.MappedResources())
adaptation_constraints_ = stream_resource_manager_.AdaptationConstraints();
adaptation_listeners_ = stream_resource_manager_.AdaptationListeners();
for (auto& resource : stream_resource_manager_.MappedResources()) {
resource_adaptation_processor_->AddResource(resource);
}
for (auto* constraint : adaptation_constraints_) {
resource_adaptation_processor_->AddAdaptationConstraint(constraint);
}
for (auto* listener : adaptation_listeners_) {
resource_adaptation_processor_->AddAdaptationListener(listener);
}
initialize_processor_event.Set();
});
initialize_processor_event.Wait(rtc::Event::kForever);
@ -312,11 +324,17 @@ void VideoStreamEncoder::Stop() {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
if (resource_adaptation_processor_) {
resource_adaptation_processor_->StopResourceAdaptation();
for (Resource* resource : stream_resource_manager_.MappedResources()) {
for (auto& resource : stream_resource_manager_.MappedResources()) {
resource_adaptation_processor_->RemoveResource(resource);
}
resource_adaptation_processor_->RemoveAdaptationListener(this);
resource_adaptation_processor_->RemoveAdaptationListener(
for (auto* constraint : adaptation_constraints_) {
resource_adaptation_processor_->RemoveAdaptationConstraint(constraint);
}
for (auto* listener : adaptation_listeners_) {
resource_adaptation_processor_->RemoveAdaptationListener(listener);
}
resource_adaptation_processor_->RemoveRestrictionsListener(this);
resource_adaptation_processor_->RemoveRestrictionsListener(
&stream_resource_manager_);
stream_resource_manager_.SetAdaptationProcessor(nullptr);
resource_adaptation_processor_.reset();
@ -1978,7 +1996,8 @@ void VideoStreamEncoder::InjectAdaptationResource(
});
map_resource_event.Wait(rtc::Event::kForever);
resource_adaptation_queue_.PostTask([this, resource] {
rtc::Event add_resource_event;
resource_adaptation_queue_.PostTask([this, resource, &add_resource_event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
if (!resource_adaptation_processor_) {
// The VideoStreamEncoder was stopped and the processor destroyed before
@ -1986,7 +2005,44 @@ void VideoStreamEncoder::InjectAdaptationResource(
return;
}
resource_adaptation_processor_->AddResource(resource);
add_resource_event.Set();
});
add_resource_event.Wait(rtc::Event::kForever);
}
void VideoStreamEncoder::InjectAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) {
rtc::Event event;
resource_adaptation_queue_.PostTask([this, adaptation_constraint, &event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
if (!resource_adaptation_processor_) {
// The VideoStreamEncoder was stopped and the processor destroyed before
// this task had a chance to execute. No action needed.
return;
}
adaptation_constraints_.push_back(adaptation_constraint);
resource_adaptation_processor_->AddAdaptationConstraint(
adaptation_constraint);
event.Set();
});
event.Wait(rtc::Event::kForever);
}
void VideoStreamEncoder::InjectAdaptationListener(
AdaptationListener* adaptation_listener) {
rtc::Event event;
resource_adaptation_queue_.PostTask([this, adaptation_listener, &event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
if (!resource_adaptation_processor_) {
// The VideoStreamEncoder was stopped and the processor destroyed before
// this task had a chance to execute. No action needed.
return;
}
adaptation_listeners_.push_back(adaptation_listener);
resource_adaptation_processor_->AddAdaptationListener(adaptation_listener);
event.Set();
});
event.Wait(rtc::Event::kForever);
}
rtc::scoped_refptr<QualityScalerResource>
@ -1995,26 +2051,27 @@ VideoStreamEncoder::quality_scaler_resource_for_testing() {
return stream_resource_manager_.quality_scaler_resource_for_testing();
}
void VideoStreamEncoder::AddAdaptationListenerForTesting(
ResourceAdaptationProcessorListener* adaptation_listener) {
void VideoStreamEncoder::AddRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener) {
rtc::Event event;
resource_adaptation_queue_.PostTask([this, adaptation_listener, &event] {
resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
RTC_DCHECK(resource_adaptation_processor_);
resource_adaptation_processor_->AddAdaptationListener(adaptation_listener);
resource_adaptation_processor_->AddRestrictionsListener(
restrictions_listener);
event.Set();
});
event.Wait(rtc::Event::kForever);
}
void VideoStreamEncoder::RemoveAdaptationListenerForTesting(
ResourceAdaptationProcessorListener* adaptation_listener) {
void VideoStreamEncoder::RemoveRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener) {
rtc::Event event;
resource_adaptation_queue_.PostTask([this, adaptation_listener, &event] {
resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
RTC_DCHECK(resource_adaptation_processor_);
resource_adaptation_processor_->RemoveAdaptationListener(
adaptation_listener);
resource_adaptation_processor_->RemoveRestrictionsListener(
restrictions_listener);
event.Set();
});
event.Wait(rtc::Event::kForever);

View File

@ -26,6 +26,9 @@
#include "api/video/video_stream_encoder_settings.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder.h"
#include "call/adaptation/adaptation_constraint.h"
#include "call/adaptation/adaptation_listener.h"
#include "call/adaptation/resource.h"
#include "call/adaptation/resource_adaptation_processor_interface.h"
#include "call/adaptation/video_source_restrictions.h"
#include "call/adaptation/video_stream_input_state_provider.h"
@ -44,6 +47,7 @@
#include "video/encoder_bitrate_adjuster.h"
#include "video/frame_encode_metadata_writer.h"
#include "video/video_source_sink_controller.h"
namespace webrtc {
// VideoStreamEncoder represent a video encoder that accepts raw video frames as
@ -56,7 +60,7 @@ namespace webrtc {
// Call Stop() when done.
class VideoStreamEncoder : public VideoStreamEncoderInterface,
private EncodedImageCallback,
public ResourceAdaptationProcessorListener {
public VideoSourceRestrictionsListener {
public:
VideoStreamEncoder(Clock* clock,
uint32_t number_of_cores,
@ -118,16 +122,17 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// Used for injected test resources.
// TODO(eshr): Move all adaptation tests out of VideoStreamEncoder tests.
void InjectAdaptationResource(rtc::scoped_refptr<Resource> resource,
VideoAdaptationReason reason)
RTC_RUN_ON(&encoder_queue_);
VideoAdaptationReason reason);
void InjectAdaptationConstraint(AdaptationConstraint* adaptation_constraint);
void InjectAdaptationListener(AdaptationListener* adaptation_listener);
rtc::scoped_refptr<QualityScalerResource>
quality_scaler_resource_for_testing();
void AddAdaptationListenerForTesting(
ResourceAdaptationProcessorListener* adaptation_listener);
void RemoveAdaptationListenerForTesting(
ResourceAdaptationProcessorListener* adaptation_listener);
void AddRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener);
void RemoveRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener);
private:
class VideoFrameInfo {
@ -406,6 +411,10 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
std::unique_ptr<ResourceAdaptationProcessorInterface>
resource_adaptation_processor_
RTC_GUARDED_BY(&resource_adaptation_queue_);
std::vector<AdaptationConstraint*> adaptation_constraints_
RTC_GUARDED_BY(&resource_adaptation_queue_);
std::vector<AdaptationListener*> adaptation_listeners_
RTC_GUARDED_BY(&resource_adaptation_queue_);
// Handles input, output and stats reporting related to VideoStreamEncoder
// specific resources, such as "encode usage percent" measurements and "QP
// scaling". Also involved with various mitigations such as inital frame

View File

@ -26,6 +26,8 @@
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/vp8_temporal_layers.h"
#include "api/video_codecs/vp8_temporal_layers_factory.h"
#include "call/adaptation/test/fake_adaptation_constraint.h"
#include "call/adaptation/test/fake_adaptation_listener.h"
#include "call/adaptation/test/fake_resource.h"
#include "common_video/h264/h264_common.h"
#include "common_video/include/video_frame_buffer.h"
@ -186,12 +188,12 @@ class FakeQualityScalerQpUsageHandlerCallback
absl::optional<bool> clear_qp_samples_result_;
};
class VideoSourceRestrictionsUpdatedListener
: public ResourceAdaptationProcessorListener {
class FakeVideoSourceRestrictionsListener
: public VideoSourceRestrictionsListener {
public:
VideoSourceRestrictionsUpdatedListener()
FakeVideoSourceRestrictionsListener()
: was_restrictions_updated_(false), restrictions_updated_event_() {}
~VideoSourceRestrictionsUpdatedListener() override {
~FakeVideoSourceRestrictionsListener() override {
RTC_DCHECK(was_restrictions_updated_);
}
@ -199,7 +201,7 @@ class VideoSourceRestrictionsUpdatedListener
return &restrictions_updated_event_;
}
// ResourceAdaptationProcessorListener implementation.
// VideoSourceRestrictionsListener implementation.
void OnVideoSourceRestrictionsUpdated(
VideoSourceRestrictions restrictions,
const VideoAdaptationCounters& adaptation_counters,
@ -317,24 +319,24 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
new CpuOveruseDetectorProxy(stats_proxy)),
task_queue_factory),
fake_cpu_resource_(FakeResource::Create("FakeResource[CPU]")),
fake_quality_resource_(FakeResource::Create("FakeResource[QP]")) {
fake_cpu_resource_->RegisterAdaptationTaskQueue(
resource_adaptation_queue()->Get());
fake_quality_resource_->RegisterAdaptationTaskQueue(
resource_adaptation_queue()->Get());
fake_quality_resource_(FakeResource::Create("FakeResource[QP]")),
fake_adaptation_constraint_("FakeAdaptationConstraint"),
fake_adaptation_listener_() {
InjectAdaptationResource(fake_quality_resource_,
VideoAdaptationReason::kQuality);
InjectAdaptationResource(fake_cpu_resource_, VideoAdaptationReason::kCpu);
InjectAdaptationConstraint(&fake_adaptation_constraint_);
InjectAdaptationListener(&fake_adaptation_listener_);
}
void SetSourceAndWaitForRestrictionsUpdated(
rtc::VideoSourceInterface<VideoFrame>* source,
const DegradationPreference& degradation_preference) {
VideoSourceRestrictionsUpdatedListener listener;
AddAdaptationListenerForTesting(&listener);
FakeVideoSourceRestrictionsListener listener;
AddRestrictionsListenerForTesting(&listener);
SetSource(source, degradation_preference);
listener.restrictions_updated_event()->Wait(5000);
RemoveAdaptationListenerForTesting(&listener);
RemoveRestrictionsListenerForTesting(&listener);
}
void SetSourceAndWaitForFramerateUpdated(
@ -379,7 +381,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
void TriggerCpuOveruse() {
rtc::Event event;
resource_adaptation_queue()->PostTask([this, &event] {
fake_cpu_resource_->set_usage_state(ResourceUsageState::kOveruse);
fake_cpu_resource_->SetUsageState(ResourceUsageState::kOveruse);
event.Set();
});
ASSERT_TRUE(event.Wait(5000));
@ -387,7 +389,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
void TriggerCpuUnderuse() {
rtc::Event event;
resource_adaptation_queue()->PostTask([this, &event] {
fake_cpu_resource_->set_usage_state(ResourceUsageState::kUnderuse);
fake_cpu_resource_->SetUsageState(ResourceUsageState::kUnderuse);
event.Set();
});
ASSERT_TRUE(event.Wait(5000));
@ -397,7 +399,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
void TriggerQualityLow() {
rtc::Event event;
resource_adaptation_queue()->PostTask([this, &event] {
fake_quality_resource_->set_usage_state(ResourceUsageState::kOveruse);
fake_quality_resource_->SetUsageState(ResourceUsageState::kOveruse);
event.Set();
});
ASSERT_TRUE(event.Wait(5000));
@ -405,7 +407,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
void TriggerQualityHigh() {
rtc::Event event;
resource_adaptation_queue()->PostTask([this, &event] {
fake_quality_resource_->set_usage_state(ResourceUsageState::kUnderuse);
fake_quality_resource_->SetUsageState(ResourceUsageState::kUnderuse);
event.Set();
});
ASSERT_TRUE(event.Wait(5000));
@ -430,6 +432,8 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
CpuOveruseDetectorProxy* overuse_detector_proxy_;
rtc::scoped_refptr<FakeResource> fake_cpu_resource_;
rtc::scoped_refptr<FakeResource> fake_quality_resource_;
FakeAdaptationConstraint fake_adaptation_constraint_;
FakeAdaptationListener fake_adaptation_listener_;
};
class VideoStreamFactory