Stop using legacy rtc::TaskQueue in VideoReceiveStream2
Bug: webrtc:14169
Change-Id: Ib18a0bd4531d69055ae0131ac749745bd74651d8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/334681
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41545}
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 21e681c..3512275 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -142,7 +142,6 @@
"../rtc_base:rate_tracker",
"../rtc_base:rtc_event",
"../rtc_base:rtc_numerics",
- "../rtc_base:rtc_task_queue",
"../rtc_base:safe_conversions",
"../rtc_base:sample_counter",
"../rtc_base:stringutils",
diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc
index 9ea3936..9e09506 100644
--- a/video/video_receive_stream2.cc
+++ b/video/video_receive_stream2.cc
@@ -187,6 +187,8 @@
NackPeriodicProcessor* nack_periodic_processor,
DecodeSynchronizer* decode_sync)
: env_(env),
+ packet_sequence_checker_(SequenceChecker::kDetached),
+ decode_sequence_checker_(SequenceChecker::kDetached),
transport_adapter_(config.rtcp_send_transport),
config_(std::move(config)),
num_cpu_cores_(num_cpu_cores),
@@ -227,7 +229,6 @@
RTC_DCHECK(call_->worker_thread());
RTC_DCHECK(config_.renderer);
RTC_DCHECK(call_stats_);
- packet_sequence_checker_.Detach();
RTC_DCHECK(!config_.decoders.empty());
RTC_CHECK(config_.decoder_factory);
@@ -378,8 +379,8 @@
// Start decoding on task queue.
stats_proxy_.DecoderThreadStarting();
- decode_queue_.PostTask([this] {
- RTC_DCHECK_RUN_ON(&decode_queue_);
+ decode_queue_->PostTask([this] {
+ RTC_DCHECK_RUN_ON(&decode_sequence_checker_);
decoder_stopped_ = false;
});
buffer_->StartNextDecode(true);
@@ -409,8 +410,8 @@
if (decoder_running_) {
rtc::Event done;
- decode_queue_.PostTask([this, &done] {
- RTC_DCHECK_RUN_ON(&decode_queue_);
+ decode_queue_->PostTask([this, &done] {
+ RTC_DCHECK_RUN_ON(&decode_sequence_checker_);
// Set `decoder_stopped_` before deregistering all decoders. This means
// that any pending encoded frame will return early without trying to
// access the decoder database.
@@ -763,10 +764,10 @@
}
stats_proxy_.OnPreDecode(frame->CodecSpecific()->codecType, qp);
- decode_queue_.PostTask([this, now, keyframe_request_is_due,
- received_frame_is_keyframe, frame = std::move(frame),
- keyframe_required = keyframe_required_]() mutable {
- RTC_DCHECK_RUN_ON(&decode_queue_);
+ decode_queue_->PostTask([this, now, keyframe_request_is_due,
+ received_frame_is_keyframe, frame = std::move(frame),
+ keyframe_required = keyframe_required_]() mutable {
+ RTC_DCHECK_RUN_ON(&decode_sequence_checker_);
if (decoder_stopped_)
return;
DecodeFrameResult result = HandleEncodedFrameOnDecodeQueue(
@@ -830,7 +831,7 @@
std::unique_ptr<EncodedFrame> frame,
bool keyframe_request_is_due,
bool keyframe_required) {
- RTC_DCHECK_RUN_ON(&decode_queue_);
+ RTC_DCHECK_RUN_ON(&decode_sequence_checker_);
bool force_request_key_frame = false;
absl::optional<int64_t> decoded_frame_picture_id;
@@ -872,7 +873,7 @@
int VideoReceiveStream2::DecodeAndMaybeDispatchEncodedFrame(
std::unique_ptr<EncodedFrame> frame) {
- RTC_DCHECK_RUN_ON(&decode_queue_);
+ RTC_DCHECK_RUN_ON(&decode_sequence_checker_);
// If `buffered_encoded_frames_` grows out of control (=60 queued frames),
// maybe due to a stuck decoder, we just halt the process here and log the
@@ -1055,10 +1056,10 @@
: Timestamp::Millis(state.last_keyframe_request_ms.value_or(0));
}
- decode_queue_.PostTask(
+ decode_queue_->PostTask(
[this, &event, &old_state, callback = std::move(state.callback),
last_keyframe_request = std::move(last_keyframe_request)] {
- RTC_DCHECK_RUN_ON(&decode_queue_);
+ RTC_DCHECK_RUN_ON(&decode_sequence_checker_);
old_state.callback = std::move(encoded_frame_buffer_function_);
encoded_frame_buffer_function_ = std::move(callback);
diff --git a/video/video_receive_stream2.h b/video/video_receive_stream2.h
index b0bd164..cfdea63 100644
--- a/video/video_receive_stream2.h
+++ b/video/video_receive_stream2.h
@@ -20,6 +20,7 @@
#include "api/environment/environment.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.h"
+#include "api/task_queue/task_queue_base.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/recordable_encoded_frame.h"
@@ -31,7 +32,6 @@
#include "modules/video_coding/nack_requester.h"
#include "modules/video_coding/video_receiver2.h"
#include "rtc_base/system/no_unique_address.h"
-#include "rtc_base/task_queue.h"
#include "rtc_base/thread_annotations.h"
#include "video/receive_statistics_proxy.h"
#include "video/rtp_streams_synchronizer2.h"
@@ -224,7 +224,7 @@
DecodeFrameResult HandleEncodedFrameOnDecodeQueue(
std::unique_ptr<EncodedFrame> frame,
bool keyframe_request_is_due,
- bool keyframe_required) RTC_RUN_ON(decode_queue_);
+ bool keyframe_required) RTC_RUN_ON(decode_sequence_checker_);
void UpdatePlayoutDelays() const
RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_sequence_checker_);
void RequestKeyFrame(Timestamp now) RTC_RUN_ON(packet_sequence_checker_);
@@ -236,10 +236,12 @@
bool IsReceivingKeyFrame(Timestamp timestamp) const
RTC_RUN_ON(packet_sequence_checker_);
int DecodeAndMaybeDispatchEncodedFrame(std::unique_ptr<EncodedFrame> frame)
- RTC_RUN_ON(decode_queue_);
+ RTC_RUN_ON(decode_sequence_checker_);
void UpdateHistograms();
+ const Environment env_;
+
RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_sequence_checker_;
// TODO(bugs.webrtc.org/11993): This checker conceptually represents
// operations that belong to the network thread. The Call class is currently
@@ -250,7 +252,7 @@
// on the network thread, this comment will be deleted.
RTC_NO_UNIQUE_ADDRESS SequenceChecker packet_sequence_checker_;
- const Environment env_;
+ RTC_NO_UNIQUE_ADDRESS SequenceChecker decode_sequence_checker_;
TransportAdapter transport_adapter_;
const VideoReceiveStreamInterface::Config config_;
@@ -260,7 +262,7 @@
CallStats* const call_stats_;
bool decoder_running_ RTC_GUARDED_BY(worker_sequence_checker_) = false;
- bool decoder_stopped_ RTC_GUARDED_BY(decode_queue_) = true;
+ bool decoder_stopped_ RTC_GUARDED_BY(decode_sequence_checker_) = true;
SourceTracker source_tracker_;
ReceiveStatisticsProxy stats_proxy_;
@@ -296,7 +298,7 @@
bool keyframe_required_ RTC_GUARDED_BY(packet_sequence_checker_) = true;
// If we have successfully decoded any frame.
- bool frame_decoded_ RTC_GUARDED_BY(decode_queue_) = false;
+ bool frame_decoded_ RTC_GUARDED_BY(decode_sequence_checker_) = false;
absl::optional<Timestamp> last_keyframe_request_
RTC_GUARDED_BY(packet_sequence_checker_);
@@ -325,7 +327,7 @@
// Function that is triggered with encoded frames, if not empty.
std::function<void(const RecordableEncodedFrame&)>
- encoded_frame_buffer_function_ RTC_GUARDED_BY(decode_queue_);
+ encoded_frame_buffer_function_ RTC_GUARDED_BY(decode_sequence_checker_);
// Set to true while we're requesting keyframes but not yet received one.
bool keyframe_generation_requested_ RTC_GUARDED_BY(packet_sequence_checker_) =
false;
@@ -338,13 +340,16 @@
RTC_GUARDED_BY(pending_resolution_mutex_);
// Buffered encoded frames held while waiting for decoded resolution.
std::vector<std::unique_ptr<EncodedFrame>> buffered_encoded_frames_
- RTC_GUARDED_BY(decode_queue_);
-
- // Defined last so they are destroyed before all other members.
- rtc::TaskQueue decode_queue_;
+ RTC_GUARDED_BY(decode_sequence_checker_);
// Used to signal destruction to potentially pending tasks.
ScopedTaskSafety task_safety_;
+
+ // Defined last so they are destroyed before all other members, in particular
+ // `decode_queue_` should be stopped before `decode_sequence_checker_` is
+ // destructed to avoid races when running tasks on the `decode_queue_` during
+ // VideoReceiveStream2 destruction.
+ std::unique_ptr<TaskQueueBase, TaskQueueDeleter> decode_queue_;
};
} // namespace internal