diff --git a/call/BUILD.gn b/call/BUILD.gn index 53d3193ab7..b2b56b273c 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -55,6 +55,7 @@ rtc_library("call_interfaces") { "../api/audio_codecs:audio_codecs_api", "../api/crypto:frame_encryptor_interface", "../api/crypto:options", + "../api/metronome", "../api/neteq:neteq_api", "../api/task_queue", "../api/transport:bitrate_settings", @@ -318,6 +319,7 @@ rtc_library("call") { "../system_wrappers:field_trial", "../system_wrappers:metrics", "../video", + "../video:decode_synchronizer", "adaptation:resource_adaptation", ] absl_deps = [ diff --git a/call/call.cc b/call/call.cc index 793de33f45..bb62365cd4 100644 --- a/call/call.cc +++ b/call/call.cc @@ -371,6 +371,7 @@ class Call final : public webrtc::Call, TaskQueueFactory* const task_queue_factory_; TaskQueueBase* const worker_thread_; TaskQueueBase* const network_thread_; + const std::unique_ptr decode_sync_; RTC_NO_UNIQUE_ADDRESS SequenceChecker send_transport_sequence_checker_; const int num_cpu_cores_; @@ -800,6 +801,11 @@ Call::Call(Clock* clock, // must be made on `worker_thread_` (i.e. they're one and the same). network_thread_(config.network_task_queue_ ? config.network_task_queue_ : worker_thread_), + decode_sync_(config.metronome + ? std::make_unique(clock_, + config.metronome, + worker_thread_) + : nullptr), num_cpu_cores_(CpuInfo::DetectNumberOfCores()), module_process_thread_(std::move(module_process_thread)), call_stats_(new CallStats(clock_, worker_thread_)), @@ -1148,7 +1154,7 @@ webrtc::VideoReceiveStream* Call::CreateVideoReceiveStream( task_queue_factory_, this, num_cpu_cores_, transport_send_->packet_router(), std::move(configuration), call_stats_.get(), clock_, new VCMTiming(clock_), - &nack_periodic_processor_); + &nack_periodic_processor_, decode_sync_.get()); // TODO(bugs.webrtc.org/11993): Set this up asynchronously on the network // thread. receive_stream->RegisterWithTransport(&video_receiver_controller_); diff --git a/call/call_config.h b/call/call_config.h index f149790150..ef505a4b0a 100644 --- a/call/call_config.h +++ b/call/call_config.h @@ -11,6 +11,7 @@ #define CALL_CALL_CONFIG_H_ #include "api/fec_controller.h" +#include "api/metronome/metronome.h" #include "api/neteq/neteq_factory.h" #include "api/network_state_predictor.h" #include "api/rtc_error.h" @@ -75,6 +76,8 @@ struct CallConfig { // RtpTransportControllerSend to use for this call. RtpTransportControllerSendFactoryInterface* rtp_transport_controller_send_factory = nullptr; + + Metronome* metronome = nullptr; }; } // namespace webrtc diff --git a/pc/peer_connection_factory.cc b/pc/peer_connection_factory.cc index 193754ea2a..db2f468a01 100644 --- a/pc/peer_connection_factory.cc +++ b/pc/peer_connection_factory.cc @@ -105,7 +105,8 @@ PeerConnectionFactory::PeerConnectionFactory( transport_controller_send_factory_( (dependencies->transport_controller_send_factory) ? std::move(dependencies->transport_controller_send_factory) - : std::make_unique()) {} + : std::make_unique()), + metronome_(std::move(dependencies->metronome)) {} PeerConnectionFactory::PeerConnectionFactory( PeerConnectionFactoryDependencies dependencies) @@ -348,6 +349,7 @@ std::unique_ptr PeerConnectionFactory::CreateCall_w( call_config.trials = &trials(); call_config.rtp_transport_controller_send_factory = transport_controller_send_factory_.get(); + call_config.metronome = metronome_.get(); return std::unique_ptr( context_->call_factory()->CreateCall(call_config)); } diff --git a/pc/peer_connection_factory.h b/pc/peer_connection_factory.h index 4946ec6ea2..c1599f4885 100644 --- a/pc/peer_connection_factory.h +++ b/pc/peer_connection_factory.h @@ -152,6 +152,7 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface { std::unique_ptr neteq_factory_; const std::unique_ptr transport_controller_send_factory_; + std::unique_ptr metronome_; }; } // namespace webrtc diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc index ef9692e61e..5436c0156e 100644 --- a/video/video_receive_stream2.cc +++ b/video/video_receive_stream2.cc @@ -211,7 +211,8 @@ VideoReceiveStream2::VideoReceiveStream2( CallStats* call_stats, Clock* clock, VCMTiming* timing, - NackPeriodicProcessor* nack_periodic_processor) + NackPeriodicProcessor* nack_periodic_processor, + DecodeSynchronizer* decode_sync) : task_queue_factory_(task_queue_factory), transport_adapter_(config.rtcp_send_transport), config_(std::move(config)), @@ -246,6 +247,7 @@ VideoReceiveStream2::VideoReceiveStream2( low_latency_renderer_include_predecode_buffer_("include_predecode_buffer", true), maximum_pre_stream_decoders_("max", kDefaultMaximumPreStreamDecoders), + decode_sync_(decode_sync), decode_queue_(task_queue_factory_->CreateTaskQueue( "DecodingQueue", TaskQueueFactory::Priority::HIGH)) { @@ -272,7 +274,7 @@ VideoReceiveStream2::VideoReceiveStream2( frame_buffer_ = FrameBufferProxy::CreateFromFieldTrial( clock_, call_->worker_thread(), timing_.get(), &stats_proxy_, &decode_queue_, this, TimeDelta::Millis(max_wait_for_keyframe_ms_), - TimeDelta::Millis(max_wait_for_frame_ms_), nullptr); + TimeDelta::Millis(max_wait_for_frame_ms_), decode_sync_); if (config_.rtp.rtx_ssrc) { rtx_receive_stream_ = std::make_unique( diff --git a/video/video_receive_stream2.h b/video/video_receive_stream2.h index 665facace4..6a7795da69 100644 --- a/video/video_receive_stream2.h +++ b/video/video_receive_stream2.h @@ -101,7 +101,8 @@ class VideoReceiveStream2 CallStats* call_stats, Clock* clock, VCMTiming* timing, - NackPeriodicProcessor* nack_periodic_processor); + NackPeriodicProcessor* nack_periodic_processor, + DecodeSynchronizer* decode_sync); // Destruction happens on the worker thread. Prior to destruction the caller // must ensure that a registration with the transport has been cleared. See // `RegisterWithTransport` for details. @@ -323,6 +324,8 @@ class VideoReceiveStream2 // any video frame has been received. FieldTrialParameter maximum_pre_stream_decoders_; + DecodeSynchronizer* decode_sync_; + // Defined last so they are destroyed before all other members. rtc::TaskQueue decode_queue_; diff --git a/video/video_receive_stream2_unittest.cc b/video/video_receive_stream2_unittest.cc index f3a5338269..41e0ecba71 100644 --- a/video/video_receive_stream2_unittest.cc +++ b/video/video_receive_stream2_unittest.cc @@ -106,7 +106,7 @@ class VideoReceiveStream2Test : public ::testing::Test { std::make_unique( task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores, &packet_router_, config_.Copy(), &call_stats_, clock_, timing_, - &nack_periodic_processor_); + &nack_periodic_processor_, nullptr); video_receive_stream_->RegisterWithTransport( &rtp_stream_receiver_controller_); } @@ -286,7 +286,7 @@ class VideoReceiveStream2TestWithFakeDecoder : public ::testing::Test { video_receive_stream_.reset(new webrtc::internal::VideoReceiveStream2( task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores, &packet_router_, config_.Copy(), &call_stats_, clock_, timing_, - &nack_periodic_processor_)); + &nack_periodic_processor_, nullptr)); video_receive_stream_->RegisterWithTransport( &rtp_stream_receiver_controller_); video_receive_stream_->SetAndGetRecordingState(std::move(state), false); @@ -556,7 +556,8 @@ class VideoReceiveStream2TestWithSimulatedClock &call_stats_, time_controller_.GetClock(), new VCMTiming(time_controller_.GetClock()), - &nack_periodic_processor_) { + &nack_periodic_processor_, + nullptr) { video_receive_stream_.RegisterWithTransport( &rtp_stream_receiver_controller_); video_receive_stream_.Start(); @@ -741,7 +742,7 @@ class VideoReceiveStream2TestWithLazyDecoderCreation : public ::testing::Test { std::make_unique( task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores, &packet_router_, config_.Copy(), &call_stats_, clock_, timing_, - &nack_periodic_processor_); + &nack_periodic_processor_, nullptr); video_receive_stream_->RegisterWithTransport( &rtp_stream_receiver_controller_); }