diff --git a/src/channel/rtp_channel/rtp_video_receiver.cpp b/src/channel/rtp_channel/rtp_video_receiver.cpp index a1b0e41..2d958cb 100644 --- a/src/channel/rtp_channel/rtp_video_receiver.cpp +++ b/src/channel/rtp_channel/rtp_video_receiver.cpp @@ -10,47 +10,47 @@ #define NV12_BUFFER_SIZE (1280 * 720 * 3 / 2) #define RTCP_RR_INTERVAL 1000 -RtpVideoReceiver::RtpVideoReceiver(std::shared_ptr clock) +RtpVideoReceiver::RtpVideoReceiver(std::shared_ptr clock) : feedback_ssrc_(GenerateUniqueSsrc()), active_remb_module_(nullptr), receive_side_congestion_controller_( - clock, + clock_, [this](std::vector> packets) { SendCombinedRtcpPacket(std::move(packets)); }, [this](int64_t bitrate_bps, std::vector ssrcs) { SendRemb(bitrate_bps, ssrcs); }), - clock_(clock), rtcp_sender_(std::make_unique( [this](const uint8_t* buffer, size_t size) -> int { return data_send_func_((const char*)buffer, size); }, 1200)), - nack_(std::make_unique(clock, this, this)) { + nack_(std::make_unique(clock_, this, this)), + clock_(webrtc::Clock::GetWebrtcClockShared(clock)) { SetPeriod(std::chrono::milliseconds(5)); // rtcp_thread_ = std::thread(&RtpVideoReceiver::RtcpThread, this); } -RtpVideoReceiver::RtpVideoReceiver(std::shared_ptr clock, +RtpVideoReceiver::RtpVideoReceiver(std::shared_ptr clock, std::shared_ptr io_statistics) : io_statistics_(io_statistics), feedback_ssrc_(GenerateUniqueSsrc()), receive_side_congestion_controller_( - clock, + clock_, [this](std::vector> packets) { SendCombinedRtcpPacket(std::move(packets)); }, [this](int64_t bitrate_bps, std::vector ssrcs) { SendRemb(bitrate_bps, ssrcs); }), - clock_(clock), rtcp_sender_(std::make_unique( [this](const uint8_t* buffer, size_t size) -> int { return data_send_func_((const char*)buffer, size); }, 1200)), - nack_(std::make_unique(clock, this, this)) { + nack_(std::make_unique(clock_, this, this)), + clock_(webrtc::Clock::GetWebrtcClockShared(clock)) { SetPeriod(std::chrono::milliseconds(5)); // rtcp_thread_ = std::thread(&RtpVideoReceiver::RtcpThread, this); diff --git a/src/channel/rtp_channel/rtp_video_receiver.h b/src/channel/rtp_channel/rtp_video_receiver.h index fabad47..5cb7e00 100644 --- a/src/channel/rtp_channel/rtp_video_receiver.h +++ b/src/channel/rtp_channel/rtp_video_receiver.h @@ -7,6 +7,7 @@ #include #include "api/clock/clock.h" +#include "clock/system_clock.h" #include "fec_decoder.h" #include "io_statistics.h" #include "nack_requester.h" @@ -28,8 +29,8 @@ class RtpVideoReceiver : public ThreadBase, public KeyFrameRequestSender, public NackSender { public: - RtpVideoReceiver(std::shared_ptr clock); - RtpVideoReceiver(std::shared_ptr clock, + RtpVideoReceiver(std::shared_ptr clock); + RtpVideoReceiver(std::shared_ptr clock, std::shared_ptr io_statistics); virtual ~RtpVideoReceiver(); @@ -113,7 +114,7 @@ class RtpVideoReceiver : public ThreadBase, int rtcp_tcc_interval_ms_ = 200; private: - std::shared_ptr clock_; + std::shared_ptr clock_; ReceiveSideCongestionController receive_side_congestion_controller_; RtcpFeedbackSenderInterface* active_remb_module_; uint32_t feedback_ssrc_ = 0; diff --git a/src/channel/rtp_channel/rtp_video_sender.cpp b/src/channel/rtp_channel/rtp_video_sender.cpp index ca350b6..bb798b2 100644 --- a/src/channel/rtp_channel/rtp_video_sender.cpp +++ b/src/channel/rtp_channel/rtp_video_sender.cpp @@ -2,6 +2,7 @@ #include +#include "api/clock/clock.h" #include "common.h" #include "log.h" @@ -11,12 +12,12 @@ RtpVideoSender::RtpVideoSender() {} -RtpVideoSender::RtpVideoSender(std::shared_ptr clock, +RtpVideoSender::RtpVideoSender(std::shared_ptr clock, std::shared_ptr io_statistics) : ssrc_(GenerateUniqueSsrc()), - clock_(clock), io_statistics_(io_statistics), - rtp_packet_history_(std::make_unique(clock)) { + rtp_packet_history_(std::make_unique(clock_)), + clock_(webrtc::Clock::GetWebrtcClockShared(clock)) { SetPeriod(std::chrono::milliseconds(5)); #ifdef SAVE_RTP_SENT_STREAM file_rtp_sent_ = fopen("rtp_sent_stream.h264", "w+b"); diff --git a/src/channel/rtp_channel/rtp_video_sender.h b/src/channel/rtp_channel/rtp_video_sender.h index 5ec34ab..06948d4 100644 --- a/src/channel/rtp_channel/rtp_video_sender.h +++ b/src/channel/rtp_channel/rtp_video_sender.h @@ -3,6 +3,8 @@ #include +#include "api/clock/clock.h" +#include "clock/system_clock.h" #include "io_statistics.h" #include "ringbuffer.h" #include "rtp_packet.h" @@ -15,7 +17,7 @@ class RtpVideoSender : public ThreadBase { public: RtpVideoSender(); - RtpVideoSender(std::shared_ptr clock, + RtpVideoSender(std::shared_ptr clock, std::shared_ptr io_statistics); virtual ~RtpVideoSender(); diff --git a/src/channel/video_channel_receive.cpp b/src/channel/video_channel_receive.cpp index f6dd0e0..4394e2e 100644 --- a/src/channel/video_channel_receive.cpp +++ b/src/channel/video_channel_receive.cpp @@ -5,7 +5,7 @@ VideoChannelReceive::VideoChannelReceive() {} VideoChannelReceive::VideoChannelReceive( - std::shared_ptr clock, std::shared_ptr ice_agent, + std::shared_ptr clock, std::shared_ptr ice_agent, std::shared_ptr ice_io_statistics, std::function on_receive_complete_frame) : ice_agent_(ice_agent), diff --git a/src/channel/video_channel_receive.h b/src/channel/video_channel_receive.h index ac740f9..98a7731 100644 --- a/src/channel/video_channel_receive.h +++ b/src/channel/video_channel_receive.h @@ -7,7 +7,7 @@ #ifndef _VIDEO_CHANNEL_RECEIVE_H_ #define _VIDEO_CHANNEL_RECEIVE_H_ -#include "api/clock/clock.h" +#include "clock/system_clock.h" #include "ice_agent.h" #include "rtp_video_receiver.h" @@ -15,7 +15,7 @@ class VideoChannelReceive { public: VideoChannelReceive(); VideoChannelReceive( - std::shared_ptr clock, std::shared_ptr ice_agent, + std::shared_ptr clock, std::shared_ptr ice_agent, std::shared_ptr ice_io_statistics, std::function on_receive_complete_frame); @@ -34,7 +34,7 @@ class VideoChannelReceive { std::function on_receive_complete_frame_ = nullptr; private: - std::shared_ptr clock_; + std::shared_ptr clock_; }; #endif \ No newline at end of file diff --git a/src/channel/video_channel_send.cpp b/src/channel/video_channel_send.cpp index c5ac8c0..bb1e63f 100644 --- a/src/channel/video_channel_send.cpp +++ b/src/channel/video_channel_send.cpp @@ -8,7 +8,7 @@ VideoChannelSend::VideoChannelSend() {} VideoChannelSend::~VideoChannelSend() {} VideoChannelSend::VideoChannelSend( - std::shared_ptr clock, std::shared_ptr ice_agent, + std::shared_ptr clock, std::shared_ptr ice_agent, std::shared_ptr ice_io_statistics, std::function on_sent_packet_func) diff --git a/src/channel/video_channel_send.h b/src/channel/video_channel_send.h index e4afa3a..d8d6f6e 100644 --- a/src/channel/video_channel_send.h +++ b/src/channel/video_channel_send.h @@ -7,9 +7,9 @@ #ifndef _VIDEO_CHANNEL_SEND_H_ #define _VIDEO_CHANNEL_SEND_H_ -#include "api/clock/clock.h" #include "api/transport/network_types.h" #include "api/units/timestamp.h" +#include "clock/system_clock.h" #include "congestion_control.h" #include "congestion_control_feedback.h" #include "ice_agent.h" @@ -20,7 +20,7 @@ class VideoChannelSend { public: VideoChannelSend(); - VideoChannelSend(std::shared_ptr clock, + VideoChannelSend(std::shared_ptr clock, std::shared_ptr ice_agent, std::shared_ptr ice_io_statistics, std::function @@ -52,7 +52,7 @@ class VideoChannelSend { on_sent_packet_func_ = nullptr; private: - std::shared_ptr clock_; + std::shared_ptr clock_; }; #endif \ No newline at end of file diff --git a/src/common/api/clock/clock.cc b/src/common/api/clock/clock.cc index 0cea39f..04e1b45 100644 --- a/src/common/api/clock/clock.cc +++ b/src/common/api/clock/clock.cc @@ -43,25 +43,51 @@ NtpTime TimeMicrosToNtp(int64_t time_us) { } // namespace -class RealTimeClock : public Clock { +class WebrtcClock : public Clock { public: - RealTimeClock() = default; + WebrtcClock(std::shared_ptr system_clock) + : system_clock_(system_clock) {} + WebrtcClock() = delete; Timestamp CurrentTime() override { - return Timestamp::Micros(rtc::TimeMicros()); + return Timestamp::Micros(system_clock_->CurrentTimeUs()); } NtpTime ConvertTimestampToNtpTime(Timestamp timestamp) override { - return TimeMicrosToNtp(timestamp.us()); + int64_t time_us = timestamp.us(); + constexpr int64_t kNtpJan1970Sec = 2208988800; + int64_t clock_time = system_clock_->CurrentTimeUs(); + int64_t utc_time = system_clock_->CurrentUtcTimeUs(); + static int64_t ntp_offset_us = + utc_time - clock_time + kNtpJan1970Sec * rtc::kNumMicrosecsPerSec; + + int64_t time_ntp_us = time_us + ntp_offset_us; + + // Convert seconds to uint32 through uint64 for a well-defined cast. + // A wrap around, which will happen in 2036, is expected for NTP time. + uint32_t ntp_seconds = + static_cast(time_ntp_us / rtc::kNumMicrosecsPerSec); + + // Scale fractions of the second to NTP resolution. + constexpr int64_t kNtpFractionsInSecond = 1LL << 32; + int64_t us_fractions = time_ntp_us % rtc::kNumMicrosecsPerSec; + uint32_t ntp_fractions = + us_fractions * kNtpFractionsInSecond / rtc::kNumMicrosecsPerSec; + + return NtpTime(ntp_seconds, ntp_fractions); } + + private: + std::shared_ptr system_clock_; }; -Clock* Clock::GetRealTimeClock() { - static Clock* const clock = new RealTimeClock(); +Clock* Clock::GetWebrtcClock(std::shared_ptr system_clock) { + static Clock* const clock = new WebrtcClock(system_clock); return clock; } -std::shared_ptr Clock::GetRealTimeClockShared() { - return std::make_shared(); +std::shared_ptr Clock::GetWebrtcClockShared( + std::shared_ptr system_clock) { + return std::make_shared(system_clock); } } // namespace webrtc \ No newline at end of file diff --git a/src/common/api/clock/clock.h b/src/common/api/clock/clock.h index 12bbff6..7c45b32 100644 --- a/src/common/api/clock/clock.h +++ b/src/common/api/clock/clock.h @@ -18,6 +18,7 @@ #include "api/ntp/ntp_time.h" #include "api/units/timestamp.h" +#include "clock/system_clock.h" namespace webrtc { @@ -65,8 +66,9 @@ class Clock { } // Returns an instance of the real-time system clock implementation. - static Clock* GetRealTimeClock(); - static std::shared_ptr GetRealTimeClockShared(); + static Clock* GetWebrtcClock(std::shared_ptr system_clock); + static std::shared_ptr GetWebrtcClockShared( + std::shared_ptr system_clock); }; } // namespace webrtc diff --git a/src/common/clock/system_clock.cpp b/src/common/clock/system_clock.cpp index 81cb9c9..ab26f0b 100644 --- a/src/common/clock/system_clock.cpp +++ b/src/common/clock/system_clock.cpp @@ -69,15 +69,15 @@ int64_t SystemClock::CurrentNtpTime() { } int64_t SystemClock::CurrentNtpTimeMs() { - return CurrentTimeMs() + kNtpEpochOffset * 1000LL; + return CurrentUtcTimeMs() + kNtpEpochOffset * 1000LL; } int64_t SystemClock::CurrentNtpTimeUs() { - return CurrentTimeUs() + kNtpEpochOffset * 1000000LL; + return CurrentUtcTimeUs() + kNtpEpochOffset * 1000000LL; } int64_t SystemClock::CurrentNtpTimeNs() { - return CurrentTimeNs() + kNtpEpochOffset * 1000000000LL; + return CurrentUtcTimeNs() + kNtpEpochOffset * 1000000000LL; } int64_t SystemClock::CurrentUtcTimeNs() { @@ -111,12 +111,3 @@ int64_t SystemClock::CurrentUtcTimeMs() { int64_t SystemClock::CurrentUtcTime() { return CurrentUtcTimeNs() / 1000000000LL; } - -static SystemClock* GetSystemClock() { - static SystemClock* const clock = new SystemClock(); - return clock; -} - -static std::shared_ptr GetSystemClockShared() { - return std::make_shared(); -} \ No newline at end of file diff --git a/src/common/clock/system_clock.h b/src/common/clock/system_clock.h index 818786c..1283e5c 100644 --- a/src/common/clock/system_clock.h +++ b/src/common/clock/system_clock.h @@ -33,7 +33,4 @@ class SystemClock { int64_t CurrentUtcTimeNs(); }; -static SystemClock* GetSystemClock(); -static std::shared_ptr GetSystemClockShared(); - #endif \ No newline at end of file diff --git a/src/pc/peer_connection.cpp b/src/pc/peer_connection.cpp index 35825db..e727bae 100644 --- a/src/pc/peer_connection.cpp +++ b/src/pc/peer_connection.cpp @@ -184,6 +184,7 @@ int PeerConnection::Init(PeerConnectionParams params, } }; + clock_ = std::make_shared(); ws_transport_ = std::make_shared(on_receive_ws_msg_, on_ws_status_); uri_ = "ws://" + cfg_signal_server_ip_ + ":" + cfg_signal_server_port_; if (ws_transport_) { @@ -595,8 +596,8 @@ void PeerConnection::ProcessIceWorkMsg(const IceWorkMsg &msg) { for (auto &remote_user_id : user_id_list) { ice_transport_list_[remote_user_id] = std::make_shared( - true, transmission_id, user_id_, remote_user_id, ws_transport_, - on_ice_status_change_, user_data_); + clock_, true, transmission_id, user_id_, remote_user_id, + ws_transport_, on_ice_status_change_, user_data_); ice_transport_list_[remote_user_id]->SetLocalCapabilities( hardware_acceleration_, trickle_ice_, reliable_ice_, enable_turn_, @@ -639,8 +640,8 @@ void PeerConnection::ProcessIceWorkMsg(const IceWorkMsg &msg) { ice_transport_list_.find(remote_user_id)) { // Enable TURN for answer peer by default ice_transport_list_[remote_user_id] = std::make_shared( - false, transmission_id, user_id_, remote_user_id, ws_transport_, - on_ice_status_change_, user_data_); + clock_, false, transmission_id, user_id_, remote_user_id, + ws_transport_, on_ice_status_change_, user_data_); ice_transport_list_[remote_user_id]->SetLocalCapabilities( hardware_acceleration_, trickle_ice_, reliable_ice_, enable_turn_, diff --git a/src/pc/peer_connection.h b/src/pc/peer_connection.h index f607729..4f24a5e 100644 --- a/src/pc/peer_connection.h +++ b/src/pc/peer_connection.h @@ -13,6 +13,7 @@ #include "audio_decoder.h" #include "audio_encoder.h" +#include "clock/system_clock.h" #include "ice_transport.h" #include "video_decoder_factory.h" #include "video_encoder_factory.h" @@ -152,6 +153,7 @@ class PeerConnection { std::vector audio_payload_types_ = {rtp::PAYLOAD_TYPE::OPUS}; private: + std::shared_ptr clock_ = nullptr; std::shared_ptr ws_transport_ = nullptr; std::function on_receive_ws_msg_ = nullptr; std::function on_ws_status_ = nullptr; diff --git a/src/transport/ice_transport.cpp b/src/transport/ice_transport.cpp index c36a400..7bc9ae5 100644 --- a/src/transport/ice_transport.cpp +++ b/src/transport/ice_transport.cpp @@ -11,11 +11,13 @@ using nlohmann::json; IceTransport::IceTransport( - bool offer_peer, std::string &transmission_id, std::string &user_id, + std::shared_ptr clock, bool offer_peer, + std::string &transmission_id, std::string &user_id, std::string &remote_user_id, std::shared_ptr ice_ws_transmission, std::function on_ice_status_change, void *user_data) - : offer_peer_(offer_peer), + : clock_(clock), + offer_peer_(offer_peer), transmission_id_(transmission_id), user_id_(user_id), remote_user_id_(remote_user_id), @@ -46,7 +48,7 @@ int IceTransport::InitIceTransmission( std::string &stun_ip, int stun_port, std::string &turn_ip, int turn_port, std::string &turn_username, std::string &turn_password, rtp::PAYLOAD_TYPE video_codec_payload_type) { - ice_transport_controller_ = std::make_shared(); + ice_transport_controller_ = std::make_shared(clock_); ice_agent_ = std::make_unique( offer_peer_, use_trickle_ice_, use_reliable_ice_, enable_turn_, force_turn_, stun_ip, stun_port, turn_ip, turn_port, turn_username, diff --git a/src/transport/ice_transport.h b/src/transport/ice_transport.h index 5b85d21..e04de4e 100644 --- a/src/transport/ice_transport.h +++ b/src/transport/ice_transport.h @@ -9,6 +9,7 @@ #include +#include "clock/system_clock.h" #include "ice_agent.h" #include "ice_transport_controller.h" #include "io_statistics.h" @@ -30,8 +31,9 @@ class IceTransport { enum TraversalType { TP2P = 0, TRelay = 1, TUnknown = 2 }; public: - IceTransport(bool offer_peer, std::string &transmission_id, - std::string &user_id, std::string &remote_user_id, + IceTransport(std::shared_ptr clock, bool offer_peer, + std::string &transmission_id, std::string &user_id, + std::string &remote_user_id, std::shared_ptr ice_ws_transmission, std::function on_ice_status_change, @@ -160,6 +162,7 @@ class IceTransport { void *user_data_ = nullptr; private: + std::shared_ptr clock_; std::shared_ptr ice_agent_ = nullptr; bool is_closed_ = false; std::shared_ptr ice_ws_transport_ = nullptr; diff --git a/src/transport/ice_transport_controller.cpp b/src/transport/ice_transport_controller.cpp index 0f03203..4100e4a 100644 --- a/src/transport/ice_transport_controller.cpp +++ b/src/transport/ice_transport_controller.cpp @@ -4,13 +4,14 @@ #include "nvcodec_api.h" #endif -IceTransportController::IceTransportController() - : b_force_i_frame_(true), +IceTransportController::IceTransportController( + std::shared_ptr clock) + : clock_(clock), + b_force_i_frame_(true), video_codec_inited_(false), audio_codec_inited_(false), load_nvcodec_dll_success_(false), - hardware_acceleration_(false), - clock_(webrtc::Clock::GetRealTimeClockShared()) {} + hardware_acceleration_(false) {} IceTransportController::~IceTransportController() { user_data_ = nullptr; @@ -334,7 +335,7 @@ void IceTransportController::OnCongestionControlFeedback( const webrtc::rtcp::CongestionControlFeedback& feedback) { std::optional feedback_msg = transport_feedback_adapter_.ProcessCongestionControlFeedback( - feedback, clock_->CurrentTime()); + feedback, Timestamp::Micros(clock_->CurrentTimeUs())); if (feedback_msg) { HandleTransportPacketsFeedback(*feedback_msg); } @@ -353,13 +354,13 @@ void IceTransportController::OnSentRtpPacket( webrtc::PacedPacketInfo pacing_info; size_t transport_overhead_bytes_per_packet_ = 0; webrtc::Timestamp creation_time = - webrtc::Timestamp::Millis(clock_->TimeInMilliseconds()); + webrtc::Timestamp::Millis(clock_->CurrentTimeMs()); transport_feedback_adapter_.AddPacket( packet, pacing_info, transport_overhead_bytes_per_packet_, creation_time); rtc::SentPacket sent_packet; sent_packet.packet_id = packet.transport_sequence_number().value(); - sent_packet.send_time_ms = clock_->TimeInMilliseconds(); + sent_packet.send_time_ms = clock_->CurrentTimeMs(); sent_packet.info.included_in_feedback = true; sent_packet.info.included_in_allocation = true; sent_packet.info.packet_size_bytes = packet.size(); diff --git a/src/transport/ice_transport_controller.h b/src/transport/ice_transport_controller.h index 4e8062d..887a113 100644 --- a/src/transport/ice_transport_controller.h +++ b/src/transport/ice_transport_controller.h @@ -14,6 +14,7 @@ #include "audio_channel_send.h" #include "audio_decoder.h" #include "audio_encoder.h" +#include "clock/system_clock.h" #include "congestion_control.h" #include "congestion_control_feedback.h" #include "data_channel_receive.h" @@ -35,7 +36,7 @@ typedef void (*OnReceiveData)(const char *, size_t, const char *, const size_t, class IceTransportController : public std::enable_shared_from_this { public: - IceTransportController(); + IceTransportController(std::shared_ptr clock); ~IceTransportController(); public: @@ -97,7 +98,7 @@ class IceTransportController void *user_data_ = nullptr; private: - std::shared_ptr clock_; + std::shared_ptr clock_; webrtc::TransportFeedbackAdapter transport_feedback_adapter_; std::unique_ptr controller_;