From 962d856946848a4fe1995e3df4d8780133e45ca0 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Thu, 27 Feb 2025 17:30:41 +0800 Subject: [PATCH] [fix] fix sender report building and parsing --- src/channel/audio_channel_receive.h | 4 +- src/channel/data_channel_receive.h | 4 +- src/channel/rtp_channel/rtp_audio_receiver.h | 3 +- src/channel/rtp_channel/rtp_data_receiver.h | 4 +- .../rtp_channel/rtp_video_receiver.cpp | 31 +++++++-- src/channel/rtp_channel/rtp_video_receiver.h | 12 +++- src/channel/video_channel_receive.h | 4 +- src/common/clock/system_clock.cpp | 8 +-- src/rtcp/rtcp_packet/rtcp_typedef.h | 2 +- src/rtcp/rtcp_packet/sender_report.cpp | 66 ++++++++++++------- src/rtcp/rtcp_packet/sender_report.h | 17 +++-- src/transport/ice_transport_controller.cpp | 18 +---- 12 files changed, 108 insertions(+), 65 deletions(-) diff --git a/src/channel/audio_channel_receive.h b/src/channel/audio_channel_receive.h index e11dbe8..9b23984 100644 --- a/src/channel/audio_channel_receive.h +++ b/src/channel/audio_channel_receive.h @@ -39,9 +39,9 @@ class AudioChannelReceive { int OnReceiveRtpPacket(const char *data, size_t size); - void OnSenderReport(int64_t now_time, uint64_t ntp_time) { + void OnSenderReport(const SenderReport &sender_report) { if (rtp_audio_receiver_) { - rtp_audio_receiver_->OnSenderReport(now_time, ntp_time); + rtp_audio_receiver_->OnSenderReport(sender_report); } } diff --git a/src/channel/data_channel_receive.h b/src/channel/data_channel_receive.h index a78af9b..d5e707f 100644 --- a/src/channel/data_channel_receive.h +++ b/src/channel/data_channel_receive.h @@ -38,9 +38,9 @@ class DataChannelReceive { int OnReceiveRtpPacket(const char *data, size_t size); - void OnSenderReport(int64_t now_time, uint64_t ntp_time) { + void OnSenderReport(const SenderReport &sender_report) { if (rtp_data_receiver_) { - rtp_data_receiver_->OnSenderReport(now_time, ntp_time); + rtp_data_receiver_->OnSenderReport(sender_report); } } diff --git a/src/channel/rtp_channel/rtp_audio_receiver.h b/src/channel/rtp_channel/rtp_audio_receiver.h index f9ec65f..f522e18 100644 --- a/src/channel/rtp_channel/rtp_audio_receiver.h +++ b/src/channel/rtp_channel/rtp_audio_receiver.h @@ -13,6 +13,7 @@ #include "receiver_report.h" #include "rtp_packet.h" #include "rtp_statistics.h" +#include "sender_report.h" class RtpAudioReceiver { public: @@ -32,7 +33,7 @@ class RtpAudioReceiver { uint32_t GetSsrc() { return ssrc_; } uint32_t GetRemoteSsrc() { return remote_ssrc_; } - void OnSenderReport(int64_t now_time, uint64_t ntp_time) {} + void OnSenderReport(const SenderReport& sender_report) {} private: bool CheckIsTimeSendRR(); diff --git a/src/channel/rtp_channel/rtp_data_receiver.h b/src/channel/rtp_channel/rtp_data_receiver.h index ea47891..00d95ad 100644 --- a/src/channel/rtp_channel/rtp_data_receiver.h +++ b/src/channel/rtp_channel/rtp_data_receiver.h @@ -7,7 +7,7 @@ #include "receiver_report.h" #include "rtp_packet.h" #include "rtp_statistics.h" - +#include "sender_report.h" class RtpDataReceiver { public: RtpDataReceiver(); @@ -26,7 +26,7 @@ class RtpDataReceiver { uint32_t GetSsrc() { return ssrc_; } uint32_t GetRemoteSsrc() { return remote_ssrc_; } - void OnSenderReport(int64_t now_time, uint64_t ntp_time) {} + void OnSenderReport(const SenderReport& sender_report) {} private: bool CheckIsTimeSendRR(); diff --git a/src/channel/rtp_channel/rtp_video_receiver.cpp b/src/channel/rtp_channel/rtp_video_receiver.cpp index a196337..d13e04a 100644 --- a/src/channel/rtp_channel/rtp_video_receiver.cpp +++ b/src/channel/rtp_channel/rtp_video_receiver.cpp @@ -1,5 +1,6 @@ #include "rtp_video_receiver.h" +#include "api/ntp/ntp_time_util.h" #include "common.h" #include "log.h" #include "nack.h" @@ -566,11 +567,29 @@ inline uint32_t DivideRoundToNearest(int64_t dividend, int64_t divisor) { return quotient; } -void RtpVideoReceiver::OnSenderReport(int64_t now_time, uint64_t ntp_time) { - last_sr_ = ((uint32_t)(ntp_time / 0x100000000) << 16) | - ((uint32_t)(ntp_time % 0x100000000) >> 16); - last_delay_ = DivideRoundToNearest( - (clock_->CurrentTime().us() - now_time) * 0x10000, 1000000); +void RtpVideoReceiver::OnSenderReport(const SenderReport& sender_report) { + remote_ssrc = sender_report.SenderSsrc(); + last_remote_ntp_timestamp = sender_report.NtpTimestamp(); + last_remote_rtp_timestamp = sender_report.Timestamp(); + last_arrival_timestamp = clock_->CurrentTime().ms(); + last_arrival_ntp_timestamp = webrtc::CompactNtp(clock_->CurrentNtpTime()); + packets_sent = sender_report.SenderPacketCount(); + bytes_sent = sender_report.SenderOctetCount(); + reports_count++; - LOG_WARN("OnSenderReport [{}][{}]", last_sr_, last_delay_); + LOG_WARN( + "OnSenderReport remote_ssrc[{}], last_remote_ntp_timestamp[{}], " + "last_remote_rtp_timestamp[{}], last_arrival_timestamp[{}], " + "last_arrival_ntp_timestamp[{}], packets_sent[{}], bytes_sent[{}], " + "reports_count[{}]", + remote_ssrc, last_remote_ntp_timestamp, last_remote_rtp_timestamp, + last_arrival_timestamp, last_arrival_ntp_timestamp, packets_sent, + bytes_sent, reports_count); + + // last_sr_ = ((uint32_t)(ntp_time / 0x100000000) << 16) | + // ((uint32_t)(ntp_time % 0x100000000) >> 16); + // last_delay_ = DivideRoundToNearest( + // (clock_->CurrentTime().us() - now_time) * 0x10000, 1000000); + + // LOG_WARN("OnSenderReport [{}][{}] {}", last_sr_, last_delay_, now_time); } \ No newline at end of file diff --git a/src/channel/rtp_channel/rtp_video_receiver.h b/src/channel/rtp_channel/rtp_video_receiver.h index 48af306..987f718 100644 --- a/src/channel/rtp_channel/rtp_video_receiver.h +++ b/src/channel/rtp_channel/rtp_video_receiver.h @@ -19,6 +19,7 @@ #include "rtp_packet_h264.h" #include "rtp_rtcp_defines.h" #include "rtp_statistics.h" +#include "sender_report.h" #include "thread_base.h" #include "video_frame.h" @@ -45,7 +46,7 @@ class RtpVideoReceiver : public ThreadBase, } uint32_t GetSsrc() { return ssrc_; } uint32_t GetRemoteSsrc() { return remote_ssrc_; } - void OnSenderReport(int64_t now_time, uint64_t ntp_time); + void OnSenderReport(const SenderReport& sender_report); private: void ProcessAv1RtpPacket(RtpPacketAv1& rtp_packet_av1); @@ -130,6 +131,15 @@ class RtpVideoReceiver : public ThreadBase, uint32_t last_sr_ = 0; uint32_t last_delay_ = 0; + uint32_t remote_ssrc = 0; + uint32_t last_remote_ntp_timestamp = 0; + uint32_t last_remote_rtp_timestamp = 0; + uint32_t last_arrival_timestamp = 0; + uint32_t last_arrival_ntp_timestamp = 0; + uint32_t packets_sent = 0; + uint32_t bytes_sent = 0; + uint32_t reports_count = 0; + private: FILE* file_rtp_recv_ = nullptr; }; diff --git a/src/channel/video_channel_receive.h b/src/channel/video_channel_receive.h index 8a71dd1..3fbaa27 100644 --- a/src/channel/video_channel_receive.h +++ b/src/channel/video_channel_receive.h @@ -41,9 +41,9 @@ class VideoChannelReceive { int OnReceiveRtpPacket(const char *data, size_t size); - void OnSenderReport(int64_t now_time, uint64_t ntp_time) { + void OnSenderReport(const SenderReport &sender_report) { if (rtp_video_receiver_) { - rtp_video_receiver_->OnSenderReport(now_time, ntp_time); + rtp_video_receiver_->OnSenderReport(sender_report); } } diff --git a/src/common/clock/system_clock.cpp b/src/common/clock/system_clock.cpp index ce314ae..84ac880 100644 --- a/src/common/clock/system_clock.cpp +++ b/src/common/clock/system_clock.cpp @@ -15,15 +15,15 @@ #include #endif -uint64_t ConvertToNtpTime(int64_t time_us) { +int64_t ConvertToNtpTime(int64_t time_us) { constexpr int64_t kMicrosecondsPerSecond = 1000000; constexpr uint64_t kNtpFractionalUnit = 0x100000000; // 2^32 uint32_t seconds = static_cast(time_us / kMicrosecondsPerSecond); - uint32_t fraction = + uint32_t fractions = static_cast((time_us % kMicrosecondsPerSecond) * kNtpFractionalUnit / kMicrosecondsPerSecond); - uint64_t ntp_time = (static_cast(seconds) << 32) | fraction; - return ntp_time; + + return seconds * kNtpFractionalUnit + fractions; } int64_t SystemClock::CurrentTimeNs() { diff --git a/src/rtcp/rtcp_packet/rtcp_typedef.h b/src/rtcp/rtcp_packet/rtcp_typedef.h index 11f4e7c..8eac213 100644 --- a/src/rtcp/rtcp_packet/rtcp_typedef.h +++ b/src/rtcp/rtcp_packet/rtcp_typedef.h @@ -8,7 +8,7 @@ #define DEFAULT_RTCP_HEADER_SIZE 4 #define DEFAULT_SR_BLOCK_NUM 1 -#define DEFAULT_SR_SIZE 52 +#define DEFAULT_SR_SIZE 28 #define DEFAULT_RR_BLOCK_NUM 1 #define DEFAULT_RR_SIZE 32 diff --git a/src/rtcp/rtcp_packet/sender_report.cpp b/src/rtcp/rtcp_packet/sender_report.cpp index 179f3c8..62de5f1 100644 --- a/src/rtcp/rtcp_packet/sender_report.cpp +++ b/src/rtcp/rtcp_packet/sender_report.cpp @@ -40,10 +40,10 @@ const uint8_t *SenderReport::Build() { buffer_[pos++] = sender_info_.sender_ssrc >> 8 & 0xFF; buffer_[pos++] = sender_info_.sender_ssrc & 0xFF; - buffer_[pos++] = sender_info_.ntp_ts_msw >> 56 & 0xFF; - buffer_[pos++] = sender_info_.ntp_ts_msw >> 48 & 0xFF; - buffer_[pos++] = sender_info_.ntp_ts_msw >> 40 & 0xFF; - buffer_[pos++] = sender_info_.ntp_ts_msw >> 32 & 0xFF; + buffer_[pos++] = sender_info_.ntp_ts_msw >> 24 & 0xFF; + buffer_[pos++] = sender_info_.ntp_ts_msw >> 16 & 0xFF; + buffer_[pos++] = sender_info_.ntp_ts_msw >> 8 & 0xFF; + buffer_[pos++] = sender_info_.ntp_ts_msw & 0xFF; buffer_[pos++] = sender_info_.ntp_ts_lsw >> 24 & 0xFF; buffer_[pos++] = sender_info_.ntp_ts_lsw >> 16 & 0xFF; buffer_[pos++] = sender_info_.ntp_ts_lsw >> 8 & 0xFF; @@ -71,36 +71,58 @@ const uint8_t *SenderReport::Build() { return buffer_; } -size_t SenderReport::Parse(const RtcpCommonHeader &packet) { +bool SenderReport::Parse(const RtcpCommonHeader &packet) { reports_.clear(); - size_t pos = packet.payload_size_bytes(); + const uint8_t *payload = packet.payload(); + const uint8_t *payload_end = packet.payload() + packet.payload_size_bytes(); + size_t pos = 0; - sender_info_.sender_ssrc = (buffer_[pos] << 24) + (buffer_[pos + 1] << 16) + - (buffer_[pos + 2] << 8) + buffer_[pos + 3]; + sender_info_.sender_ssrc = (payload[pos] << 24) + (payload[pos + 1] << 16) + + (payload[pos + 2] << 8) + payload[pos + 3]; pos += 4; - sender_info_.ntp_ts_msw = (buffer_[pos] << 24) + (buffer_[pos + 1] << 16) + - (buffer_[pos + 2] << 8) + buffer_[pos + 3]; + + if (pos > packet.payload_size_bytes()) { + return false; + } + sender_info_.ntp_ts_msw = (payload[pos] << 24) + (payload[pos + 1] << 16) + + (payload[pos + 2] << 8) + payload[pos + 3]; pos += 4; - sender_info_.ntp_ts_lsw = (buffer_[pos] << 24) + (buffer_[pos + 1] << 16) + - (buffer_[pos + 2] << 8) + buffer_[pos + 3]; + if (pos > packet.payload_size_bytes()) { + return false; + } + sender_info_.ntp_ts_lsw = (payload[pos] << 24) + (payload[pos + 1] << 16) + + (payload[pos + 2] << 8) + payload[pos + 3]; pos += 4; - sender_info_.rtp_ts = (buffer_[pos] << 24) + (buffer_[pos + 1] << 16) + - (buffer_[pos + 2] << 8) + buffer_[pos + 3]; + if (pos > packet.payload_size_bytes()) { + return false; + } + sender_info_.rtp_ts = (payload[pos] << 24) + (payload[pos + 1] << 16) + + (payload[pos + 2] << 8) + payload[pos + 3]; pos += 4; - sender_info_.sender_packet_count = (buffer_[pos] << 24) + - (buffer_[pos + 1] << 16) + - (buffer_[pos + 2] << 8) + buffer_[pos + 3]; + if (pos > packet.payload_size_bytes()) { + return false; + } + sender_info_.sender_packet_count = (payload[pos] << 24) + + (payload[pos + 1] << 16) + + (payload[pos + 2] << 8) + payload[pos + 3]; pos += 4; - sender_info_.sender_octet_count = (buffer_[pos] << 24) + - (buffer_[pos + 1] << 16) + - (buffer_[pos + 2] << 8) + buffer_[pos + 3]; + if (pos > packet.payload_size_bytes()) { + return false; + } + sender_info_.sender_octet_count = (payload[pos] << 24) + + (payload[pos + 1] << 16) + + (payload[pos + 2] << 8) + payload[pos + 3]; + pos += 4; + if (pos > packet.payload_size_bytes()) { + return false; + } for (int i = 0; i < rtcp_common_header_.fmt(); i++) { RtcpReportBlock report; - pos += report.Parse(buffer_ + pos); + pos += report.Parse(payload + pos); reports_.emplace_back(std::move(report)); } - return pos; + return pos == packet.payload_size_bytes(); } \ No newline at end of file diff --git a/src/rtcp/rtcp_packet/sender_report.h b/src/rtcp/rtcp_packet/sender_report.h index dd1758b..6f6394a 100644 --- a/src/rtcp/rtcp_packet/sender_report.h +++ b/src/rtcp/rtcp_packet/sender_report.h @@ -44,6 +44,7 @@ #include +#include "api/ntp/ntp_time.h" #include "rtcp_common_header.h" #include "rtcp_report_block.h" @@ -51,8 +52,8 @@ class SenderReport { public: typedef struct { uint32_t sender_ssrc : 32; - uint64_t ntp_ts_msw : 64; - uint64_t ntp_ts_lsw : 64; + uint32_t ntp_ts_msw : 32; + uint32_t ntp_ts_lsw : 32; uint32_t rtp_ts : 32; uint32_t sender_packet_count : 32; uint32_t sender_octet_count : 32; @@ -65,8 +66,10 @@ class SenderReport { public: void SetSenderSsrc(uint32_t ssrc) { sender_info_.sender_ssrc = ssrc; } void SetNtpTimestamp(uint64_t ntp_timestamp) { - sender_info_.ntp_ts_msw = ntp_timestamp >> 32; - sender_info_.ntp_ts_lsw = ntp_timestamp & 0xFFFFFFFF; + sender_info_.ntp_ts_msw = + ntp_timestamp / webrtc::NtpTime::kFractionsPerSecond; + sender_info_.ntp_ts_lsw = + ntp_timestamp % webrtc::NtpTime::kFractionsPerSecond; } void SetTimestamp(uint32_t timestamp) { sender_info_.rtp_ts = timestamp; } void SetSenderPacketCount(uint32_t packet_count) { @@ -79,8 +82,8 @@ class SenderReport { void SetReportBlocks(std::vector &rtcp_report_blocks); uint32_t SenderSsrc() const { return sender_info_.sender_ssrc; } - uint64_t NtpTimestamp() const { - return (sender_info_.ntp_ts_msw << 32) | sender_info_.ntp_ts_lsw; + uint32_t NtpTimestamp() const { + return (sender_info_.ntp_ts_msw << 16) | sender_info_.ntp_ts_lsw >> 16; } uint32_t Timestamp() const { return sender_info_.rtp_ts; } uint32_t SenderPacketCount() const { @@ -90,7 +93,7 @@ class SenderReport { public: const uint8_t *Build(); - size_t Parse(const RtcpCommonHeader &packet); + bool Parse(const RtcpCommonHeader &packet); // Entire RTP buffer const uint8_t *Buffer() const { return buffer_; } diff --git a/src/transport/ice_transport_controller.cpp b/src/transport/ice_transport_controller.cpp index d1fd4f2..a233861 100644 --- a/src/transport/ice_transport_controller.cpp +++ b/src/transport/ice_transport_controller.cpp @@ -333,21 +333,9 @@ int IceTransportController::CreateAudioCodec() { } void IceTransportController::OnSenderReport(const SenderReport& sender_report) { - if (video_channel_receive_ && - sender_report.SenderSsrc() == video_channel_receive_->GetRemoteSsrc()) { - video_channel_receive_->OnSenderReport(clock_->CurrentTimeUs(), - sender_report.NtpTimestamp()); - } else if (audio_channel_receive_ && - sender_report.SenderSsrc() == - audio_channel_receive_->GetRemoteSsrc()) { - audio_channel_receive_->OnSenderReport(clock_->CurrentTimeUs(), - sender_report.NtpTimestamp()); - } else if (data_channel_receive_ && - sender_report.SenderSsrc() == - data_channel_receive_->GetRemoteSsrc()) { - data_channel_receive_->OnSenderReport(clock_->CurrentTimeUs(), - sender_report.NtpTimestamp()); - } + video_channel_receive_->OnSenderReport(sender_report); + audio_channel_receive_->OnSenderReport(sender_report); + data_channel_receive_->OnSenderReport(sender_report); } void IceTransportController::OnCongestionControlFeedback(