diff --git a/video/BUILD.gn b/video/BUILD.gn index 78c780469c..0891a31f7b 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -449,7 +449,6 @@ rtc_library("video_stream_encoder_impl") { "../rtc_base:refcount", "../rtc_base:rtc_event", "../rtc_base:rtc_numerics", - "../rtc_base:rtc_task_queue", "../rtc_base:safe_conversions", "../rtc_base:stringutils", "../rtc_base:timeutils", @@ -927,7 +926,6 @@ if (rtc_include_tests) { "../rtc_base:rtc_base_tests_utils", "../rtc_base:rtc_event", "../rtc_base:rtc_numerics", - "../rtc_base:rtc_task_queue", "../rtc_base:safe_conversions", "../rtc_base:stringutils", "../rtc_base:task_queue_for_test", diff --git a/video/render/BUILD.gn b/video/render/BUILD.gn index ff721dc61c..a948a0e2fa 100644 --- a/video/render/BUILD.gn +++ b/video/render/BUILD.gn @@ -26,7 +26,6 @@ rtc_library("incoming_video_stream") { "../../rtc_base:event_tracer", "../../rtc_base:macromagic", "../../rtc_base:race_checker", - "../../rtc_base:rtc_task_queue", ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] diff --git a/video/render/incoming_video_stream.cc b/video/render/incoming_video_stream.cc index e740c47bd0..650036ddc9 100644 --- a/video/render/incoming_video_stream.cc +++ b/video/render/incoming_video_stream.cc @@ -33,17 +33,23 @@ IncomingVideoStream::IncomingVideoStream( IncomingVideoStream::~IncomingVideoStream() { 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) { TRACE_EVENT0("webrtc", "IncomingVideoStream::OnFrame"); 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 // 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. - incoming_render_queue_.PostTask([this, video_frame = video_frame]() mutable { - RTC_DCHECK_RUN_ON(&incoming_render_queue_); + incoming_render_queue_->PostTask([this, video_frame = video_frame]() mutable { + RTC_DCHECK_RUN_ON(incoming_render_queue_.get()); if (render_buffers_.AddFrame(std::move(video_frame)) == 1) Dequeue(); }); @@ -51,14 +57,14 @@ void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) { void IncomingVideoStream::Dequeue() { TRACE_EVENT0("webrtc", "IncomingVideoStream::Dequeue"); - RTC_DCHECK_RUN_ON(&incoming_render_queue_); + RTC_DCHECK_RUN_ON(incoming_render_queue_.get()); absl::optional frame_to_render = render_buffers_.FrameToRender(); if (frame_to_render) callback_->OnFrame(*frame_to_render); if (render_buffers_.HasPendingFrames()) { uint32_t wait_time = render_buffers_.TimeToNextFrameRelease(); - incoming_render_queue_.PostDelayedHighPrecisionTask( + incoming_render_queue_->PostDelayedHighPrecisionTask( [this]() { Dequeue(); }, TimeDelta::Millis(wait_time)); } } diff --git a/video/render/incoming_video_stream.h b/video/render/incoming_video_stream.h index 4873ae7dcb..066c0db317 100644 --- a/video/render/incoming_video_stream.h +++ b/video/render/incoming_video_stream.h @@ -13,12 +13,14 @@ #include +#include + #include "api/sequence_checker.h" +#include "api/task_queue/task_queue_base.h" #include "api/task_queue/task_queue_factory.h" #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" #include "rtc_base/race_checker.h" -#include "rtc_base/task_queue.h" #include "rtc_base/thread_annotations.h" #include "video/render/video_render_frames.h" @@ -38,9 +40,9 @@ class IncomingVideoStream : public rtc::VideoSinkInterface { SequenceChecker main_thread_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* const callback_; - rtc::TaskQueue incoming_render_queue_; + std::unique_ptr incoming_render_queue_; }; } // namespace webrtc diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 552463e143..3730f6eecb 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -713,10 +713,10 @@ VideoStreamEncoder::VideoStreamEncoder( RTC_DCHECK_GE(number_of_cores, 1); frame_cadence_adapter_->Initialize(&cadence_callback_); - stream_resource_manager_.Initialize(encoder_queue_.Get()); + stream_resource_manager_.Initialize(encoder_queue_.get()); - encoder_queue_.PostTask([this] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); resource_adaptation_processor_ = std::make_unique( @@ -742,6 +742,14 @@ VideoStreamEncoder::~VideoStreamEncoder() { RTC_DCHECK_RUN_ON(worker_queue_); RTC_DCHECK(!video_source_sink_controller_.HasSource()) << "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() { @@ -750,8 +758,8 @@ void VideoStreamEncoder::Stop() { rtc::Event shutdown_event; absl::Cleanup shutdown = [&shutdown_event] { shutdown_event.Set(); }; - encoder_queue_.PostTask([this, shutdown = std::move(shutdown)] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, shutdown = std::move(shutdown)] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); if (resource_adaptation_processor_) { stream_resource_manager_.StopManagedResources(); for (auto* constraint : adaptation_constraints_) { @@ -779,8 +787,8 @@ void VideoStreamEncoder::Stop() { void VideoStreamEncoder::SetFecControllerOverride( FecControllerOverride* fec_controller_override) { - encoder_queue_.PostTask([this, fec_controller_override] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, fec_controller_override] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); RTC_DCHECK(!fec_controller_override_); fec_controller_override_ = fec_controller_override; if (encoder_) { @@ -798,10 +806,10 @@ void VideoStreamEncoder::AddAdaptationResource( // of this MapResourceToReason() call. TRACE_EVENT_ASYNC_BEGIN0( "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( "webrtc", "VideoStreamEncoder::AddAdaptationResource(latency)", this); - RTC_DCHECK_RUN_ON(&encoder_queue_); + RTC_DCHECK_RUN_ON(encoder_queue_.get()); additional_resources_.push_back(resource); stream_resource_manager_.AddResource(resource, VideoAdaptationReason::kCpu); }); @@ -816,8 +824,8 @@ VideoStreamEncoder::GetAdaptationResources() { // here. rtc::Event event; std::vector> resources; - encoder_queue_.PostTask([&] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([&] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); resources = resource_adaptation_processor_->GetResources(); event.Set(); }); @@ -833,8 +841,8 @@ void VideoStreamEncoder::SetSource( input_state_provider_.OnHasInputChanged(source); // This may trigger reconfiguring the QualityScaler on the encoder queue. - encoder_queue_.PostTask([this, degradation_preference] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, degradation_preference] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); degradation_preference_manager_->SetDegradationPreference( 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_.PushSourceSinkSettings(); - encoder_queue_.PostTask([this, sink] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, sink] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); sink_ = sink; }); } void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) { - encoder_queue_.PostTask([this, start_bitrate_bps] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, start_bitrate_bps] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); RTC_LOG(LS_INFO) << "SetStartBitrate " << start_bitrate_bps; encoder_target_bitrate_bps_ = start_bitrate_bps != 0 ? absl::optional(start_bitrate_bps) @@ -879,10 +887,10 @@ void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config, size_t max_data_payload_length, SetParametersCallback callback) { RTC_DCHECK_RUN_ON(worker_queue_); - encoder_queue_.PostTask([this, config = std::move(config), - max_data_payload_length, - callback = std::move(callback)]() mutable { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, config = std::move(config), + max_data_payload_length, + callback = std::move(callback)]() mutable { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); RTC_DCHECK(sink_); RTC_LOG(LS_INFO) << "ConfigureEncoder requested."; @@ -1484,7 +1492,7 @@ void VideoStreamEncoder::OnEncoderSettingsChanged() { void VideoStreamEncoder::OnFrame(Timestamp post_time, bool queue_overload, const VideoFrame& video_frame) { - RTC_DCHECK_RUN_ON(&encoder_queue_); + RTC_DCHECK_RUN_ON(encoder_queue_.get()); VideoFrame incoming_frame = video_frame; // 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 { - 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 // pacer queue has grown too large in buffered mode. // If the pacer queue has grown too large or the network is down, @@ -1589,7 +1597,7 @@ bool VideoStreamEncoder::EncoderPaused() const { } 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. if (!encoder_paused_and_dropped_frame_) { TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this); @@ -1598,7 +1606,7 @@ void VideoStreamEncoder::TraceFrameDropStart() { } 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. if (encoder_paused_and_dropped_frame_) { TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); @@ -1731,7 +1739,7 @@ void VideoStreamEncoder::SetEncoderRates( void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame, 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()); 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, 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 << " ntp time " << video_frame.ntp_time_ms(); @@ -2030,11 +2038,11 @@ void VideoStreamEncoder::RequestRefreshFrame() { void VideoStreamEncoder::SendKeyFrame( const std::vector& layers) { - if (!encoder_queue_.IsCurrent()) { - encoder_queue_.PostTask([this, layers] { SendKeyFrame(layers); }); + if (!encoder_queue_->IsCurrent()) { + encoder_queue_->PostTask([this, layers] { SendKeyFrame(layers); }); return; } - RTC_DCHECK_RUN_ON(&encoder_queue_); + RTC_DCHECK_RUN_ON(encoder_queue_.get()); TRACE_EVENT0("webrtc", "OnKeyFrameRequest"); RTC_DCHECK(!next_frame_types_.empty()); @@ -2059,13 +2067,13 @@ void VideoStreamEncoder::SendKeyFrame( void VideoStreamEncoder::OnLossNotification( const VideoEncoder::LossNotification& loss_notification) { - if (!encoder_queue_.IsCurrent()) { - encoder_queue_.PostTask( + if (!encoder_queue_->IsCurrent()) { + encoder_queue_->PostTask( [this, loss_notification] { OnLossNotification(loss_notification); }); return; } - RTC_DCHECK_RUN_ON(&encoder_queue_); + RTC_DCHECK_RUN_ON(encoder_queue_.get()); if (encoder_) { encoder_->OnLossNotification(loss_notification); } @@ -2120,10 +2128,11 @@ EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage( // need to update on quality convergence. unsigned int image_width = image_copy._encodedWidth; unsigned int image_height = image_copy._encodedHeight; - encoder_queue_.PostTask([this, codec_type, image_width, image_height, - simulcast_index, - at_target_quality = image_copy.IsAtTargetQuality()] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, codec_type, image_width, image_height, + simulcast_index, + at_target_quality = + image_copy.IsAtTargetQuality()] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); // Let the frame cadence adapter know about quality convergence. if (frame_cadence_adapter_) @@ -2201,15 +2210,15 @@ EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage( void VideoStreamEncoder::OnDroppedFrame(DropReason reason) { sink_->OnDroppedFrame(reason); - encoder_queue_.PostTask([this, reason] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, reason] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); stream_resource_manager_.OnFrameDropped(reason); }); } DataRate VideoStreamEncoder::UpdateTargetBitrate(DataRate target_bitrate, double cwnd_reduce_ratio) { - RTC_DCHECK_RUN_ON(&encoder_queue_); + RTC_DCHECK_RUN_ON(encoder_queue_.get()); DataRate updated_target_bitrate = target_bitrate; // 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, double cwnd_reduce_ratio) { RTC_DCHECK_GE(link_allocation, target_bitrate); - if (!encoder_queue_.IsCurrent()) { - encoder_queue_.PostTask([this, target_bitrate, stable_target_bitrate, - link_allocation, fraction_lost, round_trip_time_ms, - cwnd_reduce_ratio] { + if (!encoder_queue_->IsCurrent()) { + encoder_queue_->PostTask([this, target_bitrate, stable_target_bitrate, + link_allocation, fraction_lost, + round_trip_time_ms, cwnd_reduce_ratio] { DataRate updated_target_bitrate = UpdateTargetBitrate(target_bitrate, cwnd_reduce_ratio); OnBitrateUpdated(updated_target_bitrate, stable_target_bitrate, @@ -2253,7 +2262,7 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate, }); 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_suspension_changed = video_is_suspended != EncoderPaused(); @@ -2353,7 +2362,7 @@ void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated( const VideoAdaptationCounters& adaptation_counters, rtc::scoped_refptr reason, 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 " << (reason ? reason->Name() : std::string("")) << " to " << restrictions.ToString(); @@ -2379,15 +2388,15 @@ void VideoStreamEncoder::RunPostEncode(const EncodedImage& encoded_image, int64_t time_sent_us, int temporal_index, DataSize frame_size) { - if (!encoder_queue_.IsCurrent()) { - encoder_queue_.PostTask([this, encoded_image, time_sent_us, temporal_index, - frame_size] { + if (!encoder_queue_->IsCurrent()) { + encoder_queue_->PostTask([this, encoded_image, time_sent_us, temporal_index, + frame_size] { RunPostEncode(encoded_image, time_sent_us, temporal_index, frame_size); }); return; } - RTC_DCHECK_RUN_ON(&encoder_queue_); + RTC_DCHECK_RUN_ON(encoder_queue_.get()); absl::optional encode_duration_us; if (encoded_image.timing_.flags != VideoSendTiming::kInvalid) { @@ -2539,8 +2548,8 @@ void VideoStreamEncoder::CheckForAnimatedContent( void VideoStreamEncoder::InjectAdaptationResource( rtc::scoped_refptr resource, VideoAdaptationReason reason) { - encoder_queue_.PostTask([this, resource = std::move(resource), reason] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, resource = std::move(resource), reason] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); additional_resources_.push_back(resource); stream_resource_manager_.AddResource(resource, reason); }); @@ -2549,8 +2558,8 @@ void VideoStreamEncoder::InjectAdaptationResource( void VideoStreamEncoder::InjectAdaptationConstraint( AdaptationConstraint* adaptation_constraint) { rtc::Event event; - encoder_queue_.PostTask([this, adaptation_constraint, &event] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, adaptation_constraint, &event] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); if (!resource_adaptation_processor_) { // The VideoStreamEncoder was stopped and the processor destroyed before // this task had a chance to execute. No action needed. @@ -2566,8 +2575,8 @@ void VideoStreamEncoder::InjectAdaptationConstraint( void VideoStreamEncoder::AddRestrictionsListenerForTesting( VideoSourceRestrictionsListener* restrictions_listener) { rtc::Event event; - encoder_queue_.PostTask([this, restrictions_listener, &event] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, restrictions_listener, &event] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); RTC_DCHECK(resource_adaptation_processor_); video_stream_adapter_->AddRestrictionsListener(restrictions_listener); event.Set(); @@ -2578,8 +2587,8 @@ void VideoStreamEncoder::AddRestrictionsListenerForTesting( void VideoStreamEncoder::RemoveRestrictionsListenerForTesting( VideoSourceRestrictionsListener* restrictions_listener) { rtc::Event event; - encoder_queue_.PostTask([this, restrictions_listener, &event] { - RTC_DCHECK_RUN_ON(&encoder_queue_); + encoder_queue_->PostTask([this, restrictions_listener, &event] { + RTC_DCHECK_RUN_ON(encoder_queue_.get()); RTC_DCHECK(resource_adaptation_processor_); video_stream_adapter_->RemoveRestrictionsListener(restrictions_listener); event.Set(); diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h index f2c21c12b0..2a542ffe40 100644 --- a/video/video_stream_encoder.h +++ b/video/video_stream_encoder.h @@ -42,7 +42,6 @@ #include "rtc_base/numerics/exp_filter.h" #include "rtc_base/race_checker.h" #include "rtc_base/rate_statistics.h" -#include "rtc_base/task_queue.h" #include "rtc_base/thread_annotations.h" #include "system_wrappers/include/clock.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 // be called on `encoder_queue_`. - TaskQueueBase* encoder_queue() { return encoder_queue_.Get(); } + TaskQueueBase* encoder_queue() { return encoder_queue_.get(); } void OnVideoSourceRestrictionsUpdated( VideoSourceRestrictions restrictions, @@ -210,8 +209,8 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, class DegradationPreferenceManager; - void ReconfigureEncoder() RTC_RUN_ON(&encoder_queue_); - void OnEncoderSettingsChanged() RTC_RUN_ON(&encoder_queue_); + void ReconfigureEncoder() RTC_RUN_ON(encoder_queue_); + void OnEncoderSettingsChanged() RTC_RUN_ON(encoder_queue_); void OnFrame(Timestamp post_time, bool queue_overload, const VideoFrame& video_frame); @@ -225,7 +224,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, int64_t time_when_posted_in_ms); // Indicates whether frame should be dropped because the pixel count is too // 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. EncodedImageCallback::Result OnEncodedImage( @@ -241,25 +240,25 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // Returns a copy of `rate_settings` with the `bitrate` field updated using // the current VideoBitrateAllocator. 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) - RTC_RUN_ON(&encoder_queue_); + RTC_RUN_ON(encoder_queue_); void RunPostEncode(const EncodedImage& encoded_image, int64_t time_sent_us, int temporal_index, 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. void ShutdownResourceAdaptationQueue(); void CheckForAnimatedContent(const VideoFrame& frame, 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 // information. @@ -269,7 +268,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, void ProcessDroppedFrame(const VideoFrame& frame, VideoStreamEncoderObserver::DropReason reason) - RTC_RUN_ON(&encoder_queue_); + RTC_RUN_ON(encoder_queue_); const FieldTrialsView& field_trials_; TaskQueueBase* const worker_queue_; @@ -296,67 +295,66 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // Frame cadence encoder adapter. Frames enter this adapter first, and it then // forwards them to our OnFrame method. std::unique_ptr 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_); - std::unique_ptr encoder_ RTC_GUARDED_BY(&encoder_queue_) - RTC_PT_GUARDED_BY(&encoder_queue_); + VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(encoder_queue_); + std::unique_ptr encoder_ RTC_GUARDED_BY(encoder_queue_) + RTC_PT_GUARDED_BY(encoder_queue_); bool encoder_initialized_ = false; std::unique_ptr rate_allocator_ - RTC_GUARDED_BY(&encoder_queue_) RTC_PT_GUARDED_BY(&encoder_queue_); - int max_framerate_ RTC_GUARDED_BY(&encoder_queue_) = -1; + RTC_GUARDED_BY(encoder_queue_) RTC_PT_GUARDED_BY(encoder_queue_); + int max_framerate_ RTC_GUARDED_BY(encoder_queue_) = -1; // Set when ConfigureEncoder has been called in order to lazy reconfigure the // 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., // 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 encoder_configuration_callbacks_ - RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); absl::optional last_frame_info_ - RTC_GUARDED_BY(&encoder_queue_); - int crop_width_ RTC_GUARDED_BY(&encoder_queue_) = 0; - int crop_height_ RTC_GUARDED_BY(&encoder_queue_) = 0; + RTC_GUARDED_BY(encoder_queue_); + int crop_width_ RTC_GUARDED_BY(encoder_queue_) = 0; + int crop_height_ RTC_GUARDED_BY(encoder_queue_) = 0; absl::optional encoder_target_bitrate_bps_ - RTC_GUARDED_BY(&encoder_queue_); - size_t max_data_payload_length_ RTC_GUARDED_BY(&encoder_queue_) = 0; + RTC_GUARDED_BY(encoder_queue_); + size_t max_data_payload_length_ RTC_GUARDED_BY(encoder_queue_) = 0; absl::optional last_encoder_rate_settings_ - RTC_GUARDED_BY(&encoder_queue_); - bool encoder_paused_and_dropped_frame_ RTC_GUARDED_BY(&encoder_queue_) = - false; + RTC_GUARDED_BY(encoder_queue_); + bool encoder_paused_and_dropped_frame_ RTC_GUARDED_BY(encoder_queue_) = false; // Set to true if at least one frame was sent to encoder since last encoder // 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_; // 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. - 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_); - 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_encoder_block_count_ RTC_GUARDED_BY(&encoder_queue_) = 0; - absl::optional pending_frame_ RTC_GUARDED_BY(&encoder_queue_); - int64_t pending_frame_post_time_us_ RTC_GUARDED_BY(&encoder_queue_) = 0; + int64_t last_frame_log_ms_ RTC_GUARDED_BY(encoder_queue_); + 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_encoder_block_count_ RTC_GUARDED_BY(encoder_queue_) = 0; + absl::optional pending_frame_ RTC_GUARDED_BY(encoder_queue_); + int64_t pending_frame_post_time_us_ RTC_GUARDED_BY(encoder_queue_) = 0; VideoFrame::UpdateRect accumulated_update_rect_ - RTC_GUARDED_BY(&encoder_queue_); - bool accumulated_update_rect_is_valid_ RTC_GUARDED_BY(&encoder_queue_) = true; + RTC_GUARDED_BY(encoder_queue_); + bool accumulated_update_rect_is_valid_ RTC_GUARDED_BY(encoder_queue_) = true; // Used for automatic content type detection. absl::optional last_update_rect_ - RTC_GUARDED_BY(&encoder_queue_); - Timestamp animation_start_time_ RTC_GUARDED_BY(&encoder_queue_) = + RTC_GUARDED_BY(encoder_queue_); + Timestamp animation_start_time_ RTC_GUARDED_BY(encoder_queue_) = 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; // Used to correctly ignore changes in update_rect introduced by // resize triggered by animation detection. @@ -364,24 +362,24 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, kNoResize, // Normal operation. kResize, // Resize was triggered by the animation detection. kFirstFrameAfterResize // Resize observed. - } expect_resize_state_ RTC_GUARDED_BY(&encoder_queue_) = + } expect_resize_state_ RTC_GUARDED_BY(encoder_queue_) = ExpectResizeState::kNoResize; FecControllerOverride* fec_controller_override_ - RTC_GUARDED_BY(&encoder_queue_) = nullptr; + RTC_GUARDED_BY(encoder_queue_) = nullptr; absl::optional last_parameters_update_ms_ - RTC_GUARDED_BY(&encoder_queue_); - absl::optional last_encode_info_ms_ RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); + absl::optional last_encode_info_ms_ RTC_GUARDED_BY(encoder_queue_); - VideoEncoder::EncoderInfo encoder_info_ RTC_GUARDED_BY(&encoder_queue_); - VideoCodec send_codec_ RTC_GUARDED_BY(&encoder_queue_); + VideoEncoder::EncoderInfo encoder_info_ 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 // disabled if VideoEncoder::GetEncoderInfo() indicates that the encoder has a // trusted rate controller. This is determined on a per-frame basis, as the // 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 // frame should be dropped. Decremented on whichever thread runs // 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 // cwnd_frame_drop_interval_ frames). - absl::optional cwnd_frame_drop_interval_ RTC_GUARDED_BY(&encoder_queue_); + absl::optional cwnd_frame_drop_interval_ RTC_GUARDED_BY(encoder_queue_); // 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 bitrate_adjuster_ - RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); // TODO(sprang): Change actually support keyframe per simulcast stream, or // turn this into a simple bool `pending_keyframe_request_`. - std::vector next_frame_types_ RTC_GUARDED_BY(&encoder_queue_); + std::vector next_frame_types_ RTC_GUARDED_BY(encoder_queue_); FrameEncodeMetadataWriter frame_encode_metadata_writer_{this}; @@ -421,22 +419,22 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, ParseAutomatincAnimationDetectionFieldTrial() const; 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. VideoStreamInputStateProvider input_state_provider_; const std::unique_ptr video_stream_adapter_ - RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); // Responsible for adapting input resolution or frame rate to ensure resources // (e.g. CPU or bandwidth) are not overused. Adding resources can occur on any // thread. std::unique_ptr - resource_adaptation_processor_ RTC_GUARDED_BY(&encoder_queue_); + resource_adaptation_processor_ RTC_GUARDED_BY(encoder_queue_); std::unique_ptr degradation_preference_manager_ - RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); std::vector adaptation_constraints_ - RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); // Handles input, output and stats reporting related to VideoStreamEncoder // specific resources, such as "encode usage percent" measurements and "QP // scaling". Also involved with various mitigations such as initial frame @@ -445,9 +443,9 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // tied to the VideoStreamEncoder (which is destroyed off the encoder queue) // and its resource list is accessible from any thread. VideoStreamEncoderResourceManager stream_resource_manager_ - RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); std::vector> additional_resources_ - RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); // Carries out the VideoSourceRestrictions provided by the // ResourceAdaptationProcessor, i.e. reconfigures the source of video frames // to provide us with different resolution or frame rate. @@ -479,9 +477,9 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // so that ownership on restrictions/wants is kept on &encoder_queue_, that // these extra copies would not be needed. absl::optional latest_restrictions_ - RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); absl::optional animate_restrictions_ - RTC_GUARDED_BY(&encoder_queue_); + RTC_GUARDED_BY(encoder_queue_); // Used to cancel any potentially pending tasks to the worker thread. // Refrenced by tasks running on `encoder_queue_` so need to be destroyed @@ -489,9 +487,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, // `worker_queue_`. ScopedTaskSafety task_safety_; - // Public methods are proxied to the task queues. The queues must be destroyed - // first to make sure no tasks run that use other members. - rtc::TaskQueue encoder_queue_; + std::unique_ptr encoder_queue_; }; } // namespace webrtc