aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Boström <hbos@webrtc.org>2020-06-02 13:02:36 +0200
committerCommit Bot <commit-bot@chromium.org>2020-06-02 13:02:36 +0000
commit0f0aa9c7a80524e45dbdd4ec9ec4f807fcd4a046 (patch)
tree44dcc44b9c4ee75f2875a86c413bc004426ec519
parenta0cf1eabb73e805cd714f58e56676d99e6aee695 (diff)
downloadwebrtc-0f0aa9c7a80524e45dbdd4ec9ec4f807fcd4a046.tar.gz
[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}
-rw-r--r--call/adaptation/BUILD.gn8
-rw-r--r--call/adaptation/adaptation_constraint.cc17
-rw-r--r--call/adaptation/adaptation_constraint.h43
-rw-r--r--call/adaptation/adaptation_listener.cc17
-rw-r--r--call/adaptation/adaptation_listener.h41
-rw-r--r--call/adaptation/resource.h34
-rw-r--r--call/adaptation/resource_adaptation_processor.cc103
-rw-r--r--call/adaptation/resource_adaptation_processor.h25
-rw-r--r--call/adaptation/resource_adaptation_processor_interface.cc2
-rw-r--r--call/adaptation/resource_adaptation_processor_interface.h22
-rw-r--r--call/adaptation/resource_adaptation_processor_unittest.cc201
-rw-r--r--call/adaptation/resource_unittest.cc48
-rw-r--r--call/adaptation/test/fake_adaptation_constraint.cc39
-rw-r--r--call/adaptation/test/fake_adaptation_constraint.h42
-rw-r--r--call/adaptation/test/fake_adaptation_listener.cc32
-rw-r--r--call/adaptation/test/fake_adaptation_listener.h38
-rw-r--r--call/adaptation/test/fake_resource.cc69
-rw-r--r--call/adaptation/test/fake_resource.h31
-rw-r--r--video/adaptation/encode_usage_resource.h1
-rw-r--r--video/adaptation/quality_scaler_resource.h5
-rw-r--r--video/adaptation/video_stream_encoder_resource.cc14
-rw-r--r--video/adaptation/video_stream_encoder_resource.h28
-rw-r--r--video/adaptation/video_stream_encoder_resource_manager.cc188
-rw-r--r--video/adaptation/video_stream_encoder_resource_manager.h74
-rw-r--r--video/video_stream_encoder.cc89
-rw-r--r--video/video_stream_encoder.h23
-rw-r--r--video/video_stream_encoder_unittest.cc38
27 files changed, 775 insertions, 497 deletions
diff --git a/call/adaptation/BUILD.gn b/call/adaptation/BUILD.gn
index 291911ab22..b5c72efbb1 100644
--- a/call/adaptation/BUILD.gn
+++ b/call/adaptation/BUILD.gn
@@ -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",
diff --git a/call/adaptation/adaptation_constraint.cc b/call/adaptation/adaptation_constraint.cc
new file mode 100644
index 0000000000..d62bb74f87
--- /dev/null
+++ b/call/adaptation/adaptation_constraint.cc
@@ -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
diff --git a/call/adaptation/adaptation_constraint.h b/call/adaptation/adaptation_constraint.h
new file mode 100644
index 0000000000..ce15e32a13
--- /dev/null
+++ b/call/adaptation/adaptation_constraint.h
@@ -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_
diff --git a/call/adaptation/adaptation_listener.cc b/call/adaptation/adaptation_listener.cc
new file mode 100644
index 0000000000..acc1564f77
--- /dev/null
+++ b/call/adaptation/adaptation_listener.cc
@@ -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
diff --git a/call/adaptation/adaptation_listener.h b/call/adaptation/adaptation_listener.h
new file mode 100644
index 0000000000..028897ea9d
--- /dev/null
+++ b/call/adaptation/adaptation_listener.h
@@ -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_
diff --git a/call/adaptation/resource.h b/call/adaptation/resource.h
index febc29c9bb..ddc0fe855f 100644
--- a/call/adaptation/resource.h
+++ b/call/adaptation/resource.h
@@ -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
diff --git a/call/adaptation/resource_adaptation_processor.cc b/call/adaptation/resource_adaptation_processor.cc
index a705ccfa55..ed8f78ddfd 100644
--- a/call/adaptation/resource_adaptation_processor.cc
+++ b/call/adaptation/resource_adaptation_processor.cc
@@ -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;
diff --git a/call/adaptation/resource_adaptation_processor.h b/call/adaptation/resource_adaptation_processor.h
index 06b9a4c1cd..7988439002 100644
--- a/call/adaptation/resource_adaptation_processor.h
+++ b/call/adaptation/resource_adaptation_processor.h
@@ -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_);
diff --git a/call/adaptation/resource_adaptation_processor_interface.cc b/call/adaptation/resource_adaptation_processor_interface.cc
index 4e5251ce90..f7381d3ff4 100644
--- a/call/adaptation/resource_adaptation_processor_interface.cc
+++ b/call/adaptation/resource_adaptation_processor_interface.cc
@@ -12,7 +12,7 @@
namespace webrtc {
-ResourceAdaptationProcessorListener::~ResourceAdaptationProcessorListener() {}
+VideoSourceRestrictionsListener::~VideoSourceRestrictionsListener() {}
ResourceAdaptationProcessorInterface::~ResourceAdaptationProcessorInterface() {}
diff --git a/call/adaptation/resource_adaptation_processor_interface.h b/call/adaptation/resource_adaptation_processor_interface.h
index d6295c4d75..8dafefaf2c 100644
--- a/call/adaptation/resource_adaptation_processor_interface.h
+++ b/call/adaptation/resource_adaptation_processor_interface.h
@@ -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;
diff --git a/call/adaptation/resource_adaptation_processor_unittest.cc b/call/adaptation/resource_adaptation_processor_unittest.cc
index c150700ae8..6ff24b165f 100644
--- a/call/adaptation/resource_adaptation_processor_unittest.cc
+++ b/call/adaptation/resource_adaptation_processor_unittest.cc
@@ -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_->set_usage_state(ResourceUsageState::kUnderuse);
- EXPECT_EQ(2, 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_->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());
-
- 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());
+ resource_->SetUsageState(ResourceUsageState::kUnderuse);
+ EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
+ RestrictSource(restrictions_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);
}
diff --git a/call/adaptation/resource_unittest.cc b/call/adaptation/resource_unittest.cc
index ad93fbd2fa..afa32f0879 100644
--- a/call/adaptation/resource_unittest.cc
+++ b/call/adaptation/resource_unittest.cc
@@ -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,46 +32,30 @@ 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(_))
- .Times(1)
- .WillOnce([](rtc::scoped_refptr<Resource> resource) {
- EXPECT_EQ(ResourceUsageState::kOveruse, resource->UsageState());
- });
- fake_resource_->set_usage_state(ResourceUsageState::kOveruse);
- fake_resource_->SetResourceListener(nullptr);
- },
- RTC_FROM_HERE);
+ StrictMock<MockResourceListener> resource_listener;
+ fake_resource_->SetResourceListener(&resource_listener);
+ EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
+ .Times(1)
+ .WillOnce([](rtc::scoped_refptr<Resource> resource) {
+ EXPECT_EQ(ResourceUsageState::kOveruse, resource->UsageState());
+ });
+ fake_resource_->SetUsageState(ResourceUsageState::kOveruse);
+ fake_resource_->SetResourceListener(nullptr);
}
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);
+ StrictMock<MockResourceListener> resource_listener;
+ fake_resource_->SetResourceListener(&resource_listener);
+ fake_resource_->SetResourceListener(nullptr);
+ EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_)).Times(0);
+ fake_resource_->SetUsageState(ResourceUsageState::kOveruse);
}
} // namespace webrtc
diff --git a/call/adaptation/test/fake_adaptation_constraint.cc b/call/adaptation/test/fake_adaptation_constraint.cc
new file mode 100644
index 0000000000..983885e58a
--- /dev/null
+++ b/call/adaptation/test/fake_adaptation_constraint.cc
@@ -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
diff --git a/call/adaptation/test/fake_adaptation_constraint.h b/call/adaptation/test/fake_adaptation_constraint.h
new file mode 100644
index 0000000000..74637f48fd
--- /dev/null
+++ b/call/adaptation/test/fake_adaptation_constraint.h
@@ -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_
diff --git a/call/adaptation/test/fake_adaptation_listener.cc b/call/adaptation/test/fake_adaptation_listener.cc
new file mode 100644
index 0000000000..7feecd6367
--- /dev/null
+++ b/call/adaptation/test/fake_adaptation_listener.cc
@@ -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
diff --git a/call/adaptation/test/fake_adaptation_listener.h b/call/adaptation/test/fake_adaptation_listener.h
new file mode 100644
index 0000000000..c60ba3089b
--- /dev/null
+++ b/call/adaptation/test/fake_adaptation_listener.h
@@ -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_
diff --git a/call/adaptation/test/fake_resource.cc b/call/adaptation/test/fake_resource.cc
index fef765b9e4..113f4b5450 100644
--- a/call/adaptation/test/fake_resource.cc
+++ b/call/adaptation/test/fake_resource.cc
@@ -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;
+std::string FakeResource::Name() const {
+ return name_;
}
void FakeResource::SetResourceListener(ResourceListener* listener) {
- RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
listener_ = listener;
}
-std::string FakeResource::Name() const {
- return name_;
-}
-
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
diff --git a/call/adaptation/test/fake_resource.h b/call/adaptation/test/fake_resource.h
index 19f93ad612..c67dc3af3d 100644
--- a/call/adaptation/test/fake_resource.h
+++ b/call/adaptation/test/fake_resource.h
@@ -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
diff --git a/video/adaptation/encode_usage_resource.h b/video/adaptation/encode_usage_resource.h
index 6fcd0ebd97..257988fa12 100644
--- a/video/adaptation/encode_usage_resource.h
+++ b/video/adaptation/encode_usage_resource.h
@@ -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"
diff --git a/video/adaptation/quality_scaler_resource.h b/video/adaptation/quality_scaler_resource.h
index 43e99e7ed1..372d0c91b8 100644
--- a/video/adaptation/quality_scaler_resource.h
+++ b/video/adaptation/quality_scaler_resource.h
@@ -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,
diff --git a/video/adaptation/video_stream_encoder_resource.cc b/video/adaptation/video_stream_encoder_resource.cc
index db5a15534c..9a2db1fb87 100644
--- a/video/adaptation/video_stream_encoder_resource.cc
+++ b/video/adaptation/video_stream_encoder_resource.cc
@@ -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());
diff --git a/video/adaptation/video_stream_encoder_resource.h b/video/adaptation/video_stream_encoder_resource.h
index fe66040512..f561a63ce4 100644
--- a/video/adaptation/video_stream_encoder_resource.h
+++ b/video/adaptation/video_stream_encoder_resource.h
@@ -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);
diff --git a/video/adaptation/video_stream_encoder_resource_manager.cc b/video/adaptation/video_stream_encoder_resource_manager.cc
index c88c6333e2..5b20e1f4e2 100644
--- a/video/adaptation/video_stream_encoder_resource_manager.cc
+++ b/video/adaptation/video_stream_encoder_resource_manager.cc
@@ -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* manager)
- : rtc::RefCountedObject<VideoStreamEncoderResource>(
- "PreventIncreaseResolutionDueToBitrateResource"),
- manager_(manager),
+VideoStreamEncoderResourceManager::BitrateConstraint::BitrateConstraint(
+ VideoStreamEncoderResourceManager* 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());
+void VideoStreamEncoderResourceManager::BitrateConstraint::SetAdaptationQueue(
+ TaskQueueBase* resource_adaptation_queue) {
+ resource_adaptation_queue_ = resource_adaptation_queue;
+}
+
+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::
- PreventIncreaseResolutionDueToBitrateResource::
- OnEncoderTargetBitrateUpdated(
- absl::optional<uint32_t> encoder_target_bitrate_bps) {
- RTC_DCHECK_RUN_ON(encoder_queue());
- MaybePostTaskToResourceAdaptationQueue(
- [this_ref =
- rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>(
- this),
- encoder_target_bitrate_bps] {
- RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
+void VideoStreamEncoderResourceManager::BitrateConstraint::
+ OnEncoderTargetBitrateUpdated(
+ absl::optional<uint32_t> encoder_target_bitrate_bps) {
+ 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_);
this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
- });
+ }));
}
-bool VideoStreamEncoderResourceManager::
- PreventIncreaseResolutionDueToBitrateResource::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());
+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_);
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),
- encoder_target_bitrate_bps] {
- RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
+ 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_);
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,
diff --git a/video/adaptation/video_stream_encoder_resource_manager.h b/video/adaptation/video_stream_encoder_resource_manager.h
index 4563b74212..ef426363cf 100644
--- a/video/adaptation/video_stream_encoder_resource_manager.h
+++ b/video/adaptation/video_stream_encoder_resource_manager.h
@@ -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_);
};
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 95c6055970..7014138091 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -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);
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index 193aa1e8c9..83b69113a2 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -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
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 005118dbba..6ce6265ba2 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -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