[Adaptation] Remove resource adaptation queue

Resource adaptation needs refactoring for async adaptations. For now
the resource adaptation processor can work on the encoder thread, until
it is refactored to support async adaptation.

Bug: webrtc:11867
Change-Id: I9c46da356db19c0fd52748c999ccb216f2ca923b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/182040
Commit-Queue: Evan Shrubsole <eshr@google.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31991}
This commit is contained in:
Evan Shrubsole 2020-08-25 13:12:12 +02:00 committed by Commit Bot
parent 90caa4356b
commit 8572841131
15 changed files with 169 additions and 298 deletions

View file

@ -14,7 +14,6 @@
#include <string>
#include "api/adaptation/resource.h"
#include "api/scoped_refptr.h"
#include "call/adaptation/video_source_restrictions.h"
#include "call/adaptation/video_stream_input_state.h"

View file

@ -15,7 +15,6 @@
namespace webrtc {
// Thread-safe retrieval of degradation preferences.
class DegradationPreferenceProvider {
public:
virtual ~DegradationPreferenceProvider();

View file

@ -27,34 +27,34 @@ namespace webrtc {
ResourceAdaptationProcessor::ResourceListenerDelegate::ResourceListenerDelegate(
ResourceAdaptationProcessor* processor)
: resource_adaptation_queue_(nullptr), processor_(processor) {}
: task_queue_(nullptr), processor_(processor) {}
void ResourceAdaptationProcessor::ResourceListenerDelegate::
SetResourceAdaptationQueue(TaskQueueBase* resource_adaptation_queue) {
RTC_DCHECK(!resource_adaptation_queue_);
RTC_DCHECK(resource_adaptation_queue);
resource_adaptation_queue_ = resource_adaptation_queue;
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
void ResourceAdaptationProcessor::ResourceListenerDelegate::SetTaskQueue(
TaskQueueBase* task_queue) {
RTC_DCHECK(!task_queue_);
RTC_DCHECK(task_queue);
task_queue_ = task_queue;
RTC_DCHECK_RUN_ON(task_queue_);
}
void ResourceAdaptationProcessor::ResourceListenerDelegate::
OnProcessorDestroyed() {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
processor_ = nullptr;
}
void ResourceAdaptationProcessor::ResourceListenerDelegate::
OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource,
ResourceUsageState usage_state) {
if (!resource_adaptation_queue_->IsCurrent()) {
resource_adaptation_queue_->PostTask(ToQueuedTask(
if (!task_queue_->IsCurrent()) {
task_queue_->PostTask(ToQueuedTask(
[this_ref = rtc::scoped_refptr<ResourceListenerDelegate>(this),
resource, usage_state] {
this_ref->OnResourceUsageStateMeasured(resource, usage_state);
}));
return;
}
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
if (processor_) {
processor_->OnResourceUsageStateMeasured(resource, usage_state);
}
@ -70,7 +70,7 @@ ResourceAdaptationProcessor::MitigationResultAndLogMessage::
ResourceAdaptationProcessor::ResourceAdaptationProcessor(
VideoStreamAdapter* stream_adapter)
: resource_adaptation_queue_(nullptr),
: task_queue_(nullptr),
resource_listener_delegate_(
new rtc::RefCountedObject<ResourceListenerDelegate>(this)),
resources_(),
@ -81,7 +81,7 @@ ResourceAdaptationProcessor::ResourceAdaptationProcessor(
}
ResourceAdaptationProcessor::~ResourceAdaptationProcessor() {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
RTC_DCHECK(resources_.empty())
<< "There are resource(s) attached to a ResourceAdaptationProcessor "
<< "being destroyed.";
@ -89,30 +89,29 @@ ResourceAdaptationProcessor::~ResourceAdaptationProcessor() {
resource_listener_delegate_->OnProcessorDestroyed();
}
void ResourceAdaptationProcessor::SetResourceAdaptationQueue(
TaskQueueBase* resource_adaptation_queue) {
RTC_DCHECK(!resource_adaptation_queue_);
RTC_DCHECK(resource_adaptation_queue);
resource_adaptation_queue_ = resource_adaptation_queue;
resource_listener_delegate_->SetResourceAdaptationQueue(
resource_adaptation_queue);
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
// Now that we have the adaptation queue we can attach as adaptation listener.
void ResourceAdaptationProcessor::SetTaskQueue(TaskQueueBase* task_queue) {
RTC_DCHECK(!task_queue_);
RTC_DCHECK(task_queue);
task_queue_ = task_queue;
resource_listener_delegate_->SetTaskQueue(task_queue);
RTC_DCHECK_RUN_ON(task_queue_);
// Now that we have the queue we can attach as adaptation listener.
stream_adapter_->AddRestrictionsListener(this);
}
void ResourceAdaptationProcessor::AddResourceLimitationsListener(
ResourceLimitationsListener* limitations_listener) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
RTC_DCHECK(std::find(resource_limitations_listeners_.begin(),
resource_limitations_listeners_.end(),
limitations_listener) ==
resource_limitations_listeners_.end());
resource_limitations_listeners_.push_back(limitations_listener);
}
void ResourceAdaptationProcessor::RemoveResourceLimitationsListener(
ResourceLimitationsListener* limitations_listener) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
auto it =
std::find(resource_limitations_listeners_.begin(),
resource_limitations_listeners_.end(), limitations_listener);
@ -155,12 +154,12 @@ void ResourceAdaptationProcessor::RemoveResource(
void ResourceAdaptationProcessor::RemoveLimitationsImposedByResource(
rtc::scoped_refptr<Resource> resource) {
if (!resource_adaptation_queue_->IsCurrent()) {
resource_adaptation_queue_->PostTask(ToQueuedTask(
if (!task_queue_->IsCurrent()) {
task_queue_->PostTask(ToQueuedTask(
[this, resource]() { RemoveLimitationsImposedByResource(resource); }));
return;
}
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
auto resource_adaptation_limits =
adaptation_limits_by_resources_.find(resource);
if (resource_adaptation_limits != adaptation_limits_by_resources_.end()) {
@ -198,7 +197,7 @@ void ResourceAdaptationProcessor::RemoveLimitationsImposedByResource(
void ResourceAdaptationProcessor::OnResourceUsageStateMeasured(
rtc::scoped_refptr<Resource> resource,
ResourceUsageState usage_state) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
RTC_DCHECK(resource);
// |resource| could have been removed after signalling.
{
@ -240,7 +239,7 @@ void ResourceAdaptationProcessor::OnResourceUsageStateMeasured(
ResourceAdaptationProcessor::MitigationResultAndLogMessage
ResourceAdaptationProcessor::OnResourceUnderuse(
rtc::scoped_refptr<Resource> reason_resource) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
// How can this stream be adapted up?
Adaptation adaptation = stream_adapter_->GetAdaptationUp();
if (adaptation.status() != Adaptation::Status::kValid) {
@ -296,7 +295,7 @@ ResourceAdaptationProcessor::OnResourceUnderuse(
ResourceAdaptationProcessor::MitigationResultAndLogMessage
ResourceAdaptationProcessor::OnResourceOveruse(
rtc::scoped_refptr<Resource> reason_resource) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
// How can this stream be adapted up?
Adaptation adaptation = stream_adapter_->GetAdaptationDown();
if (adaptation.status() == Adaptation::Status::kLimitReached) {
@ -375,7 +374,7 @@ void ResourceAdaptationProcessor::OnVideoSourceRestrictionsUpdated(
const VideoAdaptationCounters& adaptation_counters,
rtc::scoped_refptr<Resource> reason,
const VideoSourceRestrictions& unfiltered_restrictions) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(task_queue_);
if (reason) {
UpdateResourceLimitations(reason, unfiltered_restrictions,
adaptation_counters);

View file

@ -58,8 +58,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
VideoStreamAdapter* video_stream_adapter);
~ResourceAdaptationProcessor() override;
void SetResourceAdaptationQueue(
TaskQueueBase* resource_adaptation_queue) override;
void SetTaskQueue(TaskQueueBase* task_queue) override;
// ResourceAdaptationProcessorInterface implementation.
void AddResourceLimitationsListener(
@ -91,7 +90,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
public:
explicit ResourceListenerDelegate(ResourceAdaptationProcessor* processor);
void SetResourceAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
void SetTaskQueue(TaskQueueBase* task_queue);
void OnProcessorDestroyed();
// ResourceListener implementation.
@ -99,9 +98,8 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
ResourceUsageState usage_state) override;
private:
TaskQueueBase* resource_adaptation_queue_;
ResourceAdaptationProcessor* processor_
RTC_GUARDED_BY(resource_adaptation_queue_);
TaskQueueBase* task_queue_;
ResourceAdaptationProcessor* processor_ RTC_GUARDED_BY(task_queue_);
};
enum class MitigationResult {
@ -129,7 +127,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
void UpdateResourceLimitations(rtc::scoped_refptr<Resource> reason_resource,
const VideoSourceRestrictions& restrictions,
const VideoAdaptationCounters& counters)
RTC_RUN_ON(resource_adaptation_queue_);
RTC_RUN_ON(task_queue_);
// Searches |adaptation_limits_by_resources_| for each resource with the
// highest total adaptation counts. Adaptation up may only occur if the
@ -138,33 +136,31 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
// corresponding adaptation of that resource.
std::pair<std::vector<rtc::scoped_refptr<Resource>>,
VideoStreamAdapter::RestrictionsWithCounters>
FindMostLimitedResources() const RTC_RUN_ON(resource_adaptation_queue_);
FindMostLimitedResources() const RTC_RUN_ON(task_queue_);
void RemoveLimitationsImposedByResource(
rtc::scoped_refptr<Resource> resource);
TaskQueueBase* resource_adaptation_queue_;
TaskQueueBase* task_queue_;
rtc::scoped_refptr<ResourceListenerDelegate> resource_listener_delegate_;
// Input and output.
mutable Mutex resources_lock_;
std::vector<rtc::scoped_refptr<Resource>> resources_
RTC_GUARDED_BY(resources_lock_);
std::vector<ResourceLimitationsListener*> resource_limitations_listeners_
RTC_GUARDED_BY(resource_adaptation_queue_);
RTC_GUARDED_BY(task_queue_);
// Purely used for statistics, does not ensure mapped resources stay alive.
std::map<rtc::scoped_refptr<Resource>,
VideoStreamAdapter::RestrictionsWithCounters>
adaptation_limits_by_resources_
RTC_GUARDED_BY(resource_adaptation_queue_);
adaptation_limits_by_resources_ RTC_GUARDED_BY(task_queue_);
// Responsible for generating and applying possible adaptations.
VideoStreamAdapter* const stream_adapter_
RTC_GUARDED_BY(resource_adaptation_queue_);
VideoStreamAdapter* const stream_adapter_ RTC_GUARDED_BY(task_queue_);
VideoSourceRestrictions last_reported_source_restrictions_
RTC_GUARDED_BY(resource_adaptation_queue_);
RTC_GUARDED_BY(task_queue_);
// Keeps track of previous mitigation results per resource since the last
// successful adaptation. Used to avoid RTC_LOG spam.
std::map<Resource*, MitigationResult> previous_mitigation_results_
RTC_GUARDED_BY(resource_adaptation_queue_);
RTC_GUARDED_BY(task_queue_);
};
} // namespace webrtc

View file

@ -47,8 +47,7 @@ class ResourceAdaptationProcessorInterface {
public:
virtual ~ResourceAdaptationProcessorInterface();
virtual void SetResourceAdaptationQueue(
TaskQueueBase* resource_adaptation_queue) = 0;
virtual void SetTaskQueue(TaskQueueBase* task_queue) = 0;
virtual void AddResourceLimitationsListener(
ResourceLimitationsListener* limitations_listener) = 0;

View file

@ -93,7 +93,7 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
&frame_rate_provider_)),
processor_(std::make_unique<ResourceAdaptationProcessor>(
video_stream_adapter_.get())) {
processor_->SetResourceAdaptationQueue(TaskQueueBase::Current());
processor_->SetTaskQueue(TaskQueueBase::Current());
video_stream_adapter_->AddRestrictionsListener(&restrictions_listener_);
processor_->AddResource(resource_);
processor_->AddResource(other_resource_);

View file

@ -9,7 +9,9 @@
*/
#include <string>
#include <utility>
#include "rtc_base/synchronization/sequence_checker.h"
#include "rtc_base/task_utils/to_queued_task.h"
#include "video/adaptation/balanced_constraint.h"
@ -17,32 +19,23 @@ namespace webrtc {
BalancedConstraint::BalancedConstraint(
DegradationPreferenceProvider* degradation_preference_provider)
: resource_adaptation_queue_(nullptr),
encoder_target_bitrate_bps_(absl::nullopt),
: encoder_target_bitrate_bps_(absl::nullopt),
degradation_preference_provider_(degradation_preference_provider) {
RTC_DCHECK(degradation_preference_provider_);
}
void BalancedConstraint::SetAdaptationQueue(
TaskQueueBase* resource_adaptation_queue) {
resource_adaptation_queue_ = resource_adaptation_queue;
sequence_checker_.Detach();
}
void BalancedConstraint::OnEncoderTargetBitrateUpdated(
absl::optional<uint32_t> encoder_target_bitrate_bps) {
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;
}));
RTC_DCHECK_RUN_ON(&sequence_checker_);
encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps);
}
bool BalancedConstraint::IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after) const {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(&sequence_checker_);
// Don't adapt if BalancedDegradationSettings applies and determines this will
// exceed bitrate constraints.
if (degradation_preference_provider_->degradation_preference() ==

View file

@ -14,21 +14,19 @@
#include <string>
#include "absl/types/optional.h"
#include "api/task_queue/task_queue_base.h"
#include "call/adaptation/adaptation_constraint.h"
#include "call/adaptation/degradation_preference_provider.h"
#include "rtc_base/experiments/balanced_degradation_settings.h"
#include "rtc_base/synchronization/sequence_checker.h"
namespace webrtc {
class BalancedConstraint : public rtc::RefCountInterface,
public AdaptationConstraint {
class BalancedConstraint : public AdaptationConstraint {
public:
explicit BalancedConstraint(
DegradationPreferenceProvider* degradation_preference_provider);
~BalancedConstraint() override = default;
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
void OnEncoderTargetBitrateUpdated(
absl::optional<uint32_t> encoder_target_bitrate_bps);
@ -40,11 +38,11 @@ class BalancedConstraint : public rtc::RefCountInterface,
const VideoSourceRestrictions& restrictions_after) const override;
private:
TaskQueueBase* resource_adaptation_queue_;
SequenceChecker sequence_checker_;
absl::optional<uint32_t> encoder_target_bitrate_bps_
RTC_GUARDED_BY(resource_adaptation_queue_);
BalancedDegradationSettings balanced_settings_;
DegradationPreferenceProvider* degradation_preference_provider_;
RTC_GUARDED_BY(&sequence_checker_);
const BalancedDegradationSettings balanced_settings_;
const DegradationPreferenceProvider* degradation_preference_provider_;
};
} // namespace webrtc

View file

@ -12,46 +12,34 @@
#include <utility>
#include "call/adaptation/video_stream_adapter.h"
#include "rtc_base/task_utils/to_queued_task.h"
#include "rtc_base/synchronization/sequence_checker.h"
#include "video/adaptation/bitrate_constraint.h"
namespace webrtc {
BitrateConstraint::BitrateConstraint()
: resource_adaptation_queue_(nullptr),
encoder_settings_(absl::nullopt),
encoder_target_bitrate_bps_(absl::nullopt) {}
void BitrateConstraint::SetAdaptationQueue(
TaskQueueBase* resource_adaptation_queue) {
resource_adaptation_queue_ = resource_adaptation_queue;
: encoder_settings_(absl::nullopt),
encoder_target_bitrate_bps_(absl::nullopt) {
sequence_checker_.Detach();
}
void BitrateConstraint::OnEncoderSettingsUpdated(
absl::optional<EncoderSettings> encoder_settings) {
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);
}));
RTC_DCHECK_RUN_ON(&sequence_checker_);
encoder_settings_ = std::move(encoder_settings);
}
void BitrateConstraint::OnEncoderTargetBitrateUpdated(
absl::optional<uint32_t> encoder_target_bitrate_bps) {
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;
}));
RTC_DCHECK_RUN_ON(&sequence_checker_);
encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps);
}
bool BitrateConstraint::IsAdaptationUpAllowed(
const VideoStreamInputState& input_state,
const VideoSourceRestrictions& restrictions_before,
const VideoSourceRestrictions& restrictions_after) const {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(&sequence_checker_);
// Make sure bitrate limits are not violated.
if (DidIncreaseResolution(restrictions_before, restrictions_after)) {
uint32_t bitrate_bps = encoder_target_bitrate_bps_.value_or(0);

View file

@ -14,21 +14,19 @@
#include <string>
#include "absl/types/optional.h"
#include "api/task_queue/task_queue_base.h"
#include "call/adaptation/adaptation_constraint.h"
#include "call/adaptation/encoder_settings.h"
#include "call/adaptation/video_source_restrictions.h"
#include "call/adaptation/video_stream_input_state.h"
#include "rtc_base/synchronization/sequence_checker.h"
namespace webrtc {
class BitrateConstraint : public rtc::RefCountInterface,
public AdaptationConstraint {
class BitrateConstraint : public AdaptationConstraint {
public:
BitrateConstraint();
~BitrateConstraint() override = default;
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
void OnEncoderSettingsUpdated(
absl::optional<EncoderSettings> encoder_settings);
void OnEncoderTargetBitrateUpdated(
@ -42,13 +40,11 @@ class BitrateConstraint : public rtc::RefCountInterface,
const VideoSourceRestrictions& restrictions_after) const override;
private:
// The |manager_| must be alive as long as this resource is added to the
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
TaskQueueBase* resource_adaptation_queue_;
SequenceChecker sequence_checker_;
absl::optional<EncoderSettings> encoder_settings_
RTC_GUARDED_BY(resource_adaptation_queue_);
RTC_GUARDED_BY(&sequence_checker_);
absl::optional<uint32_t> encoder_target_bitrate_bps_
RTC_GUARDED_BY(resource_adaptation_queue_);
RTC_GUARDED_BY(&sequence_checker_);
};
} // namespace webrtc

View file

@ -26,6 +26,7 @@
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/synchronization/sequence_checker.h"
#include "rtc_base/time_utils.h"
namespace webrtc {
@ -136,15 +137,14 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager(
std::unique_ptr<OveruseFrameDetector> overuse_detector,
DegradationPreferenceProvider* degradation_preference_provider)
: degradation_preference_provider_(degradation_preference_provider),
bitrate_constraint_(new rtc::RefCountedObject<BitrateConstraint>()),
balanced_constraint_(new rtc::RefCountedObject<BalancedConstraint>(
bitrate_constraint_(std::make_unique<BitrateConstraint>()),
balanced_constraint_(std::make_unique<BalancedConstraint>(
degradation_preference_provider_)),
encode_usage_resource_(
EncodeUsageResource::Create(std::move(overuse_detector))),
quality_scaler_resource_(
QualityScalerResource::Create(degradation_preference_provider_)),
encoder_queue_(nullptr),
resource_adaptation_queue_(nullptr),
input_state_provider_(input_state_provider),
adaptation_processor_(nullptr),
encoder_stats_observer_(encoder_stats_observer),
@ -158,27 +158,20 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager(
encoder_target_bitrate_bps_(absl::nullopt),
quality_rampup_experiment_(
QualityRampUpExperimentHelper::CreateIfEnabled(this, clock_)),
encoder_settings_(absl::nullopt) {
encoder_settings_(absl::nullopt),
resources_{{encode_usage_resource_, VideoAdaptationReason::kCpu},
{quality_scaler_resource_, VideoAdaptationReason::kQuality}} {
RTC_CHECK(degradation_preference_provider_);
RTC_CHECK(encoder_stats_observer_);
MapResourceToReason(encode_usage_resource_, VideoAdaptationReason::kCpu);
MapResourceToReason(quality_scaler_resource_,
VideoAdaptationReason::kQuality);
}
VideoStreamEncoderResourceManager::~VideoStreamEncoderResourceManager() {}
void VideoStreamEncoderResourceManager::Initialize(
rtc::TaskQueue* encoder_queue,
rtc::TaskQueue* resource_adaptation_queue) {
rtc::TaskQueue* encoder_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;
bitrate_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
balanced_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
encode_usage_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
quality_scaler_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
}
@ -186,7 +179,7 @@ void VideoStreamEncoderResourceManager::Initialize(
void VideoStreamEncoderResourceManager::SetAdaptationProcessor(
ResourceAdaptationProcessorInterface* adaptation_processor,
VideoStreamAdapter* stream_adapter) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(encoder_queue_);
adaptation_processor_ = adaptation_processor;
stream_adapter_ = stream_adapter;
}
@ -222,7 +215,7 @@ void VideoStreamEncoderResourceManager::StopManagedResources() {
void VideoStreamEncoderResourceManager::MapResourceToReason(
rtc::scoped_refptr<Resource> resource,
VideoAdaptationReason reason) {
MutexLock lock(&resource_lock_);
RTC_DCHECK_RUN_ON(encoder_queue_);
RTC_DCHECK(resource);
RTC_DCHECK(absl::c_find_if(resources_,
[resource](const ResourceAndReason& r) {
@ -234,7 +227,7 @@ void VideoStreamEncoderResourceManager::MapResourceToReason(
std::vector<rtc::scoped_refptr<Resource>>
VideoStreamEncoderResourceManager::MappedResources() const {
MutexLock lock(&resource_lock_);
RTC_DCHECK_RUN_ON(encoder_queue_);
std::vector<rtc::scoped_refptr<Resource>> resources;
for (auto const& resource_and_reason : resources_) {
resources.push_back(resource_and_reason.resource);
@ -244,12 +237,13 @@ VideoStreamEncoderResourceManager::MappedResources() const {
std::vector<AdaptationConstraint*>
VideoStreamEncoderResourceManager::AdaptationConstraints() const {
return {bitrate_constraint_, balanced_constraint_};
RTC_DCHECK_RUN_ON(encoder_queue_);
return {bitrate_constraint_.get(), balanced_constraint_.get()};
}
rtc::scoped_refptr<QualityScalerResource>
VideoStreamEncoderResourceManager::quality_scaler_resource_for_testing() {
MutexLock lock(&resource_lock_);
RTC_DCHECK_RUN_ON(encoder_queue_);
return quality_scaler_resource_;
}
@ -297,24 +291,12 @@ void VideoStreamEncoderResourceManager::SetEncoderRates(
void VideoStreamEncoderResourceManager::OnFrameDroppedDueToSize() {
RTC_DCHECK_RUN_ON(encoder_queue_);
// The VideoStreamEncoder makes the manager outlive the adaptation queue. This
// means that if the task gets executed, |this| has not been freed yet.
// TODO(https://crbug.com/webrtc/11565): When the manager no longer outlives
// the adaptation queue, add logic to prevent use-after-free on |this|.
resource_adaptation_queue_->PostTask([this] {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
if (!adaptation_processor_) {
// The processor nulled before this task had a chance to execute. This
// happens if the processor is destroyed. No action needed.
return;
}
Adaptation reduce_resolution = stream_adapter_->GetAdaptDownResolution();
if (reduce_resolution.status() == Adaptation::Status::kValid) {
stream_adapter_->ApplyAdaptation(reduce_resolution,
quality_scaler_resource_);
}
});
initial_frame_dropper_->OnFrameDroppedDueToSize();
Adaptation reduce_resolution = stream_adapter_->GetAdaptDownResolution();
if (reduce_resolution.status() == Adaptation::Status::kValid) {
stream_adapter_->ApplyAdaptation(reduce_resolution,
quality_scaler_resource_);
}
}
void VideoStreamEncoderResourceManager::OnEncodeStarted(
@ -422,7 +404,7 @@ void VideoStreamEncoderResourceManager::ConfigureQualityScaler(
VideoAdaptationReason VideoStreamEncoderResourceManager::GetReasonFromResource(
rtc::scoped_refptr<Resource> resource) const {
MutexLock lock(&resource_lock_);
RTC_DCHECK_RUN_ON(encoder_queue_);
const auto& registered_resource =
absl::c_find_if(resources_, [&resource](const ResourceAndReason& r) {
return r.resource == resource;
@ -466,28 +448,23 @@ void VideoStreamEncoderResourceManager::OnVideoSourceRestrictionsUpdated(
const VideoAdaptationCounters& adaptation_counters,
rtc::scoped_refptr<Resource> reason,
const VideoSourceRestrictions& unfiltered_restrictions) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(encoder_queue_);
// TODO(bugs.webrtc.org/11553) Remove reason parameter and add reset callback.
if (!reason && adaptation_counters.Total() == 0) {
// Adaptation was manually reset - clear the per-reason counters too.
encoder_stats_observer_->ClearAdaptationStats();
}
// The VideoStreamEncoder makes the manager outlive the encoder queue. This
// means that if the task gets executed, |this| has not been freed yet.
encoder_queue_->PostTask([this, restrictions] {
RTC_DCHECK_RUN_ON(encoder_queue_);
video_source_restrictions_ = FilterRestrictionsByDegradationPreference(
restrictions, degradation_preference_);
MaybeUpdateTargetFrameRate();
});
video_source_restrictions_ = FilterRestrictionsByDegradationPreference(
restrictions, degradation_preference_);
MaybeUpdateTargetFrameRate();
}
void VideoStreamEncoderResourceManager::OnResourceLimitationChanged(
rtc::scoped_refptr<Resource> resource,
const std::map<rtc::scoped_refptr<Resource>, VideoAdaptationCounters>&
resource_limitations) {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(encoder_queue_);
if (!resource) {
encoder_stats_observer_->ClearAdaptationStats();
return;
@ -509,19 +486,14 @@ void VideoStreamEncoderResourceManager::OnResourceLimitationChanged(
adaptation_reason, limitations[VideoAdaptationReason::kCpu],
limitations[VideoAdaptationReason::kQuality]);
encoder_queue_->PostTask(ToQueuedTask(
[cpu_limited = limitations.at(VideoAdaptationReason::kCpu).Total() > 0,
qp_resolution_adaptations =
limitations.at(VideoAdaptationReason::kQuality)
.resolution_adaptations,
this]() {
RTC_DCHECK_RUN_ON(encoder_queue_);
if (quality_rampup_experiment_) {
quality_rampup_experiment_->cpu_adapted(cpu_limited);
quality_rampup_experiment_->qp_resolution_adaptations(
qp_resolution_adaptations);
}
}));
if (quality_rampup_experiment_) {
bool cpu_limited = limitations.at(VideoAdaptationReason::kCpu).Total() > 0;
auto qp_resolution_adaptations =
limitations.at(VideoAdaptationReason::kQuality).resolution_adaptations;
quality_rampup_experiment_->cpu_adapted(cpu_limited);
quality_rampup_experiment_->qp_resolution_adaptations(
qp_resolution_adaptations);
}
RTC_LOG(LS_INFO) << ActiveCountsToString(limitations);
}
@ -584,19 +556,7 @@ std::string VideoStreamEncoderResourceManager::ActiveCountsToString(
void VideoStreamEncoderResourceManager::OnQualityRampUp() {
RTC_DCHECK_RUN_ON(encoder_queue_);
// The VideoStreamEncoder makes the manager outlive the adaptation queue.
// This means that if the task gets executed, |this| has not been freed yet.
// TODO(https://crbug.com/webrtc/11565): When the manager no longer outlives
// the adaptation queue, add logic to prevent use-after-free on |this|.
resource_adaptation_queue_->PostTask([this] {
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
if (!stream_adapter_) {
// The processor nulled before this task had a chance to execute. This
// happens if the processor is destroyed. No action needed.
return;
}
stream_adapter_->ClearRestrictions();
});
stream_adapter_->ClearRestrictions();
quality_rampup_experiment_.reset();
}
} // namespace webrtc

View file

@ -40,6 +40,7 @@
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/thread_annotations.h"
#include "system_wrappers/include/clock.h"
#include "video/adaptation/balanced_constraint.h"
#include "video/adaptation/bitrate_constraint.h"
@ -79,8 +80,7 @@ class VideoStreamEncoderResourceManager
DegradationPreferenceProvider* degradation_preference_provider);
~VideoStreamEncoderResourceManager() override;
void Initialize(rtc::TaskQueue* encoder_queue,
rtc::TaskQueue* resource_adaptation_queue);
void Initialize(rtc::TaskQueue* encoder_queue);
void SetAdaptationProcessor(
ResourceAdaptationProcessorInterface* adaptation_processor,
VideoStreamAdapter* stream_adapter);
@ -166,19 +166,19 @@ class VideoStreamEncoderResourceManager
active_counts);
DegradationPreferenceProvider* const degradation_preference_provider_;
const rtc::scoped_refptr<BitrateConstraint> bitrate_constraint_;
const rtc::scoped_refptr<BalancedConstraint> balanced_constraint_;
std::unique_ptr<BitrateConstraint> bitrate_constraint_
RTC_GUARDED_BY(encoder_queue_);
const std::unique_ptr<BalancedConstraint> balanced_constraint_
RTC_GUARDED_BY(encoder_queue_);
const rtc::scoped_refptr<EncodeUsageResource> encode_usage_resource_;
const rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource_;
rtc::TaskQueue* encoder_queue_;
rtc::TaskQueue* resource_adaptation_queue_;
VideoStreamInputStateProvider* const input_state_provider_
RTC_GUARDED_BY(encoder_queue_);
ResourceAdaptationProcessorInterface* adaptation_processor_
RTC_GUARDED_BY(resource_adaptation_queue_);
VideoStreamAdapter* stream_adapter_
RTC_GUARDED_BY(resource_adaptation_queue_);
RTC_GUARDED_BY(encoder_queue_);
VideoStreamAdapter* stream_adapter_ RTC_GUARDED_BY(encoder_queue_);
// Thread-safe.
VideoStreamEncoderObserver* const encoder_stats_observer_;
@ -212,8 +212,7 @@ class VideoStreamEncoderResourceManager
const rtc::scoped_refptr<Resource> resource;
const VideoAdaptationReason reason;
};
mutable Mutex resource_lock_;
std::vector<ResourceAndReason> resources_ RTC_GUARDED_BY(&resource_lock_);
std::vector<ResourceAndReason> resources_ RTC_GUARDED_BY(encoder_queue_);
};
} // namespace webrtc

View file

@ -211,48 +211,38 @@ bool VideoStreamEncoder::EncoderRateSettings::operator!=(
class VideoStreamEncoder::DegradationPreferenceManager
: public DegradationPreferenceProvider {
public:
DegradationPreferenceManager()
explicit DegradationPreferenceManager(
VideoStreamAdapter* video_stream_adapter)
: degradation_preference_(DegradationPreference::DISABLED),
is_screenshare_(false),
effective_degradation_preference_(DegradationPreference::DISABLED) {}
~DegradationPreferenceManager() override {
RTC_DCHECK(!video_stream_adapter_);
effective_degradation_preference_(DegradationPreference::DISABLED),
video_stream_adapter_(video_stream_adapter) {
RTC_DCHECK(video_stream_adapter_);
sequence_checker_.Detach();
}
~DegradationPreferenceManager() override = default;
DegradationPreference degradation_preference() const override {
MutexLock lock(&lock_);
RTC_DCHECK_RUN_ON(&sequence_checker_);
return effective_degradation_preference_;
}
void SetDegradationPreference(DegradationPreference degradation_preference) {
MutexLock lock(&lock_);
RTC_DCHECK_RUN_ON(&sequence_checker_);
degradation_preference_ = degradation_preference;
MaybeUpdateEffectiveDegradationPreference();
}
void SetIsScreenshare(bool is_screenshare) {
MutexLock lock(&lock_);
RTC_DCHECK_RUN_ON(&sequence_checker_);
is_screenshare_ = is_screenshare;
MaybeUpdateEffectiveDegradationPreference();
}
void SetVideoStreamAdapterQueue(
TaskQueueBase* video_stream_adapter_task_queue) {
RTC_DCHECK(!video_stream_adapter_task_queue_);
RTC_DCHECK(video_stream_adapter_task_queue);
RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue);
video_stream_adapter_task_queue_ = video_stream_adapter_task_queue;
}
void SetVideoStreamAdapter(VideoStreamAdapter* video_stream_adapter) {
RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue_);
video_stream_adapter_ = video_stream_adapter;
}
private:
void MaybeUpdateEffectiveDegradationPreference()
RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_) {
RTC_RUN_ON(&sequence_checker_) {
DegradationPreference effective_degradation_preference =
(is_screenshare_ &&
degradation_preference_ == DegradationPreference::BALANCED)
@ -261,27 +251,18 @@ class VideoStreamEncoder::DegradationPreferenceManager
if (effective_degradation_preference != effective_degradation_preference_) {
effective_degradation_preference_ = effective_degradation_preference;
if (video_stream_adapter_task_queue_) {
video_stream_adapter_task_queue_->PostTask(
ToQueuedTask([this, effective_degradation_preference]() {
RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue_);
if (video_stream_adapter_) {
video_stream_adapter_->SetDegradationPreference(
effective_degradation_preference);
}
}));
}
video_stream_adapter_->SetDegradationPreference(
effective_degradation_preference);
}
}
mutable Mutex lock_;
DegradationPreference degradation_preference_ RTC_GUARDED_BY(&lock_);
bool is_screenshare_ RTC_GUARDED_BY(&lock_);
SequenceChecker sequence_checker_;
DegradationPreference degradation_preference_
RTC_GUARDED_BY(&sequence_checker_);
bool is_screenshare_ RTC_GUARDED_BY(&sequence_checker_);
DegradationPreference effective_degradation_preference_
RTC_GUARDED_BY(&lock_);
TaskQueueBase* video_stream_adapter_task_queue_ = nullptr;
VideoStreamAdapter* video_stream_adapter_
RTC_GUARDED_BY(&video_stream_adapter_task_queue_);
RTC_GUARDED_BY(&sequence_checker_);
VideoStreamAdapter* video_stream_adapter_ RTC_GUARDED_BY(&sequence_checker_);
};
VideoStreamEncoder::VideoStreamEncoder(
@ -346,7 +327,8 @@ VideoStreamEncoder::VideoStreamEncoder(
std::make_unique<ResourceAdaptationProcessor>(
video_stream_adapter_.get())),
degradation_preference_manager_(
std::make_unique<DegradationPreferenceManager>()),
std::make_unique<DegradationPreferenceManager>(
video_stream_adapter_.get())),
adaptation_constraints_(),
stream_resource_manager_(&input_state_provider_,
encoder_stats_observer,
@ -356,33 +338,24 @@ VideoStreamEncoder::VideoStreamEncoder(
degradation_preference_manager_.get()),
video_source_sink_controller_(/*sink=*/this,
/*source=*/nullptr),
resource_adaptation_queue_(task_queue_factory->CreateTaskQueue(
"ResourceAdaptationQueue",
TaskQueueFactory::Priority::NORMAL)),
encoder_queue_(task_queue_factory->CreateTaskQueue(
"EncoderQueue",
TaskQueueFactory::Priority::NORMAL)) {
RTC_DCHECK(encoder_stats_observer);
RTC_DCHECK_GE(number_of_cores, 1);
stream_resource_manager_.Initialize(&encoder_queue_,
&resource_adaptation_queue_);
stream_resource_manager_.Initialize(&encoder_queue_);
rtc::Event initialize_processor_event;
resource_adaptation_queue_.PostTask([this, &initialize_processor_event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
resource_adaptation_processor_->SetResourceAdaptationQueue(
resource_adaptation_queue_.Get());
encoder_queue_.PostTask([this, &initialize_processor_event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
resource_adaptation_processor_->SetTaskQueue(encoder_queue_.Get());
stream_resource_manager_.SetAdaptationProcessor(
resource_adaptation_processor_.get(), video_stream_adapter_.get());
resource_adaptation_processor_->AddResourceLimitationsListener(
&stream_resource_manager_);
video_stream_adapter_->AddRestrictionsListener(&stream_resource_manager_);
video_stream_adapter_->AddRestrictionsListener(this);
degradation_preference_manager_->SetVideoStreamAdapterQueue(
resource_adaptation_queue_.Get());
degradation_preference_manager_->SetVideoStreamAdapter(
video_stream_adapter_.get());
// Add the stream resource manager's resources to the processor.
adaptation_constraints_ = stream_resource_manager_.AdaptationConstraints();
@ -407,19 +380,12 @@ void VideoStreamEncoder::Stop() {
RTC_DCHECK_RUN_ON(&thread_checker_);
video_source_sink_controller_.SetSource(nullptr);
if (resource_adaptation_processor_) {
for (auto& resource : stream_resource_manager_.MappedResources()) {
resource_adaptation_processor_->RemoveResource(resource);
}
}
rtc::Event shutdown_adaptation_processor_event;
resource_adaptation_queue_.PostTask([this,
&shutdown_adaptation_processor_event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
encoder_queue_.PostTask([this] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
if (resource_adaptation_processor_) {
// Removed on the resource_adaptaiton_processor_ queue because the
// adaptation_constraints_ and adaptation_listeners_ fields are guarded by
// this queue.
for (auto& resource : stream_resource_manager_.MappedResources()) {
resource_adaptation_processor_->RemoveResource(resource);
}
for (auto* constraint : adaptation_constraints_) {
video_stream_adapter_->RemoveAdaptationConstraint(constraint);
}
@ -429,14 +395,8 @@ void VideoStreamEncoder::Stop() {
resource_adaptation_processor_->RemoveResourceLimitationsListener(
&stream_resource_manager_);
stream_resource_manager_.SetAdaptationProcessor(nullptr, nullptr);
degradation_preference_manager_->SetVideoStreamAdapter(nullptr);
resource_adaptation_processor_.reset();
}
shutdown_adaptation_processor_event.Set();
});
shutdown_adaptation_processor_event.Wait(rtc::Event::kForever);
encoder_queue_.PostTask([this] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
stream_resource_manager_.StopManagedResources();
rate_allocator_ = nullptr;
bitrate_observer_ = nullptr;
@ -496,11 +456,11 @@ void VideoStreamEncoder::SetSource(
video_source_sink_controller_.SetSource(source);
input_state_provider_.OnHasInputChanged(source);
degradation_preference_manager_->SetDegradationPreference(
degradation_preference);
// This may trigger reconfiguring the QualityScaler on the encoder queue.
encoder_queue_.PostTask([this, degradation_preference] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
degradation_preference_manager_->SetDegradationPreference(
degradation_preference);
stream_resource_manager_.SetDegradationPreferences(degradation_preference);
if (encoder_) {
stream_resource_manager_.ConfigureQualityScaler(
@ -1809,7 +1769,7 @@ void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated(
const VideoAdaptationCounters& adaptation_counters,
rtc::scoped_refptr<Resource> reason,
const VideoSourceRestrictions& unfiltered_restrictions) {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
RTC_DCHECK_RUN_ON(&encoder_queue_);
std::string resource_name = reason ? reason->Name() : "<null>";
RTC_LOG(INFO) << "Updating sink restrictions from " << resource_name << " to "
<< restrictions.ToString();
@ -2095,8 +2055,8 @@ void VideoStreamEncoder::InjectAdaptationResource(
void VideoStreamEncoder::InjectAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) {
rtc::Event event;
resource_adaptation_queue_.PostTask([this, adaptation_constraint, &event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
encoder_queue_.PostTask([this, adaptation_constraint, &event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
if (!resource_adaptation_processor_) {
// The VideoStreamEncoder was stopped and the processor destroyed before
// this task had a chance to execute. No action needed.
@ -2118,8 +2078,8 @@ VideoStreamEncoder::quality_scaler_resource_for_testing() {
void VideoStreamEncoder::AddRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener) {
rtc::Event event;
resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
encoder_queue_.PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
RTC_DCHECK(resource_adaptation_processor_);
video_stream_adapter_->AddRestrictionsListener(restrictions_listener);
event.Set();
@ -2130,8 +2090,8 @@ void VideoStreamEncoder::AddRestrictionsListenerForTesting(
void VideoStreamEncoder::RemoveRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener) {
rtc::Event event;
resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
encoder_queue_.PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
RTC_DCHECK(resource_adaptation_processor_);
video_stream_adapter_->RemoveRestrictionsListener(restrictions_listener);
event.Set();

View file

@ -40,6 +40,7 @@
#include "rtc_base/rate_statistics.h"
#include "rtc_base/synchronization/sequence_checker.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/thread_checker.h"
#include "system_wrappers/include/clock.h"
#include "video/adaptation/video_stream_encoder_resource_manager.h"
@ -112,9 +113,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// Used for testing. For example the |ScalingObserverInterface| methods must
// be called on |encoder_queue_|.
rtc::TaskQueue* encoder_queue() { return &encoder_queue_; }
rtc::TaskQueue* resource_adaptation_queue() {
return &resource_adaptation_queue_;
}
void OnVideoSourceRestrictionsUpdated(
VideoSourceRestrictions restrictions,
@ -410,24 +408,24 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
VideoStreamInputStateProvider input_state_provider_;
std::unique_ptr<VideoStreamAdapter> video_stream_adapter_
RTC_GUARDED_BY(&resource_adaptation_queue_);
RTC_GUARDED_BY(&encoder_queue_);
// Responsible for adapting input resolution or frame rate to ensure resources
// (e.g. CPU or bandwidth) are not overused.
// Adding resources can occur on any thread, but all other methods need to be
// called on the adaptation thread.
// (e.g. CPU or bandwidth) are not overused. Adding resources can occur on any
// thread.
std::unique_ptr<ResourceAdaptationProcessorInterface>
resource_adaptation_processor_;
std::unique_ptr<DegradationPreferenceManager> degradation_preference_manager_;
std::unique_ptr<DegradationPreferenceManager> degradation_preference_manager_
RTC_GUARDED_BY(&encoder_queue_);
std::vector<AdaptationConstraint*> adaptation_constraints_
RTC_GUARDED_BY(&resource_adaptation_queue_);
RTC_GUARDED_BY(&encoder_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
// dropping.
// The manager primarily operates on the |encoder_queue_| but its lifetime is
// tied to the VideoStreamEncoder (which is destroyed off the encoder queue)
// and its resource list is accessible from any thread.
VideoStreamEncoderResourceManager stream_resource_manager_;
// tied to the VideoStreamEncoder (which is destroyed off the encoder queue).
VideoStreamEncoderResourceManager stream_resource_manager_
RTC_GUARDED_BY(&encoder_queue_);
// Carries out the VideoSourceRestrictions provided by the
// ResourceAdaptationProcessor, i.e. reconfigures the source of video frames
// to provide us with different resolution or frame rate.
@ -436,10 +434,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// Public methods are proxied to the task queues. The queues must be destroyed
// first to make sure no tasks run that use other members.
// TODO(https://crbug.com/webrtc/11172): Move ownership of the
// ResourceAdaptationProcessor and its task queue to Call when processors are
// multi-stream aware.
rtc::TaskQueue resource_adaptation_queue_;
rtc::TaskQueue encoder_queue_;
RTC_DISALLOW_COPY_AND_ASSIGN(VideoStreamEncoder);

View file

@ -329,15 +329,6 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
fraction_lost, round_trip_time_ms, cwnd_reduce_ratio);
// Bitrate is updated on the encoder queue.
WaitUntilTaskQueueIsIdle();
// Give the managed resources time to react to the new bitrate.
// TODO(hbos): Can we await an appropriate event instead?
WaitUntilAdaptationTaskQueueIsIdle();
}
void WaitUntilAdaptationTaskQueueIsIdle() {
rtc::Event event;
resource_adaptation_queue()->PostTask([&event] { event.Set(); });
ASSERT_TRUE(event.Wait(5000));
}
// This is used as a synchronisation mechanism, to make sure that the
@ -351,7 +342,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
// Triggers resource usage measurements on the fake CPU resource.
void TriggerCpuOveruse() {
rtc::Event event;
resource_adaptation_queue()->PostTask([this, &event] {
encoder_queue()->PostTask([this, &event] {
fake_cpu_resource_->SetUsageState(ResourceUsageState::kOveruse);
event.Set();
});
@ -359,7 +350,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
}
void TriggerCpuUnderuse() {
rtc::Event event;
resource_adaptation_queue()->PostTask([this, &event] {
encoder_queue()->PostTask([this, &event] {
fake_cpu_resource_->SetUsageState(ResourceUsageState::kUnderuse);
event.Set();
});
@ -369,7 +360,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
// Triggers resource usage measurements on the fake quality resource.
void TriggerQualityLow() {
rtc::Event event;
resource_adaptation_queue()->PostTask([this, &event] {
encoder_queue()->PostTask([this, &event] {
fake_quality_resource_->SetUsageState(ResourceUsageState::kOveruse);
event.Set();
});
@ -377,7 +368,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
}
void TriggerQualityHigh() {
rtc::Event event;
resource_adaptation_queue()->PostTask([this, &event] {
encoder_queue()->PostTask([this, &event] {
fake_quality_resource_->SetUsageState(ResourceUsageState::kUnderuse);
event.Set();
});
@ -4172,7 +4163,7 @@ TEST_F(VideoStreamEncoderTest,
WaitForEncodedFrame(3);
// Expect the sink_wants to specify a scaled frame.
video_stream_encoder_->WaitUntilAdaptationTaskQueueIsIdle();
video_stream_encoder_->WaitUntilTaskQueueIsIdle();
EXPECT_THAT(video_source_.sink_wants(), ResolutionMax());
video_stream_encoder_->Stop();
@ -4233,7 +4224,7 @@ TEST_F(VideoStreamEncoderTest, RampsUpInQualityWhenBwIsHigh) {
WaitForEncodedFrame(timestamp_ms);
// The ramp-up code involves the adaptation queue, give it time to execute.
// TODO(hbos): Can we await an appropriate event instead?
video_stream_encoder_->WaitUntilAdaptationTaskQueueIsIdle();
video_stream_encoder_->WaitUntilTaskQueueIsIdle();
EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
// Frame should not be adapted.