Remove usage of the rtc::TaskQueue in video/

Instead embed functionality of the rtc::TaskQueue into destructors and describe the potential race.

Bug: webrtc:14169
Change-Id: I01b570b530986a0d07798893057201493a8bef5f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335141
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41592}
This commit is contained in:
Danil Chapovalov 2024-01-22 10:51:53 +01:00 committed by WebRTC LUCI CQ
parent 348438154a
commit f1fc6ab3ba
6 changed files with 147 additions and 137 deletions

View file

@ -449,7 +449,6 @@ rtc_library("video_stream_encoder_impl") {
"../rtc_base:refcount", "../rtc_base:refcount",
"../rtc_base:rtc_event", "../rtc_base:rtc_event",
"../rtc_base:rtc_numerics", "../rtc_base:rtc_numerics",
"../rtc_base:rtc_task_queue",
"../rtc_base:safe_conversions", "../rtc_base:safe_conversions",
"../rtc_base:stringutils", "../rtc_base:stringutils",
"../rtc_base:timeutils", "../rtc_base:timeutils",
@ -927,7 +926,6 @@ if (rtc_include_tests) {
"../rtc_base:rtc_base_tests_utils", "../rtc_base:rtc_base_tests_utils",
"../rtc_base:rtc_event", "../rtc_base:rtc_event",
"../rtc_base:rtc_numerics", "../rtc_base:rtc_numerics",
"../rtc_base:rtc_task_queue",
"../rtc_base:safe_conversions", "../rtc_base:safe_conversions",
"../rtc_base:stringutils", "../rtc_base:stringutils",
"../rtc_base:task_queue_for_test", "../rtc_base:task_queue_for_test",

View file

@ -26,7 +26,6 @@ rtc_library("incoming_video_stream") {
"../../rtc_base:event_tracer", "../../rtc_base:event_tracer",
"../../rtc_base:macromagic", "../../rtc_base:macromagic",
"../../rtc_base:race_checker", "../../rtc_base:race_checker",
"../../rtc_base:rtc_task_queue",
] ]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]

View file

@ -33,17 +33,23 @@ IncomingVideoStream::IncomingVideoStream(
IncomingVideoStream::~IncomingVideoStream() { IncomingVideoStream::~IncomingVideoStream() {
RTC_DCHECK(main_thread_checker_.IsCurrent()); RTC_DCHECK(main_thread_checker_.IsCurrent());
// The queue must be destroyed before its pointer is invalidated to avoid race
// between destructor and posting task to the task queue from itself.
// std::unique_ptr destructor does the same two operations in reverse order as
// it doesn't expect member would be used after its destruction has started.
incoming_render_queue_.get_deleter()(incoming_render_queue_.get());
incoming_render_queue_.release();
} }
void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) { void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) {
TRACE_EVENT0("webrtc", "IncomingVideoStream::OnFrame"); TRACE_EVENT0("webrtc", "IncomingVideoStream::OnFrame");
RTC_CHECK_RUNS_SERIALIZED(&decoder_race_checker_); RTC_CHECK_RUNS_SERIALIZED(&decoder_race_checker_);
RTC_DCHECK(!incoming_render_queue_.IsCurrent()); RTC_DCHECK(!incoming_render_queue_->IsCurrent());
// TODO(srte): Using video_frame = std::move(video_frame) would move the frame // TODO(srte): Using video_frame = std::move(video_frame) would move the frame
// into the lambda instead of copying it, but it doesn't work unless we change // into the lambda instead of copying it, but it doesn't work unless we change
// OnFrame to take its frame argument by value instead of const reference. // OnFrame to take its frame argument by value instead of const reference.
incoming_render_queue_.PostTask([this, video_frame = video_frame]() mutable { incoming_render_queue_->PostTask([this, video_frame = video_frame]() mutable {
RTC_DCHECK_RUN_ON(&incoming_render_queue_); RTC_DCHECK_RUN_ON(incoming_render_queue_.get());
if (render_buffers_.AddFrame(std::move(video_frame)) == 1) if (render_buffers_.AddFrame(std::move(video_frame)) == 1)
Dequeue(); Dequeue();
}); });
@ -51,14 +57,14 @@ void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) {
void IncomingVideoStream::Dequeue() { void IncomingVideoStream::Dequeue() {
TRACE_EVENT0("webrtc", "IncomingVideoStream::Dequeue"); TRACE_EVENT0("webrtc", "IncomingVideoStream::Dequeue");
RTC_DCHECK_RUN_ON(&incoming_render_queue_); RTC_DCHECK_RUN_ON(incoming_render_queue_.get());
absl::optional<VideoFrame> frame_to_render = render_buffers_.FrameToRender(); absl::optional<VideoFrame> frame_to_render = render_buffers_.FrameToRender();
if (frame_to_render) if (frame_to_render)
callback_->OnFrame(*frame_to_render); callback_->OnFrame(*frame_to_render);
if (render_buffers_.HasPendingFrames()) { if (render_buffers_.HasPendingFrames()) {
uint32_t wait_time = render_buffers_.TimeToNextFrameRelease(); uint32_t wait_time = render_buffers_.TimeToNextFrameRelease();
incoming_render_queue_.PostDelayedHighPrecisionTask( incoming_render_queue_->PostDelayedHighPrecisionTask(
[this]() { Dequeue(); }, TimeDelta::Millis(wait_time)); [this]() { Dequeue(); }, TimeDelta::Millis(wait_time));
} }
} }

View file

@ -13,12 +13,14 @@
#include <stdint.h> #include <stdint.h>
#include <memory>
#include "api/sequence_checker.h" #include "api/sequence_checker.h"
#include "api/task_queue/task_queue_base.h"
#include "api/task_queue/task_queue_factory.h" #include "api/task_queue/task_queue_factory.h"
#include "api/video/video_frame.h" #include "api/video/video_frame.h"
#include "api/video/video_sink_interface.h" #include "api/video/video_sink_interface.h"
#include "rtc_base/race_checker.h" #include "rtc_base/race_checker.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/thread_annotations.h" #include "rtc_base/thread_annotations.h"
#include "video/render/video_render_frames.h" #include "video/render/video_render_frames.h"
@ -38,9 +40,9 @@ class IncomingVideoStream : public rtc::VideoSinkInterface<VideoFrame> {
SequenceChecker main_thread_checker_; SequenceChecker main_thread_checker_;
rtc::RaceChecker decoder_race_checker_; rtc::RaceChecker decoder_race_checker_;
VideoRenderFrames render_buffers_ RTC_GUARDED_BY(&incoming_render_queue_); VideoRenderFrames render_buffers_ RTC_GUARDED_BY(incoming_render_queue_);
rtc::VideoSinkInterface<VideoFrame>* const callback_; rtc::VideoSinkInterface<VideoFrame>* const callback_;
rtc::TaskQueue incoming_render_queue_; std::unique_ptr<TaskQueueBase, TaskQueueDeleter> incoming_render_queue_;
}; };
} // namespace webrtc } // namespace webrtc

View file

@ -713,10 +713,10 @@ VideoStreamEncoder::VideoStreamEncoder(
RTC_DCHECK_GE(number_of_cores, 1); RTC_DCHECK_GE(number_of_cores, 1);
frame_cadence_adapter_->Initialize(&cadence_callback_); frame_cadence_adapter_->Initialize(&cadence_callback_);
stream_resource_manager_.Initialize(encoder_queue_.Get()); stream_resource_manager_.Initialize(encoder_queue_.get());
encoder_queue_.PostTask([this] { encoder_queue_->PostTask([this] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
resource_adaptation_processor_ = resource_adaptation_processor_ =
std::make_unique<ResourceAdaptationProcessor>( std::make_unique<ResourceAdaptationProcessor>(
@ -742,6 +742,14 @@ VideoStreamEncoder::~VideoStreamEncoder() {
RTC_DCHECK_RUN_ON(worker_queue_); RTC_DCHECK_RUN_ON(worker_queue_);
RTC_DCHECK(!video_source_sink_controller_.HasSource()) RTC_DCHECK(!video_source_sink_controller_.HasSource())
<< "Must call ::Stop() before destruction."; << "Must call ::Stop() before destruction.";
// The queue must be destroyed before its pointer is invalidated to avoid race
// between destructor and running task that check if function is called on the
// encoder_queue_.
// std::unique_ptr destructor does the same two operations in reverse order as
// it doesn't expect member would be used after its destruction has started.
encoder_queue_.get_deleter()(encoder_queue_.get());
encoder_queue_.release();
} }
void VideoStreamEncoder::Stop() { void VideoStreamEncoder::Stop() {
@ -750,8 +758,8 @@ void VideoStreamEncoder::Stop() {
rtc::Event shutdown_event; rtc::Event shutdown_event;
absl::Cleanup shutdown = [&shutdown_event] { shutdown_event.Set(); }; absl::Cleanup shutdown = [&shutdown_event] { shutdown_event.Set(); };
encoder_queue_.PostTask([this, shutdown = std::move(shutdown)] { encoder_queue_->PostTask([this, shutdown = std::move(shutdown)] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
if (resource_adaptation_processor_) { if (resource_adaptation_processor_) {
stream_resource_manager_.StopManagedResources(); stream_resource_manager_.StopManagedResources();
for (auto* constraint : adaptation_constraints_) { for (auto* constraint : adaptation_constraints_) {
@ -779,8 +787,8 @@ void VideoStreamEncoder::Stop() {
void VideoStreamEncoder::SetFecControllerOverride( void VideoStreamEncoder::SetFecControllerOverride(
FecControllerOverride* fec_controller_override) { FecControllerOverride* fec_controller_override) {
encoder_queue_.PostTask([this, fec_controller_override] { encoder_queue_->PostTask([this, fec_controller_override] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
RTC_DCHECK(!fec_controller_override_); RTC_DCHECK(!fec_controller_override_);
fec_controller_override_ = fec_controller_override; fec_controller_override_ = fec_controller_override;
if (encoder_) { if (encoder_) {
@ -798,10 +806,10 @@ void VideoStreamEncoder::AddAdaptationResource(
// of this MapResourceToReason() call. // of this MapResourceToReason() call.
TRACE_EVENT_ASYNC_BEGIN0( TRACE_EVENT_ASYNC_BEGIN0(
"webrtc", "VideoStreamEncoder::AddAdaptationResource(latency)", this); "webrtc", "VideoStreamEncoder::AddAdaptationResource(latency)", this);
encoder_queue_.PostTask([this, resource = std::move(resource)] { encoder_queue_->PostTask([this, resource = std::move(resource)] {
TRACE_EVENT_ASYNC_END0( TRACE_EVENT_ASYNC_END0(
"webrtc", "VideoStreamEncoder::AddAdaptationResource(latency)", this); "webrtc", "VideoStreamEncoder::AddAdaptationResource(latency)", this);
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
additional_resources_.push_back(resource); additional_resources_.push_back(resource);
stream_resource_manager_.AddResource(resource, VideoAdaptationReason::kCpu); stream_resource_manager_.AddResource(resource, VideoAdaptationReason::kCpu);
}); });
@ -816,8 +824,8 @@ VideoStreamEncoder::GetAdaptationResources() {
// here. // here.
rtc::Event event; rtc::Event event;
std::vector<rtc::scoped_refptr<Resource>> resources; std::vector<rtc::scoped_refptr<Resource>> resources;
encoder_queue_.PostTask([&] { encoder_queue_->PostTask([&] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
resources = resource_adaptation_processor_->GetResources(); resources = resource_adaptation_processor_->GetResources();
event.Set(); event.Set();
}); });
@ -833,8 +841,8 @@ void VideoStreamEncoder::SetSource(
input_state_provider_.OnHasInputChanged(source); input_state_provider_.OnHasInputChanged(source);
// This may trigger reconfiguring the QualityScaler on the encoder queue. // This may trigger reconfiguring the QualityScaler on the encoder queue.
encoder_queue_.PostTask([this, degradation_preference] { encoder_queue_->PostTask([this, degradation_preference] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
degradation_preference_manager_->SetDegradationPreference( degradation_preference_manager_->SetDegradationPreference(
degradation_preference); degradation_preference);
stream_resource_manager_.SetDegradationPreferences(degradation_preference); stream_resource_manager_.SetDegradationPreferences(degradation_preference);
@ -852,15 +860,15 @@ void VideoStreamEncoder::SetSink(EncoderSink* sink, bool rotation_applied) {
video_source_sink_controller_.SetRotationApplied(rotation_applied); video_source_sink_controller_.SetRotationApplied(rotation_applied);
video_source_sink_controller_.PushSourceSinkSettings(); video_source_sink_controller_.PushSourceSinkSettings();
encoder_queue_.PostTask([this, sink] { encoder_queue_->PostTask([this, sink] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
sink_ = sink; sink_ = sink;
}); });
} }
void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) { void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) {
encoder_queue_.PostTask([this, start_bitrate_bps] { encoder_queue_->PostTask([this, start_bitrate_bps] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
RTC_LOG(LS_INFO) << "SetStartBitrate " << start_bitrate_bps; RTC_LOG(LS_INFO) << "SetStartBitrate " << start_bitrate_bps;
encoder_target_bitrate_bps_ = encoder_target_bitrate_bps_ =
start_bitrate_bps != 0 ? absl::optional<uint32_t>(start_bitrate_bps) start_bitrate_bps != 0 ? absl::optional<uint32_t>(start_bitrate_bps)
@ -879,10 +887,10 @@ void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config,
size_t max_data_payload_length, size_t max_data_payload_length,
SetParametersCallback callback) { SetParametersCallback callback) {
RTC_DCHECK_RUN_ON(worker_queue_); RTC_DCHECK_RUN_ON(worker_queue_);
encoder_queue_.PostTask([this, config = std::move(config), encoder_queue_->PostTask([this, config = std::move(config),
max_data_payload_length, max_data_payload_length,
callback = std::move(callback)]() mutable { callback = std::move(callback)]() mutable {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
RTC_DCHECK(sink_); RTC_DCHECK(sink_);
RTC_LOG(LS_INFO) << "ConfigureEncoder requested."; RTC_LOG(LS_INFO) << "ConfigureEncoder requested.";
@ -1484,7 +1492,7 @@ void VideoStreamEncoder::OnEncoderSettingsChanged() {
void VideoStreamEncoder::OnFrame(Timestamp post_time, void VideoStreamEncoder::OnFrame(Timestamp post_time,
bool queue_overload, bool queue_overload,
const VideoFrame& video_frame) { const VideoFrame& video_frame) {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
VideoFrame incoming_frame = video_frame; VideoFrame incoming_frame = video_frame;
// In some cases, e.g., when the frame from decoder is fed to encoder, // In some cases, e.g., when the frame from decoder is fed to encoder,
@ -1579,7 +1587,7 @@ void VideoStreamEncoder::OnDiscardedFrame() {
} }
bool VideoStreamEncoder::EncoderPaused() const { bool VideoStreamEncoder::EncoderPaused() const {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
// Pause video if paused by caller or as long as the network is down or the // Pause video if paused by caller or as long as the network is down or the
// pacer queue has grown too large in buffered mode. // pacer queue has grown too large in buffered mode.
// If the pacer queue has grown too large or the network is down, // If the pacer queue has grown too large or the network is down,
@ -1589,7 +1597,7 @@ bool VideoStreamEncoder::EncoderPaused() const {
} }
void VideoStreamEncoder::TraceFrameDropStart() { void VideoStreamEncoder::TraceFrameDropStart() {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
// Start trace event only on the first frame after encoder is paused. // Start trace event only on the first frame after encoder is paused.
if (!encoder_paused_and_dropped_frame_) { if (!encoder_paused_and_dropped_frame_) {
TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this); TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);
@ -1598,7 +1606,7 @@ void VideoStreamEncoder::TraceFrameDropStart() {
} }
void VideoStreamEncoder::TraceFrameDropEnd() { void VideoStreamEncoder::TraceFrameDropEnd() {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
// End trace event on first frame after encoder resumes, if frame was dropped. // End trace event on first frame after encoder resumes, if frame was dropped.
if (encoder_paused_and_dropped_frame_) { if (encoder_paused_and_dropped_frame_) {
TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
@ -1731,7 +1739,7 @@ void VideoStreamEncoder::SetEncoderRates(
void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame, void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame,
int64_t time_when_posted_us) { int64_t time_when_posted_us) {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
input_state_provider_.OnFrameSizeObserved(video_frame.size()); input_state_provider_.OnFrameSizeObserved(video_frame.size());
if (!last_frame_info_ || video_frame.width() != last_frame_info_->width || if (!last_frame_info_ || video_frame.width() != last_frame_info_->width ||
@ -1863,7 +1871,7 @@ void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame,
void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
int64_t time_when_posted_us) { int64_t time_when_posted_us) {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
RTC_LOG(LS_VERBOSE) << __func__ << " posted " << time_when_posted_us RTC_LOG(LS_VERBOSE) << __func__ << " posted " << time_when_posted_us
<< " ntp time " << video_frame.ntp_time_ms(); << " ntp time " << video_frame.ntp_time_ms();
@ -2030,11 +2038,11 @@ void VideoStreamEncoder::RequestRefreshFrame() {
void VideoStreamEncoder::SendKeyFrame( void VideoStreamEncoder::SendKeyFrame(
const std::vector<VideoFrameType>& layers) { const std::vector<VideoFrameType>& layers) {
if (!encoder_queue_.IsCurrent()) { if (!encoder_queue_->IsCurrent()) {
encoder_queue_.PostTask([this, layers] { SendKeyFrame(layers); }); encoder_queue_->PostTask([this, layers] { SendKeyFrame(layers); });
return; return;
} }
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
TRACE_EVENT0("webrtc", "OnKeyFrameRequest"); TRACE_EVENT0("webrtc", "OnKeyFrameRequest");
RTC_DCHECK(!next_frame_types_.empty()); RTC_DCHECK(!next_frame_types_.empty());
@ -2059,13 +2067,13 @@ void VideoStreamEncoder::SendKeyFrame(
void VideoStreamEncoder::OnLossNotification( void VideoStreamEncoder::OnLossNotification(
const VideoEncoder::LossNotification& loss_notification) { const VideoEncoder::LossNotification& loss_notification) {
if (!encoder_queue_.IsCurrent()) { if (!encoder_queue_->IsCurrent()) {
encoder_queue_.PostTask( encoder_queue_->PostTask(
[this, loss_notification] { OnLossNotification(loss_notification); }); [this, loss_notification] { OnLossNotification(loss_notification); });
return; return;
} }
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
if (encoder_) { if (encoder_) {
encoder_->OnLossNotification(loss_notification); encoder_->OnLossNotification(loss_notification);
} }
@ -2120,10 +2128,11 @@ EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage(
// need to update on quality convergence. // need to update on quality convergence.
unsigned int image_width = image_copy._encodedWidth; unsigned int image_width = image_copy._encodedWidth;
unsigned int image_height = image_copy._encodedHeight; unsigned int image_height = image_copy._encodedHeight;
encoder_queue_.PostTask([this, codec_type, image_width, image_height, encoder_queue_->PostTask([this, codec_type, image_width, image_height,
simulcast_index, simulcast_index,
at_target_quality = image_copy.IsAtTargetQuality()] { at_target_quality =
RTC_DCHECK_RUN_ON(&encoder_queue_); image_copy.IsAtTargetQuality()] {
RTC_DCHECK_RUN_ON(encoder_queue_.get());
// Let the frame cadence adapter know about quality convergence. // Let the frame cadence adapter know about quality convergence.
if (frame_cadence_adapter_) if (frame_cadence_adapter_)
@ -2201,15 +2210,15 @@ EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage(
void VideoStreamEncoder::OnDroppedFrame(DropReason reason) { void VideoStreamEncoder::OnDroppedFrame(DropReason reason) {
sink_->OnDroppedFrame(reason); sink_->OnDroppedFrame(reason);
encoder_queue_.PostTask([this, reason] { encoder_queue_->PostTask([this, reason] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
stream_resource_manager_.OnFrameDropped(reason); stream_resource_manager_.OnFrameDropped(reason);
}); });
} }
DataRate VideoStreamEncoder::UpdateTargetBitrate(DataRate target_bitrate, DataRate VideoStreamEncoder::UpdateTargetBitrate(DataRate target_bitrate,
double cwnd_reduce_ratio) { double cwnd_reduce_ratio) {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
DataRate updated_target_bitrate = target_bitrate; DataRate updated_target_bitrate = target_bitrate;
// Drop frames when congestion window pushback ratio is larger than 1 // Drop frames when congestion window pushback ratio is larger than 1
@ -2241,10 +2250,10 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
int64_t round_trip_time_ms, int64_t round_trip_time_ms,
double cwnd_reduce_ratio) { double cwnd_reduce_ratio) {
RTC_DCHECK_GE(link_allocation, target_bitrate); RTC_DCHECK_GE(link_allocation, target_bitrate);
if (!encoder_queue_.IsCurrent()) { if (!encoder_queue_->IsCurrent()) {
encoder_queue_.PostTask([this, target_bitrate, stable_target_bitrate, encoder_queue_->PostTask([this, target_bitrate, stable_target_bitrate,
link_allocation, fraction_lost, round_trip_time_ms, link_allocation, fraction_lost,
cwnd_reduce_ratio] { round_trip_time_ms, cwnd_reduce_ratio] {
DataRate updated_target_bitrate = DataRate updated_target_bitrate =
UpdateTargetBitrate(target_bitrate, cwnd_reduce_ratio); UpdateTargetBitrate(target_bitrate, cwnd_reduce_ratio);
OnBitrateUpdated(updated_target_bitrate, stable_target_bitrate, OnBitrateUpdated(updated_target_bitrate, stable_target_bitrate,
@ -2253,7 +2262,7 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
}); });
return; return;
} }
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
const bool video_is_suspended = target_bitrate == DataRate::Zero(); const bool video_is_suspended = target_bitrate == DataRate::Zero();
const bool video_suspension_changed = video_is_suspended != EncoderPaused(); const bool video_suspension_changed = video_is_suspended != EncoderPaused();
@ -2353,7 +2362,7 @@ void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated(
const VideoAdaptationCounters& adaptation_counters, const VideoAdaptationCounters& adaptation_counters,
rtc::scoped_refptr<Resource> reason, rtc::scoped_refptr<Resource> reason,
const VideoSourceRestrictions& unfiltered_restrictions) { const VideoSourceRestrictions& unfiltered_restrictions) {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
RTC_LOG(LS_INFO) << "Updating sink restrictions from " RTC_LOG(LS_INFO) << "Updating sink restrictions from "
<< (reason ? reason->Name() : std::string("<null>")) << (reason ? reason->Name() : std::string("<null>"))
<< " to " << restrictions.ToString(); << " to " << restrictions.ToString();
@ -2379,15 +2388,15 @@ void VideoStreamEncoder::RunPostEncode(const EncodedImage& encoded_image,
int64_t time_sent_us, int64_t time_sent_us,
int temporal_index, int temporal_index,
DataSize frame_size) { DataSize frame_size) {
if (!encoder_queue_.IsCurrent()) { if (!encoder_queue_->IsCurrent()) {
encoder_queue_.PostTask([this, encoded_image, time_sent_us, temporal_index, encoder_queue_->PostTask([this, encoded_image, time_sent_us, temporal_index,
frame_size] { frame_size] {
RunPostEncode(encoded_image, time_sent_us, temporal_index, frame_size); RunPostEncode(encoded_image, time_sent_us, temporal_index, frame_size);
}); });
return; return;
} }
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
absl::optional<int> encode_duration_us; absl::optional<int> encode_duration_us;
if (encoded_image.timing_.flags != VideoSendTiming::kInvalid) { if (encoded_image.timing_.flags != VideoSendTiming::kInvalid) {
@ -2539,8 +2548,8 @@ void VideoStreamEncoder::CheckForAnimatedContent(
void VideoStreamEncoder::InjectAdaptationResource( void VideoStreamEncoder::InjectAdaptationResource(
rtc::scoped_refptr<Resource> resource, rtc::scoped_refptr<Resource> resource,
VideoAdaptationReason reason) { VideoAdaptationReason reason) {
encoder_queue_.PostTask([this, resource = std::move(resource), reason] { encoder_queue_->PostTask([this, resource = std::move(resource), reason] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
additional_resources_.push_back(resource); additional_resources_.push_back(resource);
stream_resource_manager_.AddResource(resource, reason); stream_resource_manager_.AddResource(resource, reason);
}); });
@ -2549,8 +2558,8 @@ void VideoStreamEncoder::InjectAdaptationResource(
void VideoStreamEncoder::InjectAdaptationConstraint( void VideoStreamEncoder::InjectAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) { AdaptationConstraint* adaptation_constraint) {
rtc::Event event; rtc::Event event;
encoder_queue_.PostTask([this, adaptation_constraint, &event] { encoder_queue_->PostTask([this, adaptation_constraint, &event] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
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
// this task had a chance to execute. No action needed. // this task had a chance to execute. No action needed.
@ -2566,8 +2575,8 @@ void VideoStreamEncoder::InjectAdaptationConstraint(
void VideoStreamEncoder::AddRestrictionsListenerForTesting( void VideoStreamEncoder::AddRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener) { VideoSourceRestrictionsListener* restrictions_listener) {
rtc::Event event; rtc::Event event;
encoder_queue_.PostTask([this, restrictions_listener, &event] { encoder_queue_->PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
RTC_DCHECK(resource_adaptation_processor_); RTC_DCHECK(resource_adaptation_processor_);
video_stream_adapter_->AddRestrictionsListener(restrictions_listener); video_stream_adapter_->AddRestrictionsListener(restrictions_listener);
event.Set(); event.Set();
@ -2578,8 +2587,8 @@ void VideoStreamEncoder::AddRestrictionsListenerForTesting(
void VideoStreamEncoder::RemoveRestrictionsListenerForTesting( void VideoStreamEncoder::RemoveRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener) { VideoSourceRestrictionsListener* restrictions_listener) {
rtc::Event event; rtc::Event event;
encoder_queue_.PostTask([this, restrictions_listener, &event] { encoder_queue_->PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(encoder_queue_.get());
RTC_DCHECK(resource_adaptation_processor_); RTC_DCHECK(resource_adaptation_processor_);
video_stream_adapter_->RemoveRestrictionsListener(restrictions_listener); video_stream_adapter_->RemoveRestrictionsListener(restrictions_listener);
event.Set(); event.Set();

View file

@ -42,7 +42,6 @@
#include "rtc_base/numerics/exp_filter.h" #include "rtc_base/numerics/exp_filter.h"
#include "rtc_base/race_checker.h" #include "rtc_base/race_checker.h"
#include "rtc_base/rate_statistics.h" #include "rtc_base/rate_statistics.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/thread_annotations.h" #include "rtc_base/thread_annotations.h"
#include "system_wrappers/include/clock.h" #include "system_wrappers/include/clock.h"
#include "video/adaptation/video_stream_encoder_resource_manager.h" #include "video/adaptation/video_stream_encoder_resource_manager.h"
@ -136,7 +135,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// Used for testing. For example the `ScalingObserverInterface` methods must // Used for testing. For example the `ScalingObserverInterface` methods must
// be called on `encoder_queue_`. // be called on `encoder_queue_`.
TaskQueueBase* encoder_queue() { return encoder_queue_.Get(); } TaskQueueBase* encoder_queue() { return encoder_queue_.get(); }
void OnVideoSourceRestrictionsUpdated( void OnVideoSourceRestrictionsUpdated(
VideoSourceRestrictions restrictions, VideoSourceRestrictions restrictions,
@ -210,8 +209,8 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
class DegradationPreferenceManager; class DegradationPreferenceManager;
void ReconfigureEncoder() RTC_RUN_ON(&encoder_queue_); void ReconfigureEncoder() RTC_RUN_ON(encoder_queue_);
void OnEncoderSettingsChanged() RTC_RUN_ON(&encoder_queue_); void OnEncoderSettingsChanged() RTC_RUN_ON(encoder_queue_);
void OnFrame(Timestamp post_time, void OnFrame(Timestamp post_time,
bool queue_overload, bool queue_overload,
const VideoFrame& video_frame); const VideoFrame& video_frame);
@ -225,7 +224,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
int64_t time_when_posted_in_ms); int64_t time_when_posted_in_ms);
// Indicates whether frame should be dropped because the pixel count is too // Indicates whether frame should be dropped because the pixel count is too
// large for the current bitrate configuration. // large for the current bitrate configuration.
bool DropDueToSize(uint32_t pixel_count) const RTC_RUN_ON(&encoder_queue_); bool DropDueToSize(uint32_t pixel_count) const RTC_RUN_ON(encoder_queue_);
// Implements EncodedImageCallback. // Implements EncodedImageCallback.
EncodedImageCallback::Result OnEncodedImage( EncodedImageCallback::Result OnEncodedImage(
@ -241,25 +240,25 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// Returns a copy of `rate_settings` with the `bitrate` field updated using // Returns a copy of `rate_settings` with the `bitrate` field updated using
// the current VideoBitrateAllocator. // the current VideoBitrateAllocator.
EncoderRateSettings UpdateBitrateAllocation( EncoderRateSettings UpdateBitrateAllocation(
const EncoderRateSettings& rate_settings) RTC_RUN_ON(&encoder_queue_); const EncoderRateSettings& rate_settings) RTC_RUN_ON(encoder_queue_);
uint32_t GetInputFramerateFps() RTC_RUN_ON(&encoder_queue_); uint32_t GetInputFramerateFps() RTC_RUN_ON(encoder_queue_);
void SetEncoderRates(const EncoderRateSettings& rate_settings) void SetEncoderRates(const EncoderRateSettings& rate_settings)
RTC_RUN_ON(&encoder_queue_); RTC_RUN_ON(encoder_queue_);
void RunPostEncode(const EncodedImage& encoded_image, void RunPostEncode(const EncodedImage& encoded_image,
int64_t time_sent_us, int64_t time_sent_us,
int temporal_index, int temporal_index,
DataSize frame_size); DataSize frame_size);
void ReleaseEncoder() RTC_RUN_ON(&encoder_queue_); void ReleaseEncoder() RTC_RUN_ON(encoder_queue_);
// After calling this function `resource_adaptation_processor_` will be null. // After calling this function `resource_adaptation_processor_` will be null.
void ShutdownResourceAdaptationQueue(); void ShutdownResourceAdaptationQueue();
void CheckForAnimatedContent(const VideoFrame& frame, void CheckForAnimatedContent(const VideoFrame& frame,
int64_t time_when_posted_in_ms) int64_t time_when_posted_in_ms)
RTC_RUN_ON(&encoder_queue_); RTC_RUN_ON(encoder_queue_);
void RequestEncoderSwitch() RTC_RUN_ON(&encoder_queue_); void RequestEncoderSwitch() RTC_RUN_ON(encoder_queue_);
// Augments an EncodedImage received from an encoder with parsable // Augments an EncodedImage received from an encoder with parsable
// information. // information.
@ -269,7 +268,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
void ProcessDroppedFrame(const VideoFrame& frame, void ProcessDroppedFrame(const VideoFrame& frame,
VideoStreamEncoderObserver::DropReason reason) VideoStreamEncoderObserver::DropReason reason)
RTC_RUN_ON(&encoder_queue_); RTC_RUN_ON(encoder_queue_);
const FieldTrialsView& field_trials_; const FieldTrialsView& field_trials_;
TaskQueueBase* const worker_queue_; TaskQueueBase* const worker_queue_;
@ -296,67 +295,66 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// Frame cadence encoder adapter. Frames enter this adapter first, and it then // Frame cadence encoder adapter. Frames enter this adapter first, and it then
// forwards them to our OnFrame method. // forwards them to our OnFrame method.
std::unique_ptr<FrameCadenceAdapterInterface> frame_cadence_adapter_ std::unique_ptr<FrameCadenceAdapterInterface> frame_cadence_adapter_
RTC_GUARDED_BY(&encoder_queue_) RTC_PT_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_) RTC_PT_GUARDED_BY(encoder_queue_);
VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(&encoder_queue_); VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(encoder_queue_);
std::unique_ptr<VideoEncoder> encoder_ RTC_GUARDED_BY(&encoder_queue_) std::unique_ptr<VideoEncoder> encoder_ RTC_GUARDED_BY(encoder_queue_)
RTC_PT_GUARDED_BY(&encoder_queue_); RTC_PT_GUARDED_BY(encoder_queue_);
bool encoder_initialized_ = false; bool encoder_initialized_ = false;
std::unique_ptr<VideoBitrateAllocator> rate_allocator_ std::unique_ptr<VideoBitrateAllocator> rate_allocator_
RTC_GUARDED_BY(&encoder_queue_) RTC_PT_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_) RTC_PT_GUARDED_BY(encoder_queue_);
int max_framerate_ RTC_GUARDED_BY(&encoder_queue_) = -1; int max_framerate_ RTC_GUARDED_BY(encoder_queue_) = -1;
// Set when ConfigureEncoder has been called in order to lazy reconfigure the // Set when ConfigureEncoder has been called in order to lazy reconfigure the
// encoder on the next frame. // encoder on the next frame.
bool pending_encoder_reconfiguration_ RTC_GUARDED_BY(&encoder_queue_) = false; bool pending_encoder_reconfiguration_ RTC_GUARDED_BY(encoder_queue_) = false;
// Set when configuration must create a new encoder object, e.g., // Set when configuration must create a new encoder object, e.g.,
// because of a codec change. // because of a codec change.
bool pending_encoder_creation_ RTC_GUARDED_BY(&encoder_queue_) = false; bool pending_encoder_creation_ RTC_GUARDED_BY(encoder_queue_) = false;
absl::InlinedVector<SetParametersCallback, 2> encoder_configuration_callbacks_ absl::InlinedVector<SetParametersCallback, 2> encoder_configuration_callbacks_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
absl::optional<VideoFrameInfo> last_frame_info_ absl::optional<VideoFrameInfo> last_frame_info_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
int crop_width_ RTC_GUARDED_BY(&encoder_queue_) = 0; int crop_width_ RTC_GUARDED_BY(encoder_queue_) = 0;
int crop_height_ RTC_GUARDED_BY(&encoder_queue_) = 0; int crop_height_ RTC_GUARDED_BY(encoder_queue_) = 0;
absl::optional<uint32_t> encoder_target_bitrate_bps_ absl::optional<uint32_t> encoder_target_bitrate_bps_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
size_t max_data_payload_length_ RTC_GUARDED_BY(&encoder_queue_) = 0; size_t max_data_payload_length_ RTC_GUARDED_BY(encoder_queue_) = 0;
absl::optional<EncoderRateSettings> last_encoder_rate_settings_ absl::optional<EncoderRateSettings> last_encoder_rate_settings_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
bool encoder_paused_and_dropped_frame_ RTC_GUARDED_BY(&encoder_queue_) = bool encoder_paused_and_dropped_frame_ RTC_GUARDED_BY(encoder_queue_) = false;
false;
// Set to true if at least one frame was sent to encoder since last encoder // Set to true if at least one frame was sent to encoder since last encoder
// initialization. // initialization.
bool was_encode_called_since_last_initialization_ bool was_encode_called_since_last_initialization_
RTC_GUARDED_BY(&encoder_queue_) = false; RTC_GUARDED_BY(encoder_queue_) = false;
bool encoder_failed_ RTC_GUARDED_BY(&encoder_queue_) = false; bool encoder_failed_ RTC_GUARDED_BY(encoder_queue_) = false;
Clock* const clock_; Clock* const clock_;
// Used to make sure incoming time stamp is increasing for every frame. // Used to make sure incoming time stamp is increasing for every frame.
int64_t last_captured_timestamp_ RTC_GUARDED_BY(&encoder_queue_) = 0; int64_t last_captured_timestamp_ RTC_GUARDED_BY(encoder_queue_) = 0;
// Delta used for translating between NTP and internal timestamps. // Delta used for translating between NTP and internal timestamps.
const int64_t delta_ntp_internal_ms_ RTC_GUARDED_BY(&encoder_queue_); const int64_t delta_ntp_internal_ms_ RTC_GUARDED_BY(encoder_queue_);
int64_t last_frame_log_ms_ RTC_GUARDED_BY(&encoder_queue_); int64_t last_frame_log_ms_ RTC_GUARDED_BY(encoder_queue_);
int captured_frame_count_ RTC_GUARDED_BY(&encoder_queue_) = 0; int captured_frame_count_ RTC_GUARDED_BY(encoder_queue_) = 0;
int dropped_frame_cwnd_pushback_count_ RTC_GUARDED_BY(&encoder_queue_) = 0; int dropped_frame_cwnd_pushback_count_ RTC_GUARDED_BY(encoder_queue_) = 0;
int dropped_frame_encoder_block_count_ RTC_GUARDED_BY(&encoder_queue_) = 0; int dropped_frame_encoder_block_count_ RTC_GUARDED_BY(encoder_queue_) = 0;
absl::optional<VideoFrame> pending_frame_ RTC_GUARDED_BY(&encoder_queue_); absl::optional<VideoFrame> pending_frame_ RTC_GUARDED_BY(encoder_queue_);
int64_t pending_frame_post_time_us_ RTC_GUARDED_BY(&encoder_queue_) = 0; int64_t pending_frame_post_time_us_ RTC_GUARDED_BY(encoder_queue_) = 0;
VideoFrame::UpdateRect accumulated_update_rect_ VideoFrame::UpdateRect accumulated_update_rect_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
bool accumulated_update_rect_is_valid_ RTC_GUARDED_BY(&encoder_queue_) = true; bool accumulated_update_rect_is_valid_ RTC_GUARDED_BY(encoder_queue_) = true;
// Used for automatic content type detection. // Used for automatic content type detection.
absl::optional<VideoFrame::UpdateRect> last_update_rect_ absl::optional<VideoFrame::UpdateRect> last_update_rect_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
Timestamp animation_start_time_ RTC_GUARDED_BY(&encoder_queue_) = Timestamp animation_start_time_ RTC_GUARDED_BY(encoder_queue_) =
Timestamp::PlusInfinity(); Timestamp::PlusInfinity();
bool cap_resolution_due_to_video_content_ RTC_GUARDED_BY(&encoder_queue_) = bool cap_resolution_due_to_video_content_ RTC_GUARDED_BY(encoder_queue_) =
false; false;
// Used to correctly ignore changes in update_rect introduced by // Used to correctly ignore changes in update_rect introduced by
// resize triggered by animation detection. // resize triggered by animation detection.
@ -364,24 +362,24 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
kNoResize, // Normal operation. kNoResize, // Normal operation.
kResize, // Resize was triggered by the animation detection. kResize, // Resize was triggered by the animation detection.
kFirstFrameAfterResize // Resize observed. kFirstFrameAfterResize // Resize observed.
} expect_resize_state_ RTC_GUARDED_BY(&encoder_queue_) = } expect_resize_state_ RTC_GUARDED_BY(encoder_queue_) =
ExpectResizeState::kNoResize; ExpectResizeState::kNoResize;
FecControllerOverride* fec_controller_override_ FecControllerOverride* fec_controller_override_
RTC_GUARDED_BY(&encoder_queue_) = nullptr; RTC_GUARDED_BY(encoder_queue_) = nullptr;
absl::optional<int64_t> last_parameters_update_ms_ absl::optional<int64_t> last_parameters_update_ms_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
absl::optional<int64_t> last_encode_info_ms_ RTC_GUARDED_BY(&encoder_queue_); absl::optional<int64_t> last_encode_info_ms_ RTC_GUARDED_BY(encoder_queue_);
VideoEncoder::EncoderInfo encoder_info_ RTC_GUARDED_BY(&encoder_queue_); VideoEncoder::EncoderInfo encoder_info_ RTC_GUARDED_BY(encoder_queue_);
VideoCodec send_codec_ RTC_GUARDED_BY(&encoder_queue_); VideoCodec send_codec_ RTC_GUARDED_BY(encoder_queue_);
FrameDropper frame_dropper_ RTC_GUARDED_BY(&encoder_queue_); FrameDropper frame_dropper_ RTC_GUARDED_BY(encoder_queue_);
// If frame dropper is not force disabled, frame dropping might still be // If frame dropper is not force disabled, frame dropping might still be
// disabled if VideoEncoder::GetEncoderInfo() indicates that the encoder has a // disabled if VideoEncoder::GetEncoderInfo() indicates that the encoder has a
// trusted rate controller. This is determined on a per-frame basis, as the // trusted rate controller. This is determined on a per-frame basis, as the
// encoder behavior might dynamically change. // encoder behavior might dynamically change.
bool force_disable_frame_dropper_ RTC_GUARDED_BY(&encoder_queue_) = false; bool force_disable_frame_dropper_ RTC_GUARDED_BY(encoder_queue_) = false;
// Incremented on worker thread whenever `frame_dropper_` determines that a // Incremented on worker thread whenever `frame_dropper_` determines that a
// frame should be dropped. Decremented on whichever thread runs // frame should be dropped. Decremented on whichever thread runs
// OnEncodedImage(), which is only called by one thread but not necessarily // OnEncodedImage(), which is only called by one thread but not necessarily
@ -390,16 +388,16 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// Congestion window frame drop ratio (drop 1 in every // Congestion window frame drop ratio (drop 1 in every
// cwnd_frame_drop_interval_ frames). // cwnd_frame_drop_interval_ frames).
absl::optional<int> cwnd_frame_drop_interval_ RTC_GUARDED_BY(&encoder_queue_); absl::optional<int> cwnd_frame_drop_interval_ RTC_GUARDED_BY(encoder_queue_);
// Frame counter for congestion window frame drop. // Frame counter for congestion window frame drop.
int cwnd_frame_counter_ RTC_GUARDED_BY(&encoder_queue_) = 0; int cwnd_frame_counter_ RTC_GUARDED_BY(encoder_queue_) = 0;
std::unique_ptr<EncoderBitrateAdjuster> bitrate_adjuster_ std::unique_ptr<EncoderBitrateAdjuster> bitrate_adjuster_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
// TODO(sprang): Change actually support keyframe per simulcast stream, or // TODO(sprang): Change actually support keyframe per simulcast stream, or
// turn this into a simple bool `pending_keyframe_request_`. // turn this into a simple bool `pending_keyframe_request_`.
std::vector<VideoFrameType> next_frame_types_ RTC_GUARDED_BY(&encoder_queue_); std::vector<VideoFrameType> next_frame_types_ RTC_GUARDED_BY(encoder_queue_);
FrameEncodeMetadataWriter frame_encode_metadata_writer_{this}; FrameEncodeMetadataWriter frame_encode_metadata_writer_{this};
@ -421,22 +419,22 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
ParseAutomatincAnimationDetectionFieldTrial() const; ParseAutomatincAnimationDetectionFieldTrial() const;
AutomaticAnimationDetectionExperiment AutomaticAnimationDetectionExperiment
automatic_animation_detection_experiment_ RTC_GUARDED_BY(&encoder_queue_); automatic_animation_detection_experiment_ RTC_GUARDED_BY(encoder_queue_);
// Provides video stream input states: current resolution and frame rate. // Provides video stream input states: current resolution and frame rate.
VideoStreamInputStateProvider input_state_provider_; VideoStreamInputStateProvider input_state_provider_;
const std::unique_ptr<VideoStreamAdapter> video_stream_adapter_ const std::unique_ptr<VideoStreamAdapter> video_stream_adapter_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
// Responsible for adapting input resolution or frame rate to ensure resources // Responsible for adapting input resolution or frame rate to ensure resources
// (e.g. CPU or bandwidth) are not overused. Adding resources can occur on any // (e.g. CPU or bandwidth) are not overused. Adding resources can occur on any
// thread. // thread.
std::unique_ptr<ResourceAdaptationProcessorInterface> std::unique_ptr<ResourceAdaptationProcessorInterface>
resource_adaptation_processor_ RTC_GUARDED_BY(&encoder_queue_); resource_adaptation_processor_ RTC_GUARDED_BY(encoder_queue_);
std::unique_ptr<DegradationPreferenceManager> degradation_preference_manager_ std::unique_ptr<DegradationPreferenceManager> degradation_preference_manager_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
std::vector<AdaptationConstraint*> adaptation_constraints_ std::vector<AdaptationConstraint*> adaptation_constraints_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_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 initial frame // scaling". Also involved with various mitigations such as initial frame
@ -445,9 +443,9 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// tied to the VideoStreamEncoder (which is destroyed off the encoder queue) // tied to the VideoStreamEncoder (which is destroyed off the encoder queue)
// and its resource list is accessible from any thread. // and its resource list is accessible from any thread.
VideoStreamEncoderResourceManager stream_resource_manager_ VideoStreamEncoderResourceManager stream_resource_manager_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
std::vector<rtc::scoped_refptr<Resource>> additional_resources_ std::vector<rtc::scoped_refptr<Resource>> additional_resources_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
// Carries out the VideoSourceRestrictions provided by the // Carries out the VideoSourceRestrictions provided by the
// ResourceAdaptationProcessor, i.e. reconfigures the source of video frames // ResourceAdaptationProcessor, i.e. reconfigures the source of video frames
// to provide us with different resolution or frame rate. // to provide us with different resolution or frame rate.
@ -479,9 +477,9 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// so that ownership on restrictions/wants is kept on &encoder_queue_, that // so that ownership on restrictions/wants is kept on &encoder_queue_, that
// these extra copies would not be needed. // these extra copies would not be needed.
absl::optional<VideoSourceRestrictions> latest_restrictions_ absl::optional<VideoSourceRestrictions> latest_restrictions_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
absl::optional<VideoSourceRestrictions> animate_restrictions_ absl::optional<VideoSourceRestrictions> animate_restrictions_
RTC_GUARDED_BY(&encoder_queue_); RTC_GUARDED_BY(encoder_queue_);
// Used to cancel any potentially pending tasks to the worker thread. // Used to cancel any potentially pending tasks to the worker thread.
// Refrenced by tasks running on `encoder_queue_` so need to be destroyed // Refrenced by tasks running on `encoder_queue_` so need to be destroyed
@ -489,9 +487,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// `worker_queue_`. // `worker_queue_`.
ScopedTaskSafety task_safety_; ScopedTaskSafety task_safety_;
// Public methods are proxied to the task queues. The queues must be destroyed std::unique_ptr<TaskQueueBase, TaskQueueDeleter> encoder_queue_;
// first to make sure no tasks run that use other members.
rtc::TaskQueue encoder_queue_;
}; };
} // namespace webrtc } // namespace webrtc