[Adaptation] Prep Resource for api/ move. Introduce VSE-Resource.

This CL is in preparation for moving Resource to the api/ folder. It
does not move it, but makes it such that the moving CL can be a pure
move.

In order to do this, we must stop depending on rtc_base/rtc::TaskQueue
in favor of api/webrtc::TaskQueueBase.

There are also other rtc_base/ dependencies that we do not want to
expose to the api/ folder, like critical sections and thread
annotations which are not publically exposed. To get around this, we
make Resource an abstract interface and move all of the base class
functionality into a new non-api/ class: VideoStreamEncoderResource.

The Resource now has Register/UnregisterAdaptationTaskQueue() methods.
By explicitly unregistering, we can ensure validity of the pointer even
if the Resource outlives the PeerConnection. While public interface
methods are only to be called on the adaptation task queue, posting to
the task queue happens off-queue, so a |lock_| is introduced to guard
it.

Bug: webrtc:11525
Change-Id: I50b3a30960cdec9032016c779b47001c01dad32f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176320
Reviewed-by: Evan Shrubsole <eshr@google.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31402}
diff --git a/call/adaptation/BUILD.gn b/call/adaptation/BUILD.gn
index 2a6933e..291911a 100644
--- a/call/adaptation/BUILD.gn
+++ b/call/adaptation/BUILD.gn
@@ -30,6 +30,7 @@
   deps = [
     "../../api:rtp_parameters",
     "../../api:scoped_refptr",
+    "../../api/task_queue:task_queue",
     "../../api/video:video_adaptation",
     "../../api/video:video_frame",
     "../../api/video:video_stream_encoder",
@@ -86,9 +87,14 @@
     ]
     deps = [
       ":resource_adaptation",
+      "../../api:scoped_refptr",
+      "../../api/task_queue:task_queue",
       "../../api/video:video_stream_encoder",
       "../../rtc_base:rtc_base_approved",
+      "../../rtc_base/synchronization:sequence_checker",
+      "../../rtc_base/task_utils:to_queued_task",
       "../../test:test_support",
+      "//third_party/abseil-cpp/absl/types:optional",
     ]
   }
 }
diff --git a/call/adaptation/resource.cc b/call/adaptation/resource.cc
index 7d83c4d..6b1028e 100644
--- a/call/adaptation/resource.cc
+++ b/call/adaptation/resource.cc
@@ -26,77 +26,8 @@
 
 ResourceListener::~ResourceListener() {}
 
-Resource::Resource()
-    : encoder_queue_(nullptr),
-      resource_adaptation_queue_(nullptr),
-      usage_state_(absl::nullopt),
-      listener_(nullptr) {}
+Resource::Resource() {}
 
-Resource::~Resource() {
-  RTC_DCHECK(!listener_)
-      << "There is a listener depending on a Resource being destroyed.";
-}
-
-void Resource::Initialize(rtc::TaskQueue* encoder_queue,
-                          rtc::TaskQueue* resource_adaptation_queue) {
-  RTC_DCHECK(!encoder_queue_);
-  RTC_DCHECK(encoder_queue);
-  RTC_DCHECK(!resource_adaptation_queue_);
-  RTC_DCHECK(resource_adaptation_queue);
-  encoder_queue_ = encoder_queue;
-  resource_adaptation_queue_ = resource_adaptation_queue;
-}
-
-void Resource::SetResourceListener(ResourceListener* listener) {
-  RTC_DCHECK(resource_adaptation_queue_);
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
-  // If you want to change listener you need to unregister the old listener by
-  // setting it to null first.
-  RTC_DCHECK(!listener_ || !listener) << "A listener is already set";
-  listener_ = listener;
-}
-
-absl::optional<ResourceUsageState> Resource::usage_state() const {
-  RTC_DCHECK(resource_adaptation_queue_);
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
-  return usage_state_;
-}
-
-void Resource::ClearUsageState() {
-  RTC_DCHECK(resource_adaptation_queue_);
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
-  usage_state_ = absl::nullopt;
-}
-
-bool Resource::IsAdaptationUpAllowed(
-    const VideoStreamInputState& input_state,
-    const VideoSourceRestrictions& restrictions_before,
-    const VideoSourceRestrictions& restrictions_after,
-    rtc::scoped_refptr<Resource> reason_resource) const {
-  return true;
-}
-
-void Resource::OnAdaptationApplied(
-    const VideoStreamInputState& input_state,
-    const VideoSourceRestrictions& restrictions_before,
-    const VideoSourceRestrictions& restrictions_after,
-    rtc::scoped_refptr<Resource> reason_resource) {}
-
-rtc::TaskQueue* Resource::encoder_queue() const {
-  return encoder_queue_;
-}
-
-rtc::TaskQueue* Resource::resource_adaptation_queue() const {
-  return resource_adaptation_queue_;
-}
-
-void Resource::OnResourceUsageStateMeasured(ResourceUsageState usage_state) {
-  RTC_DCHECK(resource_adaptation_queue_);
-  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
-  usage_state_ = usage_state;
-  if (!listener_)
-    return;
-  listener_->OnResourceUsageStateMeasured(this);
-}
+Resource::~Resource() {}
 
 }  // namespace webrtc
diff --git a/call/adaptation/resource.h b/call/adaptation/resource.h
index d7ecf94..febc29c 100644
--- a/call/adaptation/resource.h
+++ b/call/adaptation/resource.h
@@ -16,10 +16,10 @@
 
 #include "absl/types/optional.h"
 #include "api/scoped_refptr.h"
+#include "api/task_queue/task_queue_base.h"
 #include "call/adaptation/video_source_restrictions.h"
 #include "call/adaptation/video_stream_input_state.h"
 #include "rtc_base/ref_count.h"
-#include "rtc_base/task_queue.h"
 
 namespace webrtc {
 
@@ -44,49 +44,62 @@
       rtc::scoped_refptr<Resource> resource) = 0;
 };
 
+// A Resource monitors an implementation-specific system resource. It may report
+// 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.
+//
+// Usage measurements may be performed on an implementation-specific task queue.
+// The Resource is reference counted to prevent use-after-free when posting
+// between task queues. As such, the implementation MUST NOT make any
+// assumptions about which task queue Resource is destructed on.
 class Resource : public rtc::RefCountInterface {
  public:
-  // By default, usage_state() is null until a measurement is made.
   Resource();
+  // Destruction may happen on any task queue.
   ~Resource() override;
 
-  void Initialize(rtc::TaskQueue* encoder_queue,
-                  rtc::TaskQueue* resource_adaptation_queue);
+  // 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;
 
-  void SetResourceListener(ResourceListener* listener);
+  // The listeners MUST be informed any time UsageState() changes.
+  virtual void SetResourceListener(ResourceListener* listener) = 0;
 
-  absl::optional<ResourceUsageState> usage_state() const;
-  void ClearUsageState();
+  virtual std::string Name() const = 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
+  // favor of passing the use usage state directly to the ResourceListener. This
+  // gets rid of this strange requirement of having to return the same thing
+  // every time.
+  virtual absl::optional<ResourceUsageState> UsageState() const = 0;
+  // 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. The
-  // default implementation unconditionally returns true (= allowed).
+  // 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;
+      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);
-
-  virtual std::string name() const = 0;
-
- protected:
-  rtc::TaskQueue* encoder_queue() const;
-  rtc::TaskQueue* resource_adaptation_queue() const;
-
-  // Updates the usage state and informs all registered listeners.
-  void OnResourceUsageStateMeasured(ResourceUsageState usage_state);
-
- private:
-  rtc::TaskQueue* encoder_queue_;
-  rtc::TaskQueue* resource_adaptation_queue_;
-  absl::optional<ResourceUsageState> usage_state_
-      RTC_GUARDED_BY(resource_adaptation_queue_);
-  ResourceListener* listener_ RTC_GUARDED_BY(resource_adaptation_queue_);
+      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 57ace71..a705ccf 100644
--- a/call/adaptation/resource_adaptation_processor.cc
+++ b/call/adaptation/resource_adaptation_processor.cc
@@ -195,8 +195,8 @@
 void ResourceAdaptationProcessor::OnResourceUsageStateMeasured(
     rtc::scoped_refptr<Resource> resource) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
-  RTC_DCHECK(resource->usage_state().has_value());
-  ResourceUsageState usage_state = resource->usage_state().value();
+  RTC_DCHECK(resource->UsageState().has_value());
+  ResourceUsageState usage_state = resource->UsageState().value();
   MitigationResultAndLogMessage result_and_message;
   switch (usage_state) {
     case ResourceUsageState::kOveruse:
@@ -214,7 +214,7 @@
     // successfully adapted since - don't log to avoid spam.
     return;
   }
-  RTC_LOG(INFO) << "Resource \"" << resource->name() << "\" signalled "
+  RTC_LOG(INFO) << "Resource \"" << resource->Name() << "\" signalled "
                 << ResourceUsageStateToString(usage_state) << ". "
                 << result_and_message.message;
   if (result_and_message.result == MitigationResult::kAdaptationApplied) {
@@ -289,7 +289,7 @@
                                          restrictions_after, reason_resource)) {
       processing_in_progress_ = false;
       rtc::StringBuilder message;
-      message << "Not adapting up because resource \"" << resource->name()
+      message << "Not adapting up because resource \"" << resource->Name()
               << "\" disallowed it";
       return MitigationResultAndLogMessage(
           MitigationResult::kRejectedByResource, message.Release());
diff --git a/call/adaptation/resource_adaptation_processor_unittest.cc b/call/adaptation/resource_adaptation_processor_unittest.cc
index e94b3a9..c150700 100644
--- a/call/adaptation/resource_adaptation_processor_unittest.cc
+++ b/call/adaptation/resource_adaptation_processor_unittest.cc
@@ -70,16 +70,16 @@
  public:
   ResourceAdaptationProcessorTest()
       : resource_adaptation_queue_("ResourceAdaptationQueue"),
-        encoder_queue_("EncoderQueue"),
         frame_rate_provider_(),
         input_state_provider_(&frame_rate_provider_),
-        resource_(new FakeResource("FakeResource")),
-        other_resource_(new FakeResource("OtherFakeResource")),
+        resource_(FakeResource::Create("FakeResource")),
+        other_resource_(FakeResource::Create("OtherFakeResource")),
         processor_(std::make_unique<ResourceAdaptationProcessor>(
             &input_state_provider_,
             /*encoder_stats_observer=*/&frame_rate_provider_)) {
-    resource_->Initialize(&encoder_queue_, &resource_adaptation_queue_);
-    other_resource_->Initialize(&encoder_queue_, &resource_adaptation_queue_);
+    resource_->RegisterAdaptationTaskQueue(resource_adaptation_queue_.Get());
+    other_resource_->RegisterAdaptationTaskQueue(
+        resource_adaptation_queue_.Get());
     rtc::Event event;
     resource_adaptation_queue_.PostTask([this, &event] {
       processor_->InitializeOnResourceAdaptationQueue();
@@ -119,7 +119,6 @@
 
  protected:
   TaskQueueForTest resource_adaptation_queue_;
-  TaskQueueForTest encoder_queue_;
   FakeFrameRateProvider frame_rate_provider_;
   VideoStreamInputStateProvider input_state_provider_;
   rtc::scoped_refptr<FakeResource> resource_;
@@ -397,7 +396,7 @@
         SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
         resource_->set_usage_state(ResourceUsageState::kOveruse);
         EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
-        EXPECT_FALSE(resource_->usage_state().has_value());
+        EXPECT_FALSE(resource_->UsageState().has_value());
       },
       RTC_FROM_HERE);
 }
@@ -410,7 +409,7 @@
         processor_->StartResourceAdaptation();
         resource_->set_usage_state(ResourceUsageState::kOveruse);
         EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
-        EXPECT_FALSE(resource_->usage_state().has_value());
+        EXPECT_FALSE(resource_->UsageState().has_value());
       },
       RTC_FROM_HERE);
 }
diff --git a/call/adaptation/resource_unittest.cc b/call/adaptation/resource_unittest.cc
index 9436a02..ad93fbd 100644
--- a/call/adaptation/resource_unittest.cc
+++ b/call/adaptation/resource_unittest.cc
@@ -36,15 +36,14 @@
  public:
   ResourceTest()
       : resource_adaptation_queue_("ResourceAdaptationQueue"),
-        encoder_queue_("EncoderQueue"),
-        fake_resource_(new FakeResource("FakeResource")) {
-    fake_resource_->Initialize(&encoder_queue_, &resource_adaptation_queue_);
+        fake_resource_(FakeResource::Create("FakeResource")) {
+    fake_resource_->RegisterAdaptationTaskQueue(
+        resource_adaptation_queue_.Get());
   }
 
  protected:
   const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
   TaskQueueForTest resource_adaptation_queue_;
-  TaskQueueForTest encoder_queue_;
   rtc::scoped_refptr<FakeResource> fake_resource_;
 };
 
@@ -56,7 +55,7 @@
         EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
             .Times(1)
             .WillOnce([](rtc::scoped_refptr<Resource> resource) {
-              EXPECT_EQ(ResourceUsageState::kOveruse, resource->usage_state());
+              EXPECT_EQ(ResourceUsageState::kOveruse, resource->UsageState());
             });
         fake_resource_->set_usage_state(ResourceUsageState::kOveruse);
         fake_resource_->SetResourceListener(nullptr);
diff --git a/call/adaptation/test/fake_resource.cc b/call/adaptation/test/fake_resource.cc
index 4c0a129..fef765b 100644
--- a/call/adaptation/test/fake_resource.cc
+++ b/call/adaptation/test/fake_resource.cc
@@ -10,35 +10,95 @@
 
 #include "call/adaptation/test/fake_resource.h"
 
+#include <algorithm>
 #include <utility>
 
+#include "rtc_base/ref_counted_object.h"
+#include "rtc_base/task_utils/to_queued_task.h"
+
 namespace webrtc {
 
+// static
+rtc::scoped_refptr<FakeResource> FakeResource::Create(std::string name) {
+  return new rtc::RefCountedObject<FakeResource>(name);
+}
+
 FakeResource::FakeResource(std::string name)
-    : rtc::RefCountedObject<Resource>(),
+    : Resource(),
+      lock_(),
       name_(std::move(name)),
+      resource_adaptation_queue_(nullptr),
       is_adaptation_up_allowed_(true),
-      num_adaptations_applied_(0) {}
+      num_adaptations_applied_(0),
+      usage_state_(absl::nullopt),
+      listener_(nullptr) {}
 
 FakeResource::~FakeResource() {}
 
 void FakeResource::set_usage_state(ResourceUsageState usage_state) {
-  OnResourceUsageStateMeasured(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_);
+  usage_state_ = usage_state;
+  if (listener_) {
+    listener_->OnResourceUsageStateMeasured(this);
+  }
 }
 
 void FakeResource::set_is_adaptation_up_allowed(bool is_adaptation_up_allowed) {
+  rtc::CritScope crit(&lock_);
   is_adaptation_up_allowed_ = is_adaptation_up_allowed;
 }
 
 size_t FakeResource::num_adaptations_applied() const {
+  rtc::CritScope crit(&lock_);
   return num_adaptations_applied_;
 }
 
+void FakeResource::RegisterAdaptationTaskQueue(
+    TaskQueueBase* resource_adaptation_queue) {
+  RTC_DCHECK(!resource_adaptation_queue_);
+  RTC_DCHECK(resource_adaptation_queue);
+  resource_adaptation_queue_ = resource_adaptation_queue;
+}
+
+void FakeResource::UnregisterAdaptationTaskQueue() {
+  RTC_DCHECK(resource_adaptation_queue_);
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
+  resource_adaptation_queue_ = nullptr;
+}
+
+void FakeResource::SetResourceListener(ResourceListener* listener) {
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
+  listener_ = listener;
+}
+
+std::string FakeResource::Name() const {
+  return name_;
+}
+
+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_;
 }
 
@@ -47,6 +107,8 @@
     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_;
 }
 
diff --git a/call/adaptation/test/fake_resource.h b/call/adaptation/test/fake_resource.h
index beaca54..19f93ad 100644
--- a/call/adaptation/test/fake_resource.h
+++ b/call/adaptation/test/fake_resource.h
@@ -12,15 +12,22 @@
 #define CALL_ADAPTATION_TEST_FAKE_RESOURCE_H_
 
 #include <string>
+#include <vector>
 
+#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/ref_counted_object.h"
+#include "rtc_base/critical_section.h"
+#include "rtc_base/synchronization/sequence_checker.h"
 
 namespace webrtc {
 
 // Fake resource used for testing.
-class FakeResource : public rtc::RefCountedObject<Resource> {
+class FakeResource : public Resource {
  public:
+  static rtc::scoped_refptr<FakeResource> Create(std::string name);
+
   explicit FakeResource(std::string name);
   ~FakeResource() override;
 
@@ -29,7 +36,13 @@
   size_t num_adaptations_applied() const;
 
   // Resource implementation.
-  std::string name() const override { return name_; }
+  void RegisterAdaptationTaskQueue(
+      TaskQueueBase* resource_adaptation_queue) override;
+  void UnregisterAdaptationTaskQueue() override;
+  void SetResourceListener(ResourceListener* listener) override;
+  std::string Name() const override;
+  absl::optional<ResourceUsageState> UsageState() const override;
+  void ClearUsageState() override;
   bool IsAdaptationUpAllowed(
       const VideoStreamInputState& input_state,
       const VideoSourceRestrictions& restrictions_before,
@@ -42,9 +55,14 @@
       rtc::scoped_refptr<Resource> reason_resource) override;
 
  private:
+  rtc::CriticalSection lock_;
   const std::string name_;
-  bool is_adaptation_up_allowed_;
-  size_t num_adaptations_applied_;
+  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_);
 };
 
 }  // namespace webrtc
diff --git a/video/adaptation/BUILD.gn b/video/adaptation/BUILD.gn
index 51e6a2d..e27e5b5 100644
--- a/video/adaptation/BUILD.gn
+++ b/video/adaptation/BUILD.gn
@@ -16,6 +16,8 @@
     "overuse_frame_detector.h",
     "quality_scaler_resource.cc",
     "quality_scaler_resource.h",
+    "video_stream_encoder_resource.cc",
+    "video_stream_encoder_resource.h",
     "video_stream_encoder_resource_manager.cc",
     "video_stream_encoder_resource_manager.h",
   ]
@@ -44,6 +46,7 @@
     "../../rtc_base/experiments:quality_scaler_settings",
     "../../rtc_base/synchronization:sequence_checker",
     "../../rtc_base/task_utils:repeating_task",
+    "../../rtc_base/task_utils:to_queued_task",
     "../../system_wrappers:field_trial",
     "../../system_wrappers:system_wrappers",
     "//third_party/abseil-cpp/absl/algorithm:container",
diff --git a/video/adaptation/encode_usage_resource.cc b/video/adaptation/encode_usage_resource.cc
index 49531a3..d6f2334 100644
--- a/video/adaptation/encode_usage_resource.cc
+++ b/video/adaptation/encode_usage_resource.cc
@@ -15,18 +15,28 @@
 
 #include "api/video/video_adaptation_reason.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/ref_counted_object.h"
 
 namespace webrtc {
 
+// static
+rtc::scoped_refptr<EncodeUsageResource> EncodeUsageResource::Create(
+    std::unique_ptr<OveruseFrameDetector> overuse_detector) {
+  return new rtc::RefCountedObject<EncodeUsageResource>(
+      std::move(overuse_detector));
+}
+
 EncodeUsageResource::EncodeUsageResource(
     std::unique_ptr<OveruseFrameDetector> overuse_detector)
-    : rtc::RefCountedObject<Resource>(),
+    : VideoStreamEncoderResource("EncoderUsageResource"),
       overuse_detector_(std::move(overuse_detector)),
       is_started_(false),
       target_frame_rate_(absl::nullopt) {
   RTC_DCHECK(overuse_detector_);
 }
 
+EncodeUsageResource::~EncodeUsageResource() {}
+
 bool EncodeUsageResource::is_started() const {
   RTC_DCHECK_RUN_ON(encoder_queue());
   return is_started_;
@@ -81,7 +91,7 @@
   RTC_DCHECK_RUN_ON(encoder_queue());
   // Reference counting guarantees that this object is still alive by the time
   // the task is executed.
-  resource_adaptation_queue()->PostTask(
+  MaybePostTaskToResourceAdaptationQueue(
       [this_ref = rtc::scoped_refptr<EncodeUsageResource>(this)] {
         RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
         this_ref->OnResourceUsageStateMeasured(ResourceUsageState::kUnderuse);
@@ -92,7 +102,7 @@
   RTC_DCHECK_RUN_ON(encoder_queue());
   // Reference counting guarantees that this object is still alive by the time
   // the task is executed.
-  resource_adaptation_queue()->PostTask(
+  MaybePostTaskToResourceAdaptationQueue(
       [this_ref = rtc::scoped_refptr<EncodeUsageResource>(this)] {
         RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
         this_ref->OnResourceUsageStateMeasured(ResourceUsageState::kOveruse);
diff --git a/video/adaptation/encode_usage_resource.h b/video/adaptation/encode_usage_resource.h
index 3c6f02b..6fcd0eb 100644
--- a/video/adaptation/encode_usage_resource.h
+++ b/video/adaptation/encode_usage_resource.h
@@ -15,11 +15,13 @@
 #include <string>
 
 #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"
+#include "video/adaptation/video_stream_encoder_resource.h"
 
 namespace webrtc {
 
@@ -28,11 +30,15 @@
 // indirectly by usage in the ResourceAdaptationProcessor (which is only tested
 // because of its usage in VideoStreamEncoder); all tests are currently in
 // video_stream_encoder_unittest.cc.
-class EncodeUsageResource : public rtc::RefCountedObject<Resource>,
+class EncodeUsageResource : public VideoStreamEncoderResource,
                             public OveruseFrameDetectorObserverInterface {
  public:
+  static rtc::scoped_refptr<EncodeUsageResource> Create(
+      std::unique_ptr<OveruseFrameDetector> overuse_detector);
+
   explicit EncodeUsageResource(
       std::unique_ptr<OveruseFrameDetector> overuse_detector);
+  ~EncodeUsageResource() override;
 
   bool is_started() const;
 
@@ -51,8 +57,6 @@
   void AdaptUp() override;
   void AdaptDown() override;
 
-  std::string name() const override { return "EncoderUsageResource"; }
-
  private:
   int TargetFrameRateAsInt();
 
diff --git a/video/adaptation/quality_scaler_resource.cc b/video/adaptation/quality_scaler_resource.cc
index c88bfa2..514a2d7 100644
--- a/video/adaptation/quality_scaler_resource.cc
+++ b/video/adaptation/quality_scaler_resource.cc
@@ -13,6 +13,8 @@
 #include <utility>
 
 #include "rtc_base/experiments/balanced_degradation_settings.h"
+#include "rtc_base/ref_counted_object.h"
+#include "rtc_base/task_utils/to_queued_task.h"
 #include "rtc_base/time_utils.h"
 
 namespace webrtc {
@@ -23,8 +25,13 @@
 
 }  // namespace
 
+// static
+rtc::scoped_refptr<QualityScalerResource> QualityScalerResource::Create() {
+  return new rtc::RefCountedObject<QualityScalerResource>();
+}
+
 QualityScalerResource::QualityScalerResource()
-    : rtc::RefCountedObject<Resource>(),
+    : VideoStreamEncoderResource("QualityScalerResource"),
       quality_scaler_(nullptr),
       last_underuse_due_to_disabled_timestamp_ms_(absl::nullopt),
       num_handled_callbacks_(0),
@@ -95,7 +102,7 @@
         timestamp_ms - last_underuse_due_to_disabled_timestamp_ms_.value() >=
             kUnderuseDueToDisabledCooldownMs) {
       last_underuse_due_to_disabled_timestamp_ms_ = timestamp_ms;
-      resource_adaptation_queue()->PostTask(
+      MaybePostTaskToResourceAdaptationQueue(
           [this_ref = rtc::scoped_refptr<QualityScalerResource>(this)] {
             RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
             this_ref->OnResourceUsageStateMeasured(
@@ -126,7 +133,7 @@
   size_t callback_id = QueuePendingCallback(callback);
   // Reference counting guarantees that this object is still alive by the time
   // the task is executed.
-  resource_adaptation_queue()->PostTask(
+  MaybePostTaskToResourceAdaptationQueue(
       [this_ref = rtc::scoped_refptr<QualityScalerResource>(this),
        callback_id] {
         RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
@@ -146,7 +153,7 @@
   size_t callback_id = QueuePendingCallback(callback);
   // Reference counting guarantees that this object is still alive by the time
   // the task is executed.
-  resource_adaptation_queue()->PostTask(
+  MaybePostTaskToResourceAdaptationQueue(
       [this_ref = rtc::scoped_refptr<QualityScalerResource>(this),
        callback_id] {
         RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
@@ -206,8 +213,8 @@
   // Reference counting guarantees that this object is still alive by the time
   // the task is executed.
   encoder_queue()->PostTask(
-      [this_ref = rtc::scoped_refptr<QualityScalerResource>(this), callback_id,
-       clear_qp_samples] {
+      ToQueuedTask([this_ref = rtc::scoped_refptr<QualityScalerResource>(this),
+                    callback_id, clear_qp_samples] {
         RTC_DCHECK_RUN_ON(this_ref->encoder_queue());
         if (this_ref->num_handled_callbacks_ >= callback_id) {
           // The callback with this ID has already been handled.
@@ -220,7 +227,7 @@
             clear_qp_samples);
         ++this_ref->num_handled_callbacks_;
         this_ref->pending_callbacks_.pop();
-      });
+      }));
 }
 
 void QualityScalerResource::AbortPendingCallbacks() {
diff --git a/video/adaptation/quality_scaler_resource.h b/video/adaptation/quality_scaler_resource.h
index 2632f2e..43e99e7 100644
--- a/video/adaptation/quality_scaler_resource.h
+++ b/video/adaptation/quality_scaler_resource.h
@@ -16,6 +16,7 @@
 #include <string>
 
 #include "absl/types/optional.h"
+#include "api/scoped_refptr.h"
 #include "api/video/video_adaptation_reason.h"
 #include "api/video_codecs/video_encoder.h"
 #include "call/adaptation/resource.h"
@@ -24,13 +25,16 @@
 #include "rtc_base/critical_section.h"
 #include "rtc_base/ref_counted_object.h"
 #include "rtc_base/task_queue.h"
+#include "video/adaptation/video_stream_encoder_resource.h"
 
 namespace webrtc {
 
 // Handles interaction with the QualityScaler.
-class QualityScalerResource : public rtc::RefCountedObject<Resource>,
+class QualityScalerResource : public VideoStreamEncoderResource,
                               public QualityScalerQpUsageHandlerInterface {
  public:
+  static rtc::scoped_refptr<QualityScalerResource> Create();
+
   QualityScalerResource();
   ~QualityScalerResource() override;
 
@@ -56,9 +60,7 @@
       rtc::scoped_refptr<QualityScalerQpUsageHandlerCallbackInterface> callback)
       override;
 
-  std::string name() const override { return "QualityScalerResource"; }
-
-  // Resource implementation.
+  // VideoStreamEncoderResource implementation.
   void OnAdaptationApplied(
       const VideoStreamInputState& input_state,
       const VideoSourceRestrictions& restrictions_before,
@@ -81,9 +83,9 @@
   absl::optional<int64_t> last_underuse_due_to_disabled_timestamp_ms_
       RTC_GUARDED_BY(encoder_queue());
   // Every OnReportQpUsageHigh/Low() operation has a callback that MUST be
-  // invoked on the |encoder_queue_|. Because usage measurements are reported on
-  // the |encoder_queue_| but handled by the processor on the the
-  // |resource_adaptation_queue_|, handling a measurement entails a task queue
+  // invoked on the encoder_queue(). Because usage measurements are reported on
+  // the encoder_queue() but handled by the processor on the the
+  // resource_adaptation_queue_(), handling a measurement entails a task queue
   // "ping" round-trip. Multiple callbacks in-flight is thus possible.
   size_t num_handled_callbacks_ RTC_GUARDED_BY(encoder_queue());
   std::queue<rtc::scoped_refptr<QualityScalerQpUsageHandlerCallbackInterface>>
diff --git a/video/adaptation/quality_scaler_resource_unittest.cc b/video/adaptation/quality_scaler_resource_unittest.cc
index 66f4e13..e2098d7 100644
--- a/video/adaptation/quality_scaler_resource_unittest.cc
+++ b/video/adaptation/quality_scaler_resource_unittest.cc
@@ -74,9 +74,10 @@
         encoder_queue_(task_queue_factory_->CreateTaskQueue(
             "EncoderQueue",
             TaskQueueFactory::Priority::NORMAL)),
-        quality_scaler_resource_(new QualityScalerResource()) {
-    quality_scaler_resource_->Initialize(&encoder_queue_,
-                                         &resource_adaptation_queue_);
+        quality_scaler_resource_(QualityScalerResource::Create()) {
+    quality_scaler_resource_->RegisterEncoderTaskQueue(encoder_queue_.Get());
+    quality_scaler_resource_->RegisterAdaptationTaskQueue(
+        resource_adaptation_queue_.Get());
     rtc::Event event;
     encoder_queue_.PostTask([this, &event] {
       quality_scaler_resource_->StartCheckForOveruse(
diff --git a/video/adaptation/video_stream_encoder_resource.cc b/video/adaptation/video_stream_encoder_resource.cc
new file mode 100644
index 0000000..db5a155
--- /dev/null
+++ b/video/adaptation/video_stream_encoder_resource.cc
@@ -0,0 +1,112 @@
+/*
+ *  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 "video/adaptation/video_stream_encoder_resource.h"
+
+#include <algorithm>
+#include <utility>
+
+namespace webrtc {
+
+VideoStreamEncoderResource::VideoStreamEncoderResource(std::string name)
+    : lock_(),
+      name_(std::move(name)),
+      encoder_queue_(nullptr),
+      resource_adaptation_queue_(nullptr),
+      usage_state_(absl::nullopt),
+      listener_(nullptr) {}
+
+VideoStreamEncoderResource::~VideoStreamEncoderResource() {
+  RTC_DCHECK(!listener_)
+      << "There is a listener depending on a VideoStreamEncoderResource being "
+      << "destroyed.";
+}
+
+void VideoStreamEncoderResource::RegisterEncoderTaskQueue(
+    TaskQueueBase* encoder_queue) {
+  RTC_DCHECK(!encoder_queue_);
+  RTC_DCHECK(encoder_queue);
+  encoder_queue_ = encoder_queue;
+}
+
+void VideoStreamEncoderResource::RegisterAdaptationTaskQueue(
+    TaskQueueBase* resource_adaptation_queue) {
+  rtc::CritScope crit(&lock_);
+  RTC_DCHECK(!resource_adaptation_queue_);
+  RTC_DCHECK(resource_adaptation_queue);
+  resource_adaptation_queue_ = resource_adaptation_queue;
+}
+
+void VideoStreamEncoderResource::UnregisterAdaptationTaskQueue() {
+  rtc::CritScope crit(&lock_);
+  RTC_DCHECK(resource_adaptation_queue_);
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
+  resource_adaptation_queue_ = nullptr;
+}
+
+void VideoStreamEncoderResource::SetResourceListener(
+    ResourceListener* listener) {
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue());
+  // If you want to change listener you need to unregister the old listener by
+  // setting it to null first.
+  RTC_DCHECK(!listener_ || !listener) << "A listener is already set";
+  listener_ = listener;
+}
+
+std::string VideoStreamEncoderResource::Name() const {
+  return name_;
+}
+
+absl::optional<ResourceUsageState> VideoStreamEncoderResource::UsageState()
+    const {
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue());
+  return usage_state_;
+}
+
+void VideoStreamEncoderResource::ClearUsageState() {
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue());
+  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());
+  usage_state_ = usage_state;
+  if (listener_) {
+    listener_->OnResourceUsageStateMeasured(this);
+  }
+}
+
+TaskQueueBase* VideoStreamEncoderResource::encoder_queue() const {
+  return encoder_queue_;
+}
+
+TaskQueueBase* VideoStreamEncoderResource::resource_adaptation_queue() const {
+  rtc::CritScope crit(&lock_);
+  RTC_DCHECK(resource_adaptation_queue_);
+  RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
+  return resource_adaptation_queue_;
+}
+
+}  // namespace webrtc
diff --git a/video/adaptation/video_stream_encoder_resource.h b/video/adaptation/video_stream_encoder_resource.h
new file mode 100644
index 0000000..fe66040
--- /dev/null
+++ b/video/adaptation/video_stream_encoder_resource.h
@@ -0,0 +1,86 @@
+/*
+ *  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 VIDEO_ADAPTATION_VIDEO_STREAM_ENCODER_RESOURCE_H_
+#define VIDEO_ADAPTATION_VIDEO_STREAM_ENCODER_RESOURCE_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.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 {
+
+class VideoStreamEncoderResource : public Resource {
+ public:
+  ~VideoStreamEncoderResource() override;
+
+  // Registering task queues must be performed as part of initialization.
+  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;
+  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;
+
+ protected:
+  explicit VideoStreamEncoderResource(std::string name);
+
+  void OnResourceUsageStateMeasured(ResourceUsageState usage_state);
+
+  // The caller is responsible for ensuring the task queue is still valid.
+  TaskQueueBase* encoder_queue() const;
+  // Validity of returned pointer is ensured by only allowing this method to be
+  // called on the adaptation task queue. Designed for use with RTC_GUARDED_BY.
+  // For posting from a different queue, use
+  // MaybePostTaskToResourceAdaptationQueue() instead, which only posts if the
+  // task queue is currently registered.
+  TaskQueueBase* resource_adaptation_queue() const;
+  template <typename Closure>
+  void MaybePostTaskToResourceAdaptationQueue(Closure&& closure) {
+    rtc::CritScope crit(&lock_);
+    if (!resource_adaptation_queue_)
+      return;
+    resource_adaptation_queue_->PostTask(ToQueuedTask(closure));
+  }
+
+ private:
+  rtc::CriticalSection lock_;
+  const std::string name_;
+  // Treated as const after initialization.
+  TaskQueueBase* encoder_queue_;
+  TaskQueueBase* resource_adaptation_queue_ RTC_GUARDED_BY(lock_);
+  absl::optional<ResourceUsageState> usage_state_
+      RTC_GUARDED_BY(resource_adaptation_queue());
+  ResourceListener* listener_ RTC_GUARDED_BY(resource_adaptation_queue());
+};
+
+}  // namespace webrtc
+
+#endif  // VIDEO_ADAPTATION_VIDEO_STREAM_ENCODER_RESOURCE_H_
diff --git a/video/adaptation/video_stream_encoder_resource_manager.cc b/video/adaptation/video_stream_encoder_resource_manager.cc
index b309dd3..c88c633 100644
--- a/video/adaptation/video_stream_encoder_resource_manager.cc
+++ b/video/adaptation/video_stream_encoder_resource_manager.cc
@@ -26,6 +26,7 @@
 #include "call/adaptation/video_source_restrictions.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/ref_counted_object.h"
 #include "rtc_base/strings/string_builder.h"
 #include "rtc_base/time_utils.h"
 
@@ -140,7 +141,8 @@
 
 VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
     PreventAdaptUpDueToActiveCounts(VideoStreamEncoderResourceManager* manager)
-    : rtc::RefCountedObject<Resource>(),
+    : rtc::RefCountedObject<VideoStreamEncoderResource>(
+          "PreventAdaptUpDueToActiveCounts"),
       manager_(manager),
       adaptation_processor_(nullptr) {}
 
@@ -187,7 +189,8 @@
     PreventIncreaseResolutionDueToBitrateResource::
         PreventIncreaseResolutionDueToBitrateResource(
             VideoStreamEncoderResourceManager* manager)
-    : rtc::RefCountedObject<Resource>(),
+    : rtc::RefCountedObject<VideoStreamEncoderResource>(
+          "PreventIncreaseResolutionDueToBitrateResource"),
       manager_(manager),
       encoder_settings_(absl::nullopt),
       encoder_target_bitrate_bps_(absl::nullopt) {}
@@ -196,7 +199,7 @@
     PreventIncreaseResolutionDueToBitrateResource::OnEncoderSettingsUpdated(
         absl::optional<EncoderSettings> encoder_settings) {
   RTC_DCHECK_RUN_ON(encoder_queue());
-  resource_adaptation_queue()->PostTask(
+  MaybePostTaskToResourceAdaptationQueue(
       [this_ref =
            rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>(
                this),
@@ -211,7 +214,7 @@
         OnEncoderTargetBitrateUpdated(
             absl::optional<uint32_t> encoder_target_bitrate_bps) {
   RTC_DCHECK_RUN_ON(encoder_queue());
-  resource_adaptation_queue()->PostTask(
+  MaybePostTaskToResourceAdaptationQueue(
       [this_ref =
            rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>(
                this),
@@ -258,7 +261,8 @@
 
 VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
     PreventAdaptUpInBalancedResource(VideoStreamEncoderResourceManager* manager)
-    : rtc::RefCountedObject<Resource>(),
+    : rtc::RefCountedObject<VideoStreamEncoderResource>(
+          "PreventAdaptUpInBalancedResource"),
       manager_(manager),
       adaptation_processor_(nullptr),
       encoder_target_bitrate_bps_(absl::nullopt) {}
@@ -274,7 +278,7 @@
     OnEncoderTargetBitrateUpdated(
         absl::optional<uint32_t> encoder_target_bitrate_bps) {
   RTC_DCHECK_RUN_ON(encoder_queue());
-  resource_adaptation_queue()->PostTask(
+  MaybePostTaskToResourceAdaptationQueue(
       [this_ref = rtc::scoped_refptr<PreventAdaptUpInBalancedResource>(this),
        encoder_target_bitrate_bps] {
         RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
@@ -328,8 +332,8 @@
       prevent_adapt_up_in_balanced_resource_(
           new PreventAdaptUpInBalancedResource(this)),
       encode_usage_resource_(
-          new EncodeUsageResource(std::move(overuse_detector))),
-      quality_scaler_resource_(new QualityScalerResource()),
+          EncodeUsageResource::Create(std::move(overuse_detector))),
+      quality_scaler_resource_(QualityScalerResource::Create()),
       encoder_queue_(nullptr),
       resource_adaptation_queue_(nullptr),
       input_state_provider_(input_state_provider),
@@ -370,16 +374,24 @@
   RTC_DCHECK(resource_adaptation_queue);
   encoder_queue_ = encoder_queue;
   resource_adaptation_queue_ = resource_adaptation_queue;
-  prevent_adapt_up_due_to_active_counts_->Initialize(
-      encoder_queue_, resource_adaptation_queue_);
-  prevent_increase_resolution_due_to_bitrate_resource_->Initialize(
-      encoder_queue_, resource_adaptation_queue_);
-  prevent_adapt_up_in_balanced_resource_->Initialize(
-      encoder_queue_, resource_adaptation_queue_);
-  encode_usage_resource_->Initialize(encoder_queue_,
-                                     resource_adaptation_queue_);
-  quality_scaler_resource_->Initialize(encoder_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(
+      resource_adaptation_queue_->Get());
+  encode_usage_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
+  encode_usage_resource_->RegisterAdaptationTaskQueue(
+      resource_adaptation_queue_->Get());
+  quality_scaler_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
+  quality_scaler_resource_->RegisterAdaptationTaskQueue(
+      resource_adaptation_queue_->Get());
 }
 
 void VideoStreamEncoderResourceManager::SetAdaptationProcessor(
@@ -428,7 +440,7 @@
                              [resource](const ResourceAndReason& r) {
                                return r.resource == resource;
                              }) == resources_.end())
-      << "Resource " << resource->name() << " already was inserted";
+      << "Resource " << resource->Name() << " already was inserted";
   resources_.emplace_back(resource, reason);
 }
 
@@ -616,7 +628,7 @@
         return r.resource == resource;
       });
   RTC_DCHECK(registered_resource != resources_.end())
-      << resource->name() << " not found.";
+      << resource->Name() << " not found.";
   return registered_resource->reason;
 }
 
diff --git a/video/adaptation/video_stream_encoder_resource_manager.h b/video/adaptation/video_stream_encoder_resource_manager.h
index d028e50..4563b74 100644
--- a/video/adaptation/video_stream_encoder_resource_manager.h
+++ b/video/adaptation/video_stream_encoder_resource_manager.h
@@ -43,6 +43,7 @@
 #include "video/adaptation/encode_usage_resource.h"
 #include "video/adaptation/overuse_frame_detector.h"
 #include "video/adaptation/quality_scaler_resource.h"
+#include "video/adaptation/video_stream_encoder_resource.h"
 
 namespace webrtc {
 
@@ -178,7 +179,7 @@
   // Does not trigger adaptations, only prevents adapting up based on
   // |active_counts_|.
   class PreventAdaptUpDueToActiveCounts final
-      : public rtc::RefCountedObject<Resource> {
+      : public rtc::RefCountedObject<VideoStreamEncoderResource> {
    public:
     explicit PreventAdaptUpDueToActiveCounts(
         VideoStreamEncoderResourceManager* manager);
@@ -188,9 +189,6 @@
         ResourceAdaptationProcessorInterface* adaptation_processor);
 
     // Resource overrides.
-    std::string name() const override {
-      return "PreventAdaptUpDueToActiveCounts";
-    }
     bool IsAdaptationUpAllowed(
         const VideoStreamInputState& input_state,
         const VideoSourceRestrictions& restrictions_before,
@@ -207,7 +205,7 @@
 
   // Does not trigger adaptations, only prevents adapting up resolution.
   class PreventIncreaseResolutionDueToBitrateResource final
-      : public rtc::RefCountedObject<Resource> {
+      : public rtc::RefCountedObject<VideoStreamEncoderResource> {
    public:
     explicit PreventIncreaseResolutionDueToBitrateResource(
         VideoStreamEncoderResourceManager* manager);
@@ -219,9 +217,6 @@
         absl::optional<uint32_t> encoder_target_bitrate_bps);
 
     // Resource overrides.
-    std::string name() const override {
-      return "PreventIncreaseResolutionDueToBitrateResource";
-    }
     bool IsAdaptationUpAllowed(
         const VideoStreamInputState& input_state,
         const VideoSourceRestrictions& restrictions_before,
@@ -240,7 +235,7 @@
 
   // Does not trigger adaptations, only prevents adapting up in BALANCED.
   class PreventAdaptUpInBalancedResource final
-      : public rtc::RefCountedObject<Resource> {
+      : public rtc::RefCountedObject<VideoStreamEncoderResource> {
    public:
     explicit PreventAdaptUpInBalancedResource(
         VideoStreamEncoderResourceManager* manager);
@@ -252,9 +247,6 @@
         absl::optional<uint32_t> encoder_target_bitrate_bps);
 
     // Resource overrides.
-    std::string name() const override {
-      return "PreventAdaptUpInBalancedResource";
-    }
     bool IsAdaptationUpAllowed(
         const VideoStreamInputState& input_state,
         const VideoSourceRestrictions& restrictions_before,
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 6d148cd..95c6055 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -1698,7 +1698,7 @@
     const VideoAdaptationCounters& adaptation_counters,
     rtc::scoped_refptr<Resource> reason) {
   RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
-  std::string resource_name = reason ? reason->name() : "<null>";
+  std::string resource_name = reason ? reason->Name() : "<null>";
   RTC_LOG(INFO) << "Updating sink restrictions from " << resource_name << " to "
                 << restrictions.ToString();
   video_source_sink_controller_.SetRestrictions(std::move(restrictions));
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 277c00b..69a966b 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -316,12 +316,12 @@
                                overuse_detector_proxy_ =
                                    new CpuOveruseDetectorProxy(stats_proxy)),
                            task_queue_factory),
-        fake_cpu_resource_(new FakeResource("FakeResource[CPU]")),
-        fake_quality_resource_(new FakeResource("FakeResource[QP]")) {
-    fake_cpu_resource_->Initialize(encoder_queue(),
-                                   resource_adaptation_queue());
-    fake_quality_resource_->Initialize(encoder_queue(),
-                                       resource_adaptation_queue());
+        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());
     InjectAdaptationResource(fake_quality_resource_,
                              VideoAdaptationReason::kQuality);
     InjectAdaptationResource(fake_cpu_resource_, VideoAdaptationReason::kCpu);