Move DegradationPreference logic to the encoder queue.
This moves SetHasInputVideoAndDegradationPreference() to the encoder queue. OveruseFrameDetectorResourceAdaptationModule is now entirely single-threaded, including its inner class VideoSourceRestrictor. VideoStreamEncoder now protects the module with RTC_GUARDED_BY. This ensures it is safely used, even without a SequenceChecker inside of the module. The module's |encoder_queue_| is removed. The one task queue reference that is needed - passing down the current task queue to StartCheckForOveruse() - is replaced by a TaskQueueBase* (instead of rtc::TaskQueue*), enabling obtaining the current queue with TaskQueueBase::Current(). (There is no rtc::TaskQueue::Current().) Furthermore, the only uses of VideoSourceSinkController that isn't on the encoder queue are documented, with a TODO saying if these are moved the VideoSourceSinkController could also be made single-threaded. However since this requires introducing a delay to VideoStreamEncoder::SetSource() and VideoStreamEncoder::Stop(), arguably a more risky change, if this is to be attempted that should be in a separate CL. Bug: webrtc:11222 Change-Id: I448ca5125708d5f66b95b0b180d6d24cc356dfa9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/165783 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30263}
This commit is contained in:
parent
6ef59d1ced
commit
07b17df771
@ -194,6 +194,7 @@ rtc_library("video_stream_encoder_impl") {
|
|||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
"../api:rtp_parameters",
|
"../api:rtp_parameters",
|
||||||
|
"../api/task_queue:task_queue",
|
||||||
"../api/units:data_rate",
|
"../api/units:data_rate",
|
||||||
"../api/video:encoded_image",
|
"../api/video:encoded_image",
|
||||||
"../api/video:video_bitrate_allocation",
|
"../api/video:video_bitrate_allocation",
|
||||||
|
|||||||
@ -540,7 +540,7 @@ OveruseFrameDetector::OveruseFrameDetector(
|
|||||||
OveruseFrameDetector::~OveruseFrameDetector() {}
|
OveruseFrameDetector::~OveruseFrameDetector() {}
|
||||||
|
|
||||||
void OveruseFrameDetector::StartCheckForOveruse(
|
void OveruseFrameDetector::StartCheckForOveruse(
|
||||||
rtc::TaskQueue* task_queue,
|
TaskQueueBase* task_queue_base,
|
||||||
const CpuOveruseOptions& options,
|
const CpuOveruseOptions& options,
|
||||||
AdaptationObserverInterface* overuse_observer) {
|
AdaptationObserverInterface* overuse_observer) {
|
||||||
RTC_DCHECK_RUN_ON(&task_checker_);
|
RTC_DCHECK_RUN_ON(&task_checker_);
|
||||||
@ -549,7 +549,7 @@ void OveruseFrameDetector::StartCheckForOveruse(
|
|||||||
|
|
||||||
SetOptions(options);
|
SetOptions(options);
|
||||||
check_overuse_task_ = RepeatingTaskHandle::DelayedStart(
|
check_overuse_task_ = RepeatingTaskHandle::DelayedStart(
|
||||||
task_queue->Get(), TimeDelta::ms(kTimeToFirstCheckForOveruseMs),
|
task_queue_base, TimeDelta::ms(kTimeToFirstCheckForOveruseMs),
|
||||||
[this, overuse_observer] {
|
[this, overuse_observer] {
|
||||||
CheckForOveruse(overuse_observer);
|
CheckForOveruse(overuse_observer);
|
||||||
return TimeDelta::ms(kCheckForOveruseIntervalMs);
|
return TimeDelta::ms(kCheckForOveruseIntervalMs);
|
||||||
|
|||||||
@ -15,13 +15,13 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
|
#include "api/task_queue/task_queue_base.h"
|
||||||
#include "api/video/video_stream_encoder_observer.h"
|
#include "api/video/video_stream_encoder_observer.h"
|
||||||
#include "modules/video_coding/utility/quality_scaler.h"
|
#include "modules/video_coding/utility/quality_scaler.h"
|
||||||
#include "rtc_base/constructor_magic.h"
|
#include "rtc_base/constructor_magic.h"
|
||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
#include "rtc_base/numerics/exp_filter.h"
|
#include "rtc_base/numerics/exp_filter.h"
|
||||||
#include "rtc_base/synchronization/sequence_checker.h"
|
#include "rtc_base/synchronization/sequence_checker.h"
|
||||||
#include "rtc_base/task_queue.h"
|
|
||||||
#include "rtc_base/task_utils/repeating_task.h"
|
#include "rtc_base/task_utils/repeating_task.h"
|
||||||
#include "rtc_base/thread_annotations.h"
|
#include "rtc_base/thread_annotations.h"
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ class OveruseFrameDetector {
|
|||||||
virtual ~OveruseFrameDetector();
|
virtual ~OveruseFrameDetector();
|
||||||
|
|
||||||
// Start to periodically check for overuse.
|
// Start to periodically check for overuse.
|
||||||
void StartCheckForOveruse(rtc::TaskQueue* task_queue,
|
void StartCheckForOveruse(TaskQueueBase* task_queue_base,
|
||||||
const CpuOveruseOptions& options,
|
const CpuOveruseOptions& options,
|
||||||
AdaptationObserverInterface* overuse_observer);
|
AdaptationObserverInterface* overuse_observer);
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "absl/algorithm/container.h"
|
#include "absl/algorithm/container.h"
|
||||||
|
#include "api/task_queue/task_queue_base.h"
|
||||||
#include "api/video/video_source_interface.h"
|
#include "api/video/video_source_interface.h"
|
||||||
#include "call/adaptation/video_source_restrictions.h"
|
#include "call/adaptation/video_source_restrictions.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
@ -73,10 +74,6 @@ VideoSourceRestrictions ApplyDegradationPreference(
|
|||||||
// AdaptDown() - only how to modify the source/sink restrictions when this
|
// AdaptDown() - only how to modify the source/sink restrictions when this
|
||||||
// happens. Note that it is also not responsible for reconfigruring the
|
// happens. Note that it is also not responsible for reconfigruring the
|
||||||
// source/sink, it is only a keeper of desired restrictions.
|
// source/sink, it is only a keeper of desired restrictions.
|
||||||
//
|
|
||||||
// Thread safety is ensured between SetHasInputVideoAndDegradationPreference()
|
|
||||||
// calls on the worker thread and adaptation logic on the encoder task queue
|
|
||||||
// using a lock.
|
|
||||||
class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
||||||
public:
|
public:
|
||||||
VideoSourceRestrictor()
|
VideoSourceRestrictor()
|
||||||
@ -84,25 +81,19 @@ class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
|||||||
degradation_preference_(DegradationPreference::DISABLED) {}
|
degradation_preference_(DegradationPreference::DISABLED) {}
|
||||||
|
|
||||||
VideoSourceRestrictions source_restrictions() {
|
VideoSourceRestrictions source_restrictions() {
|
||||||
rtc::CritScope lock(&crit_);
|
|
||||||
return source_restrictions_;
|
return source_restrictions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inform the restrictor of new source status and degradation preference.
|
|
||||||
// TODO(hbos): Can this be moved to the encoder queue? If so, the |crit_| lock
|
|
||||||
// can be removed and we only need a sequence checker.
|
|
||||||
void SetHasInputVideoAndDegradationPreference(
|
void SetHasInputVideoAndDegradationPreference(
|
||||||
bool has_input_video,
|
bool has_input_video,
|
||||||
DegradationPreference degradation_preference) {
|
DegradationPreference degradation_preference) {
|
||||||
// Called on libjingle's worker thread.
|
|
||||||
RTC_DCHECK_RUN_ON(&main_checker_);
|
|
||||||
rtc::CritScope lock(&crit_);
|
|
||||||
has_input_video_ = has_input_video;
|
has_input_video_ = has_input_video;
|
||||||
degradation_preference_ = degradation_preference;
|
degradation_preference_ = degradation_preference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Updates the source_restrictions(). The source/sink has to be informed of
|
||||||
|
// this separately.
|
||||||
void ClearRestrictions() {
|
void ClearRestrictions() {
|
||||||
rtc::CritScope lock(&crit_);
|
|
||||||
source_restrictions_ = VideoSourceRestrictions();
|
source_restrictions_ = VideoSourceRestrictions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,14 +102,9 @@ class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
|||||||
bool RequestResolutionLowerThan(int pixel_count,
|
bool RequestResolutionLowerThan(int pixel_count,
|
||||||
int min_pixels_per_frame,
|
int min_pixels_per_frame,
|
||||||
bool* min_pixels_reached) {
|
bool* min_pixels_reached) {
|
||||||
// Called on the encoder task queue.
|
RTC_DCHECK(IsResolutionScalingEnabled(degradation_preference_));
|
||||||
rtc::CritScope lock(&crit_);
|
if (!has_input_video_)
|
||||||
if (!has_input_video_ ||
|
|
||||||
!IsResolutionScalingEnabled(degradation_preference_)) {
|
|
||||||
// This can happen since |degradation_preference_| is set on libjingle's
|
|
||||||
// worker thread but the adaptation is done on the encoder task queue.
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
// The input video frame size will have a resolution less than or equal to
|
// The input video frame size will have a resolution less than or equal to
|
||||||
// |max_pixel_count| depending on how the source can scale the frame size.
|
// |max_pixel_count| depending on how the source can scale the frame size.
|
||||||
const int pixels_wanted = (pixel_count * 3) / 5;
|
const int pixels_wanted = (pixel_count * 3) / 5;
|
||||||
@ -145,7 +131,6 @@ class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
|||||||
// Updates the source_restrictions(). The source/sink has to be informed of
|
// Updates the source_restrictions(). The source/sink has to be informed of
|
||||||
// this separately.
|
// this separately.
|
||||||
int RequestFramerateLowerThan(int fps) {
|
int RequestFramerateLowerThan(int fps) {
|
||||||
// Called on the encoder task queue.
|
|
||||||
// The input video frame rate will be scaled down to 2/3, rounding down.
|
// The input video frame rate will be scaled down to 2/3, rounding down.
|
||||||
int framerate_wanted = (fps * 2) / 3;
|
int framerate_wanted = (fps * 2) / 3;
|
||||||
return RestrictFramerate(framerate_wanted) ? framerate_wanted : -1;
|
return RestrictFramerate(framerate_wanted) ? framerate_wanted : -1;
|
||||||
@ -164,14 +149,9 @@ class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
|||||||
// Updates the source_restrictions(). The source/sink has to be informed of
|
// Updates the source_restrictions(). The source/sink has to be informed of
|
||||||
// this separately.
|
// this separately.
|
||||||
bool RequestHigherResolutionThan(int pixel_count) {
|
bool RequestHigherResolutionThan(int pixel_count) {
|
||||||
// Called on the encoder task queue.
|
RTC_DCHECK(IsResolutionScalingEnabled(degradation_preference_));
|
||||||
rtc::CritScope lock(&crit_);
|
if (!has_input_video_)
|
||||||
if (!has_input_video_ ||
|
|
||||||
!IsResolutionScalingEnabled(degradation_preference_)) {
|
|
||||||
// This can happen since |degradation_preference_| is set on libjingle's
|
|
||||||
// worker thread but the adaptation is done on the encoder task queue.
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
int max_pixels_wanted = pixel_count;
|
int max_pixels_wanted = pixel_count;
|
||||||
if (max_pixels_wanted != std::numeric_limits<int>::max())
|
if (max_pixels_wanted != std::numeric_limits<int>::max())
|
||||||
max_pixels_wanted = pixel_count * 4;
|
max_pixels_wanted = pixel_count * 4;
|
||||||
@ -203,7 +183,6 @@ class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
|||||||
// adaptation requests are removed completely. In that case, consider
|
// adaptation requests are removed completely. In that case, consider
|
||||||
// |max_framerate_| to be the current limit (assuming the capturer complies).
|
// |max_framerate_| to be the current limit (assuming the capturer complies).
|
||||||
int RequestHigherFramerateThan(int fps) {
|
int RequestHigherFramerateThan(int fps) {
|
||||||
// Called on the encoder task queue.
|
|
||||||
// The input frame rate will be scaled up to the last step, with rounding.
|
// The input frame rate will be scaled up to the last step, with rounding.
|
||||||
int framerate_wanted = fps;
|
int framerate_wanted = fps;
|
||||||
if (fps != std::numeric_limits<int>::max())
|
if (fps != std::numeric_limits<int>::max())
|
||||||
@ -215,10 +194,8 @@ class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
|||||||
// Updates the source_restrictions(). The source/sink has to be informed of
|
// Updates the source_restrictions(). The source/sink has to be informed of
|
||||||
// this separately.
|
// this separately.
|
||||||
bool RestrictFramerate(int fps) {
|
bool RestrictFramerate(int fps) {
|
||||||
// Called on the encoder task queue.
|
RTC_DCHECK(IsFramerateScalingEnabled(degradation_preference_));
|
||||||
rtc::CritScope lock(&crit_);
|
if (!has_input_video_)
|
||||||
if (!has_input_video_ ||
|
|
||||||
!IsFramerateScalingEnabled(degradation_preference_))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const int fps_wanted = std::max(kMinFramerateFps, fps);
|
const int fps_wanted = std::max(kMinFramerateFps, fps);
|
||||||
@ -238,10 +215,8 @@ class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
|||||||
// Updates the source_restrictions(). The source/sink has to be informed of
|
// Updates the source_restrictions(). The source/sink has to be informed of
|
||||||
// this separately.
|
// this separately.
|
||||||
bool IncreaseFramerate(int fps) {
|
bool IncreaseFramerate(int fps) {
|
||||||
// Called on the encoder task queue.
|
RTC_DCHECK(IsFramerateScalingEnabled(degradation_preference_));
|
||||||
rtc::CritScope lock(&crit_);
|
if (!has_input_video_)
|
||||||
if (!has_input_video_ ||
|
|
||||||
!IsFramerateScalingEnabled(degradation_preference_))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const int fps_wanted = std::max(kMinFramerateFps, fps);
|
const int fps_wanted = std::max(kMinFramerateFps, fps);
|
||||||
@ -259,11 +234,9 @@ class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rtc::CriticalSection crit_;
|
VideoSourceRestrictions source_restrictions_;
|
||||||
SequenceChecker main_checker_;
|
bool has_input_video_;
|
||||||
VideoSourceRestrictions source_restrictions_ RTC_GUARDED_BY(&crit_);
|
DegradationPreference degradation_preference_;
|
||||||
bool has_input_video_ RTC_GUARDED_BY(&crit_);
|
|
||||||
DegradationPreference degradation_preference_ RTC_GUARDED_BY(&crit_);
|
|
||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceRestrictor);
|
RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceRestrictor);
|
||||||
};
|
};
|
||||||
@ -397,8 +370,7 @@ OveruseFrameDetectorResourceAdaptationModule::
|
|||||||
std::unique_ptr<OveruseFrameDetector> overuse_detector,
|
std::unique_ptr<OveruseFrameDetector> overuse_detector,
|
||||||
VideoStreamEncoderObserver* encoder_stats_observer,
|
VideoStreamEncoderObserver* encoder_stats_observer,
|
||||||
ResourceAdaptationModuleListener* adaptation_listener)
|
ResourceAdaptationModuleListener* adaptation_listener)
|
||||||
: encoder_queue_(nullptr),
|
: adaptation_listener_(adaptation_listener),
|
||||||
adaptation_listener_(adaptation_listener),
|
|
||||||
video_stream_encoder_(video_stream_encoder),
|
video_stream_encoder_(video_stream_encoder),
|
||||||
degradation_preference_(DegradationPreference::DISABLED),
|
degradation_preference_(DegradationPreference::DISABLED),
|
||||||
adapt_counters_(),
|
adapt_counters_(),
|
||||||
@ -422,24 +394,13 @@ OveruseFrameDetectorResourceAdaptationModule::
|
|||||||
OveruseFrameDetectorResourceAdaptationModule::
|
OveruseFrameDetectorResourceAdaptationModule::
|
||||||
~OveruseFrameDetectorResourceAdaptationModule() {}
|
~OveruseFrameDetectorResourceAdaptationModule() {}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::Initialize(
|
|
||||||
rtc::TaskQueue* encoder_queue) {
|
|
||||||
RTC_DCHECK(!encoder_queue_);
|
|
||||||
encoder_queue_ = encoder_queue;
|
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::SetEncoder(
|
void OveruseFrameDetectorResourceAdaptationModule::SetEncoder(
|
||||||
VideoEncoder* encoder) {
|
VideoEncoder* encoder) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
encoder_ = encoder;
|
encoder_ = encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::StartCheckForOveruse(
|
void OveruseFrameDetectorResourceAdaptationModule::StartCheckForOveruse(
|
||||||
ResourceAdaptationModuleListener* adaptation_listener) {
|
ResourceAdaptationModuleListener* adaptation_listener) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
RTC_DCHECK(encoder_);
|
RTC_DCHECK(encoder_);
|
||||||
// TODO(hbos): When AdaptUp() and AdaptDown() are no longer invoked outside
|
// TODO(hbos): When AdaptUp() and AdaptDown() are no longer invoked outside
|
||||||
// the interval between StartCheckForOveruse() and StopCheckForOveruse(),
|
// the interval between StartCheckForOveruse() and StopCheckForOveruse(),
|
||||||
@ -449,20 +410,17 @@ void OveruseFrameDetectorResourceAdaptationModule::StartCheckForOveruse(
|
|||||||
// AdaptUp() and AdaptDown() even when the OveruseDetector is inactive.
|
// AdaptUp() and AdaptDown() even when the OveruseDetector is inactive.
|
||||||
RTC_DCHECK_EQ(adaptation_listener, adaptation_listener_);
|
RTC_DCHECK_EQ(adaptation_listener, adaptation_listener_);
|
||||||
overuse_detector_->StartCheckForOveruse(
|
overuse_detector_->StartCheckForOveruse(
|
||||||
encoder_queue_, video_stream_encoder_->GetCpuOveruseOptions(), this);
|
TaskQueueBase::Current(), video_stream_encoder_->GetCpuOveruseOptions(),
|
||||||
|
this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::StopCheckForOveruse() {
|
void OveruseFrameDetectorResourceAdaptationModule::StopCheckForOveruse() {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
overuse_detector_->StopCheckForOveruse();
|
overuse_detector_->StopCheckForOveruse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::FrameCaptured(
|
void OveruseFrameDetectorResourceAdaptationModule::FrameCaptured(
|
||||||
const VideoFrame& frame,
|
const VideoFrame& frame,
|
||||||
int64_t time_when_first_seen_us) {
|
int64_t time_when_first_seen_us) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
overuse_detector_->FrameCaptured(frame, time_when_first_seen_us);
|
overuse_detector_->FrameCaptured(frame, time_when_first_seen_us);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,44 +429,32 @@ void OveruseFrameDetectorResourceAdaptationModule::FrameSent(
|
|||||||
int64_t time_sent_in_us,
|
int64_t time_sent_in_us,
|
||||||
int64_t capture_time_us,
|
int64_t capture_time_us,
|
||||||
absl::optional<int> encode_duration_us) {
|
absl::optional<int> encode_duration_us) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
overuse_detector_->FrameSent(timestamp, time_sent_in_us, capture_time_us,
|
overuse_detector_->FrameSent(timestamp, time_sent_in_us, capture_time_us,
|
||||||
encode_duration_us);
|
encode_duration_us);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::SetLastFramePixelCount(
|
void OveruseFrameDetectorResourceAdaptationModule::SetLastFramePixelCount(
|
||||||
absl::optional<int> last_frame_pixel_count) {
|
absl::optional<int> last_frame_pixel_count) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
last_frame_pixel_count_ = last_frame_pixel_count;
|
last_frame_pixel_count_ = last_frame_pixel_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::SetEncoderConfig(
|
void OveruseFrameDetectorResourceAdaptationModule::SetEncoderConfig(
|
||||||
VideoEncoderConfig encoder_config) {
|
VideoEncoderConfig encoder_config) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
encoder_config_ = std::move(encoder_config);
|
encoder_config_ = std::move(encoder_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::SetCodecMaxFramerate(
|
void OveruseFrameDetectorResourceAdaptationModule::SetCodecMaxFramerate(
|
||||||
int codec_max_framerate) {
|
int codec_max_framerate) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
codec_max_framerate_ = codec_max_framerate;
|
codec_max_framerate_ = codec_max_framerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::SetEncoderStartBitrateBps(
|
void OveruseFrameDetectorResourceAdaptationModule::SetEncoderStartBitrateBps(
|
||||||
uint32_t encoder_start_bitrate_bps) {
|
uint32_t encoder_start_bitrate_bps) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
encoder_start_bitrate_bps_ = encoder_start_bitrate_bps;
|
encoder_start_bitrate_bps_ = encoder_start_bitrate_bps;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::SetIsQualityScalerEnabled(
|
void OveruseFrameDetectorResourceAdaptationModule::SetIsQualityScalerEnabled(
|
||||||
bool is_quality_scaler_enabled) {
|
bool is_quality_scaler_enabled) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
is_quality_scaler_enabled_ = is_quality_scaler_enabled;
|
is_quality_scaler_enabled_ = is_quality_scaler_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,43 +462,25 @@ void OveruseFrameDetectorResourceAdaptationModule::
|
|||||||
SetHasInputVideoAndDegradationPreference(
|
SetHasInputVideoAndDegradationPreference(
|
||||||
bool has_input_video,
|
bool has_input_video,
|
||||||
DegradationPreference degradation_preference) {
|
DegradationPreference degradation_preference) {
|
||||||
// TODO(https://crbug.com/webrtc/11222): Move this call to the encoder queue,
|
if (degradation_preference_ != degradation_preference) {
|
||||||
// making VideoSourceRestrictor single-threaded and removing the only call to
|
// Reset adaptation state, so that we're not tricked into thinking there's
|
||||||
// MaybeUpdateVideoSourceRestrictions() that isn't on the |encoder_queue_|.
|
// an already pending request of the same type.
|
||||||
source_restrictor_->SetHasInputVideoAndDegradationPreference(
|
last_adaptation_request_.reset();
|
||||||
has_input_video, degradation_preference);
|
if (degradation_preference == DegradationPreference::BALANCED ||
|
||||||
MaybeUpdateVideoSourceRestrictions(degradation_preference);
|
degradation_preference_ == DegradationPreference::BALANCED) {
|
||||||
encoder_queue_->PostTask([this, degradation_preference] {
|
// TODO(asapersson): Consider removing |adapt_counters_| map and use one
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
// AdaptCounter for all modes.
|
||||||
if (degradation_preference_ != degradation_preference) {
|
source_restrictor_->ClearRestrictions();
|
||||||
// Reset adaptation state, so that we're not tricked into thinking there's
|
adapt_counters_.clear();
|
||||||
// an already pending request of the same type.
|
|
||||||
last_adaptation_request_.reset();
|
|
||||||
if (degradation_preference == DegradationPreference::BALANCED ||
|
|
||||||
degradation_preference_ == DegradationPreference::BALANCED) {
|
|
||||||
// TODO(asapersson): Consider removing |adapt_counters_| map and use one
|
|
||||||
// AdaptCounter for all modes.
|
|
||||||
source_restrictor_->ClearRestrictions();
|
|
||||||
adapt_counters_.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
degradation_preference_ = degradation_preference;
|
}
|
||||||
// This is the second time we're invoking
|
degradation_preference_ = degradation_preference;
|
||||||
// MaybeUpdateVideoSourceRestrictions() in this method. This is because
|
source_restrictor_->SetHasInputVideoAndDegradationPreference(
|
||||||
// current tests expect the changes to the source restrictions to be
|
has_input_video, degradation_preference_);
|
||||||
// immediate (outside of the encoder queue) while it is possible that they
|
MaybeUpdateVideoSourceRestrictions();
|
||||||
// change again after ClearRestrictions() on the encoder queue.
|
|
||||||
// TODO(https://crbug.com/webrtc/11222): Change the expectations to allow
|
|
||||||
// source restrictions only to change on the encoder queue. This unblocks
|
|
||||||
// making OveruseFrameDetectorResourceAdaptationModule and
|
|
||||||
// VideoSourceRestrictor single-threaded.
|
|
||||||
MaybeUpdateVideoSourceRestrictions(degradation_preference_);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::RefreshTargetFramerate() {
|
void OveruseFrameDetectorResourceAdaptationModule::RefreshTargetFramerate() {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
absl::optional<double> restricted_frame_rate =
|
absl::optional<double> restricted_frame_rate =
|
||||||
ApplyDegradationPreference(source_restrictor_->source_restrictions(),
|
ApplyDegradationPreference(source_restrictor_->source_restrictions(),
|
||||||
degradation_preference_)
|
degradation_preference_)
|
||||||
@ -571,17 +499,13 @@ void OveruseFrameDetectorResourceAdaptationModule::RefreshTargetFramerate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::ResetAdaptationCounters() {
|
void OveruseFrameDetectorResourceAdaptationModule::ResetAdaptationCounters() {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
last_adaptation_request_.reset();
|
last_adaptation_request_.reset();
|
||||||
source_restrictor_->ClearRestrictions();
|
source_restrictor_->ClearRestrictions();
|
||||||
adapt_counters_.clear();
|
adapt_counters_.clear();
|
||||||
MaybeUpdateVideoSourceRestrictions(degradation_preference_);
|
MaybeUpdateVideoSourceRestrictions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
|
void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
const AdaptCounter& adapt_counter = GetConstAdaptCounter();
|
const AdaptCounter& adapt_counter = GetConstAdaptCounter();
|
||||||
int num_downgrades = adapt_counter.TotalCount(reason);
|
int num_downgrades = adapt_counter.TotalCount(reason);
|
||||||
if (num_downgrades == 0)
|
if (num_downgrades == 0)
|
||||||
@ -685,7 +609,7 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
|
|||||||
|
|
||||||
// Tell the adaptation listener to reconfigure the source for us according to
|
// Tell the adaptation listener to reconfigure the source for us according to
|
||||||
// the latest adaptation.
|
// the latest adaptation.
|
||||||
MaybeUpdateVideoSourceRestrictions(degradation_preference_);
|
MaybeUpdateVideoSourceRestrictions();
|
||||||
|
|
||||||
last_adaptation_request_.emplace(adaptation_request);
|
last_adaptation_request_.emplace(adaptation_request);
|
||||||
|
|
||||||
@ -696,8 +620,6 @@ void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
|
|||||||
|
|
||||||
bool OveruseFrameDetectorResourceAdaptationModule::AdaptDown(
|
bool OveruseFrameDetectorResourceAdaptationModule::AdaptDown(
|
||||||
AdaptReason reason) {
|
AdaptReason reason) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
AdaptationRequest adaptation_request = {
|
AdaptationRequest adaptation_request = {
|
||||||
*last_frame_pixel_count_, encoder_stats_observer_->GetInputFrameRate(),
|
*last_frame_pixel_count_, encoder_stats_observer_->GetInputFrameRate(),
|
||||||
AdaptationRequest::Mode::kAdaptDown};
|
AdaptationRequest::Mode::kAdaptDown};
|
||||||
@ -791,7 +713,7 @@ bool OveruseFrameDetectorResourceAdaptationModule::AdaptDown(
|
|||||||
|
|
||||||
// Tell the adaptation listener to reconfigure the source for us according to
|
// Tell the adaptation listener to reconfigure the source for us according to
|
||||||
// the latest adaptation.
|
// the latest adaptation.
|
||||||
MaybeUpdateVideoSourceRestrictions(degradation_preference_);
|
MaybeUpdateVideoSourceRestrictions();
|
||||||
|
|
||||||
last_adaptation_request_.emplace(adaptation_request);
|
last_adaptation_request_.emplace(adaptation_request);
|
||||||
|
|
||||||
@ -802,21 +724,13 @@ bool OveruseFrameDetectorResourceAdaptationModule::AdaptDown(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetectorResourceAdaptationModule::
|
void OveruseFrameDetectorResourceAdaptationModule::
|
||||||
MaybeUpdateVideoSourceRestrictions(
|
MaybeUpdateVideoSourceRestrictions() {
|
||||||
DegradationPreference degradation_preference) {
|
VideoSourceRestrictions new_restrictions = ApplyDegradationPreference(
|
||||||
absl::optional<VideoSourceRestrictions> updated_restrictions;
|
source_restrictor_->source_restrictions(), degradation_preference_);
|
||||||
{
|
if (video_source_restrictions_ != new_restrictions) {
|
||||||
rtc::CritScope lock(&video_source_restrictions_crit_);
|
video_source_restrictions_ = std::move(new_restrictions);
|
||||||
VideoSourceRestrictions new_restrictions = ApplyDegradationPreference(
|
|
||||||
source_restrictor_->source_restrictions(), degradation_preference);
|
|
||||||
if (video_source_restrictions_ != new_restrictions) {
|
|
||||||
video_source_restrictions_ = std::move(new_restrictions);
|
|
||||||
updated_restrictions = video_source_restrictions_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (updated_restrictions.has_value()) {
|
|
||||||
adaptation_listener_->OnVideoSourceRestrictionsUpdated(
|
adaptation_listener_->OnVideoSourceRestrictionsUpdated(
|
||||||
updated_restrictions.value());
|
video_source_restrictions_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -840,8 +754,6 @@ void OveruseFrameDetectorResourceAdaptationModule::UpdateAdaptationStats(
|
|||||||
VideoStreamEncoderObserver::AdaptationSteps
|
VideoStreamEncoderObserver::AdaptationSteps
|
||||||
OveruseFrameDetectorResourceAdaptationModule::GetActiveCounts(
|
OveruseFrameDetectorResourceAdaptationModule::GetActiveCounts(
|
||||||
AdaptReason reason) {
|
AdaptReason reason) {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
VideoStreamEncoderObserver::AdaptationSteps counts =
|
VideoStreamEncoderObserver::AdaptationSteps counts =
|
||||||
GetConstAdaptCounter().Counts(reason);
|
GetConstAdaptCounter().Counts(reason);
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
@ -885,15 +797,11 @@ OveruseFrameDetectorResourceAdaptationModule::GetAdaptCounter() {
|
|||||||
|
|
||||||
const OveruseFrameDetectorResourceAdaptationModule::AdaptCounter&
|
const OveruseFrameDetectorResourceAdaptationModule::AdaptCounter&
|
||||||
OveruseFrameDetectorResourceAdaptationModule::GetConstAdaptCounter() {
|
OveruseFrameDetectorResourceAdaptationModule::GetConstAdaptCounter() {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
return adapt_counters_[degradation_preference_];
|
return adapt_counters_[degradation_preference_];
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::optional<VideoEncoder::QpThresholds>
|
absl::optional<VideoEncoder::QpThresholds>
|
||||||
OveruseFrameDetectorResourceAdaptationModule::GetQpThresholds() const {
|
OveruseFrameDetectorResourceAdaptationModule::GetQpThresholds() const {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
RTC_DCHECK(last_frame_pixel_count_.has_value());
|
RTC_DCHECK(last_frame_pixel_count_.has_value());
|
||||||
return balanced_settings_.GetQpThresholds(encoder_config_.codec_type,
|
return balanced_settings_.GetQpThresholds(encoder_config_.codec_type,
|
||||||
last_frame_pixel_count_.value());
|
last_frame_pixel_count_.value());
|
||||||
|
|||||||
@ -36,6 +36,9 @@ class VideoStreamEncoder;
|
|||||||
// resolution up or down based on encode usage percent. It keeps track of video
|
// resolution up or down based on encode usage percent. It keeps track of video
|
||||||
// source settings, adaptation counters and may get influenced by
|
// source settings, adaptation counters and may get influenced by
|
||||||
// VideoStreamEncoder's quality scaler through AdaptUp() and AdaptDown() calls.
|
// VideoStreamEncoder's quality scaler through AdaptUp() and AdaptDown() calls.
|
||||||
|
//
|
||||||
|
// This class is single-threaded. The caller is responsible for ensuring safe
|
||||||
|
// usage.
|
||||||
// TODO(hbos): Reduce the coupling with VideoStreamEncoder.
|
// TODO(hbos): Reduce the coupling with VideoStreamEncoder.
|
||||||
// TODO(hbos): Add unittests specific to this class, it is currently only tested
|
// TODO(hbos): Add unittests specific to this class, it is currently only tested
|
||||||
// indirectly in video_stream_encoder_unittest.cc and other tests exercising
|
// indirectly in video_stream_encoder_unittest.cc and other tests exercising
|
||||||
@ -48,6 +51,8 @@ class OveruseFrameDetectorResourceAdaptationModule
|
|||||||
: public ResourceAdaptationModuleInterface,
|
: public ResourceAdaptationModuleInterface,
|
||||||
public AdaptationObserverInterface {
|
public AdaptationObserverInterface {
|
||||||
public:
|
public:
|
||||||
|
// The module can be constructed on any sequence, but must be initialized and
|
||||||
|
// used on a single sequence, e.g. the encoder queue.
|
||||||
OveruseFrameDetectorResourceAdaptationModule(
|
OveruseFrameDetectorResourceAdaptationModule(
|
||||||
VideoStreamEncoder* video_stream_encoder,
|
VideoStreamEncoder* video_stream_encoder,
|
||||||
std::unique_ptr<OveruseFrameDetector> overuse_detector,
|
std::unique_ptr<OveruseFrameDetector> overuse_detector,
|
||||||
@ -55,7 +60,6 @@ class OveruseFrameDetectorResourceAdaptationModule
|
|||||||
ResourceAdaptationModuleListener* adaptation_listener);
|
ResourceAdaptationModuleListener* adaptation_listener);
|
||||||
~OveruseFrameDetectorResourceAdaptationModule() override;
|
~OveruseFrameDetectorResourceAdaptationModule() override;
|
||||||
|
|
||||||
void Initialize(rtc::TaskQueue* encoder_queue);
|
|
||||||
// Sets the encoder to reconfigure based on overuse.
|
// Sets the encoder to reconfigure based on overuse.
|
||||||
// TODO(hbos): Don't reconfigure the encoder directly. Instead, define the
|
// TODO(hbos): Don't reconfigure the encoder directly. Instead, define the
|
||||||
// output of a resource adaptation module as a struct and let the
|
// output of a resource adaptation module as a struct and let the
|
||||||
@ -63,8 +67,6 @@ class OveruseFrameDetectorResourceAdaptationModule
|
|||||||
void SetEncoder(VideoEncoder* encoder);
|
void SetEncoder(VideoEncoder* encoder);
|
||||||
|
|
||||||
DegradationPreference degradation_preference() const {
|
DegradationPreference degradation_preference() const {
|
||||||
RTC_DCHECK(encoder_queue_);
|
|
||||||
RTC_DCHECK_RUN_ON(encoder_queue_);
|
|
||||||
return degradation_preference_;
|
return degradation_preference_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,60 +189,39 @@ class OveruseFrameDetectorResourceAdaptationModule
|
|||||||
// Makes |video_source_restrictions_| up-to-date and informs the
|
// Makes |video_source_restrictions_| up-to-date and informs the
|
||||||
// |adaptation_listener_| if restrictions are changed, allowing the listener
|
// |adaptation_listener_| if restrictions are changed, allowing the listener
|
||||||
// to reconfigure the source accordingly.
|
// to reconfigure the source accordingly.
|
||||||
// TODO(https://crbug.com/webrtc/11222): When
|
void MaybeUpdateVideoSourceRestrictions();
|
||||||
// SetHasInputVideoAndDegradationPreference() stops calling this method prior
|
|
||||||
// to updating |degradation_preference_| on the encoder queue, remove its
|
|
||||||
// argument in favor of using |degradation_preference_| directly.
|
|
||||||
void MaybeUpdateVideoSourceRestrictions(
|
|
||||||
DegradationPreference degradation_preference);
|
|
||||||
|
|
||||||
void UpdateAdaptationStats(AdaptReason reason) RTC_RUN_ON(encoder_queue_);
|
void UpdateAdaptationStats(AdaptReason reason);
|
||||||
DegradationPreference EffectiveDegradataionPreference()
|
DegradationPreference EffectiveDegradataionPreference();
|
||||||
RTC_RUN_ON(encoder_queue_);
|
AdaptCounter& GetAdaptCounter();
|
||||||
AdaptCounter& GetAdaptCounter() RTC_RUN_ON(encoder_queue_);
|
bool CanAdaptUpResolution(int pixels, uint32_t bitrate_bps) const;
|
||||||
bool CanAdaptUpResolution(int pixels, uint32_t bitrate_bps) const
|
|
||||||
RTC_RUN_ON(encoder_queue_);
|
|
||||||
|
|
||||||
rtc::TaskQueue* encoder_queue_;
|
|
||||||
// TODO(https://crbug.com/webrtc/11222): Update
|
|
||||||
// SetHasInputVideoAndDegradationPreference() to do all work on the encoder
|
|
||||||
// queue (including |source_restrictor_| and |adaptation_listener_| usage).
|
|
||||||
// When this is the case, remove |VideoSourceRestrictor::crit_| and
|
|
||||||
// |video_source_restrictions_crit_| and replace |encoder_queue_| with a
|
|
||||||
// sequence checker.
|
|
||||||
rtc::CriticalSection video_source_restrictions_crit_;
|
|
||||||
ResourceAdaptationModuleListener* const adaptation_listener_;
|
ResourceAdaptationModuleListener* const adaptation_listener_;
|
||||||
// The restrictions that |adaptation_listener_| is informed of.
|
// The restrictions that |adaptation_listener_| is informed of.
|
||||||
VideoSourceRestrictions video_source_restrictions_
|
VideoSourceRestrictions video_source_restrictions_;
|
||||||
RTC_GUARDED_BY(&video_source_restrictions_crit_);
|
|
||||||
// Used to query CpuOveruseOptions at StartCheckForOveruse().
|
// Used to query CpuOveruseOptions at StartCheckForOveruse().
|
||||||
VideoStreamEncoder* video_stream_encoder_ RTC_GUARDED_BY(encoder_queue_);
|
VideoStreamEncoder* video_stream_encoder_;
|
||||||
DegradationPreference degradation_preference_ RTC_GUARDED_BY(encoder_queue_);
|
DegradationPreference degradation_preference_;
|
||||||
// Counters used for deciding if the video resolution or framerate is
|
// Counters used for deciding if the video resolution or framerate is
|
||||||
// currently restricted, and if so, why, on a per degradation preference
|
// currently restricted, and if so, why, on a per degradation preference
|
||||||
// basis.
|
// basis.
|
||||||
// TODO(sprang): Replace this with a state holding a relative overuse measure
|
// TODO(sprang): Replace this with a state holding a relative overuse measure
|
||||||
// instead, that can be translated into suitable down-scale or fps limit.
|
// instead, that can be translated into suitable down-scale or fps limit.
|
||||||
std::map<const DegradationPreference, AdaptCounter> adapt_counters_
|
std::map<const DegradationPreference, AdaptCounter> adapt_counters_;
|
||||||
RTC_GUARDED_BY(encoder_queue_);
|
const BalancedDegradationSettings balanced_settings_;
|
||||||
const BalancedDegradationSettings balanced_settings_
|
|
||||||
RTC_GUARDED_BY(encoder_queue_);
|
|
||||||
// Stores a snapshot of the last adaptation request triggered by an AdaptUp
|
// Stores a snapshot of the last adaptation request triggered by an AdaptUp
|
||||||
// or AdaptDown signal.
|
// or AdaptDown signal.
|
||||||
absl::optional<AdaptationRequest> last_adaptation_request_
|
absl::optional<AdaptationRequest> last_adaptation_request_;
|
||||||
RTC_GUARDED_BY(encoder_queue_);
|
absl::optional<int> last_frame_pixel_count_;
|
||||||
absl::optional<int> last_frame_pixel_count_ RTC_GUARDED_BY(encoder_queue_);
|
|
||||||
// Keeps track of source restrictions that this adaptation module outputs.
|
// Keeps track of source restrictions that this adaptation module outputs.
|
||||||
const std::unique_ptr<VideoSourceRestrictor> source_restrictor_;
|
const std::unique_ptr<VideoSourceRestrictor> source_restrictor_;
|
||||||
const std::unique_ptr<OveruseFrameDetector> overuse_detector_
|
const std::unique_ptr<OveruseFrameDetector> overuse_detector_;
|
||||||
RTC_PT_GUARDED_BY(encoder_queue_);
|
int codec_max_framerate_;
|
||||||
int codec_max_framerate_ RTC_GUARDED_BY(encoder_queue_);
|
uint32_t encoder_start_bitrate_bps_;
|
||||||
uint32_t encoder_start_bitrate_bps_ RTC_GUARDED_BY(encoder_queue_);
|
bool is_quality_scaler_enabled_;
|
||||||
bool is_quality_scaler_enabled_ RTC_GUARDED_BY(encoder_queue_);
|
VideoEncoderConfig encoder_config_;
|
||||||
VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(encoder_queue_);
|
VideoEncoder* encoder_;
|
||||||
VideoEncoder* encoder_ RTC_GUARDED_BY(encoder_queue_);
|
VideoStreamEncoderObserver* const encoder_stats_observer_;
|
||||||
VideoStreamEncoderObserver* const encoder_stats_observer_
|
|
||||||
RTC_GUARDED_BY(encoder_queue_);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -433,7 +433,8 @@ TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) {
|
|||||||
|
|
||||||
queue.SendTask(
|
queue.SendTask(
|
||||||
[&] {
|
[&] {
|
||||||
overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
|
overuse_detector_->StartCheckForOveruse(queue.Get(), options_,
|
||||||
|
observer_);
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
|
|
||||||
@ -914,7 +915,8 @@ TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) {
|
|||||||
|
|
||||||
queue.SendTask(
|
queue.SendTask(
|
||||||
[&] {
|
[&] {
|
||||||
overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
|
overuse_detector_->StartCheckForOveruse(queue.Get(), options_,
|
||||||
|
observer_);
|
||||||
},
|
},
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
|
|
||||||
|
|||||||
@ -332,7 +332,6 @@ VideoStreamEncoder::VideoStreamEncoder(
|
|||||||
TaskQueueFactory::Priority::NORMAL)) {
|
TaskQueueFactory::Priority::NORMAL)) {
|
||||||
RTC_DCHECK(encoder_stats_observer);
|
RTC_DCHECK(encoder_stats_observer);
|
||||||
RTC_DCHECK_GE(number_of_cores, 1);
|
RTC_DCHECK_GE(number_of_cores, 1);
|
||||||
resource_adaptation_module_->Initialize(encoder_queue());
|
|
||||||
|
|
||||||
for (auto& state : encoder_buffer_state_)
|
for (auto& state : encoder_buffer_state_)
|
||||||
state.fill(std::numeric_limits<int64_t>::max());
|
state.fill(std::numeric_limits<int64_t>::max());
|
||||||
@ -388,10 +387,10 @@ void VideoStreamEncoder::SetSource(
|
|||||||
const DegradationPreference& degradation_preference) {
|
const DegradationPreference& degradation_preference) {
|
||||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
RTC_DCHECK_RUN_ON(&thread_checker_);
|
||||||
video_source_sink_controller_->SetSource(source);
|
video_source_sink_controller_->SetSource(source);
|
||||||
resource_adaptation_module_->SetHasInputVideoAndDegradationPreference(
|
encoder_queue_.PostTask([this, source, degradation_preference] {
|
||||||
source, degradation_preference);
|
|
||||||
encoder_queue_.PostTask([this, degradation_preference] {
|
|
||||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||||
|
resource_adaptation_module_->SetHasInputVideoAndDegradationPreference(
|
||||||
|
source, degradation_preference);
|
||||||
if (encoder_)
|
if (encoder_)
|
||||||
ConfigureQualityScaler(encoder_->GetEncoderInfo());
|
ConfigureQualityScaler(encoder_->GetEncoderInfo());
|
||||||
|
|
||||||
@ -1731,19 +1730,19 @@ CpuOveruseOptions VideoStreamEncoder::GetCpuOveruseOptions() const {
|
|||||||
|
|
||||||
bool VideoStreamEncoder::TriggerAdaptDown(
|
bool VideoStreamEncoder::TriggerAdaptDown(
|
||||||
AdaptationObserverInterface::AdaptReason reason) {
|
AdaptationObserverInterface::AdaptReason reason) {
|
||||||
|
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||||
return resource_adaptation_module_->AdaptDown(reason);
|
return resource_adaptation_module_->AdaptDown(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoStreamEncoder::TriggerAdaptUp(
|
void VideoStreamEncoder::TriggerAdaptUp(
|
||||||
AdaptationObserverInterface::AdaptReason reason) {
|
AdaptationObserverInterface::AdaptReason reason) {
|
||||||
|
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||||
resource_adaptation_module_->AdaptUp(reason);
|
resource_adaptation_module_->AdaptUp(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated(
|
void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated(
|
||||||
VideoSourceRestrictions restrictions) {
|
VideoSourceRestrictions restrictions) {
|
||||||
// TODO(https://crbug.com/webrtc/11222): DCHECK that we are using the
|
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||||
// |encoder_queue_| when OnVideoSourceRestrictionsUpdated() is no longer
|
|
||||||
// invoked off this thread due to VideoStreamEncoder::SetSource() stuff.
|
|
||||||
video_source_sink_controller_->SetRestrictions(std::move(restrictions));
|
video_source_sink_controller_->SetRestrictions(std::move(restrictions));
|
||||||
video_source_sink_controller_->PushSourceSinkSettings();
|
video_source_sink_controller_->PushSourceSinkSettings();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -408,9 +408,20 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
|
|||||||
// track of whether a request has been made or not.
|
// track of whether a request has been made or not.
|
||||||
bool encoder_switch_requested_ RTC_GUARDED_BY(&encoder_queue_);
|
bool encoder_switch_requested_ RTC_GUARDED_BY(&encoder_queue_);
|
||||||
|
|
||||||
|
// The controller updates the sink wants based on restrictions that come from
|
||||||
|
// the resource adaptation module or adaptation due to bandwidth adaptation.
|
||||||
|
//
|
||||||
|
// This is used on the encoder queue, with a few exceptions:
|
||||||
|
// - VideoStreamEncoder::SetSource() invokes SetSource().
|
||||||
|
// - VideoStreamEncoder::SetSink() invokes SetRotationApplied() and
|
||||||
|
// PushSourceSinkSettings().
|
||||||
|
// - VideoStreamEncoder::Stop() invokes SetSource().
|
||||||
|
// TODO(hbos): If these can be moved to the encoder queue,
|
||||||
|
// VideoSourceSinkController can be made single-threaded, and its lock can be
|
||||||
|
// replaced with a sequence checker.
|
||||||
std::unique_ptr<VideoSourceSinkController> video_source_sink_controller_;
|
std::unique_ptr<VideoSourceSinkController> video_source_sink_controller_;
|
||||||
std::unique_ptr<OveruseFrameDetectorResourceAdaptationModule>
|
std::unique_ptr<OveruseFrameDetectorResourceAdaptationModule>
|
||||||
resource_adaptation_module_;
|
resource_adaptation_module_ RTC_GUARDED_BY(&encoder_queue_);
|
||||||
|
|
||||||
// All public methods are proxied to |encoder_queue_|. It must must be
|
// All public methods are proxied to |encoder_queue_|. It must must be
|
||||||
// destroyed first to make sure no tasks are run that use other members.
|
// destroyed first to make sure no tasks are run that use other members.
|
||||||
|
|||||||
@ -1805,7 +1805,12 @@ TEST_F(VideoStreamEncoderTest, SinkWantsStoredByDegradationPreference) {
|
|||||||
test::FrameForwarder new_video_source;
|
test::FrameForwarder new_video_source;
|
||||||
video_stream_encoder_->SetSource(
|
video_stream_encoder_->SetSource(
|
||||||
&new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
|
&new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
|
||||||
|
// Give the encoder queue time to process the change in degradation preference
|
||||||
|
// by waiting for an encoded frame.
|
||||||
|
new_video_source.IncomingCapturedFrame(
|
||||||
|
CreateFrame(frame_timestamp, kFrameWidth, kFrameWidth));
|
||||||
|
sink_.WaitForEncodedFrame(frame_timestamp);
|
||||||
|
frame_timestamp += kFrameIntervalMs;
|
||||||
// Initially no degradation registered.
|
// Initially no degradation registered.
|
||||||
VerifyFpsMaxResolutionMax(new_video_source.sink_wants());
|
VerifyFpsMaxResolutionMax(new_video_source.sink_wants());
|
||||||
|
|
||||||
@ -1831,6 +1836,12 @@ TEST_F(VideoStreamEncoderTest, SinkWantsStoredByDegradationPreference) {
|
|||||||
// Turn off degradation completely.
|
// Turn off degradation completely.
|
||||||
video_stream_encoder_->SetSource(&new_video_source,
|
video_stream_encoder_->SetSource(&new_video_source,
|
||||||
webrtc::DegradationPreference::DISABLED);
|
webrtc::DegradationPreference::DISABLED);
|
||||||
|
// Give the encoder queue time to process the change in degradation preference
|
||||||
|
// by waiting for an encoded frame.
|
||||||
|
new_video_source.IncomingCapturedFrame(
|
||||||
|
CreateFrame(frame_timestamp, kFrameWidth, kFrameWidth));
|
||||||
|
sink_.WaitForEncodedFrame(frame_timestamp);
|
||||||
|
frame_timestamp += kFrameIntervalMs;
|
||||||
VerifyFpsMaxResolutionMax(new_video_source.sink_wants());
|
VerifyFpsMaxResolutionMax(new_video_source.sink_wants());
|
||||||
|
|
||||||
video_stream_encoder_->TriggerCpuOveruse();
|
video_stream_encoder_->TriggerCpuOveruse();
|
||||||
@ -1845,6 +1856,12 @@ TEST_F(VideoStreamEncoderTest, SinkWantsStoredByDegradationPreference) {
|
|||||||
// Calling SetSource with resolution scaling enabled apply the old SinkWants.
|
// Calling SetSource with resolution scaling enabled apply the old SinkWants.
|
||||||
video_stream_encoder_->SetSource(
|
video_stream_encoder_->SetSource(
|
||||||
&new_video_source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
|
&new_video_source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
|
||||||
|
// Give the encoder queue time to process the change in degradation preference
|
||||||
|
// by waiting for an encoded frame.
|
||||||
|
new_video_source.IncomingCapturedFrame(
|
||||||
|
CreateFrame(frame_timestamp, kFrameWidth, kFrameWidth));
|
||||||
|
sink_.WaitForEncodedFrame(frame_timestamp);
|
||||||
|
frame_timestamp += kFrameIntervalMs;
|
||||||
EXPECT_LT(new_video_source.sink_wants().max_pixel_count,
|
EXPECT_LT(new_video_source.sink_wants().max_pixel_count,
|
||||||
kFrameWidth * kFrameHeight);
|
kFrameWidth * kFrameHeight);
|
||||||
EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count);
|
EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count);
|
||||||
@ -1853,6 +1870,12 @@ TEST_F(VideoStreamEncoderTest, SinkWantsStoredByDegradationPreference) {
|
|||||||
// Calling SetSource with framerate scaling enabled apply the old SinkWants.
|
// Calling SetSource with framerate scaling enabled apply the old SinkWants.
|
||||||
video_stream_encoder_->SetSource(
|
video_stream_encoder_->SetSource(
|
||||||
&new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
|
&new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
|
||||||
|
// Give the encoder queue time to process the change in degradation preference
|
||||||
|
// by waiting for an encoded frame.
|
||||||
|
new_video_source.IncomingCapturedFrame(
|
||||||
|
CreateFrame(frame_timestamp, kFrameWidth, kFrameWidth));
|
||||||
|
sink_.WaitForEncodedFrame(frame_timestamp);
|
||||||
|
frame_timestamp += kFrameIntervalMs;
|
||||||
EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count);
|
EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count);
|
||||||
EXPECT_EQ(std::numeric_limits<int>::max(),
|
EXPECT_EQ(std::numeric_limits<int>::max(),
|
||||||
new_video_source.sink_wants().max_pixel_count);
|
new_video_source.sink_wants().max_pixel_count);
|
||||||
@ -2561,12 +2584,16 @@ TEST_F(VideoStreamEncoderTest,
|
|||||||
test::FrameForwarder new_video_source;
|
test::FrameForwarder new_video_source;
|
||||||
video_stream_encoder_->SetSource(
|
video_stream_encoder_->SetSource(
|
||||||
&new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
|
&new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
|
||||||
|
// Give the encoder queue time to process the change in degradation preference
|
||||||
|
// by waiting for an encoded frame.
|
||||||
|
new_video_source.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
|
||||||
|
sink_.WaitForEncodedFrame(3);
|
||||||
VerifyFpsMaxResolutionMax(new_video_source.sink_wants());
|
VerifyFpsMaxResolutionMax(new_video_source.sink_wants());
|
||||||
|
|
||||||
// Trigger adapt down, expect reduced framerate.
|
// Trigger adapt down, expect reduced framerate.
|
||||||
video_stream_encoder_->TriggerQualityLow();
|
video_stream_encoder_->TriggerQualityLow();
|
||||||
new_video_source.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
|
new_video_source.IncomingCapturedFrame(CreateFrame(4, kWidth, kHeight));
|
||||||
sink_.WaitForEncodedFrame(3);
|
sink_.WaitForEncodedFrame(4);
|
||||||
VerifyFpsLtResolutionMax(new_video_source.sink_wants(), kInputFps);
|
VerifyFpsLtResolutionMax(new_video_source.sink_wants(), kInputFps);
|
||||||
|
|
||||||
// Trigger adapt up, expect no restriction.
|
// Trigger adapt up, expect no restriction.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user