From d1177747fd771ece5d797fbe8728e0a261bdccb7 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Fri, 21 Feb 2025 17:36:32 +0800 Subject: [PATCH] [feat] add timestamp to sender report --- src/channel/rtp_channel/rtp_audio_sender.cpp | 6 +-- src/channel/rtp_channel/rtp_audio_sender.h | 2 +- src/channel/rtp_channel/rtp_data_sender.cpp | 6 +-- src/channel/rtp_channel/rtp_data_sender.h | 2 +- src/channel/rtp_channel/rtp_video_sender.cpp | 49 ++++++++++++-------- src/channel/rtp_channel/rtp_video_sender.h | 11 +++-- src/channel/video_channel_send.cpp | 2 +- src/rtp/rtp_packet/rtp_defines.h | 2 + 8 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/channel/rtp_channel/rtp_audio_sender.cpp b/src/channel/rtp_channel/rtp_audio_sender.cpp index a038d2f..03e3f90 100644 --- a/src/channel/rtp_channel/rtp_audio_sender.cpp +++ b/src/channel/rtp_channel/rtp_audio_sender.cpp @@ -30,7 +30,7 @@ void RtpAudioSender::Enqueue( } for (auto& rtp_packet : rtp_packets) { - rtp_packe_queue_.push(rtp_packet); + rtp_packet_queue_.push(rtp_packet); } } @@ -139,9 +139,9 @@ bool RtpAudioSender::Process() { last_send_bytes_ = 0; for (size_t i = 0; i < 10; i++) - if (!rtp_packe_queue_.isEmpty()) { + if (!rtp_packet_queue_.isEmpty()) { std::shared_ptr rtp_packet; - rtp_packe_queue_.pop(rtp_packet); + rtp_packet_queue_.pop(rtp_packet); SendRtpPacket(rtp_packet); } diff --git a/src/channel/rtp_channel/rtp_audio_sender.h b/src/channel/rtp_channel/rtp_audio_sender.h index 2467310..b02de7d 100644 --- a/src/channel/rtp_channel/rtp_audio_sender.h +++ b/src/channel/rtp_channel/rtp_audio_sender.h @@ -38,7 +38,7 @@ class RtpAudioSender : public ThreadBase { private: std::function data_send_func_ = nullptr; - RingBuffer> rtp_packe_queue_; + RingBuffer> rtp_packet_queue_; private: uint32_t ssrc_ = 0; diff --git a/src/channel/rtp_channel/rtp_data_sender.cpp b/src/channel/rtp_channel/rtp_data_sender.cpp index d9d4cb9..9bf9f0c 100644 --- a/src/channel/rtp_channel/rtp_data_sender.cpp +++ b/src/channel/rtp_channel/rtp_data_sender.cpp @@ -30,7 +30,7 @@ void RtpDataSender::Enqueue( } for (auto& rtp_packet : rtp_packets) { - rtp_packe_queue_.push(rtp_packet); + rtp_packet_queue_.push(rtp_packet); } } @@ -139,9 +139,9 @@ bool RtpDataSender::Process() { last_send_bytes_ = 0; for (size_t i = 0; i < 10; i++) - if (!rtp_packe_queue_.isEmpty()) { + if (!rtp_packet_queue_.isEmpty()) { std::shared_ptr rtp_packet; - rtp_packe_queue_.pop(rtp_packet); + rtp_packet_queue_.pop(rtp_packet); SendRtpPacket(rtp_packet); } diff --git a/src/channel/rtp_channel/rtp_data_sender.h b/src/channel/rtp_channel/rtp_data_sender.h index df69052..d23cc60 100644 --- a/src/channel/rtp_channel/rtp_data_sender.h +++ b/src/channel/rtp_channel/rtp_data_sender.h @@ -39,7 +39,7 @@ class RtpDataSender : public ThreadBase { private: std::function data_send_func_ = nullptr; - RingBuffer> rtp_packe_queue_; + RingBuffer> rtp_packet_queue_; private: uint32_t ssrc_ = 0; diff --git a/src/channel/rtp_channel/rtp_video_sender.cpp b/src/channel/rtp_channel/rtp_video_sender.cpp index bb798b2..67d8152 100644 --- a/src/channel/rtp_channel/rtp_video_sender.cpp +++ b/src/channel/rtp_channel/rtp_video_sender.cpp @@ -44,14 +44,21 @@ RtpVideoSender::~RtpVideoSender() { } void RtpVideoSender::Enqueue( - std::vector>& rtp_packets) { + std::vector>& rtp_packets, + int64_t capture_timestamp) { if (!rtp_statistics_) { rtp_statistics_ = std::make_unique(); rtp_statistics_->Start(); } for (auto& rtp_packet : rtp_packets) { - rtp_packe_queue_.push(std::move(rtp_packet)); + std::shared_ptr rtp_packet_to_send = + std::dynamic_pointer_cast(rtp_packet); + rtp_packet_to_send->set_capture_time( + webrtc::Timestamp::Millis(capture_timestamp)); + rtp_packet_to_send->set_transport_sequence_number(transport_seq_++); + rtp_packet_to_send->set_packet_type(webrtc::RtpPacketMediaType::kVideo); + rtp_packet_queue_.push(std::move(rtp_packet_to_send)); } } @@ -65,34 +72,32 @@ void RtpVideoSender::SetOnSentPacketFunc( on_sent_packet_func_ = on_sent_packet_func; } -int RtpVideoSender::SendRtpPacket(std::shared_ptr rtp_packet) { +int RtpVideoSender::SendRtpPacket( + std::shared_ptr rtp_packet_to_send) { if (!data_send_func_) { LOG_ERROR("data_send_func_ is nullptr"); return -1; } if (on_sent_packet_func_) { - std::shared_ptr rtp_packet_to_send = - std::dynamic_pointer_cast(rtp_packet); - rtp_packet_to_send->set_transport_sequence_number(transport_seq_++); - rtp_packet_to_send->set_packet_type(webrtc::RtpPacketMediaType::kVideo); on_sent_packet_func_(*rtp_packet_to_send); rtp_packet_history_->AddPacket(rtp_packet_to_send, clock_->CurrentTime()); } - if (0 != data_send_func_((const char*)rtp_packet->Buffer().data(), - rtp_packet->Size())) { + last_rtp_timestamp_ = rtp_packet_to_send->capture_time().ms(); + if (0 != data_send_func_((const char*)rtp_packet_to_send->Buffer().data(), + rtp_packet_to_send->Size())) { // LOG_ERROR("Send rtp packet failed"); return -1; } #ifdef SAVE_RTP_SENT_STREAM - fwrite((unsigned char*)rtp_packet->Payload(), 1, rtp_packet->PayloadSize(), - file_rtp_sent_); + fwrite((unsigned char*)rtp_packet_to_send->Payload(), 1, + rtp_packet_to_send->PayloadSize(), file_rtp_sent_); #endif - last_send_bytes_ += (uint32_t)rtp_packet->Size(); - total_rtp_payload_sent_ += (uint32_t)rtp_packet->PayloadSize(); + last_send_bytes_ += (uint32_t)rtp_packet_to_send->Size(); + total_rtp_payload_sent_ += (uint32_t)rtp_packet_to_send->PayloadSize(); total_rtp_packets_sent_++; if (io_statistics_) { @@ -103,13 +108,17 @@ int RtpVideoSender::SendRtpPacket(std::shared_ptr rtp_packet) { if (CheckIsTimeSendSR()) { SenderReport rtcp_sr; rtcp_sr.SetSenderSsrc(ssrc_); - rtcp_sr.SetTimestamp(0); - rtcp_sr.SetNtpTimestamp(0); + + uint32_t rtp_timestamp = + last_rtp_timestamp_ + + ((clock_->CurrentTime().us() + 500) / 1000 - last_frame_capture_time_) * + rtp::kVideoPayloadTypeFrequency; + rtcp_sr.SetTimestamp(rtp_timestamp); + rtcp_sr.SetNtpTimestamp((uint64_t)clock_->CurrentNtpTime()); rtcp_sr.SetSenderPacketCount(total_rtp_packets_sent_); rtcp_sr.SetSenderOctetCount(total_rtp_payload_sent_); RtcpReportBlock report; - report.SetMediaSsrc(ssrc_); report.SetFractionLost(0); report.SetCumulativeLost(0); @@ -162,11 +171,11 @@ bool RtpVideoSender::Process() { last_send_bytes_ = 0; for (size_t i = 0; i < 10; i++) - if (!rtp_packe_queue_.isEmpty()) { - std::shared_ptr rtp_packet; - pop_success = rtp_packe_queue_.pop(rtp_packet); + if (!rtp_packet_queue_.isEmpty()) { + std::shared_ptr rtp_packet_to_send; + pop_success = rtp_packet_queue_.pop(rtp_packet_to_send); if (pop_success) { - SendRtpPacket(rtp_packet); + SendRtpPacket(rtp_packet_to_send); } } diff --git a/src/channel/rtp_channel/rtp_video_sender.h b/src/channel/rtp_channel/rtp_video_sender.h index 06948d4..57083c7 100644 --- a/src/channel/rtp_channel/rtp_video_sender.h +++ b/src/channel/rtp_channel/rtp_video_sender.h @@ -22,14 +22,16 @@ class RtpVideoSender : public ThreadBase { virtual ~RtpVideoSender(); public: - void Enqueue(std::vector> &rtp_packets); + void Enqueue(std::vector> &rtp_packets, + int64_t capture_timestamp); void SetSendDataFunc(std::function data_send_func); void SetOnSentPacketFunc( std::function on_sent_packet_func); uint32_t GetSsrc() { return ssrc_; } private: - int SendRtpPacket(std::shared_ptr rtp_packet); + int SendRtpPacket( + std::shared_ptr rtp_packet_to_send); int SendRtcpSR(SenderReport &rtcp_sr); bool CheckIsTimeSendSR(); @@ -41,7 +43,7 @@ class RtpVideoSender : public ThreadBase { std::function data_send_func_ = nullptr; std::function on_sent_packet_func_ = nullptr; - RingBuffer> rtp_packe_queue_; + RingBuffer> rtp_packet_queue_; private: uint32_t ssrc_ = 0; @@ -54,6 +56,9 @@ class RtpVideoSender : public ThreadBase { uint32_t total_rtp_payload_sent_ = 0; uint32_t total_rtp_packets_sent_ = 0; + uint32_t last_rtp_timestamp_ = 0; + int64_t last_frame_capture_time_ = 0; + private: int64_t transport_seq_ = 0; diff --git a/src/channel/video_channel_send.cpp b/src/channel/video_channel_send.cpp index 18a8c1e..df9d0ea 100644 --- a/src/channel/video_channel_send.cpp +++ b/src/channel/video_channel_send.cpp @@ -63,7 +63,7 @@ int VideoChannelSend::SendVideo( std::vector> rtp_packets = rtp_packetizer_->Build((uint8_t*)encoded_frame->Buffer(), (uint32_t)encoded_frame->Size(), true); - rtp_video_sender_->Enqueue(rtp_packets); + rtp_video_sender_->Enqueue(rtp_packets, encoded_frame->CaptureTimestamp()); } return 0; diff --git a/src/rtp/rtp_packet/rtp_defines.h b/src/rtp/rtp_packet/rtp_defines.h index 3f141b4..4536338 100644 --- a/src/rtp/rtp_packet/rtp_defines.h +++ b/src/rtp/rtp_packet/rtp_defines.h @@ -39,5 +39,7 @@ typedef struct { } FU_HEADER; typedef enum { UNKNOWN = 0, NALU = 1, FU_A = 28, FU_B = 29 } NAL_UNIT_TYPE; + +const int kVideoPayloadTypeFrequency = 90000; } // namespace rtp #endif \ No newline at end of file