[Adaptation] Move IsAdaptationUpAllowed/OnAdaptationApplied out of API.
IsAdaptationUpAllowed is moved from Resource to AdaptationConstraint. OnAdaptationApplied is moved from Resource to AdaptationListener. In a future CL, Resource will be moved to api/, but AdaptationConstraint and AdaptationListener will stay in call/. The processor, encode stream and manager are updated to keep track of both resources, constraints and listeners. Fakes and tests are updated. After this CL, the manager's inner classes that prevent adaptation implement AdaptationConstraint instead of Resource. Bug: webrtc:11525 Change-Id: Ie9cd5b1ba7d8e161951e131ab8f6bd9d5cf765bf Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176368 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31409}
This commit is contained in:
parent
a0cf1eabb7
commit
0f0aa9c7a8
@ -10,6 +10,10 @@ import("../../webrtc.gni")
|
|||||||
|
|
||||||
rtc_library("resource_adaptation") {
|
rtc_library("resource_adaptation") {
|
||||||
sources = [
|
sources = [
|
||||||
|
"adaptation_constraint.cc",
|
||||||
|
"adaptation_constraint.h",
|
||||||
|
"adaptation_listener.cc",
|
||||||
|
"adaptation_listener.h",
|
||||||
"encoder_settings.cc",
|
"encoder_settings.cc",
|
||||||
"encoder_settings.h",
|
"encoder_settings.h",
|
||||||
"resource.cc",
|
"resource.cc",
|
||||||
@ -80,6 +84,10 @@ if (rtc_include_tests) {
|
|||||||
testonly = true
|
testonly = true
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
|
"test/fake_adaptation_constraint.cc",
|
||||||
|
"test/fake_adaptation_constraint.h",
|
||||||
|
"test/fake_adaptation_listener.cc",
|
||||||
|
"test/fake_adaptation_listener.h",
|
||||||
"test/fake_frame_rate_provider.cc",
|
"test/fake_frame_rate_provider.cc",
|
||||||
"test/fake_frame_rate_provider.h",
|
"test/fake_frame_rate_provider.h",
|
||||||
"test/fake_resource.cc",
|
"test/fake_resource.cc",
|
||||||
|
|||||||
17
call/adaptation/adaptation_constraint.cc
Normal file
17
call/adaptation/adaptation_constraint.cc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "call/adaptation/adaptation_constraint.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
AdaptationConstraint::~AdaptationConstraint() {}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
43
call/adaptation/adaptation_constraint.h
Normal file
43
call/adaptation/adaptation_constraint.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CALL_ADAPTATION_ADAPTATION_CONSTRAINT_H_
|
||||||
|
#define CALL_ADAPTATION_ADAPTATION_CONSTRAINT_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "api/scoped_refptr.h"
|
||||||
|
#include "call/adaptation/resource.h"
|
||||||
|
#include "call/adaptation/video_source_restrictions.h"
|
||||||
|
#include "call/adaptation/video_stream_input_state.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// Adaptation constraints have the ability to prevent applying a proposed
|
||||||
|
// adaptation (expressed as restrictions before/after adaptation).
|
||||||
|
class AdaptationConstraint {
|
||||||
|
public:
|
||||||
|
virtual ~AdaptationConstraint();
|
||||||
|
|
||||||
|
virtual std::string Name() const = 0;
|
||||||
|
|
||||||
|
// TODO(https://crbug.com/webrtc/11172): When we have multi-stream adaptation
|
||||||
|
// support, this interface needs to indicate which stream the adaptation
|
||||||
|
// applies to.
|
||||||
|
virtual bool IsAdaptationUpAllowed(
|
||||||
|
const VideoStreamInputState& input_state,
|
||||||
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
|
const VideoSourceRestrictions& restrictions_after,
|
||||||
|
rtc::scoped_refptr<Resource> reason_resource) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // CALL_ADAPTATION_ADAPTATION_CONSTRAINT_H_
|
||||||
17
call/adaptation/adaptation_listener.cc
Normal file
17
call/adaptation/adaptation_listener.cc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "call/adaptation/adaptation_listener.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
AdaptationListener::~AdaptationListener() {}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
41
call/adaptation/adaptation_listener.h
Normal file
41
call/adaptation/adaptation_listener.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CALL_ADAPTATION_ADAPTATION_LISTENER_H_
|
||||||
|
#define CALL_ADAPTATION_ADAPTATION_LISTENER_H_
|
||||||
|
|
||||||
|
#include "api/scoped_refptr.h"
|
||||||
|
#include "call/adaptation/resource.h"
|
||||||
|
#include "call/adaptation/video_source_restrictions.h"
|
||||||
|
#include "call/adaptation/video_stream_input_state.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// TODO(hbos): Can this be consolidated with
|
||||||
|
// ResourceAdaptationProcessorListener::OnVideoSourceRestrictionsUpdated()? Both
|
||||||
|
// listen to adaptations being applied, but on different layers with different
|
||||||
|
// arguments.
|
||||||
|
class AdaptationListener {
|
||||||
|
public:
|
||||||
|
virtual ~AdaptationListener();
|
||||||
|
|
||||||
|
// TODO(https://crbug.com/webrtc/11172): When we have multi-stream adaptation
|
||||||
|
// support, this interface needs to indicate which stream the adaptation
|
||||||
|
// applies to.
|
||||||
|
virtual void OnAdaptationApplied(
|
||||||
|
const VideoStreamInputState& input_state,
|
||||||
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
|
const VideoSourceRestrictions& restrictions_after,
|
||||||
|
rtc::scoped_refptr<Resource> reason_resource) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // CALL_ADAPTATION_ADAPTATION_LISTENER_H_
|
||||||
@ -48,8 +48,8 @@ class ResourceListener {
|
|||||||
// kOveruse or kUnderuse when resource usage is high or low enough that we
|
// 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.
|
// should perform some sort of mitigation to fulfil the resource's constraints.
|
||||||
//
|
//
|
||||||
// All methods defined in this interface, except RegisterAdaptationTaskQueue(),
|
// All methods defined in this interface, except SetResourceListener(), MUST be
|
||||||
// MUST be invoked on the resource adaptation task queue.
|
// invoked on the resource adaptation task queue.
|
||||||
//
|
//
|
||||||
// Usage measurements may be performed on an implementation-specific 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
|
// The Resource is reference counted to prevent use-after-free when posting
|
||||||
@ -61,21 +61,9 @@ class Resource : public rtc::RefCountInterface {
|
|||||||
// Destruction may happen on any task queue.
|
// Destruction may happen on any task queue.
|
||||||
~Resource() override;
|
~Resource() override;
|
||||||
|
|
||||||
// Provides a pointer to the adaptation task queue. After this call, all
|
|
||||||
// methods defined in this interface, including
|
|
||||||
// UnregisterAdaptationTaskQueue() MUST be invoked on the adaptation task
|
|
||||||
// queue. Registering the adaptation task queue may, however, happen off the
|
|
||||||
// adaptation task queue.
|
|
||||||
virtual void RegisterAdaptationTaskQueue(
|
|
||||||
TaskQueueBase* resource_adaptation_queue) = 0;
|
|
||||||
// Signals that the adaptation task queue is no longer safe to use. No
|
|
||||||
// assumptions must be made as to whether or not tasks in-flight will run.
|
|
||||||
virtual void UnregisterAdaptationTaskQueue() = 0;
|
|
||||||
|
|
||||||
// The listeners MUST be informed any time UsageState() changes.
|
|
||||||
virtual void SetResourceListener(ResourceListener* listener) = 0;
|
|
||||||
|
|
||||||
virtual std::string Name() const = 0;
|
virtual std::string Name() const = 0;
|
||||||
|
// The listener MUST be informed any time UsageState() changes.
|
||||||
|
virtual void SetResourceListener(ResourceListener* listener) = 0;
|
||||||
// Within a single task running on the adaptation task queue, UsageState()
|
// Within a single task running on the adaptation task queue, UsageState()
|
||||||
// MUST return the same value every time it is called.
|
// MUST return the same value every time it is called.
|
||||||
// TODO(https://crbug.com/webrtc/11618): Remove the UsageState() getter in
|
// TODO(https://crbug.com/webrtc/11618): Remove the UsageState() getter in
|
||||||
@ -86,20 +74,6 @@ class Resource : public rtc::RefCountInterface {
|
|||||||
// Invalidates current usage measurements, i.e. in response to the system load
|
// Invalidates current usage measurements, i.e. in response to the system load
|
||||||
// changing. Example: an adaptation was just applied.
|
// changing. Example: an adaptation was just applied.
|
||||||
virtual void ClearUsageState() = 0;
|
virtual void ClearUsageState() = 0;
|
||||||
|
|
||||||
// This method allows the Resource to reject a proposed adaptation in the "up"
|
|
||||||
// direction if it predicts this would cause overuse of this resource.
|
|
||||||
virtual bool IsAdaptationUpAllowed(
|
|
||||||
const VideoStreamInputState& input_state,
|
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
|
||||||
rtc::scoped_refptr<Resource> reason_resource) const = 0;
|
|
||||||
|
|
||||||
virtual void OnAdaptationApplied(
|
|
||||||
const VideoStreamInputState& input_state,
|
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
|
||||||
rtc::scoped_refptr<Resource> reason_resource) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -49,12 +49,18 @@ ResourceAdaptationProcessor::ResourceAdaptationProcessor(
|
|||||||
ResourceAdaptationProcessor::~ResourceAdaptationProcessor() {
|
ResourceAdaptationProcessor::~ResourceAdaptationProcessor() {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
RTC_DCHECK(!is_resource_adaptation_enabled_);
|
RTC_DCHECK(!is_resource_adaptation_enabled_);
|
||||||
RTC_DCHECK(adaptation_listeners_.empty())
|
RTC_DCHECK(restrictions_listeners_.empty())
|
||||||
<< "There are listener(s) depending on a ResourceAdaptationProcessor "
|
<< "There are restrictions listener(s) depending on a "
|
||||||
<< "being destroyed.";
|
<< "ResourceAdaptationProcessor being destroyed.";
|
||||||
RTC_DCHECK(resources_.empty())
|
RTC_DCHECK(resources_.empty())
|
||||||
<< "There are resource(s) attached to a ResourceAdaptationProcessor "
|
<< "There are resource(s) attached to a ResourceAdaptationProcessor "
|
||||||
<< "being destroyed.";
|
<< "being destroyed.";
|
||||||
|
RTC_DCHECK(adaptation_constraints_.empty())
|
||||||
|
<< "There are constaint(s) attached to a ResourceAdaptationProcessor "
|
||||||
|
<< "being destroyed.";
|
||||||
|
RTC_DCHECK(adaptation_listeners_.empty())
|
||||||
|
<< "There are listener(s) attached to a ResourceAdaptationProcessor "
|
||||||
|
<< "being destroyed.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceAdaptationProcessor::InitializeOnResourceAdaptationQueue() {
|
void ResourceAdaptationProcessor::InitializeOnResourceAdaptationQueue() {
|
||||||
@ -95,22 +101,22 @@ void ResourceAdaptationProcessor::StopResourceAdaptation() {
|
|||||||
is_resource_adaptation_enabled_ = false;
|
is_resource_adaptation_enabled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceAdaptationProcessor::AddAdaptationListener(
|
void ResourceAdaptationProcessor::AddRestrictionsListener(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener) {
|
VideoSourceRestrictionsListener* restrictions_listener) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
RTC_DCHECK(std::find(adaptation_listeners_.begin(),
|
RTC_DCHECK(std::find(restrictions_listeners_.begin(),
|
||||||
adaptation_listeners_.end(),
|
restrictions_listeners_.end(),
|
||||||
adaptation_listener) == adaptation_listeners_.end());
|
restrictions_listener) == restrictions_listeners_.end());
|
||||||
adaptation_listeners_.push_back(adaptation_listener);
|
restrictions_listeners_.push_back(restrictions_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceAdaptationProcessor::RemoveAdaptationListener(
|
void ResourceAdaptationProcessor::RemoveRestrictionsListener(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener) {
|
VideoSourceRestrictionsListener* restrictions_listener) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
auto it = std::find(adaptation_listeners_.begin(),
|
auto it = std::find(restrictions_listeners_.begin(),
|
||||||
adaptation_listeners_.end(), adaptation_listener);
|
restrictions_listeners_.end(), restrictions_listener);
|
||||||
RTC_DCHECK(it != adaptation_listeners_.end());
|
RTC_DCHECK(it != restrictions_listeners_.end());
|
||||||
adaptation_listeners_.erase(it);
|
restrictions_listeners_.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceAdaptationProcessor::AddResource(
|
void ResourceAdaptationProcessor::AddResource(
|
||||||
@ -136,6 +142,42 @@ void ResourceAdaptationProcessor::RemoveResource(
|
|||||||
resources_.erase(it);
|
resources_.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceAdaptationProcessor::AddAdaptationConstraint(
|
||||||
|
AdaptationConstraint* adaptation_constraint) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
RTC_DCHECK(std::find(adaptation_constraints_.begin(),
|
||||||
|
adaptation_constraints_.end(),
|
||||||
|
adaptation_constraint) == adaptation_constraints_.end());
|
||||||
|
adaptation_constraints_.push_back(adaptation_constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceAdaptationProcessor::RemoveAdaptationConstraint(
|
||||||
|
AdaptationConstraint* adaptation_constraint) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
auto it = std::find(adaptation_constraints_.begin(),
|
||||||
|
adaptation_constraints_.end(), adaptation_constraint);
|
||||||
|
RTC_DCHECK(it != adaptation_constraints_.end());
|
||||||
|
adaptation_constraints_.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceAdaptationProcessor::AddAdaptationListener(
|
||||||
|
AdaptationListener* adaptation_listener) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
RTC_DCHECK(std::find(adaptation_listeners_.begin(),
|
||||||
|
adaptation_listeners_.end(),
|
||||||
|
adaptation_listener) == adaptation_listeners_.end());
|
||||||
|
adaptation_listeners_.push_back(adaptation_listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceAdaptationProcessor::RemoveAdaptationListener(
|
||||||
|
AdaptationListener* adaptation_listener) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
auto it = std::find(adaptation_listeners_.begin(),
|
||||||
|
adaptation_listeners_.end(), adaptation_listener);
|
||||||
|
RTC_DCHECK(it != adaptation_listeners_.end());
|
||||||
|
adaptation_listeners_.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
void ResourceAdaptationProcessor::SetDegradationPreference(
|
void ResourceAdaptationProcessor::SetDegradationPreference(
|
||||||
DegradationPreference degradation_preference) {
|
DegradationPreference degradation_preference) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
@ -181,8 +223,8 @@ void ResourceAdaptationProcessor::MaybeUpdateVideoSourceRestrictions(
|
|||||||
effective_degradation_preference_)
|
effective_degradation_preference_)
|
||||||
<< "): " << new_source_restrictions.ToString();
|
<< "): " << new_source_restrictions.ToString();
|
||||||
last_reported_source_restrictions_ = std::move(new_source_restrictions);
|
last_reported_source_restrictions_ = std::move(new_source_restrictions);
|
||||||
for (auto* adaptation_listener : adaptation_listeners_) {
|
for (auto* restrictions_listener : restrictions_listeners_) {
|
||||||
adaptation_listener->OnVideoSourceRestrictionsUpdated(
|
restrictions_listener->OnVideoSourceRestrictionsUpdated(
|
||||||
last_reported_source_restrictions_,
|
last_reported_source_restrictions_,
|
||||||
stream_adapter_->adaptation_counters(), reason);
|
stream_adapter_->adaptation_counters(), reason);
|
||||||
}
|
}
|
||||||
@ -284,25 +326,26 @@ ResourceAdaptationProcessor::OnResourceUnderuse(
|
|||||||
stream_adapter_->source_restrictions();
|
stream_adapter_->source_restrictions();
|
||||||
VideoSourceRestrictions restrictions_after =
|
VideoSourceRestrictions restrictions_after =
|
||||||
stream_adapter_->PeekNextRestrictions(adaptation);
|
stream_adapter_->PeekNextRestrictions(adaptation);
|
||||||
for (const auto& resource : resources_) {
|
for (const auto* constraint : adaptation_constraints_) {
|
||||||
if (!resource->IsAdaptationUpAllowed(input_state, restrictions_before,
|
if (!constraint->IsAdaptationUpAllowed(input_state, restrictions_before,
|
||||||
restrictions_after, reason_resource)) {
|
restrictions_after,
|
||||||
|
reason_resource)) {
|
||||||
processing_in_progress_ = false;
|
processing_in_progress_ = false;
|
||||||
rtc::StringBuilder message;
|
rtc::StringBuilder message;
|
||||||
message << "Not adapting up because resource \"" << resource->Name()
|
message << "Not adapting up because constraint \"" << constraint->Name()
|
||||||
<< "\" disallowed it";
|
<< "\" disallowed it";
|
||||||
return MitigationResultAndLogMessage(
|
return MitigationResultAndLogMessage(
|
||||||
MitigationResult::kRejectedByResource, message.Release());
|
MitigationResult::kRejectedByConstraint, message.Release());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Apply adaptation.
|
// Apply adaptation.
|
||||||
stream_adapter_->ApplyAdaptation(adaptation);
|
stream_adapter_->ApplyAdaptation(adaptation);
|
||||||
for (const auto& resource : resources_) {
|
for (auto* adaptation_listener : adaptation_listeners_) {
|
||||||
resource->OnAdaptationApplied(input_state, restrictions_before,
|
adaptation_listener->OnAdaptationApplied(
|
||||||
restrictions_after, reason_resource);
|
input_state, restrictions_before, restrictions_after, reason_resource);
|
||||||
}
|
}
|
||||||
// Update VideoSourceRestrictions based on adaptation. This also informs the
|
// Update VideoSourceRestrictions based on adaptation. This also informs the
|
||||||
// |adaptation_listeners_|.
|
// |restrictions_listeners_|.
|
||||||
MaybeUpdateVideoSourceRestrictions(reason_resource);
|
MaybeUpdateVideoSourceRestrictions(reason_resource);
|
||||||
processing_in_progress_ = false;
|
processing_in_progress_ = false;
|
||||||
rtc::StringBuilder message;
|
rtc::StringBuilder message;
|
||||||
@ -359,12 +402,12 @@ ResourceAdaptationProcessor::OnResourceOveruse(
|
|||||||
VideoSourceRestrictions restrictions_after =
|
VideoSourceRestrictions restrictions_after =
|
||||||
stream_adapter_->PeekNextRestrictions(adaptation);
|
stream_adapter_->PeekNextRestrictions(adaptation);
|
||||||
stream_adapter_->ApplyAdaptation(adaptation);
|
stream_adapter_->ApplyAdaptation(adaptation);
|
||||||
for (const auto& resource : resources_) {
|
for (auto* adaptation_listener : adaptation_listeners_) {
|
||||||
resource->OnAdaptationApplied(input_state, restrictions_before,
|
adaptation_listener->OnAdaptationApplied(
|
||||||
restrictions_after, reason_resource);
|
input_state, restrictions_before, restrictions_after, reason_resource);
|
||||||
}
|
}
|
||||||
// Update VideoSourceRestrictions based on adaptation. This also informs the
|
// Update VideoSourceRestrictions based on adaptation. This also informs the
|
||||||
// |adaptation_listeners_|.
|
// |restrictions_listeners_|.
|
||||||
MaybeUpdateVideoSourceRestrictions(reason_resource);
|
MaybeUpdateVideoSourceRestrictions(reason_resource);
|
||||||
processing_in_progress_ = false;
|
processing_in_progress_ = false;
|
||||||
rtc::StringBuilder message;
|
rtc::StringBuilder message;
|
||||||
|
|||||||
@ -21,6 +21,8 @@
|
|||||||
#include "api/scoped_refptr.h"
|
#include "api/scoped_refptr.h"
|
||||||
#include "api/video/video_frame.h"
|
#include "api/video/video_frame.h"
|
||||||
#include "api/video/video_stream_encoder_observer.h"
|
#include "api/video/video_stream_encoder_observer.h"
|
||||||
|
#include "call/adaptation/adaptation_constraint.h"
|
||||||
|
#include "call/adaptation/adaptation_listener.h"
|
||||||
#include "call/adaptation/resource.h"
|
#include "call/adaptation/resource.h"
|
||||||
#include "call/adaptation/resource_adaptation_processor_interface.h"
|
#include "call/adaptation/resource_adaptation_processor_interface.h"
|
||||||
#include "call/adaptation/video_source_restrictions.h"
|
#include "call/adaptation/video_source_restrictions.h"
|
||||||
@ -63,12 +65,19 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
|||||||
|
|
||||||
void StartResourceAdaptation() override;
|
void StartResourceAdaptation() override;
|
||||||
void StopResourceAdaptation() override;
|
void StopResourceAdaptation() override;
|
||||||
void AddAdaptationListener(
|
void AddRestrictionsListener(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener) override;
|
VideoSourceRestrictionsListener* restrictions_listener) override;
|
||||||
void RemoveAdaptationListener(
|
void RemoveRestrictionsListener(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener) override;
|
VideoSourceRestrictionsListener* restrictions_listener) override;
|
||||||
void AddResource(rtc::scoped_refptr<Resource> resource) override;
|
void AddResource(rtc::scoped_refptr<Resource> resource) override;
|
||||||
void RemoveResource(rtc::scoped_refptr<Resource> resource) override;
|
void RemoveResource(rtc::scoped_refptr<Resource> resource) override;
|
||||||
|
void AddAdaptationConstraint(
|
||||||
|
AdaptationConstraint* adaptation_constraint) override;
|
||||||
|
void RemoveAdaptationConstraint(
|
||||||
|
AdaptationConstraint* adaptation_constraint) override;
|
||||||
|
void AddAdaptationListener(AdaptationListener* adaptation_listener) override;
|
||||||
|
void RemoveAdaptationListener(
|
||||||
|
AdaptationListener* adaptation_listener) override;
|
||||||
|
|
||||||
void SetDegradationPreference(
|
void SetDegradationPreference(
|
||||||
DegradationPreference degradation_preference) override;
|
DegradationPreference degradation_preference) override;
|
||||||
@ -95,7 +104,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
|||||||
kInsufficientInput,
|
kInsufficientInput,
|
||||||
kRejectedByAdaptationCounts,
|
kRejectedByAdaptationCounts,
|
||||||
kRejectedByAdapter,
|
kRejectedByAdapter,
|
||||||
kRejectedByResource,
|
kRejectedByConstraint,
|
||||||
kAdaptationApplied,
|
kAdaptationApplied,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -139,10 +148,14 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
|
|||||||
RTC_GUARDED_BY(sequence_checker_);
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
VideoStreamEncoderObserver* const encoder_stats_observer_
|
VideoStreamEncoderObserver* const encoder_stats_observer_
|
||||||
RTC_GUARDED_BY(sequence_checker_);
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
std::vector<ResourceAdaptationProcessorListener*> adaptation_listeners_
|
std::vector<VideoSourceRestrictionsListener*> restrictions_listeners_
|
||||||
RTC_GUARDED_BY(sequence_checker_);
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
std::vector<rtc::scoped_refptr<Resource>> resources_
|
std::vector<rtc::scoped_refptr<Resource>> resources_
|
||||||
RTC_GUARDED_BY(sequence_checker_);
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
|
std::vector<AdaptationConstraint*> adaptation_constraints_
|
||||||
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
|
std::vector<AdaptationListener*> adaptation_listeners_
|
||||||
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
// Purely used for statistics, does not ensure mapped resources stay alive.
|
// Purely used for statistics, does not ensure mapped resources stay alive.
|
||||||
std::map<const Resource*, int> adaptations_counts_by_resource_
|
std::map<const Resource*, int> adaptations_counts_by_resource_
|
||||||
RTC_GUARDED_BY(sequence_checker_);
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
ResourceAdaptationProcessorListener::~ResourceAdaptationProcessorListener() {}
|
VideoSourceRestrictionsListener::~VideoSourceRestrictionsListener() {}
|
||||||
|
|
||||||
ResourceAdaptationProcessorInterface::~ResourceAdaptationProcessorInterface() {}
|
ResourceAdaptationProcessorInterface::~ResourceAdaptationProcessorInterface() {}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
#include "api/scoped_refptr.h"
|
#include "api/scoped_refptr.h"
|
||||||
#include "api/video/video_adaptation_counters.h"
|
#include "api/video/video_adaptation_counters.h"
|
||||||
#include "api/video/video_frame.h"
|
#include "api/video/video_frame.h"
|
||||||
|
#include "call/adaptation/adaptation_constraint.h"
|
||||||
|
#include "call/adaptation/adaptation_listener.h"
|
||||||
#include "call/adaptation/encoder_settings.h"
|
#include "call/adaptation/encoder_settings.h"
|
||||||
#include "call/adaptation/resource.h"
|
#include "call/adaptation/resource.h"
|
||||||
#include "call/adaptation/video_source_restrictions.h"
|
#include "call/adaptation/video_source_restrictions.h"
|
||||||
@ -25,9 +27,9 @@ namespace webrtc {
|
|||||||
|
|
||||||
// The listener is responsible for carrying out the reconfiguration of the video
|
// The listener is responsible for carrying out the reconfiguration of the video
|
||||||
// source such that the VideoSourceRestrictions are fulfilled.
|
// source such that the VideoSourceRestrictions are fulfilled.
|
||||||
class ResourceAdaptationProcessorListener {
|
class VideoSourceRestrictionsListener {
|
||||||
public:
|
public:
|
||||||
virtual ~ResourceAdaptationProcessorListener();
|
virtual ~VideoSourceRestrictionsListener();
|
||||||
|
|
||||||
// The |restrictions| are filtered by degradation preference but not the
|
// The |restrictions| are filtered by degradation preference but not the
|
||||||
// |adaptation_counters|, which are currently only reported for legacy stats
|
// |adaptation_counters|, which are currently only reported for legacy stats
|
||||||
@ -63,12 +65,20 @@ class ResourceAdaptationProcessorInterface {
|
|||||||
// over time.
|
// over time.
|
||||||
virtual void StartResourceAdaptation() = 0;
|
virtual void StartResourceAdaptation() = 0;
|
||||||
virtual void StopResourceAdaptation() = 0;
|
virtual void StopResourceAdaptation() = 0;
|
||||||
virtual void AddAdaptationListener(
|
virtual void AddRestrictionsListener(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener) = 0;
|
VideoSourceRestrictionsListener* restrictions_listener) = 0;
|
||||||
virtual void RemoveAdaptationListener(
|
virtual void RemoveRestrictionsListener(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener) = 0;
|
VideoSourceRestrictionsListener* restrictions_listener) = 0;
|
||||||
virtual void AddResource(rtc::scoped_refptr<Resource> resource) = 0;
|
virtual void AddResource(rtc::scoped_refptr<Resource> resource) = 0;
|
||||||
virtual void RemoveResource(rtc::scoped_refptr<Resource> resource) = 0;
|
virtual void RemoveResource(rtc::scoped_refptr<Resource> resource) = 0;
|
||||||
|
virtual void AddAdaptationConstraint(
|
||||||
|
AdaptationConstraint* adaptation_constraint) = 0;
|
||||||
|
virtual void RemoveAdaptationConstraint(
|
||||||
|
AdaptationConstraint* adaptation_constraint) = 0;
|
||||||
|
virtual void AddAdaptationListener(
|
||||||
|
AdaptationListener* adaptation_listener) = 0;
|
||||||
|
virtual void RemoveAdaptationListener(
|
||||||
|
AdaptationListener* adaptation_listener) = 0;
|
||||||
|
|
||||||
virtual void SetDegradationPreference(
|
virtual void SetDegradationPreference(
|
||||||
DegradationPreference degradation_preference) = 0;
|
DegradationPreference degradation_preference) = 0;
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
#include "api/video/video_adaptation_counters.h"
|
#include "api/video/video_adaptation_counters.h"
|
||||||
#include "call/adaptation/resource.h"
|
#include "call/adaptation/resource.h"
|
||||||
#include "call/adaptation/resource_adaptation_processor_interface.h"
|
#include "call/adaptation/resource_adaptation_processor_interface.h"
|
||||||
|
#include "call/adaptation/test/fake_adaptation_constraint.h"
|
||||||
|
#include "call/adaptation/test/fake_adaptation_listener.h"
|
||||||
#include "call/adaptation/test/fake_frame_rate_provider.h"
|
#include "call/adaptation/test/fake_frame_rate_provider.h"
|
||||||
#include "call/adaptation/test/fake_resource.h"
|
#include "call/adaptation/test/fake_resource.h"
|
||||||
#include "call/adaptation/video_source_restrictions.h"
|
#include "call/adaptation/video_source_restrictions.h"
|
||||||
@ -29,15 +31,15 @@ namespace {
|
|||||||
const int kDefaultFrameRate = 30;
|
const int kDefaultFrameRate = 30;
|
||||||
const int kDefaultFrameSize = 1280 * 720;
|
const int kDefaultFrameSize = 1280 * 720;
|
||||||
|
|
||||||
class ResourceAdaptationProcessorListenerForTesting
|
class VideoSourceRestrictionsListenerForTesting
|
||||||
: public ResourceAdaptationProcessorListener {
|
: public VideoSourceRestrictionsListener {
|
||||||
public:
|
public:
|
||||||
ResourceAdaptationProcessorListenerForTesting()
|
VideoSourceRestrictionsListenerForTesting()
|
||||||
: restrictions_updated_count_(0),
|
: restrictions_updated_count_(0),
|
||||||
restrictions_(),
|
restrictions_(),
|
||||||
adaptation_counters_(),
|
adaptation_counters_(),
|
||||||
reason_(nullptr) {}
|
reason_(nullptr) {}
|
||||||
~ResourceAdaptationProcessorListenerForTesting() override {}
|
~VideoSourceRestrictionsListenerForTesting() override {}
|
||||||
|
|
||||||
size_t restrictions_updated_count() const {
|
size_t restrictions_updated_count() const {
|
||||||
return restrictions_updated_count_;
|
return restrictions_updated_count_;
|
||||||
@ -48,7 +50,7 @@ class ResourceAdaptationProcessorListenerForTesting
|
|||||||
}
|
}
|
||||||
rtc::scoped_refptr<Resource> reason() const { return reason_; }
|
rtc::scoped_refptr<Resource> reason() const { return reason_; }
|
||||||
|
|
||||||
// ResourceAdaptationProcessorListener implementation.
|
// VideoSourceRestrictionsListener implementation.
|
||||||
void OnVideoSourceRestrictionsUpdated(
|
void OnVideoSourceRestrictionsUpdated(
|
||||||
VideoSourceRestrictions restrictions,
|
VideoSourceRestrictions restrictions,
|
||||||
const VideoAdaptationCounters& adaptation_counters,
|
const VideoAdaptationCounters& adaptation_counters,
|
||||||
@ -74,18 +76,19 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
|
|||||||
input_state_provider_(&frame_rate_provider_),
|
input_state_provider_(&frame_rate_provider_),
|
||||||
resource_(FakeResource::Create("FakeResource")),
|
resource_(FakeResource::Create("FakeResource")),
|
||||||
other_resource_(FakeResource::Create("OtherFakeResource")),
|
other_resource_(FakeResource::Create("OtherFakeResource")),
|
||||||
|
adaptation_constraint_("FakeAdaptationConstraint"),
|
||||||
|
adaptation_listener_(),
|
||||||
processor_(std::make_unique<ResourceAdaptationProcessor>(
|
processor_(std::make_unique<ResourceAdaptationProcessor>(
|
||||||
&input_state_provider_,
|
&input_state_provider_,
|
||||||
/*encoder_stats_observer=*/&frame_rate_provider_)) {
|
/*encoder_stats_observer=*/&frame_rate_provider_)) {
|
||||||
resource_->RegisterAdaptationTaskQueue(resource_adaptation_queue_.Get());
|
|
||||||
other_resource_->RegisterAdaptationTaskQueue(
|
|
||||||
resource_adaptation_queue_.Get());
|
|
||||||
rtc::Event event;
|
rtc::Event event;
|
||||||
resource_adaptation_queue_.PostTask([this, &event] {
|
resource_adaptation_queue_.PostTask([this, &event] {
|
||||||
processor_->InitializeOnResourceAdaptationQueue();
|
processor_->InitializeOnResourceAdaptationQueue();
|
||||||
processor_->AddAdaptationListener(&processor_listener_);
|
processor_->AddRestrictionsListener(&restrictions_listener_);
|
||||||
processor_->AddResource(resource_);
|
processor_->AddResource(resource_);
|
||||||
processor_->AddResource(other_resource_);
|
processor_->AddResource(other_resource_);
|
||||||
|
processor_->AddAdaptationConstraint(&adaptation_constraint_);
|
||||||
|
processor_->AddAdaptationListener(&adaptation_listener_);
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
event.Wait(rtc::Event::kForever);
|
event.Wait(rtc::Event::kForever);
|
||||||
@ -94,9 +97,11 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
|
|||||||
rtc::Event event;
|
rtc::Event event;
|
||||||
resource_adaptation_queue_.PostTask([this, &event] {
|
resource_adaptation_queue_.PostTask([this, &event] {
|
||||||
processor_->StopResourceAdaptation();
|
processor_->StopResourceAdaptation();
|
||||||
|
processor_->RemoveRestrictionsListener(&restrictions_listener_);
|
||||||
processor_->RemoveResource(resource_);
|
processor_->RemoveResource(resource_);
|
||||||
processor_->RemoveResource(other_resource_);
|
processor_->RemoveResource(other_resource_);
|
||||||
processor_->RemoveAdaptationListener(&processor_listener_);
|
processor_->RemoveAdaptationConstraint(&adaptation_constraint_);
|
||||||
|
processor_->RemoveAdaptationListener(&adaptation_listener_);
|
||||||
processor_.reset();
|
processor_.reset();
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
@ -123,8 +128,10 @@ class ResourceAdaptationProcessorTest : public ::testing::Test {
|
|||||||
VideoStreamInputStateProvider input_state_provider_;
|
VideoStreamInputStateProvider input_state_provider_;
|
||||||
rtc::scoped_refptr<FakeResource> resource_;
|
rtc::scoped_refptr<FakeResource> resource_;
|
||||||
rtc::scoped_refptr<FakeResource> other_resource_;
|
rtc::scoped_refptr<FakeResource> other_resource_;
|
||||||
|
FakeAdaptationConstraint adaptation_constraint_;
|
||||||
|
FakeAdaptationListener adaptation_listener_;
|
||||||
std::unique_ptr<ResourceAdaptationProcessor> processor_;
|
std::unique_ptr<ResourceAdaptationProcessor> processor_;
|
||||||
ResourceAdaptationProcessorListenerForTesting processor_listener_;
|
VideoSourceRestrictionsListenerForTesting restrictions_listener_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -139,8 +146,8 @@ TEST_F(ResourceAdaptationProcessorTest, DisabledByDefault) {
|
|||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
// Adaptation does not happen when disabled.
|
// Adaptation does not happen when disabled.
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -154,12 +161,12 @@ TEST_F(ResourceAdaptationProcessorTest, InsufficientInput) {
|
|||||||
// Adaptation does not happen if input is insufficient.
|
// Adaptation does not happen if input is insufficient.
|
||||||
// When frame size is missing (OnFrameSizeObserved not called yet).
|
// When frame size is missing (OnFrameSizeObserved not called yet).
|
||||||
input_state_provider_.OnHasInputChanged(true);
|
input_state_provider_.OnHasInputChanged(true);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
|
||||||
// When "has input" is missing.
|
// When "has input" is missing.
|
||||||
SetInputStates(false, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(false, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
|
||||||
// Note: frame rate cannot be missing, if unset it is 0.
|
// Note: frame rate cannot be missing, if unset it is 0.
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
@ -177,9 +184,9 @@ TEST_F(ResourceAdaptationProcessorTest,
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
EXPECT_TRUE(processor_listener_.restrictions()
|
EXPECT_TRUE(restrictions_listener_.restrictions()
|
||||||
.max_pixels_per_frame()
|
.max_pixels_per_frame()
|
||||||
.has_value());
|
.has_value());
|
||||||
},
|
},
|
||||||
@ -194,10 +201,10 @@ TEST_F(ResourceAdaptationProcessorTest,
|
|||||||
DegradationPreference::MAINTAIN_RESOLUTION);
|
DegradationPreference::MAINTAIN_RESOLUTION);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
processor_listener_.restrictions().max_frame_rate().has_value());
|
restrictions_listener_.restrictions().max_frame_rate().has_value());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -214,15 +221,15 @@ TEST_F(ResourceAdaptationProcessorTest,
|
|||||||
// BalancedDegradationSettings, VideoStreamAdapter and default input
|
// BalancedDegradationSettings, VideoStreamAdapter and default input
|
||||||
// states. This test requires it to be achieved within 4 adaptations.
|
// states. This test requires it to be achieved within 4 adaptations.
|
||||||
for (size_t i = 0; i < 4; ++i) {
|
for (size_t i = 0; i < 4; ++i) {
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(i + 1, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(i + 1, restrictions_listener_.restrictions_updated_count());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
}
|
}
|
||||||
EXPECT_TRUE(processor_listener_.restrictions()
|
EXPECT_TRUE(restrictions_listener_.restrictions()
|
||||||
.max_pixels_per_frame()
|
.max_pixels_per_frame()
|
||||||
.has_value());
|
.has_value());
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
processor_listener_.restrictions().max_frame_rate().has_value());
|
restrictions_listener_.restrictions().max_frame_rate().has_value());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -234,12 +241,12 @@ TEST_F(ResourceAdaptationProcessorTest, AwaitingPreviousAdaptation) {
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
// If we don't restrict the source then adaptation will not happen again
|
// If we don't restrict the source then adaptation will not happen again
|
||||||
// due to "awaiting previous adaptation". This prevents "double-adapt".
|
// due to "awaiting previous adaptation". This prevents "double-adapt".
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -251,8 +258,8 @@ TEST_F(ResourceAdaptationProcessorTest, CannotAdaptUpWhenUnrestricted) {
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -264,13 +271,13 @@ TEST_F(ResourceAdaptationProcessorTest, UnderuseTakesUsBackToUnrestricted) {
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
EXPECT_EQ(2u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(2u, restrictions_listener_.restrictions_updated_count());
|
||||||
EXPECT_EQ(VideoSourceRestrictions(),
|
EXPECT_EQ(VideoSourceRestrictions(),
|
||||||
processor_listener_.restrictions());
|
restrictions_listener_.restrictions());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -283,13 +290,13 @@ TEST_F(ResourceAdaptationProcessorTest, ResourcesCanPreventAdaptingUp) {
|
|||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
// Adapt down so that we can adapt up.
|
// Adapt down so that we can adapt up.
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
// Adapting up is prevented.
|
// Adapting up is prevented.
|
||||||
resource_->set_is_adaptation_up_allowed(false);
|
adaptation_constraint_.set_is_adaptation_up_allowed(false);
|
||||||
resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -302,13 +309,13 @@ TEST_F(ResourceAdaptationProcessorTest,
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
|
|
||||||
// Other resource signals under-use
|
// Other resource signals under-use
|
||||||
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -321,19 +328,19 @@ TEST_F(ResourceAdaptationProcessorTest,
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
|
|
||||||
processor_->ResetVideoSourceRestrictions();
|
processor_->ResetVideoSourceRestrictions();
|
||||||
EXPECT_EQ(0, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
|
||||||
other_resource_->set_usage_state(ResourceUsageState::kOveruse);
|
other_resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
|
|
||||||
// resource_ did not overuse after we reset the restrictions, so adapt
|
// resource_ did not overuse after we reset the restrictions, so adapt
|
||||||
// up should be disallowed.
|
// up should be disallowed.
|
||||||
resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -346,30 +353,30 @@ TEST_F(ResourceAdaptationProcessorTest,
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
other_resource_->set_usage_state(ResourceUsageState::kOveruse);
|
other_resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(2, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
other_resource_->set_usage_state(ResourceUsageState::kOveruse);
|
other_resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(3, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(3, restrictions_listener_.adaptation_counters().Total());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
|
|
||||||
resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
EXPECT_EQ(2, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
// Does not trigger adaptation since resource has no adaptations left.
|
// Does not trigger adaptation since resource has no adaptations left.
|
||||||
resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
EXPECT_EQ(2, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
|
|
||||||
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
EXPECT_EQ(0, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -381,8 +388,8 @@ TEST_F(ResourceAdaptationProcessorTest, AdaptingTriggersOnAdaptationApplied) {
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, resource_->num_adaptations_applied());
|
EXPECT_EQ(1u, adaptation_listener_.num_adaptations_applied());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
@ -394,8 +401,8 @@ TEST_F(ResourceAdaptationProcessorTest, AdaptingClearsResourceUsageState) {
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(1u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
|
||||||
EXPECT_FALSE(resource_->UsageState().has_value());
|
EXPECT_FALSE(resource_->UsageState().has_value());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
@ -407,8 +414,8 @@ TEST_F(ResourceAdaptationProcessorTest,
|
|||||||
[this] {
|
[this] {
|
||||||
processor_->SetDegradationPreference(DegradationPreference::DISABLED);
|
processor_->SetDegradationPreference(DegradationPreference::DISABLED);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
EXPECT_EQ(0u, processor_listener_.restrictions_updated_count());
|
EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
|
||||||
EXPECT_FALSE(resource_->UsageState().has_value());
|
EXPECT_FALSE(resource_->UsageState().has_value());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
@ -422,20 +429,20 @@ TEST_F(ResourceAdaptationProcessorTest,
|
|||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
processor_->StartResourceAdaptation();
|
processor_->StartResourceAdaptation();
|
||||||
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
|
||||||
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
// Does not trigger adapataion because there's no restriction.
|
// Does not trigger adapataion because there's no restriction.
|
||||||
EXPECT_EQ(0, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
|
||||||
|
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
resource_->set_usage_state(ResourceUsageState::kOveruse);
|
resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
// Adapts down even if other resource asked for adapting up.
|
// Adapts down even if other resource asked for adapting up.
|
||||||
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
|
||||||
|
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
other_resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
// Doesn't adapt up because adaptation is due to another resource.
|
// Doesn't adapt up because adaptation is due to another resource.
|
||||||
EXPECT_EQ(1, processor_listener_.adaptation_counters().Total());
|
EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
|
||||||
RestrictSource(processor_listener_.restrictions());
|
RestrictSource(restrictions_listener_.restrictions());
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
#include "api/scoped_refptr.h"
|
#include "api/scoped_refptr.h"
|
||||||
#include "call/adaptation/test/fake_resource.h"
|
#include "call/adaptation/test/fake_resource.h"
|
||||||
#include "rtc_base/event.h"
|
|
||||||
#include "rtc_base/task_queue_for_test.h"
|
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
@ -34,22 +32,13 @@ class MockResourceListener : public ResourceListener {
|
|||||||
|
|
||||||
class ResourceTest : public ::testing::Test {
|
class ResourceTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
ResourceTest()
|
ResourceTest() : fake_resource_(FakeResource::Create("FakeResource")) {}
|
||||||
: resource_adaptation_queue_("ResourceAdaptationQueue"),
|
|
||||||
fake_resource_(FakeResource::Create("FakeResource")) {
|
|
||||||
fake_resource_->RegisterAdaptationTaskQueue(
|
|
||||||
resource_adaptation_queue_.Get());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
|
|
||||||
TaskQueueForTest resource_adaptation_queue_;
|
|
||||||
rtc::scoped_refptr<FakeResource> fake_resource_;
|
rtc::scoped_refptr<FakeResource> fake_resource_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ResourceTest, RegisteringListenerReceivesCallbacks) {
|
TEST_F(ResourceTest, RegisteringListenerReceivesCallbacks) {
|
||||||
resource_adaptation_queue_.SendTask(
|
|
||||||
[this] {
|
|
||||||
StrictMock<MockResourceListener> resource_listener;
|
StrictMock<MockResourceListener> resource_listener;
|
||||||
fake_resource_->SetResourceListener(&resource_listener);
|
fake_resource_->SetResourceListener(&resource_listener);
|
||||||
EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
|
EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
|
||||||
@ -57,23 +46,16 @@ TEST_F(ResourceTest, RegisteringListenerReceivesCallbacks) {
|
|||||||
.WillOnce([](rtc::scoped_refptr<Resource> resource) {
|
.WillOnce([](rtc::scoped_refptr<Resource> resource) {
|
||||||
EXPECT_EQ(ResourceUsageState::kOveruse, resource->UsageState());
|
EXPECT_EQ(ResourceUsageState::kOveruse, resource->UsageState());
|
||||||
});
|
});
|
||||||
fake_resource_->set_usage_state(ResourceUsageState::kOveruse);
|
fake_resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
fake_resource_->SetResourceListener(nullptr);
|
fake_resource_->SetResourceListener(nullptr);
|
||||||
},
|
|
||||||
RTC_FROM_HERE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResourceTest, UnregisteringListenerStopsCallbacks) {
|
TEST_F(ResourceTest, UnregisteringListenerStopsCallbacks) {
|
||||||
resource_adaptation_queue_.SendTask(
|
|
||||||
[this] {
|
|
||||||
StrictMock<MockResourceListener> resource_listener;
|
StrictMock<MockResourceListener> resource_listener;
|
||||||
fake_resource_->SetResourceListener(&resource_listener);
|
fake_resource_->SetResourceListener(&resource_listener);
|
||||||
fake_resource_->SetResourceListener(nullptr);
|
fake_resource_->SetResourceListener(nullptr);
|
||||||
EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_))
|
EXPECT_CALL(resource_listener, OnResourceUsageStateMeasured(_)).Times(0);
|
||||||
.Times(0);
|
fake_resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
fake_resource_->set_usage_state(ResourceUsageState::kOveruse);
|
|
||||||
},
|
|
||||||
RTC_FROM_HERE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
39
call/adaptation/test/fake_adaptation_constraint.cc
Normal file
39
call/adaptation/test/fake_adaptation_constraint.cc
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "call/adaptation/test/fake_adaptation_constraint.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
FakeAdaptationConstraint::FakeAdaptationConstraint(std::string name)
|
||||||
|
: name_(std::move(name)), is_adaptation_up_allowed_(true) {}
|
||||||
|
|
||||||
|
FakeAdaptationConstraint::~FakeAdaptationConstraint() {}
|
||||||
|
|
||||||
|
void FakeAdaptationConstraint::set_is_adaptation_up_allowed(
|
||||||
|
bool is_adaptation_up_allowed) {
|
||||||
|
is_adaptation_up_allowed_ = is_adaptation_up_allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FakeAdaptationConstraint::Name() const {
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FakeAdaptationConstraint::IsAdaptationUpAllowed(
|
||||||
|
const VideoStreamInputState& input_state,
|
||||||
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
|
const VideoSourceRestrictions& restrictions_after,
|
||||||
|
rtc::scoped_refptr<Resource> reason_resource) const {
|
||||||
|
return is_adaptation_up_allowed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
42
call/adaptation/test/fake_adaptation_constraint.h
Normal file
42
call/adaptation/test/fake_adaptation_constraint.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CALL_ADAPTATION_TEST_FAKE_ADAPTATION_CONSTRAINT_H_
|
||||||
|
#define CALL_ADAPTATION_TEST_FAKE_ADAPTATION_CONSTRAINT_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "call/adaptation/adaptation_constraint.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
class FakeAdaptationConstraint : public AdaptationConstraint {
|
||||||
|
public:
|
||||||
|
explicit FakeAdaptationConstraint(std::string name);
|
||||||
|
~FakeAdaptationConstraint() override;
|
||||||
|
|
||||||
|
void set_is_adaptation_up_allowed(bool is_adaptation_up_allowed);
|
||||||
|
|
||||||
|
// AdaptationConstraint implementation.
|
||||||
|
std::string Name() const override;
|
||||||
|
bool IsAdaptationUpAllowed(
|
||||||
|
const VideoStreamInputState& input_state,
|
||||||
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
|
const VideoSourceRestrictions& restrictions_after,
|
||||||
|
rtc::scoped_refptr<Resource> reason_resource) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string name_;
|
||||||
|
bool is_adaptation_up_allowed_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // CALL_ADAPTATION_TEST_FAKE_ADAPTATION_CONSTRAINT_H_
|
||||||
32
call/adaptation/test/fake_adaptation_listener.cc
Normal file
32
call/adaptation/test/fake_adaptation_listener.cc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "call/adaptation/test/fake_adaptation_listener.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
FakeAdaptationListener::FakeAdaptationListener()
|
||||||
|
: num_adaptations_applied_(0) {}
|
||||||
|
|
||||||
|
FakeAdaptationListener::~FakeAdaptationListener() {}
|
||||||
|
|
||||||
|
size_t FakeAdaptationListener::num_adaptations_applied() const {
|
||||||
|
return num_adaptations_applied_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeAdaptationListener::OnAdaptationApplied(
|
||||||
|
const VideoStreamInputState& input_state,
|
||||||
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
|
const VideoSourceRestrictions& restrictions_after,
|
||||||
|
rtc::scoped_refptr<Resource> reason_resource) {
|
||||||
|
++num_adaptations_applied_;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
38
call/adaptation/test/fake_adaptation_listener.h
Normal file
38
call/adaptation/test/fake_adaptation_listener.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CALL_ADAPTATION_TEST_FAKE_ADAPTATION_LISTENER_H_
|
||||||
|
#define CALL_ADAPTATION_TEST_FAKE_ADAPTATION_LISTENER_H_
|
||||||
|
|
||||||
|
#include "call/adaptation/adaptation_listener.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
class FakeAdaptationListener : public AdaptationListener {
|
||||||
|
public:
|
||||||
|
FakeAdaptationListener();
|
||||||
|
~FakeAdaptationListener() override;
|
||||||
|
|
||||||
|
size_t num_adaptations_applied() const;
|
||||||
|
|
||||||
|
// AdaptationListener implementation.
|
||||||
|
void OnAdaptationApplied(
|
||||||
|
const VideoStreamInputState& input_state,
|
||||||
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
|
const VideoSourceRestrictions& restrictions_after,
|
||||||
|
rtc::scoped_refptr<Resource> reason_resource) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t num_adaptations_applied_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // CALL_ADAPTATION_TEST_FAKE_ADAPTATION_LISTENER_H_
|
||||||
@ -14,7 +14,6 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "rtc_base/ref_counted_object.h"
|
#include "rtc_base/ref_counted_object.h"
|
||||||
#include "rtc_base/task_utils/to_queued_task.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -25,91 +24,33 @@ rtc::scoped_refptr<FakeResource> FakeResource::Create(std::string name) {
|
|||||||
|
|
||||||
FakeResource::FakeResource(std::string name)
|
FakeResource::FakeResource(std::string name)
|
||||||
: Resource(),
|
: Resource(),
|
||||||
lock_(),
|
|
||||||
name_(std::move(name)),
|
name_(std::move(name)),
|
||||||
resource_adaptation_queue_(nullptr),
|
listener_(nullptr),
|
||||||
is_adaptation_up_allowed_(true),
|
usage_state_(absl::nullopt) {}
|
||||||
num_adaptations_applied_(0),
|
|
||||||
usage_state_(absl::nullopt),
|
|
||||||
listener_(nullptr) {}
|
|
||||||
|
|
||||||
FakeResource::~FakeResource() {}
|
FakeResource::~FakeResource() {}
|
||||||
|
|
||||||
void FakeResource::set_usage_state(ResourceUsageState usage_state) {
|
void FakeResource::SetUsageState(ResourceUsageState usage_state) {
|
||||||
if (!resource_adaptation_queue_->IsCurrent()) {
|
|
||||||
resource_adaptation_queue_->PostTask(ToQueuedTask(
|
|
||||||
[this_ref = rtc::scoped_refptr<FakeResource>(this), usage_state] {
|
|
||||||
this_ref->set_usage_state(usage_state);
|
|
||||||
}));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
|
||||||
usage_state_ = usage_state;
|
usage_state_ = usage_state;
|
||||||
if (listener_) {
|
if (listener_) {
|
||||||
listener_->OnResourceUsageStateMeasured(this);
|
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 {
|
std::string FakeResource::Name() const {
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeResource::SetResourceListener(ResourceListener* listener) {
|
||||||
|
listener_ = listener;
|
||||||
|
}
|
||||||
|
|
||||||
absl::optional<ResourceUsageState> FakeResource::UsageState() const {
|
absl::optional<ResourceUsageState> FakeResource::UsageState() const {
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
|
||||||
return usage_state_;
|
return usage_state_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeResource::ClearUsageState() {
|
void FakeResource::ClearUsageState() {
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
|
||||||
usage_state_ = absl::nullopt;
|
usage_state_ = absl::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FakeResource::IsAdaptationUpAllowed(
|
|
||||||
const VideoStreamInputState& input_state,
|
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
|
||||||
rtc::scoped_refptr<Resource> reason_resource) const {
|
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
|
||||||
rtc::CritScope crit(&lock_);
|
|
||||||
return is_adaptation_up_allowed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FakeResource::OnAdaptationApplied(
|
|
||||||
const VideoStreamInputState& input_state,
|
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
|
||||||
rtc::scoped_refptr<Resource> reason_resource) {
|
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
|
||||||
rtc::CritScope crit(&lock_);
|
|
||||||
++num_adaptations_applied_;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/scoped_refptr.h"
|
#include "api/scoped_refptr.h"
|
||||||
#include "api/task_queue/task_queue_base.h"
|
|
||||||
#include "call/adaptation/resource.h"
|
#include "call/adaptation/resource.h"
|
||||||
#include "rtc_base/critical_section.h"
|
|
||||||
#include "rtc_base/synchronization/sequence_checker.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -31,38 +28,18 @@ class FakeResource : public Resource {
|
|||||||
explicit FakeResource(std::string name);
|
explicit FakeResource(std::string name);
|
||||||
~FakeResource() override;
|
~FakeResource() override;
|
||||||
|
|
||||||
void set_usage_state(ResourceUsageState usage_state);
|
void SetUsageState(ResourceUsageState usage_state);
|
||||||
void set_is_adaptation_up_allowed(bool is_adaptation_up_allowed);
|
|
||||||
size_t num_adaptations_applied() const;
|
|
||||||
|
|
||||||
// Resource implementation.
|
// Resource implementation.
|
||||||
void RegisterAdaptationTaskQueue(
|
|
||||||
TaskQueueBase* resource_adaptation_queue) override;
|
|
||||||
void UnregisterAdaptationTaskQueue() override;
|
|
||||||
void SetResourceListener(ResourceListener* listener) override;
|
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
void SetResourceListener(ResourceListener* listener) override;
|
||||||
absl::optional<ResourceUsageState> UsageState() const override;
|
absl::optional<ResourceUsageState> UsageState() const override;
|
||||||
void ClearUsageState() override;
|
void ClearUsageState() override;
|
||||||
bool IsAdaptationUpAllowed(
|
|
||||||
const VideoStreamInputState& input_state,
|
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
|
||||||
rtc::scoped_refptr<Resource> reason_resource) const override;
|
|
||||||
void OnAdaptationApplied(
|
|
||||||
const VideoStreamInputState& input_state,
|
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
|
||||||
rtc::scoped_refptr<Resource> reason_resource) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rtc::CriticalSection lock_;
|
|
||||||
const std::string name_;
|
const std::string name_;
|
||||||
TaskQueueBase* resource_adaptation_queue_;
|
ResourceListener* listener_;
|
||||||
bool is_adaptation_up_allowed_ RTC_GUARDED_BY(lock_);
|
absl::optional<ResourceUsageState> usage_state_;
|
||||||
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
|
} // namespace webrtc
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/scoped_refptr.h"
|
#include "api/scoped_refptr.h"
|
||||||
#include "api/video/video_adaptation_reason.h"
|
#include "api/video/video_adaptation_reason.h"
|
||||||
#include "call/adaptation/resource.h"
|
|
||||||
#include "rtc_base/ref_counted_object.h"
|
#include "rtc_base/ref_counted_object.h"
|
||||||
#include "rtc_base/task_queue.h"
|
#include "rtc_base/task_queue.h"
|
||||||
#include "video/adaptation/overuse_frame_detector.h"
|
#include "video/adaptation/overuse_frame_detector.h"
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
#include "api/scoped_refptr.h"
|
#include "api/scoped_refptr.h"
|
||||||
#include "api/video/video_adaptation_reason.h"
|
#include "api/video/video_adaptation_reason.h"
|
||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "call/adaptation/resource.h"
|
#include "call/adaptation/adaptation_listener.h"
|
||||||
#include "call/adaptation/resource_adaptation_processor_interface.h"
|
#include "call/adaptation/resource_adaptation_processor_interface.h"
|
||||||
#include "modules/video_coding/utility/quality_scaler.h"
|
#include "modules/video_coding/utility/quality_scaler.h"
|
||||||
#include "rtc_base/critical_section.h"
|
#include "rtc_base/critical_section.h"
|
||||||
@ -31,6 +31,7 @@ namespace webrtc {
|
|||||||
|
|
||||||
// Handles interaction with the QualityScaler.
|
// Handles interaction with the QualityScaler.
|
||||||
class QualityScalerResource : public VideoStreamEncoderResource,
|
class QualityScalerResource : public VideoStreamEncoderResource,
|
||||||
|
public AdaptationListener,
|
||||||
public QualityScalerQpUsageHandlerInterface {
|
public QualityScalerQpUsageHandlerInterface {
|
||||||
public:
|
public:
|
||||||
static rtc::scoped_refptr<QualityScalerResource> Create();
|
static rtc::scoped_refptr<QualityScalerResource> Create();
|
||||||
@ -60,7 +61,7 @@ class QualityScalerResource : public VideoStreamEncoderResource,
|
|||||||
rtc::scoped_refptr<QualityScalerQpUsageHandlerCallbackInterface> callback)
|
rtc::scoped_refptr<QualityScalerQpUsageHandlerCallbackInterface> callback)
|
||||||
override;
|
override;
|
||||||
|
|
||||||
// VideoStreamEncoderResource implementation.
|
// AdaptationListener implementation.
|
||||||
void OnAdaptationApplied(
|
void OnAdaptationApplied(
|
||||||
const VideoStreamInputState& input_state,
|
const VideoStreamInputState& input_state,
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
|
|||||||
@ -75,20 +75,6 @@ void VideoStreamEncoderResource::ClearUsageState() {
|
|||||||
usage_state_ = absl::nullopt;
|
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(
|
void VideoStreamEncoderResource::OnResourceUsageStateMeasured(
|
||||||
ResourceUsageState usage_state) {
|
ResourceUsageState usage_state) {
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
|
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/task_queue/task_queue_base.h"
|
#include "api/task_queue/task_queue_base.h"
|
||||||
|
#include "call/adaptation/adaptation_constraint.h"
|
||||||
|
#include "call/adaptation/adaptation_listener.h"
|
||||||
#include "call/adaptation/resource.h"
|
#include "call/adaptation/resource.h"
|
||||||
#include "rtc_base/critical_section.h"
|
#include "rtc_base/critical_section.h"
|
||||||
#include "rtc_base/synchronization/sequence_checker.h"
|
#include "rtc_base/synchronization/sequence_checker.h"
|
||||||
@ -30,24 +32,20 @@ class VideoStreamEncoderResource : public Resource {
|
|||||||
void RegisterEncoderTaskQueue(TaskQueueBase* encoder_queue);
|
void RegisterEncoderTaskQueue(TaskQueueBase* encoder_queue);
|
||||||
|
|
||||||
// Resource implementation.
|
// Resource implementation.
|
||||||
void RegisterAdaptationTaskQueue(
|
|
||||||
TaskQueueBase* resource_adaptation_queue) override;
|
|
||||||
void UnregisterAdaptationTaskQueue() override;
|
|
||||||
void SetResourceListener(ResourceListener* listener) override;
|
|
||||||
std::string Name() const override;
|
std::string Name() const override;
|
||||||
|
void SetResourceListener(ResourceListener* listener) override;
|
||||||
absl::optional<ResourceUsageState> UsageState() const override;
|
absl::optional<ResourceUsageState> UsageState() const override;
|
||||||
void ClearUsageState() override;
|
void ClearUsageState() override;
|
||||||
// Default implementations, may be overriden again by child classes.
|
|
||||||
bool IsAdaptationUpAllowed(
|
// Provides a pointer to the adaptation task queue. After this call, all
|
||||||
const VideoStreamInputState& input_state,
|
// methods defined in this interface, including
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
// UnregisterAdaptationTaskQueue() MUST be invoked on the adaptation task
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
// queue. Registering the adaptation task queue may, however, happen off the
|
||||||
rtc::scoped_refptr<Resource> reason_resource) const override;
|
// adaptation task queue.
|
||||||
void OnAdaptationApplied(
|
void RegisterAdaptationTaskQueue(TaskQueueBase* resource_adaptation_queue);
|
||||||
const VideoStreamInputState& input_state,
|
// Signals that the adaptation task queue is no longer safe to use. No
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
// assumptions must be made as to whether or not tasks in-flight will run.
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
void UnregisterAdaptationTaskQueue();
|
||||||
rtc::scoped_refptr<Resource> reason_resource) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit VideoStreamEncoderResource(std::string name);
|
explicit VideoStreamEncoderResource(std::string name);
|
||||||
|
|||||||
@ -139,26 +139,30 @@ class VideoStreamEncoderResourceManager::InitialFrameDropper {
|
|||||||
int initial_framedrop_;
|
int initial_framedrop_;
|
||||||
};
|
};
|
||||||
|
|
||||||
VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
|
VideoStreamEncoderResourceManager::ActiveCountsConstraint::
|
||||||
PreventAdaptUpDueToActiveCounts(VideoStreamEncoderResourceManager* manager)
|
ActiveCountsConstraint(VideoStreamEncoderResourceManager* manager)
|
||||||
: rtc::RefCountedObject<VideoStreamEncoderResource>(
|
: manager_(manager),
|
||||||
"PreventAdaptUpDueToActiveCounts"),
|
resource_adaptation_queue_(nullptr),
|
||||||
manager_(manager),
|
|
||||||
adaptation_processor_(nullptr) {}
|
adaptation_processor_(nullptr) {}
|
||||||
|
|
||||||
void VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
|
void VideoStreamEncoderResourceManager::ActiveCountsConstraint::
|
||||||
|
SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue) {
|
||||||
|
resource_adaptation_queue_ = resource_adaptation_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoStreamEncoderResourceManager::ActiveCountsConstraint::
|
||||||
SetAdaptationProcessor(
|
SetAdaptationProcessor(
|
||||||
ResourceAdaptationProcessorInterface* adaptation_processor) {
|
ResourceAdaptationProcessorInterface* adaptation_processor) {
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
|
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||||
adaptation_processor_ = adaptation_processor;
|
adaptation_processor_ = adaptation_processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
|
bool VideoStreamEncoderResourceManager::ActiveCountsConstraint::
|
||||||
IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
|
IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
const VideoSourceRestrictions& restrictions_after,
|
||||||
rtc::scoped_refptr<Resource> reason_resource) const {
|
rtc::scoped_refptr<Resource> reason_resource) const {
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
|
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||||
RTC_DCHECK(adaptation_processor_);
|
RTC_DCHECK(adaptation_processor_);
|
||||||
VideoAdaptationReason reason =
|
VideoAdaptationReason reason =
|
||||||
manager_->GetReasonFromResource(reason_resource);
|
manager_->GetReasonFromResource(reason_resource);
|
||||||
@ -185,52 +189,47 @@ bool VideoStreamEncoderResourceManager::PreventAdaptUpDueToActiveCounts::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoStreamEncoderResourceManager::
|
VideoStreamEncoderResourceManager::BitrateConstraint::BitrateConstraint(
|
||||||
PreventIncreaseResolutionDueToBitrateResource::
|
|
||||||
PreventIncreaseResolutionDueToBitrateResource(
|
|
||||||
VideoStreamEncoderResourceManager* manager)
|
VideoStreamEncoderResourceManager* manager)
|
||||||
: rtc::RefCountedObject<VideoStreamEncoderResource>(
|
: manager_(manager),
|
||||||
"PreventIncreaseResolutionDueToBitrateResource"),
|
resource_adaptation_queue_(nullptr),
|
||||||
manager_(manager),
|
|
||||||
encoder_settings_(absl::nullopt),
|
encoder_settings_(absl::nullopt),
|
||||||
encoder_target_bitrate_bps_(absl::nullopt) {}
|
encoder_target_bitrate_bps_(absl::nullopt) {}
|
||||||
|
|
||||||
void VideoStreamEncoderResourceManager::
|
void VideoStreamEncoderResourceManager::BitrateConstraint::SetAdaptationQueue(
|
||||||
PreventIncreaseResolutionDueToBitrateResource::OnEncoderSettingsUpdated(
|
TaskQueueBase* resource_adaptation_queue) {
|
||||||
absl::optional<EncoderSettings> encoder_settings) {
|
resource_adaptation_queue_ = resource_adaptation_queue;
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue());
|
|
||||||
MaybePostTaskToResourceAdaptationQueue(
|
|
||||||
[this_ref =
|
|
||||||
rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>(
|
|
||||||
this),
|
|
||||||
encoder_settings] {
|
|
||||||
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
|
|
||||||
this_ref->encoder_settings_ = std::move(encoder_settings);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoStreamEncoderResourceManager::
|
void VideoStreamEncoderResourceManager::BitrateConstraint::
|
||||||
PreventIncreaseResolutionDueToBitrateResource::
|
OnEncoderSettingsUpdated(absl::optional<EncoderSettings> encoder_settings) {
|
||||||
|
RTC_DCHECK_RUN_ON(manager_->encoder_queue_);
|
||||||
|
resource_adaptation_queue_->PostTask(
|
||||||
|
ToQueuedTask([this_ref = rtc::scoped_refptr<BitrateConstraint>(this),
|
||||||
|
encoder_settings] {
|
||||||
|
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
|
||||||
|
this_ref->encoder_settings_ = std::move(encoder_settings);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoStreamEncoderResourceManager::BitrateConstraint::
|
||||||
OnEncoderTargetBitrateUpdated(
|
OnEncoderTargetBitrateUpdated(
|
||||||
absl::optional<uint32_t> encoder_target_bitrate_bps) {
|
absl::optional<uint32_t> encoder_target_bitrate_bps) {
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue());
|
RTC_DCHECK_RUN_ON(manager_->encoder_queue_);
|
||||||
MaybePostTaskToResourceAdaptationQueue(
|
resource_adaptation_queue_->PostTask(
|
||||||
[this_ref =
|
ToQueuedTask([this_ref = rtc::scoped_refptr<BitrateConstraint>(this),
|
||||||
rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>(
|
|
||||||
this),
|
|
||||||
encoder_target_bitrate_bps] {
|
encoder_target_bitrate_bps] {
|
||||||
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
|
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
|
||||||
this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
|
this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoStreamEncoderResourceManager::
|
bool VideoStreamEncoderResourceManager::BitrateConstraint::
|
||||||
PreventIncreaseResolutionDueToBitrateResource::IsAdaptationUpAllowed(
|
IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
|
||||||
const VideoStreamInputState& input_state,
|
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
const VideoSourceRestrictions& restrictions_after,
|
||||||
rtc::scoped_refptr<Resource> reason_resource) const {
|
rtc::scoped_refptr<Resource> reason_resource) const {
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
|
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||||
VideoAdaptationReason reason =
|
VideoAdaptationReason reason =
|
||||||
manager_->GetReasonFromResource(reason_resource);
|
manager_->GetReasonFromResource(reason_resource);
|
||||||
// If increasing resolution due to kQuality, make sure bitrate limits are not
|
// If increasing resolution due to kQuality, make sure bitrate limits are not
|
||||||
@ -259,39 +258,43 @@ bool VideoStreamEncoderResourceManager::
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
|
VideoStreamEncoderResourceManager::BalancedConstraint::BalancedConstraint(
|
||||||
PreventAdaptUpInBalancedResource(VideoStreamEncoderResourceManager* manager)
|
VideoStreamEncoderResourceManager* manager)
|
||||||
: rtc::RefCountedObject<VideoStreamEncoderResource>(
|
: manager_(manager),
|
||||||
"PreventAdaptUpInBalancedResource"),
|
resource_adaptation_queue_(nullptr),
|
||||||
manager_(manager),
|
|
||||||
adaptation_processor_(nullptr),
|
adaptation_processor_(nullptr),
|
||||||
encoder_target_bitrate_bps_(absl::nullopt) {}
|
encoder_target_bitrate_bps_(absl::nullopt) {}
|
||||||
|
|
||||||
void VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
|
void VideoStreamEncoderResourceManager::BalancedConstraint::SetAdaptationQueue(
|
||||||
|
TaskQueueBase* resource_adaptation_queue) {
|
||||||
|
resource_adaptation_queue_ = resource_adaptation_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoStreamEncoderResourceManager::BalancedConstraint::
|
||||||
SetAdaptationProcessor(
|
SetAdaptationProcessor(
|
||||||
ResourceAdaptationProcessorInterface* adaptation_processor) {
|
ResourceAdaptationProcessorInterface* adaptation_processor) {
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
|
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||||
adaptation_processor_ = adaptation_processor;
|
adaptation_processor_ = adaptation_processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
|
void VideoStreamEncoderResourceManager::BalancedConstraint::
|
||||||
OnEncoderTargetBitrateUpdated(
|
OnEncoderTargetBitrateUpdated(
|
||||||
absl::optional<uint32_t> encoder_target_bitrate_bps) {
|
absl::optional<uint32_t> encoder_target_bitrate_bps) {
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue());
|
RTC_DCHECK_RUN_ON(manager_->encoder_queue_);
|
||||||
MaybePostTaskToResourceAdaptationQueue(
|
resource_adaptation_queue_->PostTask(
|
||||||
[this_ref = rtc::scoped_refptr<PreventAdaptUpInBalancedResource>(this),
|
ToQueuedTask([this_ref = rtc::scoped_refptr<BalancedConstraint>(this),
|
||||||
encoder_target_bitrate_bps] {
|
encoder_target_bitrate_bps] {
|
||||||
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue());
|
RTC_DCHECK_RUN_ON(this_ref->resource_adaptation_queue_);
|
||||||
this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
|
this_ref->encoder_target_bitrate_bps_ = encoder_target_bitrate_bps;
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoStreamEncoderResourceManager::PreventAdaptUpInBalancedResource::
|
bool VideoStreamEncoderResourceManager::BalancedConstraint::
|
||||||
IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
|
IsAdaptationUpAllowed(const VideoStreamInputState& input_state,
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
const VideoSourceRestrictions& restrictions_after,
|
const VideoSourceRestrictions& restrictions_after,
|
||||||
rtc::scoped_refptr<Resource> reason_resource) const {
|
rtc::scoped_refptr<Resource> reason_resource) const {
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue());
|
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||||
RTC_DCHECK(adaptation_processor_);
|
RTC_DCHECK(adaptation_processor_);
|
||||||
VideoAdaptationReason reason =
|
VideoAdaptationReason reason =
|
||||||
manager_->GetReasonFromResource(reason_resource);
|
manager_->GetReasonFromResource(reason_resource);
|
||||||
@ -325,12 +328,10 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager(
|
|||||||
Clock* clock,
|
Clock* clock,
|
||||||
bool experiment_cpu_load_estimator,
|
bool experiment_cpu_load_estimator,
|
||||||
std::unique_ptr<OveruseFrameDetector> overuse_detector)
|
std::unique_ptr<OveruseFrameDetector> overuse_detector)
|
||||||
: prevent_adapt_up_due_to_active_counts_(
|
: active_counts_constraint_(
|
||||||
new PreventAdaptUpDueToActiveCounts(this)),
|
new rtc::RefCountedObject<ActiveCountsConstraint>(this)),
|
||||||
prevent_increase_resolution_due_to_bitrate_resource_(
|
bitrate_constraint_(new rtc::RefCountedObject<BitrateConstraint>(this)),
|
||||||
new PreventIncreaseResolutionDueToBitrateResource(this)),
|
balanced_constraint_(new rtc::RefCountedObject<BalancedConstraint>(this)),
|
||||||
prevent_adapt_up_in_balanced_resource_(
|
|
||||||
new PreventAdaptUpInBalancedResource(this)),
|
|
||||||
encode_usage_resource_(
|
encode_usage_resource_(
|
||||||
EncodeUsageResource::Create(std::move(overuse_detector))),
|
EncodeUsageResource::Create(std::move(overuse_detector))),
|
||||||
quality_scaler_resource_(QualityScalerResource::Create()),
|
quality_scaler_resource_(QualityScalerResource::Create()),
|
||||||
@ -352,12 +353,6 @@ VideoStreamEncoderResourceManager::VideoStreamEncoderResourceManager(
|
|||||||
encoder_settings_(absl::nullopt),
|
encoder_settings_(absl::nullopt),
|
||||||
active_counts_() {
|
active_counts_() {
|
||||||
RTC_DCHECK(encoder_stats_observer_);
|
RTC_DCHECK(encoder_stats_observer_);
|
||||||
MapResourceToReason(prevent_adapt_up_due_to_active_counts_,
|
|
||||||
VideoAdaptationReason::kQuality);
|
|
||||||
MapResourceToReason(prevent_increase_resolution_due_to_bitrate_resource_,
|
|
||||||
VideoAdaptationReason::kQuality);
|
|
||||||
MapResourceToReason(prevent_adapt_up_in_balanced_resource_,
|
|
||||||
VideoAdaptationReason::kQuality);
|
|
||||||
MapResourceToReason(encode_usage_resource_, VideoAdaptationReason::kCpu);
|
MapResourceToReason(encode_usage_resource_, VideoAdaptationReason::kCpu);
|
||||||
MapResourceToReason(quality_scaler_resource_,
|
MapResourceToReason(quality_scaler_resource_,
|
||||||
VideoAdaptationReason::kQuality);
|
VideoAdaptationReason::kQuality);
|
||||||
@ -374,18 +369,10 @@ void VideoStreamEncoderResourceManager::Initialize(
|
|||||||
RTC_DCHECK(resource_adaptation_queue);
|
RTC_DCHECK(resource_adaptation_queue);
|
||||||
encoder_queue_ = encoder_queue;
|
encoder_queue_ = encoder_queue;
|
||||||
resource_adaptation_queue_ = resource_adaptation_queue;
|
resource_adaptation_queue_ = resource_adaptation_queue;
|
||||||
prevent_adapt_up_due_to_active_counts_->RegisterEncoderTaskQueue(
|
active_counts_constraint_->SetAdaptationQueue(
|
||||||
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());
|
resource_adaptation_queue_->Get());
|
||||||
|
bitrate_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
|
||||||
|
balanced_constraint_->SetAdaptationQueue(resource_adaptation_queue_->Get());
|
||||||
encode_usage_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
|
encode_usage_resource_->RegisterEncoderTaskQueue(encoder_queue_->Get());
|
||||||
encode_usage_resource_->RegisterAdaptationTaskQueue(
|
encode_usage_resource_->RegisterAdaptationTaskQueue(
|
||||||
resource_adaptation_queue_->Get());
|
resource_adaptation_queue_->Get());
|
||||||
@ -398,10 +385,8 @@ void VideoStreamEncoderResourceManager::SetAdaptationProcessor(
|
|||||||
ResourceAdaptationProcessorInterface* adaptation_processor) {
|
ResourceAdaptationProcessorInterface* adaptation_processor) {
|
||||||
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
RTC_DCHECK_RUN_ON(resource_adaptation_queue_);
|
||||||
adaptation_processor_ = adaptation_processor;
|
adaptation_processor_ = adaptation_processor;
|
||||||
prevent_adapt_up_due_to_active_counts_->SetAdaptationProcessor(
|
active_counts_constraint_->SetAdaptationProcessor(adaptation_processor);
|
||||||
adaptation_processor);
|
balanced_constraint_->SetAdaptationProcessor(adaptation_processor);
|
||||||
prevent_adapt_up_in_balanced_resource_->SetAdaptationProcessor(
|
|
||||||
adaptation_processor);
|
|
||||||
quality_scaler_resource_->SetAdaptationProcessor(adaptation_processor);
|
quality_scaler_resource_->SetAdaptationProcessor(adaptation_processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,6 +439,16 @@ VideoStreamEncoderResourceManager::MappedResources() const {
|
|||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<AdaptationConstraint*>
|
||||||
|
VideoStreamEncoderResourceManager::AdaptationConstraints() const {
|
||||||
|
return {active_counts_constraint_, bitrate_constraint_, balanced_constraint_};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<AdaptationListener*>
|
||||||
|
VideoStreamEncoderResourceManager::AdaptationListeners() const {
|
||||||
|
return {quality_scaler_resource_};
|
||||||
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<QualityScalerResource>
|
rtc::scoped_refptr<QualityScalerResource>
|
||||||
VideoStreamEncoderResourceManager::quality_scaler_resource_for_testing() {
|
VideoStreamEncoderResourceManager::quality_scaler_resource_for_testing() {
|
||||||
rtc::CritScope crit(&resource_lock_);
|
rtc::CritScope crit(&resource_lock_);
|
||||||
@ -464,8 +459,7 @@ void VideoStreamEncoderResourceManager::SetEncoderSettings(
|
|||||||
EncoderSettings encoder_settings) {
|
EncoderSettings encoder_settings) {
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||||
encoder_settings_ = std::move(encoder_settings);
|
encoder_settings_ = std::move(encoder_settings);
|
||||||
prevent_increase_resolution_due_to_bitrate_resource_
|
bitrate_constraint_->OnEncoderSettingsUpdated(encoder_settings_);
|
||||||
->OnEncoderSettingsUpdated(encoder_settings_);
|
|
||||||
|
|
||||||
quality_rampup_experiment_.SetMaxBitrate(
|
quality_rampup_experiment_.SetMaxBitrate(
|
||||||
LastInputFrameSizeOrDefault(),
|
LastInputFrameSizeOrDefault(),
|
||||||
@ -478,9 +472,9 @@ void VideoStreamEncoderResourceManager::SetStartBitrate(
|
|||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||||
if (!start_bitrate.IsZero()) {
|
if (!start_bitrate.IsZero()) {
|
||||||
encoder_target_bitrate_bps_ = start_bitrate.bps();
|
encoder_target_bitrate_bps_ = start_bitrate.bps();
|
||||||
prevent_increase_resolution_due_to_bitrate_resource_
|
bitrate_constraint_->OnEncoderTargetBitrateUpdated(
|
||||||
->OnEncoderTargetBitrateUpdated(encoder_target_bitrate_bps_);
|
encoder_target_bitrate_bps_);
|
||||||
prevent_adapt_up_in_balanced_resource_->OnEncoderTargetBitrateUpdated(
|
balanced_constraint_->OnEncoderTargetBitrateUpdated(
|
||||||
encoder_target_bitrate_bps_);
|
encoder_target_bitrate_bps_);
|
||||||
}
|
}
|
||||||
initial_frame_dropper_->SetStartBitrate(start_bitrate,
|
initial_frame_dropper_->SetStartBitrate(start_bitrate,
|
||||||
@ -492,9 +486,9 @@ void VideoStreamEncoderResourceManager::SetTargetBitrate(
|
|||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
RTC_DCHECK_RUN_ON(encoder_queue_);
|
||||||
if (!target_bitrate.IsZero()) {
|
if (!target_bitrate.IsZero()) {
|
||||||
encoder_target_bitrate_bps_ = target_bitrate.bps();
|
encoder_target_bitrate_bps_ = target_bitrate.bps();
|
||||||
prevent_increase_resolution_due_to_bitrate_resource_
|
bitrate_constraint_->OnEncoderTargetBitrateUpdated(
|
||||||
->OnEncoderTargetBitrateUpdated(encoder_target_bitrate_bps_);
|
encoder_target_bitrate_bps_);
|
||||||
prevent_adapt_up_in_balanced_resource_->OnEncoderTargetBitrateUpdated(
|
balanced_constraint_->OnEncoderTargetBitrateUpdated(
|
||||||
encoder_target_bitrate_bps_);
|
encoder_target_bitrate_bps_);
|
||||||
}
|
}
|
||||||
initial_frame_dropper_->SetTargetBitrate(target_bitrate,
|
initial_frame_dropper_->SetTargetBitrate(target_bitrate,
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/rtp_parameters.h"
|
#include "api/rtp_parameters.h"
|
||||||
#include "api/scoped_refptr.h"
|
#include "api/scoped_refptr.h"
|
||||||
|
#include "api/task_queue/task_queue_base.h"
|
||||||
#include "api/video/video_adaptation_counters.h"
|
#include "api/video/video_adaptation_counters.h"
|
||||||
#include "api/video/video_adaptation_reason.h"
|
#include "api/video/video_adaptation_reason.h"
|
||||||
#include "api/video/video_frame.h"
|
#include "api/video/video_frame.h"
|
||||||
@ -37,6 +38,7 @@
|
|||||||
#include "rtc_base/critical_section.h"
|
#include "rtc_base/critical_section.h"
|
||||||
#include "rtc_base/experiments/quality_rampup_experiment.h"
|
#include "rtc_base/experiments/quality_rampup_experiment.h"
|
||||||
#include "rtc_base/experiments/quality_scaler_settings.h"
|
#include "rtc_base/experiments/quality_scaler_settings.h"
|
||||||
|
#include "rtc_base/ref_count.h"
|
||||||
#include "rtc_base/strings/string_builder.h"
|
#include "rtc_base/strings/string_builder.h"
|
||||||
#include "rtc_base/task_queue.h"
|
#include "rtc_base/task_queue.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
@ -62,7 +64,7 @@ extern const int kDefaultInputPixelsHeight;
|
|||||||
// The manager is also involved with various mitigations not part of the
|
// The manager is also involved with various mitigations not part of the
|
||||||
// ResourceAdaptationProcessor code such as the inital frame dropping.
|
// ResourceAdaptationProcessor code such as the inital frame dropping.
|
||||||
class VideoStreamEncoderResourceManager
|
class VideoStreamEncoderResourceManager
|
||||||
: public ResourceAdaptationProcessorListener {
|
: public VideoSourceRestrictionsListener {
|
||||||
public:
|
public:
|
||||||
VideoStreamEncoderResourceManager(
|
VideoStreamEncoderResourceManager(
|
||||||
VideoStreamInputStateProvider* input_state_provider,
|
VideoStreamInputStateProvider* input_state_provider,
|
||||||
@ -117,13 +119,15 @@ class VideoStreamEncoderResourceManager
|
|||||||
void MapResourceToReason(rtc::scoped_refptr<Resource> resource,
|
void MapResourceToReason(rtc::scoped_refptr<Resource> resource,
|
||||||
VideoAdaptationReason reason);
|
VideoAdaptationReason reason);
|
||||||
std::vector<rtc::scoped_refptr<Resource>> MappedResources() const;
|
std::vector<rtc::scoped_refptr<Resource>> MappedResources() const;
|
||||||
|
std::vector<AdaptationConstraint*> AdaptationConstraints() const;
|
||||||
|
std::vector<AdaptationListener*> AdaptationListeners() const;
|
||||||
rtc::scoped_refptr<QualityScalerResource>
|
rtc::scoped_refptr<QualityScalerResource>
|
||||||
quality_scaler_resource_for_testing();
|
quality_scaler_resource_for_testing();
|
||||||
// If true, the VideoStreamEncoder should eexecute its logic to maybe drop
|
// If true, the VideoStreamEncoder should eexecute its logic to maybe drop
|
||||||
// frames baseed on size and bitrate.
|
// frames baseed on size and bitrate.
|
||||||
bool DropInitialFrames() const;
|
bool DropInitialFrames() const;
|
||||||
|
|
||||||
// ResourceAdaptationProcessorListener implementation.
|
// VideoSourceRestrictionsListener implementation.
|
||||||
// Updates |video_source_restrictions_| and |active_counts_|.
|
// Updates |video_source_restrictions_| and |active_counts_|.
|
||||||
void OnVideoSourceRestrictionsUpdated(
|
void OnVideoSourceRestrictionsUpdated(
|
||||||
VideoSourceRestrictions restrictions,
|
VideoSourceRestrictions restrictions,
|
||||||
@ -173,22 +177,22 @@ class VideoStreamEncoderResourceManager
|
|||||||
void ResetActiveCounts();
|
void ResetActiveCounts();
|
||||||
std::string ActiveCountsToString() const;
|
std::string ActiveCountsToString() const;
|
||||||
|
|
||||||
// TODO(hbos): Consider moving all of the manager's resources into separate
|
// TODO(hbos): Add tests for manager's constraints.
|
||||||
// files for testability.
|
|
||||||
|
|
||||||
// Does not trigger adaptations, only prevents adapting up based on
|
// Does not trigger adaptations, only prevents adapting up based on
|
||||||
// |active_counts_|.
|
// |active_counts_|.
|
||||||
class PreventAdaptUpDueToActiveCounts final
|
class ActiveCountsConstraint : public rtc::RefCountInterface,
|
||||||
: public rtc::RefCountedObject<VideoStreamEncoderResource> {
|
public AdaptationConstraint {
|
||||||
public:
|
public:
|
||||||
explicit PreventAdaptUpDueToActiveCounts(
|
explicit ActiveCountsConstraint(VideoStreamEncoderResourceManager* manager);
|
||||||
VideoStreamEncoderResourceManager* manager);
|
~ActiveCountsConstraint() override = default;
|
||||||
~PreventAdaptUpDueToActiveCounts() override = default;
|
|
||||||
|
|
||||||
|
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
|
||||||
void SetAdaptationProcessor(
|
void SetAdaptationProcessor(
|
||||||
ResourceAdaptationProcessorInterface* adaptation_processor);
|
ResourceAdaptationProcessorInterface* adaptation_processor);
|
||||||
|
|
||||||
// Resource overrides.
|
// AdaptationConstraint implementation.
|
||||||
|
std::string Name() const override { return "ActiveCountsConstraint"; }
|
||||||
bool IsAdaptationUpAllowed(
|
bool IsAdaptationUpAllowed(
|
||||||
const VideoStreamInputState& input_state,
|
const VideoStreamInputState& input_state,
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
@ -199,24 +203,26 @@ class VideoStreamEncoderResourceManager
|
|||||||
// The |manager_| must be alive as long as this resource is added to the
|
// The |manager_| must be alive as long as this resource is added to the
|
||||||
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
|
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
|
||||||
VideoStreamEncoderResourceManager* const manager_;
|
VideoStreamEncoderResourceManager* const manager_;
|
||||||
|
TaskQueueBase* resource_adaptation_queue_;
|
||||||
ResourceAdaptationProcessorInterface* adaptation_processor_
|
ResourceAdaptationProcessorInterface* adaptation_processor_
|
||||||
RTC_GUARDED_BY(resource_adaptation_queue());
|
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Does not trigger adaptations, only prevents adapting up resolution.
|
// Does not trigger adaptations, only prevents adapting up resolution.
|
||||||
class PreventIncreaseResolutionDueToBitrateResource final
|
class BitrateConstraint : public rtc::RefCountInterface,
|
||||||
: public rtc::RefCountedObject<VideoStreamEncoderResource> {
|
public AdaptationConstraint {
|
||||||
public:
|
public:
|
||||||
explicit PreventIncreaseResolutionDueToBitrateResource(
|
explicit BitrateConstraint(VideoStreamEncoderResourceManager* manager);
|
||||||
VideoStreamEncoderResourceManager* manager);
|
~BitrateConstraint() override = default;
|
||||||
~PreventIncreaseResolutionDueToBitrateResource() override = default;
|
|
||||||
|
|
||||||
|
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
|
||||||
void OnEncoderSettingsUpdated(
|
void OnEncoderSettingsUpdated(
|
||||||
absl::optional<EncoderSettings> encoder_settings);
|
absl::optional<EncoderSettings> encoder_settings);
|
||||||
void OnEncoderTargetBitrateUpdated(
|
void OnEncoderTargetBitrateUpdated(
|
||||||
absl::optional<uint32_t> encoder_target_bitrate_bps);
|
absl::optional<uint32_t> encoder_target_bitrate_bps);
|
||||||
|
|
||||||
// Resource overrides.
|
// AdaptationConstraint implementation.
|
||||||
|
std::string Name() const override { return "BitrateConstraint"; }
|
||||||
bool IsAdaptationUpAllowed(
|
bool IsAdaptationUpAllowed(
|
||||||
const VideoStreamInputState& input_state,
|
const VideoStreamInputState& input_state,
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
@ -227,26 +233,28 @@ class VideoStreamEncoderResourceManager
|
|||||||
// The |manager_| must be alive as long as this resource is added to the
|
// The |manager_| must be alive as long as this resource is added to the
|
||||||
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
|
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
|
||||||
VideoStreamEncoderResourceManager* const manager_;
|
VideoStreamEncoderResourceManager* const manager_;
|
||||||
|
TaskQueueBase* resource_adaptation_queue_;
|
||||||
absl::optional<EncoderSettings> encoder_settings_
|
absl::optional<EncoderSettings> encoder_settings_
|
||||||
RTC_GUARDED_BY(resource_adaptation_queue());
|
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||||
absl::optional<uint32_t> encoder_target_bitrate_bps_
|
absl::optional<uint32_t> encoder_target_bitrate_bps_
|
||||||
RTC_GUARDED_BY(resource_adaptation_queue());
|
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Does not trigger adaptations, only prevents adapting up in BALANCED.
|
// Does not trigger adaptations, only prevents adapting up in BALANCED.
|
||||||
class PreventAdaptUpInBalancedResource final
|
class BalancedConstraint : public rtc::RefCountInterface,
|
||||||
: public rtc::RefCountedObject<VideoStreamEncoderResource> {
|
public AdaptationConstraint {
|
||||||
public:
|
public:
|
||||||
explicit PreventAdaptUpInBalancedResource(
|
explicit BalancedConstraint(VideoStreamEncoderResourceManager* manager);
|
||||||
VideoStreamEncoderResourceManager* manager);
|
~BalancedConstraint() override = default;
|
||||||
~PreventAdaptUpInBalancedResource() override = default;
|
|
||||||
|
|
||||||
|
void SetAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
|
||||||
void SetAdaptationProcessor(
|
void SetAdaptationProcessor(
|
||||||
ResourceAdaptationProcessorInterface* adaptation_processor);
|
ResourceAdaptationProcessorInterface* adaptation_processor);
|
||||||
void OnEncoderTargetBitrateUpdated(
|
void OnEncoderTargetBitrateUpdated(
|
||||||
absl::optional<uint32_t> encoder_target_bitrate_bps);
|
absl::optional<uint32_t> encoder_target_bitrate_bps);
|
||||||
|
|
||||||
// Resource overrides.
|
// AdaptationConstraint implementation.
|
||||||
|
std::string Name() const override { return "BalancedConstraint"; }
|
||||||
bool IsAdaptationUpAllowed(
|
bool IsAdaptationUpAllowed(
|
||||||
const VideoStreamInputState& input_state,
|
const VideoStreamInputState& input_state,
|
||||||
const VideoSourceRestrictions& restrictions_before,
|
const VideoSourceRestrictions& restrictions_before,
|
||||||
@ -257,18 +265,16 @@ class VideoStreamEncoderResourceManager
|
|||||||
// The |manager_| must be alive as long as this resource is added to the
|
// The |manager_| must be alive as long as this resource is added to the
|
||||||
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
|
// ResourceAdaptationProcessor, i.e. when IsAdaptationUpAllowed() is called.
|
||||||
VideoStreamEncoderResourceManager* const manager_;
|
VideoStreamEncoderResourceManager* const manager_;
|
||||||
|
TaskQueueBase* resource_adaptation_queue_;
|
||||||
ResourceAdaptationProcessorInterface* adaptation_processor_
|
ResourceAdaptationProcessorInterface* adaptation_processor_
|
||||||
RTC_GUARDED_BY(resource_adaptation_queue());
|
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||||
absl::optional<uint32_t> encoder_target_bitrate_bps_
|
absl::optional<uint32_t> encoder_target_bitrate_bps_
|
||||||
RTC_GUARDED_BY(resource_adaptation_queue());
|
RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||||
};
|
};
|
||||||
|
|
||||||
const rtc::scoped_refptr<PreventAdaptUpDueToActiveCounts>
|
const rtc::scoped_refptr<ActiveCountsConstraint> active_counts_constraint_;
|
||||||
prevent_adapt_up_due_to_active_counts_;
|
const rtc::scoped_refptr<BitrateConstraint> bitrate_constraint_;
|
||||||
const rtc::scoped_refptr<PreventIncreaseResolutionDueToBitrateResource>
|
const rtc::scoped_refptr<BalancedConstraint> balanced_constraint_;
|
||||||
prevent_increase_resolution_due_to_bitrate_resource_;
|
|
||||||
const rtc::scoped_refptr<PreventAdaptUpInBalancedResource>
|
|
||||||
prevent_adapt_up_in_balanced_resource_;
|
|
||||||
const rtc::scoped_refptr<EncodeUsageResource> encode_usage_resource_;
|
const rtc::scoped_refptr<EncodeUsageResource> encode_usage_resource_;
|
||||||
const rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource_;
|
const rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource_;
|
||||||
|
|
||||||
@ -321,7 +327,7 @@ class VideoStreamEncoderResourceManager
|
|||||||
// TODO(https://crbug.com/webrtc/11542): When we have an adaptation queue,
|
// TODO(https://crbug.com/webrtc/11542): When we have an adaptation queue,
|
||||||
// guard the activec counts by it instead. The |encoder_stats_observer_| is
|
// guard the activec counts by it instead. The |encoder_stats_observer_| is
|
||||||
// thread-safe anyway, and active counts are used by
|
// thread-safe anyway, and active counts are used by
|
||||||
// PreventAdaptUpDueToActiveCounts to make decisions.
|
// ActiveCountsConstraint to make decisions.
|
||||||
std::unordered_map<VideoAdaptationReason, VideoAdaptationCounters>
|
std::unordered_map<VideoAdaptationReason, VideoAdaptationCounters>
|
||||||
active_counts_ RTC_GUARDED_BY(resource_adaptation_queue_);
|
active_counts_ RTC_GUARDED_BY(resource_adaptation_queue_);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -260,6 +260,8 @@ VideoStreamEncoder::VideoStreamEncoder(
|
|||||||
std::make_unique<ResourceAdaptationProcessor>(
|
std::make_unique<ResourceAdaptationProcessor>(
|
||||||
&input_state_provider_,
|
&input_state_provider_,
|
||||||
encoder_stats_observer)),
|
encoder_stats_observer)),
|
||||||
|
adaptation_constraints_(),
|
||||||
|
adaptation_listeners_(),
|
||||||
stream_resource_manager_(&input_state_provider_,
|
stream_resource_manager_(&input_state_provider_,
|
||||||
encoder_stats_observer,
|
encoder_stats_observer,
|
||||||
clock_,
|
clock_,
|
||||||
@ -285,12 +287,22 @@ VideoStreamEncoder::VideoStreamEncoder(
|
|||||||
resource_adaptation_processor_->InitializeOnResourceAdaptationQueue();
|
resource_adaptation_processor_->InitializeOnResourceAdaptationQueue();
|
||||||
stream_resource_manager_.SetAdaptationProcessor(
|
stream_resource_manager_.SetAdaptationProcessor(
|
||||||
resource_adaptation_processor_.get());
|
resource_adaptation_processor_.get());
|
||||||
resource_adaptation_processor_->AddAdaptationListener(
|
resource_adaptation_processor_->AddRestrictionsListener(
|
||||||
&stream_resource_manager_);
|
&stream_resource_manager_);
|
||||||
resource_adaptation_processor_->AddAdaptationListener(this);
|
resource_adaptation_processor_->AddRestrictionsListener(this);
|
||||||
|
|
||||||
// Add the stream resource manager's resources to the processor.
|
// Add the stream resource manager's resources to the processor.
|
||||||
for (Resource* resource : stream_resource_manager_.MappedResources())
|
adaptation_constraints_ = stream_resource_manager_.AdaptationConstraints();
|
||||||
|
adaptation_listeners_ = stream_resource_manager_.AdaptationListeners();
|
||||||
|
for (auto& resource : stream_resource_manager_.MappedResources()) {
|
||||||
resource_adaptation_processor_->AddResource(resource);
|
resource_adaptation_processor_->AddResource(resource);
|
||||||
|
}
|
||||||
|
for (auto* constraint : adaptation_constraints_) {
|
||||||
|
resource_adaptation_processor_->AddAdaptationConstraint(constraint);
|
||||||
|
}
|
||||||
|
for (auto* listener : adaptation_listeners_) {
|
||||||
|
resource_adaptation_processor_->AddAdaptationListener(listener);
|
||||||
|
}
|
||||||
initialize_processor_event.Set();
|
initialize_processor_event.Set();
|
||||||
});
|
});
|
||||||
initialize_processor_event.Wait(rtc::Event::kForever);
|
initialize_processor_event.Wait(rtc::Event::kForever);
|
||||||
@ -312,11 +324,17 @@ void VideoStreamEncoder::Stop() {
|
|||||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||||
if (resource_adaptation_processor_) {
|
if (resource_adaptation_processor_) {
|
||||||
resource_adaptation_processor_->StopResourceAdaptation();
|
resource_adaptation_processor_->StopResourceAdaptation();
|
||||||
for (Resource* resource : stream_resource_manager_.MappedResources()) {
|
for (auto& resource : stream_resource_manager_.MappedResources()) {
|
||||||
resource_adaptation_processor_->RemoveResource(resource);
|
resource_adaptation_processor_->RemoveResource(resource);
|
||||||
}
|
}
|
||||||
resource_adaptation_processor_->RemoveAdaptationListener(this);
|
for (auto* constraint : adaptation_constraints_) {
|
||||||
resource_adaptation_processor_->RemoveAdaptationListener(
|
resource_adaptation_processor_->RemoveAdaptationConstraint(constraint);
|
||||||
|
}
|
||||||
|
for (auto* listener : adaptation_listeners_) {
|
||||||
|
resource_adaptation_processor_->RemoveAdaptationListener(listener);
|
||||||
|
}
|
||||||
|
resource_adaptation_processor_->RemoveRestrictionsListener(this);
|
||||||
|
resource_adaptation_processor_->RemoveRestrictionsListener(
|
||||||
&stream_resource_manager_);
|
&stream_resource_manager_);
|
||||||
stream_resource_manager_.SetAdaptationProcessor(nullptr);
|
stream_resource_manager_.SetAdaptationProcessor(nullptr);
|
||||||
resource_adaptation_processor_.reset();
|
resource_adaptation_processor_.reset();
|
||||||
@ -1978,7 +1996,8 @@ void VideoStreamEncoder::InjectAdaptationResource(
|
|||||||
});
|
});
|
||||||
map_resource_event.Wait(rtc::Event::kForever);
|
map_resource_event.Wait(rtc::Event::kForever);
|
||||||
|
|
||||||
resource_adaptation_queue_.PostTask([this, resource] {
|
rtc::Event add_resource_event;
|
||||||
|
resource_adaptation_queue_.PostTask([this, resource, &add_resource_event] {
|
||||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||||
if (!resource_adaptation_processor_) {
|
if (!resource_adaptation_processor_) {
|
||||||
// The VideoStreamEncoder was stopped and the processor destroyed before
|
// The VideoStreamEncoder was stopped and the processor destroyed before
|
||||||
@ -1986,7 +2005,44 @@ void VideoStreamEncoder::InjectAdaptationResource(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resource_adaptation_processor_->AddResource(resource);
|
resource_adaptation_processor_->AddResource(resource);
|
||||||
|
add_resource_event.Set();
|
||||||
});
|
});
|
||||||
|
add_resource_event.Wait(rtc::Event::kForever);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoStreamEncoder::InjectAdaptationConstraint(
|
||||||
|
AdaptationConstraint* adaptation_constraint) {
|
||||||
|
rtc::Event event;
|
||||||
|
resource_adaptation_queue_.PostTask([this, adaptation_constraint, &event] {
|
||||||
|
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||||
|
if (!resource_adaptation_processor_) {
|
||||||
|
// The VideoStreamEncoder was stopped and the processor destroyed before
|
||||||
|
// this task had a chance to execute. No action needed.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
adaptation_constraints_.push_back(adaptation_constraint);
|
||||||
|
resource_adaptation_processor_->AddAdaptationConstraint(
|
||||||
|
adaptation_constraint);
|
||||||
|
event.Set();
|
||||||
|
});
|
||||||
|
event.Wait(rtc::Event::kForever);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoStreamEncoder::InjectAdaptationListener(
|
||||||
|
AdaptationListener* adaptation_listener) {
|
||||||
|
rtc::Event event;
|
||||||
|
resource_adaptation_queue_.PostTask([this, adaptation_listener, &event] {
|
||||||
|
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||||
|
if (!resource_adaptation_processor_) {
|
||||||
|
// The VideoStreamEncoder was stopped and the processor destroyed before
|
||||||
|
// this task had a chance to execute. No action needed.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
adaptation_listeners_.push_back(adaptation_listener);
|
||||||
|
resource_adaptation_processor_->AddAdaptationListener(adaptation_listener);
|
||||||
|
event.Set();
|
||||||
|
});
|
||||||
|
event.Wait(rtc::Event::kForever);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<QualityScalerResource>
|
rtc::scoped_refptr<QualityScalerResource>
|
||||||
@ -1995,26 +2051,27 @@ VideoStreamEncoder::quality_scaler_resource_for_testing() {
|
|||||||
return stream_resource_manager_.quality_scaler_resource_for_testing();
|
return stream_resource_manager_.quality_scaler_resource_for_testing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoStreamEncoder::AddAdaptationListenerForTesting(
|
void VideoStreamEncoder::AddRestrictionsListenerForTesting(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener) {
|
VideoSourceRestrictionsListener* restrictions_listener) {
|
||||||
rtc::Event event;
|
rtc::Event event;
|
||||||
resource_adaptation_queue_.PostTask([this, adaptation_listener, &event] {
|
resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
|
||||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||||
RTC_DCHECK(resource_adaptation_processor_);
|
RTC_DCHECK(resource_adaptation_processor_);
|
||||||
resource_adaptation_processor_->AddAdaptationListener(adaptation_listener);
|
resource_adaptation_processor_->AddRestrictionsListener(
|
||||||
|
restrictions_listener);
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
event.Wait(rtc::Event::kForever);
|
event.Wait(rtc::Event::kForever);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoStreamEncoder::RemoveAdaptationListenerForTesting(
|
void VideoStreamEncoder::RemoveRestrictionsListenerForTesting(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener) {
|
VideoSourceRestrictionsListener* restrictions_listener) {
|
||||||
rtc::Event event;
|
rtc::Event event;
|
||||||
resource_adaptation_queue_.PostTask([this, adaptation_listener, &event] {
|
resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
|
||||||
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
|
||||||
RTC_DCHECK(resource_adaptation_processor_);
|
RTC_DCHECK(resource_adaptation_processor_);
|
||||||
resource_adaptation_processor_->RemoveAdaptationListener(
|
resource_adaptation_processor_->RemoveRestrictionsListener(
|
||||||
adaptation_listener);
|
restrictions_listener);
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
event.Wait(rtc::Event::kForever);
|
event.Wait(rtc::Event::kForever);
|
||||||
|
|||||||
@ -26,6 +26,9 @@
|
|||||||
#include "api/video/video_stream_encoder_settings.h"
|
#include "api/video/video_stream_encoder_settings.h"
|
||||||
#include "api/video_codecs/video_codec.h"
|
#include "api/video_codecs/video_codec.h"
|
||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
|
#include "call/adaptation/adaptation_constraint.h"
|
||||||
|
#include "call/adaptation/adaptation_listener.h"
|
||||||
|
#include "call/adaptation/resource.h"
|
||||||
#include "call/adaptation/resource_adaptation_processor_interface.h"
|
#include "call/adaptation/resource_adaptation_processor_interface.h"
|
||||||
#include "call/adaptation/video_source_restrictions.h"
|
#include "call/adaptation/video_source_restrictions.h"
|
||||||
#include "call/adaptation/video_stream_input_state_provider.h"
|
#include "call/adaptation/video_stream_input_state_provider.h"
|
||||||
@ -44,6 +47,7 @@
|
|||||||
#include "video/encoder_bitrate_adjuster.h"
|
#include "video/encoder_bitrate_adjuster.h"
|
||||||
#include "video/frame_encode_metadata_writer.h"
|
#include "video/frame_encode_metadata_writer.h"
|
||||||
#include "video/video_source_sink_controller.h"
|
#include "video/video_source_sink_controller.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
// VideoStreamEncoder represent a video encoder that accepts raw video frames as
|
// VideoStreamEncoder represent a video encoder that accepts raw video frames as
|
||||||
@ -56,7 +60,7 @@ namespace webrtc {
|
|||||||
// Call Stop() when done.
|
// Call Stop() when done.
|
||||||
class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
||||||
private EncodedImageCallback,
|
private EncodedImageCallback,
|
||||||
public ResourceAdaptationProcessorListener {
|
public VideoSourceRestrictionsListener {
|
||||||
public:
|
public:
|
||||||
VideoStreamEncoder(Clock* clock,
|
VideoStreamEncoder(Clock* clock,
|
||||||
uint32_t number_of_cores,
|
uint32_t number_of_cores,
|
||||||
@ -118,16 +122,17 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
|||||||
// Used for injected test resources.
|
// Used for injected test resources.
|
||||||
// TODO(eshr): Move all adaptation tests out of VideoStreamEncoder tests.
|
// TODO(eshr): Move all adaptation tests out of VideoStreamEncoder tests.
|
||||||
void InjectAdaptationResource(rtc::scoped_refptr<Resource> resource,
|
void InjectAdaptationResource(rtc::scoped_refptr<Resource> resource,
|
||||||
VideoAdaptationReason reason)
|
VideoAdaptationReason reason);
|
||||||
RTC_RUN_ON(&encoder_queue_);
|
void InjectAdaptationConstraint(AdaptationConstraint* adaptation_constraint);
|
||||||
|
void InjectAdaptationListener(AdaptationListener* adaptation_listener);
|
||||||
|
|
||||||
rtc::scoped_refptr<QualityScalerResource>
|
rtc::scoped_refptr<QualityScalerResource>
|
||||||
quality_scaler_resource_for_testing();
|
quality_scaler_resource_for_testing();
|
||||||
|
|
||||||
void AddAdaptationListenerForTesting(
|
void AddRestrictionsListenerForTesting(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener);
|
VideoSourceRestrictionsListener* restrictions_listener);
|
||||||
void RemoveAdaptationListenerForTesting(
|
void RemoveRestrictionsListenerForTesting(
|
||||||
ResourceAdaptationProcessorListener* adaptation_listener);
|
VideoSourceRestrictionsListener* restrictions_listener);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class VideoFrameInfo {
|
class VideoFrameInfo {
|
||||||
@ -406,6 +411,10 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
|||||||
std::unique_ptr<ResourceAdaptationProcessorInterface>
|
std::unique_ptr<ResourceAdaptationProcessorInterface>
|
||||||
resource_adaptation_processor_
|
resource_adaptation_processor_
|
||||||
RTC_GUARDED_BY(&resource_adaptation_queue_);
|
RTC_GUARDED_BY(&resource_adaptation_queue_);
|
||||||
|
std::vector<AdaptationConstraint*> adaptation_constraints_
|
||||||
|
RTC_GUARDED_BY(&resource_adaptation_queue_);
|
||||||
|
std::vector<AdaptationListener*> adaptation_listeners_
|
||||||
|
RTC_GUARDED_BY(&resource_adaptation_queue_);
|
||||||
// Handles input, output and stats reporting related to VideoStreamEncoder
|
// Handles input, output and stats reporting related to VideoStreamEncoder
|
||||||
// specific resources, such as "encode usage percent" measurements and "QP
|
// specific resources, such as "encode usage percent" measurements and "QP
|
||||||
// scaling". Also involved with various mitigations such as inital frame
|
// scaling". Also involved with various mitigations such as inital frame
|
||||||
|
|||||||
@ -26,6 +26,8 @@
|
|||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||||
#include "api/video_codecs/vp8_temporal_layers_factory.h"
|
#include "api/video_codecs/vp8_temporal_layers_factory.h"
|
||||||
|
#include "call/adaptation/test/fake_adaptation_constraint.h"
|
||||||
|
#include "call/adaptation/test/fake_adaptation_listener.h"
|
||||||
#include "call/adaptation/test/fake_resource.h"
|
#include "call/adaptation/test/fake_resource.h"
|
||||||
#include "common_video/h264/h264_common.h"
|
#include "common_video/h264/h264_common.h"
|
||||||
#include "common_video/include/video_frame_buffer.h"
|
#include "common_video/include/video_frame_buffer.h"
|
||||||
@ -186,12 +188,12 @@ class FakeQualityScalerQpUsageHandlerCallback
|
|||||||
absl::optional<bool> clear_qp_samples_result_;
|
absl::optional<bool> clear_qp_samples_result_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VideoSourceRestrictionsUpdatedListener
|
class FakeVideoSourceRestrictionsListener
|
||||||
: public ResourceAdaptationProcessorListener {
|
: public VideoSourceRestrictionsListener {
|
||||||
public:
|
public:
|
||||||
VideoSourceRestrictionsUpdatedListener()
|
FakeVideoSourceRestrictionsListener()
|
||||||
: was_restrictions_updated_(false), restrictions_updated_event_() {}
|
: was_restrictions_updated_(false), restrictions_updated_event_() {}
|
||||||
~VideoSourceRestrictionsUpdatedListener() override {
|
~FakeVideoSourceRestrictionsListener() override {
|
||||||
RTC_DCHECK(was_restrictions_updated_);
|
RTC_DCHECK(was_restrictions_updated_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +201,7 @@ class VideoSourceRestrictionsUpdatedListener
|
|||||||
return &restrictions_updated_event_;
|
return &restrictions_updated_event_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceAdaptationProcessorListener implementation.
|
// VideoSourceRestrictionsListener implementation.
|
||||||
void OnVideoSourceRestrictionsUpdated(
|
void OnVideoSourceRestrictionsUpdated(
|
||||||
VideoSourceRestrictions restrictions,
|
VideoSourceRestrictions restrictions,
|
||||||
const VideoAdaptationCounters& adaptation_counters,
|
const VideoAdaptationCounters& adaptation_counters,
|
||||||
@ -317,24 +319,24 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||||||
new CpuOveruseDetectorProxy(stats_proxy)),
|
new CpuOveruseDetectorProxy(stats_proxy)),
|
||||||
task_queue_factory),
|
task_queue_factory),
|
||||||
fake_cpu_resource_(FakeResource::Create("FakeResource[CPU]")),
|
fake_cpu_resource_(FakeResource::Create("FakeResource[CPU]")),
|
||||||
fake_quality_resource_(FakeResource::Create("FakeResource[QP]")) {
|
fake_quality_resource_(FakeResource::Create("FakeResource[QP]")),
|
||||||
fake_cpu_resource_->RegisterAdaptationTaskQueue(
|
fake_adaptation_constraint_("FakeAdaptationConstraint"),
|
||||||
resource_adaptation_queue()->Get());
|
fake_adaptation_listener_() {
|
||||||
fake_quality_resource_->RegisterAdaptationTaskQueue(
|
|
||||||
resource_adaptation_queue()->Get());
|
|
||||||
InjectAdaptationResource(fake_quality_resource_,
|
InjectAdaptationResource(fake_quality_resource_,
|
||||||
VideoAdaptationReason::kQuality);
|
VideoAdaptationReason::kQuality);
|
||||||
InjectAdaptationResource(fake_cpu_resource_, VideoAdaptationReason::kCpu);
|
InjectAdaptationResource(fake_cpu_resource_, VideoAdaptationReason::kCpu);
|
||||||
|
InjectAdaptationConstraint(&fake_adaptation_constraint_);
|
||||||
|
InjectAdaptationListener(&fake_adaptation_listener_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSourceAndWaitForRestrictionsUpdated(
|
void SetSourceAndWaitForRestrictionsUpdated(
|
||||||
rtc::VideoSourceInterface<VideoFrame>* source,
|
rtc::VideoSourceInterface<VideoFrame>* source,
|
||||||
const DegradationPreference& degradation_preference) {
|
const DegradationPreference& degradation_preference) {
|
||||||
VideoSourceRestrictionsUpdatedListener listener;
|
FakeVideoSourceRestrictionsListener listener;
|
||||||
AddAdaptationListenerForTesting(&listener);
|
AddRestrictionsListenerForTesting(&listener);
|
||||||
SetSource(source, degradation_preference);
|
SetSource(source, degradation_preference);
|
||||||
listener.restrictions_updated_event()->Wait(5000);
|
listener.restrictions_updated_event()->Wait(5000);
|
||||||
RemoveAdaptationListenerForTesting(&listener);
|
RemoveRestrictionsListenerForTesting(&listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSourceAndWaitForFramerateUpdated(
|
void SetSourceAndWaitForFramerateUpdated(
|
||||||
@ -379,7 +381,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||||||
void TriggerCpuOveruse() {
|
void TriggerCpuOveruse() {
|
||||||
rtc::Event event;
|
rtc::Event event;
|
||||||
resource_adaptation_queue()->PostTask([this, &event] {
|
resource_adaptation_queue()->PostTask([this, &event] {
|
||||||
fake_cpu_resource_->set_usage_state(ResourceUsageState::kOveruse);
|
fake_cpu_resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
ASSERT_TRUE(event.Wait(5000));
|
ASSERT_TRUE(event.Wait(5000));
|
||||||
@ -387,7 +389,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||||||
void TriggerCpuUnderuse() {
|
void TriggerCpuUnderuse() {
|
||||||
rtc::Event event;
|
rtc::Event event;
|
||||||
resource_adaptation_queue()->PostTask([this, &event] {
|
resource_adaptation_queue()->PostTask([this, &event] {
|
||||||
fake_cpu_resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
fake_cpu_resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
ASSERT_TRUE(event.Wait(5000));
|
ASSERT_TRUE(event.Wait(5000));
|
||||||
@ -397,7 +399,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||||||
void TriggerQualityLow() {
|
void TriggerQualityLow() {
|
||||||
rtc::Event event;
|
rtc::Event event;
|
||||||
resource_adaptation_queue()->PostTask([this, &event] {
|
resource_adaptation_queue()->PostTask([this, &event] {
|
||||||
fake_quality_resource_->set_usage_state(ResourceUsageState::kOveruse);
|
fake_quality_resource_->SetUsageState(ResourceUsageState::kOveruse);
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
ASSERT_TRUE(event.Wait(5000));
|
ASSERT_TRUE(event.Wait(5000));
|
||||||
@ -405,7 +407,7 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||||||
void TriggerQualityHigh() {
|
void TriggerQualityHigh() {
|
||||||
rtc::Event event;
|
rtc::Event event;
|
||||||
resource_adaptation_queue()->PostTask([this, &event] {
|
resource_adaptation_queue()->PostTask([this, &event] {
|
||||||
fake_quality_resource_->set_usage_state(ResourceUsageState::kUnderuse);
|
fake_quality_resource_->SetUsageState(ResourceUsageState::kUnderuse);
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
ASSERT_TRUE(event.Wait(5000));
|
ASSERT_TRUE(event.Wait(5000));
|
||||||
@ -430,6 +432,8 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||||||
CpuOveruseDetectorProxy* overuse_detector_proxy_;
|
CpuOveruseDetectorProxy* overuse_detector_proxy_;
|
||||||
rtc::scoped_refptr<FakeResource> fake_cpu_resource_;
|
rtc::scoped_refptr<FakeResource> fake_cpu_resource_;
|
||||||
rtc::scoped_refptr<FakeResource> fake_quality_resource_;
|
rtc::scoped_refptr<FakeResource> fake_quality_resource_;
|
||||||
|
FakeAdaptationConstraint fake_adaptation_constraint_;
|
||||||
|
FakeAdaptationListener fake_adaptation_listener_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VideoStreamFactory
|
class VideoStreamFactory
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user