mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
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:
parent
348438154a
commit
f1fc6ab3ba
6 changed files with 147 additions and 137 deletions
|
@ -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",
|
||||
|
|
|
@ -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" ]
|
||||
|
|
|
@ -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<VideoFrame> 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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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<VideoFrame> {
|
|||
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<VideoFrame>* const callback_;
|
||||
rtc::TaskQueue incoming_render_queue_;
|
||||
std::unique_ptr<TaskQueueBase, TaskQueueDeleter> incoming_render_queue_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -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<ResourceAdaptationProcessor>(
|
||||
|
@ -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<rtc::scoped_refptr<Resource>> 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<uint32_t>(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),
|
||||
encoder_queue_->PostTask([this, config = std::move(config),
|
||||
max_data_payload_length,
|
||||
callback = std::move(callback)]() mutable {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
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<VideoFrameType>& 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,
|
||||
encoder_queue_->PostTask([this, codec_type, image_width, image_height,
|
||||
simulcast_index,
|
||||
at_target_quality = image_copy.IsAtTargetQuality()] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
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<Resource> 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("<null>"))
|
||||
<< " 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,
|
||||
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<int> encode_duration_us;
|
||||
if (encoded_image.timing_.flags != VideoSendTiming::kInvalid) {
|
||||
|
@ -2539,8 +2548,8 @@ void VideoStreamEncoder::CheckForAnimatedContent(
|
|||
void VideoStreamEncoder::InjectAdaptationResource(
|
||||
rtc::scoped_refptr<Resource> 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();
|
||||
|
|
|
@ -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<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_);
|
||||
std::unique_ptr<VideoEncoder> encoder_ RTC_GUARDED_BY(&encoder_queue_)
|
||||
RTC_PT_GUARDED_BY(&encoder_queue_);
|
||||
VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(encoder_queue_);
|
||||
std::unique_ptr<VideoEncoder> encoder_ RTC_GUARDED_BY(encoder_queue_)
|
||||
RTC_PT_GUARDED_BY(encoder_queue_);
|
||||
bool encoder_initialized_ = false;
|
||||
std::unique_ptr<VideoBitrateAllocator> 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<SetParametersCallback, 2> encoder_configuration_callbacks_
|
||||
RTC_GUARDED_BY(&encoder_queue_);
|
||||
RTC_GUARDED_BY(encoder_queue_);
|
||||
|
||||
absl::optional<VideoFrameInfo> 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<uint32_t> 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<EncoderRateSettings> 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<VideoFrame> 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<VideoFrame> 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<VideoFrame::UpdateRect> 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<int64_t> last_parameters_update_ms_
|
||||
RTC_GUARDED_BY(&encoder_queue_);
|
||||
absl::optional<int64_t> last_encode_info_ms_ RTC_GUARDED_BY(&encoder_queue_);
|
||||
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_);
|
||||
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<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.
|
||||
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_
|
||||
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<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};
|
||||
|
||||
|
@ -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<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
|
||||
// (e.g. CPU or bandwidth) are not overused. Adding resources can occur on any
|
||||
// thread.
|
||||
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_
|
||||
RTC_GUARDED_BY(&encoder_queue_);
|
||||
RTC_GUARDED_BY(encoder_queue_);
|
||||
std::vector<AdaptationConstraint*> 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<rtc::scoped_refptr<Resource>> 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<VideoSourceRestrictions> latest_restrictions_
|
||||
RTC_GUARDED_BY(&encoder_queue_);
|
||||
RTC_GUARDED_BY(encoder_queue_);
|
||||
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.
|
||||
// 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<TaskQueueBase, TaskQueueDeleter> encoder_queue_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
Loading…
Reference in a new issue