From e2fee23271c4325cb460a6641c62a931d6cfbe8d Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Thu, 29 Aug 2024 11:50:33 +0200 Subject: [PATCH] Propagate Environment into RtpVideoStreamReceiver2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make it available for constructing ModuleRtpRtcpImpl2 Bug: webrtc:362762208 Change-Id: Ic6ad339170c6aedb6c0bf42419964741d4d32bcc Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/360921 Reviewed-by: Åsa Persson Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#42888} --- video/BUILD.gn | 2 +- video/rtp_video_stream_receiver2.cc | 88 +++++++++----------- video/rtp_video_stream_receiver2.h | 13 ++- video/rtp_video_stream_receiver2_unittest.cc | 47 ++++++----- video/video_receive_stream2.cc | 8 +- 5 files changed, 77 insertions(+), 81 deletions(-) diff --git a/video/BUILD.gn b/video/BUILD.gn index aa18fd019a..507e42848b 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -936,10 +936,10 @@ if (rtc_include_tests) { "../rtc_base/experiments:encoder_info_settings", "../rtc_base/synchronization:mutex", "../system_wrappers", - "../system_wrappers:field_trial", "../system_wrappers:metrics", "../test:direct_transport", "../test:encoder_settings", + "../test:explicit_key_value_config", "../test:fake_encoded_frame", "../test:fake_video_codecs", "../test:field_trial", diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc index caf373cd6a..4c43bec9ce 100644 --- a/video/rtp_video_stream_receiver2.cc +++ b/video/rtp_video_stream_receiver2.cc @@ -75,17 +75,16 @@ int PacketBufferMaxSize(const FieldTrialsView& field_trials) { } std::unique_ptr CreateRtpRtcpModule( - Clock* clock, + const Environment& env, ReceiveStatistics* receive_statistics, Transport* outgoing_transport, RtcpRttStats* rtt_stats, RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, RtcpCnameCallback* rtcp_cname_callback, bool non_sender_rtt_measurement, - uint32_t local_ssrc, - RtcEventLog* rtc_event_log) { + uint32_t local_ssrc) { RtpRtcpInterface::Configuration configuration; - configuration.clock = clock; + configuration.clock = &env.clock(); configuration.audio = false; configuration.receiver_only = true; configuration.receive_statistics = receive_statistics; @@ -96,7 +95,8 @@ std::unique_ptr CreateRtpRtcpModule( configuration.rtcp_cname_callback = rtcp_cname_callback; configuration.local_media_ssrc = local_ssrc; configuration.non_sender_rtt_measurement = non_sender_rtt_measurement; - configuration.event_log = rtc_event_log; + configuration.event_log = &env.event_log(); + configuration.field_trials = &env.field_trials(); std::unique_ptr rtp_rtcp = ModuleRtpRtcpImpl2::Create(configuration); @@ -106,20 +106,19 @@ std::unique_ptr CreateRtpRtcpModule( } std::unique_ptr MaybeConstructNackModule( + const Environment& env, TaskQueueBase* current_queue, NackPeriodicProcessor* nack_periodic_processor, const NackConfig& nack, - Clock* clock, NackSender* nack_sender, - KeyFrameRequestSender* keyframe_request_sender, - const FieldTrialsView& field_trials) { + KeyFrameRequestSender* keyframe_request_sender) { if (nack.rtp_history_ms == 0) return nullptr; // TODO(bugs.webrtc.org/12420): pass rtp_history_ms to the nack module. - return std::make_unique(current_queue, nack_periodic_processor, - clock, nack_sender, - keyframe_request_sender, field_trials); + return std::make_unique( + current_queue, nack_periodic_processor, &env.clock(), nack_sender, + keyframe_request_sender, env.field_trials()); } std::unique_ptr MaybeConstructUlpfecReceiver( @@ -232,8 +231,8 @@ void RtpVideoStreamReceiver2::RtcpFeedbackBuffer::ClearLossNotificationState() { } RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( + const Environment& env, TaskQueueBase* current_queue, - Clock* clock, Transport* transport, RtcpRttStats* rtt_stats, PacketRouter* packet_router, @@ -243,16 +242,13 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( RtcpCnameCallback* rtcp_cname_callback, NackPeriodicProcessor* nack_periodic_processor, OnCompleteFrameCallback* complete_frame_callback, - rtc::scoped_refptr frame_decryptor, - rtc::scoped_refptr frame_transformer, - const FieldTrialsView& field_trials, - RtcEventLog* event_log) - : field_trials_(field_trials), + scoped_refptr frame_decryptor, + scoped_refptr frame_transformer) + : env_(env), worker_queue_(current_queue), - clock_(clock), config_(*config), packet_router_(packet_router), - ntp_estimator_(clock), + ntp_estimator_(&env_.clock()), forced_playout_delay_max_ms_("max_ms", absl::nullopt), forced_playout_delay_min_ms_("min_ms", absl::nullopt), rtp_receive_statistics_(rtp_receive_statistics), @@ -261,40 +257,38 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( config->rtp.red_payload_type, config->rtp.ulpfec_payload_type, this, - clock_)), + &env_.clock())), red_payload_type_(config_.rtp.red_payload_type), packet_sink_(config->rtp.packet_sink_), receiving_(false), last_packet_log_ms_(-1), rtp_rtcp_(CreateRtpRtcpModule( - clock, + env_, rtp_receive_statistics_, transport, rtt_stats, rtcp_packet_type_counter_observer, rtcp_cname_callback, config_.rtp.rtcp_xr.receiver_reference_time_report, - config_.rtp.local_ssrc, - event_log)), + config_.rtp.local_ssrc)), nack_periodic_processor_(nack_periodic_processor), complete_frame_callback_(complete_frame_callback), keyframe_request_method_(config_.rtp.keyframe_method), // TODO(bugs.webrtc.org/10336): Let `rtcp_feedback_buffer_` communicate // directly with `rtp_rtcp_`. rtcp_feedback_buffer_(this, this, this), - nack_module_(MaybeConstructNackModule(current_queue, + nack_module_(MaybeConstructNackModule(env_, + current_queue, nack_periodic_processor, config_.rtp.nack, - clock_, &rtcp_feedback_buffer_, - &rtcp_feedback_buffer_, - field_trials_)), + &rtcp_feedback_buffer_)), packet_buffer_(kPacketBufferStartSize, - PacketBufferMaxSize(field_trials_)), + PacketBufferMaxSize(env_.field_trials())), reference_finder_(std::make_unique()), has_received_frame_(false), frames_decryptable_(false), - absolute_capture_time_interpolator_(clock) { + absolute_capture_time_interpolator_(&env_.clock()) { packet_sequence_checker_.Detach(); if (packet_router_) { // Do not register as REMB candidate, this is only done when starting to @@ -319,7 +313,7 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( } ParseFieldTrial( {&forced_playout_delay_max_ms_, &forced_playout_delay_min_ms_}, - field_trials_.Lookup("WebRTC-ForcePlayoutDelay")); + env_.field_trials().Lookup("WebRTC-ForcePlayoutDelay")); if (config_.rtp.lntf.enabled) { loss_notification_controller_ = @@ -329,8 +323,8 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( // Only construct the encrypted receiver if frame encryption is enabled. if (config_.crypto_options.sframe.require_frame_encryption) { - buffered_frame_decryptor_ = - std::make_unique(this, this, field_trials_); + buffered_frame_decryptor_ = std::make_unique( + this, this, env_.field_trials()); if (frame_decryptor != nullptr) { buffered_frame_decryptor_->SetFrameDecryptor(std::move(frame_decryptor)); } @@ -339,8 +333,8 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( if (frame_transformer) { frame_transformer_delegate_ = rtc::make_ref_counted( - this, clock_, std::move(frame_transformer), rtc::Thread::Current(), - config_.rtp.remote_ssrc); + this, &env_.clock(), std::move(frame_transformer), + rtc::Thread::Current(), config_.rtp.remote_ssrc); frame_transformer_delegate_->Init(); } } @@ -360,7 +354,7 @@ void RtpVideoStreamReceiver2::AddReceiveCodec( bool raw_payload) { RTC_DCHECK_RUN_ON(&packet_sequence_checker_); if (codec_params.count(cricket::kH264FmtpSpsPpsIdrInKeyframe) > 0 || - field_trials_.IsEnabled("WebRTC-SpsPpsIdrIsH264Keyframe")) { + env_.field_trials().IsEnabled("WebRTC-SpsPpsIdrIsH264Keyframe")) { packet_buffer_.ForceSpsPpsIdrIsH264Keyframe(); sps_pps_idr_is_h264_keyframe_ = true; } @@ -525,7 +519,7 @@ bool RtpVideoStreamReceiver2::OnReceivedPayloadData( .emplace(unwrapped_rtp_seq_num, RtpPacketInfo(rtp_packet.Ssrc(), rtp_packet.Csrcs(), rtp_packet.Timestamp(), - /*receive_time_ms=*/clock_->CurrentTime())) + /*receive_time=*/env_.clock().CurrentTime())) .first->second; // Try to extrapolate absolute capture time if it is missing. @@ -575,7 +569,7 @@ bool RtpVideoStreamReceiver2::OnReceivedPayloadData( if (generic_descriptor_state == kStashPacket) { return true; } else if (generic_descriptor_state == kDropPacket) { - Timestamp now = clock_->CurrentTime(); + Timestamp now = env_.clock().CurrentTime(); if (now - last_logged_failed_to_parse_dd_ > TimeDelta::Seconds(1)) { last_logged_failed_to_parse_dd_ = now; RTC_LOG(LS_WARNING) << "ssrc: " << rtp_packet.Ssrc() @@ -931,8 +925,8 @@ void RtpVideoStreamReceiver2::SetFrameDecryptor( // the network thread. RTC_DCHECK_RUN_ON(&packet_sequence_checker_); if (buffered_frame_decryptor_ == nullptr) { - buffered_frame_decryptor_ = - std::make_unique(this, this, field_trials_); + buffered_frame_decryptor_ = std::make_unique( + this, this, env_.field_trials()); } buffered_frame_decryptor_->SetFrameDecryptor(std::move(frame_decryptor)); } @@ -942,8 +936,8 @@ void RtpVideoStreamReceiver2::SetDepacketizerToDecoderFrameTransformer( RTC_DCHECK_RUN_ON(&worker_task_checker_); frame_transformer_delegate_ = rtc::make_ref_counted( - this, clock_, std::move(frame_transformer), rtc::Thread::Current(), - config_.rtp.remote_ssrc); + this, &env_.clock(), std::move(frame_transformer), + rtc::Thread::Current(), config_.rtp.remote_ssrc); frame_transformer_delegate_->Init(); } @@ -992,8 +986,8 @@ void RtpVideoStreamReceiver2::SetNackHistory(TimeDelta history) { nack_module_.reset(); } else if (!nack_module_) { nack_module_ = std::make_unique( - worker_queue_, nack_periodic_processor_, clock_, &rtcp_feedback_buffer_, - &rtcp_feedback_buffer_, field_trials_); + worker_queue_, nack_periodic_processor_, &env_.clock(), + &rtcp_feedback_buffer_, &rtcp_feedback_buffer_, env_.field_trials()); } rtp_receive_statistics_->SetMaxReorderingThreshold( @@ -1020,7 +1014,7 @@ void RtpVideoStreamReceiver2::SetProtectionPayloadTypes( red_payload_type_ = red_payload_type; ulpfec_receiver_ = MaybeConstructUlpfecReceiver(config_.rtp.remote_ssrc, red_payload_type, - ulpfec_payload_type, this, clock_); + ulpfec_payload_type, this, &env_.clock()); } absl::optional RtpVideoStreamReceiver2::LastReceivedPacketMs() const { @@ -1186,7 +1180,7 @@ bool RtpVideoStreamReceiver2::DeliverRtcp(const uint8_t* rtcp_packet, // Waiting for RTCP. return true; } - int64_t time_since_received = clock_->CurrentNtpInMilliseconds() - + int64_t time_since_received = env_.clock().CurrentNtpInMilliseconds() - last_sr->last_arrival_timestamp.ToMs(); // Don't use old SRs to estimate time. if (time_since_received <= 1) { @@ -1245,7 +1239,7 @@ void RtpVideoStreamReceiver2::StartReceive() { RTC_DCHECK_RUN_ON(&packet_sequence_checker_); // |h26x_packet_buffer_| is created here instead of in the ctor because we // need to know the value of |sps_pps_id_is_h264_keyframe_|. - if (field_trials_.IsEnabled("WebRTC-Video-H26xPacketBuffer") && + if (env_.field_trials().IsEnabled("WebRTC-Video-H26xPacketBuffer") && !h26x_packet_buffer_) { h26x_packet_buffer_ = std::make_unique(!sps_pps_idr_is_h264_keyframe_); @@ -1303,7 +1297,7 @@ void RtpVideoStreamReceiver2::InsertSpsPpsIntoTracker(uint8_t payload_type) { void RtpVideoStreamReceiver2::UpdatePacketReceiveTimestamps( const RtpPacketReceived& packet, bool is_keyframe) { - Timestamp now = clock_->CurrentTime(); + Timestamp now = env_.clock().CurrentTime(); if (is_keyframe || last_received_keyframe_rtp_timestamp_ == packet.Timestamp()) { last_received_keyframe_rtp_timestamp_ = packet.Timestamp(); diff --git a/video/rtp_video_stream_receiver2.h b/video/rtp_video_stream_receiver2.h index 8ea3ffd310..221fc099e0 100644 --- a/video/rtp_video_stream_receiver2.h +++ b/video/rtp_video_stream_receiver2.h @@ -18,6 +18,7 @@ #include "absl/types/optional.h" #include "api/crypto/frame_decryptor_interface.h" +#include "api/environment/environment.h" #include "api/sequence_checker.h" #include "api/units/timestamp.h" #include "api/video/color_space.h" @@ -79,8 +80,8 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender, }; RtpVideoStreamReceiver2( + const Environment& env, TaskQueueBase* current_queue, - Clock* clock, Transport* transport, RtcpRttStats* rtt_stats, // The packet router is optional; if provided, the RtpRtcp module for this @@ -95,10 +96,8 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender, // The KeyFrameRequestSender is optional; if not provided, key frame // requests are sent via the internal RtpRtcp module. OnCompleteFrameCallback* complete_frame_callback, - rtc::scoped_refptr frame_decryptor, - rtc::scoped_refptr frame_transformer, - const FieldTrialsView& field_trials, - RtcEventLog* event_log); + scoped_refptr frame_decryptor, + scoped_refptr frame_transformer); ~RtpVideoStreamReceiver2() override; void AddReceiveCodec(uint8_t payload_type, @@ -315,9 +314,9 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender, bool is_keyframe) RTC_RUN_ON(packet_sequence_checker_); - const FieldTrialsView& field_trials_; + const Environment env_; TaskQueueBase* const worker_queue_; - Clock* const clock_; + // Ownership of this object lies with VideoReceiveStreamInterface, which owns // `this`. const VideoReceiveStreamInterface::Config& config_; diff --git a/video/rtp_video_stream_receiver2_unittest.cc b/video/rtp_video_stream_receiver2_unittest.cc index d87dc2626e..335bb81eaf 100644 --- a/video/rtp_video_stream_receiver2_unittest.cc +++ b/video/rtp_video_stream_receiver2_unittest.cc @@ -13,6 +13,8 @@ #include #include +#include "api/environment/environment.h" +#include "api/environment/environment_factory.h" #include "api/task_queue/task_queue_base.h" #include "api/test/mock_frame_transformer.h" #include "api/video/video_codec_type.h" @@ -34,14 +36,19 @@ #include "rtc_base/byte_buffer.h" #include "rtc_base/logging.h" #include "system_wrappers/include/clock.h" +#include "test/explicit_key_value_config.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/mock_transport.h" #include "test/rtcp_packet_parser.h" -#include "test/scoped_key_value_config.h" #include "test/time_controller/simulated_task_queue.h" #include "test/time_controller/simulated_time_controller.h" +namespace webrtc { + +namespace { + +using test::ExplicitKeyValueConfig; using ::testing::_; using ::testing::ElementsAre; using ::testing::Eq; @@ -49,10 +56,6 @@ using ::testing::Invoke; using ::testing::SizeIs; using ::testing::Values; -namespace webrtc { - -namespace { - const uint8_t kH264StartCode[] = {0x00, 0x00, 0x00, 0x01}; std::vector GetAbsoluteCaptureTimestamps(const EncodedFrame* frame) { @@ -149,19 +152,21 @@ class RtpVideoStreamReceiver2Test : public ::testing::Test, RtpVideoStreamReceiver2Test() : RtpVideoStreamReceiver2Test("") {} explicit RtpVideoStreamReceiver2Test(std::string field_trials) : time_controller_(Timestamp::Millis(100)), + env_(CreateEnvironment( + std::make_unique(field_trials), + time_controller_.GetClock(), + time_controller_.GetTaskQueueFactory())), task_queue_(time_controller_.GetTaskQueueFactory()->CreateTaskQueue( "RtpVideoStreamReceiver2Test", TaskQueueFactory::Priority::NORMAL)), task_queue_setter_(task_queue_.get()), - field_trials_(field_trials), config_(CreateConfig()) { - rtp_receive_statistics_ = - ReceiveStatistics::Create(Clock::GetRealTimeClock()); + rtp_receive_statistics_ = ReceiveStatistics::Create(&env_.clock()); rtp_video_stream_receiver_ = std::make_unique( - TaskQueueBase::Current(), Clock::GetRealTimeClock(), &mock_transport_, - nullptr, nullptr, &config_, rtp_receive_statistics_.get(), nullptr, - nullptr, &nack_periodic_processor_, &mock_on_complete_frame_callback_, - nullptr, nullptr, field_trials_, nullptr); + env_, TaskQueueBase::Current(), &mock_transport_, nullptr, nullptr, + &config_, rtp_receive_statistics_.get(), nullptr, nullptr, + &nack_periodic_processor_, &mock_on_complete_frame_callback_, nullptr, + nullptr); rtp_video_stream_receiver_->AddReceiveCodec(kPayloadType, kVideoCodecGeneric, {}, /*raw_payload=*/false); @@ -229,10 +234,10 @@ class RtpVideoStreamReceiver2Test : public ::testing::Test, } GlobalSimulatedTimeController time_controller_; + Environment env_; std::unique_ptr task_queue_; TokenTaskQueue::CurrentTaskQueueSetter task_queue_setter_; - webrtc::test::ScopedKeyValueConfig field_trials_; VideoReceiveStreamInterface::Config config_; NackPeriodicProcessor nack_periodic_processor_; test::RtcpPacketParser rtcp_packet_parser_; @@ -624,8 +629,8 @@ TEST_P(RtpVideoStreamReceiver2TestH264, OutOfBandFmtpSpsPps) { // IDR frames without SPS/PPS are not returned by // |H26xPacketBuffer.InsertPacket| until SPS and PPS are received when // WebRTC-SpsPpsIdrIsH264Keyframe is enabled. - if (!field_trials_.IsEnabled("WebRTC-SpsPpsIdrIsH264Keyframe") || - !field_trials_.IsEnabled("WebRTC-Video-H26xPacketBuffer")) { + if (!env_.field_trials().IsEnabled("WebRTC-SpsPpsIdrIsH264Keyframe") || + !env_.field_trials().IsEnabled("WebRTC-Video-H26xPacketBuffer")) { EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_)); } rtp_video_stream_receiver_->OnReceivedPayloadData(data, rtp_packet, @@ -636,7 +641,7 @@ TEST_P(RtpVideoStreamReceiver2TestH264, ForceSpsPpsIdrIsKeyframe) { constexpr int kPayloadType = 99; webrtc::CodecParameterMap codec_params; // Forcing can be done either with field trial or codec_params. - if (!field_trials_.IsEnabled("WebRTC-SpsPpsIdrIsH264Keyframe")) { + if (!env_.field_trials().IsEnabled("WebRTC-SpsPpsIdrIsH264Keyframe")) { codec_params.insert({cricket::kH264FmtpSpsPpsIdrInKeyframe, ""}); } rtp_video_stream_receiver_->AddReceiveCodec(kPayloadType, kVideoCodecH264, @@ -699,7 +704,7 @@ TEST_P(RtpVideoStreamReceiver2TestH264, ForceSpsPpsIdrIsKeyframe) { // IDR frames without SPS/PPS are not returned by // |H26xPacketBuffer.InsertPacket| until SPS and PPS are received, while // |PacketBuffer| returns it as a delta frame. - if (field_trials_.IsEnabled("WebRTC-Video-H26xPacketBuffer")) { + if (env_.field_trials().IsEnabled("WebRTC-Video-H26xPacketBuffer")) { EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame).Times(0); } else { EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame) @@ -1278,10 +1283,10 @@ TEST_F(RtpVideoStreamReceiver2Test, TransformFrame) { EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameSinkCallback(_, config_.rtp.remote_ssrc)); auto receiver = std::make_unique( - TaskQueueBase::Current(), Clock::GetRealTimeClock(), &mock_transport_, - nullptr, nullptr, &config_, rtp_receive_statistics_.get(), nullptr, - nullptr, &nack_periodic_processor_, &mock_on_complete_frame_callback_, - nullptr, mock_frame_transformer, field_trials_, nullptr); + env_, TaskQueueBase::Current(), &mock_transport_, nullptr, nullptr, + &config_, rtp_receive_statistics_.get(), nullptr, nullptr, + &nack_periodic_processor_, &mock_on_complete_frame_callback_, nullptr, + mock_frame_transformer); receiver->AddReceiveCodec(kPayloadType, kVideoCodecGeneric, {}, /*raw_payload=*/false); diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc index 92b4cb1500..85a3afa6c7 100644 --- a/video/video_receive_stream2.cc +++ b/video/video_receive_stream2.cc @@ -199,8 +199,8 @@ VideoReceiveStream2::VideoReceiveStream2( rtp_receive_statistics_(ReceiveStatistics::Create(&env_.clock())), timing_(std::move(timing)), video_receiver_(&env_.clock(), timing_.get(), env_.field_trials()), - rtp_video_stream_receiver_(call->worker_thread(), - &env_.clock(), + rtp_video_stream_receiver_(env_, + call->worker_thread(), &transport_adapter_, call_stats->AsRtcpRttStats(), packet_router, @@ -211,9 +211,7 @@ VideoReceiveStream2::VideoReceiveStream2( nack_periodic_processor, this, // OnCompleteFrameCallback std::move(config_.frame_decryptor), - std::move(config_.frame_transformer), - env_.field_trials(), - &env_.event_log()), + std::move(config_.frame_transformer)), rtp_stream_sync_(call->worker_thread(), this), max_wait_for_keyframe_(DetermineMaxWaitForFrame( TimeDelta::Millis(config_.rtp.nack.rtp_history_ms),