mirror of
				https://github.com/kunkundi/crossdesk.git
				synced 2025-10-26 20:25:34 +08:00 
			
		
		
		
	[fix] update sr and rr module
This commit is contained in:
		| @@ -33,35 +33,35 @@ void RtpAudioReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { | ||||
|     io_statistics_->UpdateAudioPacketLossCount(rtp_packet.SequenceNumber()); | ||||
|   } | ||||
|  | ||||
|   if (CheckIsTimeSendRR()) { | ||||
|     RtcpReceiverReport rtcp_rr; | ||||
|     RtcpReportBlock report; | ||||
|   // if (CheckIsTimeSendRR()) { | ||||
|   //   ReceiverReport rtcp_rr; | ||||
|   //   RtcpReportBlock report; | ||||
|  | ||||
|     // auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|     // auto seconds = | ||||
|     // std::chrono::duration_cast<std::chrono::seconds>(duration); uint32_t | ||||
|     // seconds_u32 = static_cast<uint32_t>( | ||||
|     //     std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|   //   // auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|   //   // auto seconds = | ||||
|   //   // std::chrono::duration_cast<std::chrono::seconds>(duration); uint32_t | ||||
|   //   // seconds_u32 = static_cast<uint32_t>( | ||||
|   //   // std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|  | ||||
|     // uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|     //     std::chrono::duration_cast<std::chrono::nanoseconds>(duration - | ||||
|     //     seconds) | ||||
|     //         .count()); | ||||
|   //   // uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|   //   //     std::chrono::duration_cast<std::chrono::nanoseconds>(duration - | ||||
|   //   //     seconds) | ||||
|   //   //         .count()); | ||||
|  | ||||
|     report.source_ssrc = 0x00; | ||||
|     report.fraction_lost = 0; | ||||
|     report.cumulative_lost = 0; | ||||
|     report.extended_high_seq_num = 0; | ||||
|     report.jitter = 0; | ||||
|     report.lsr = 0; | ||||
|     report.dlsr = 0; | ||||
|   //   report.source_ssrc = 0x00; | ||||
|   //   report.fraction_lost = 0; | ||||
|   //   report.cumulative_lost = 0; | ||||
|   //   report.extended_high_seq_num = 0; | ||||
|   //   report.jitter = 0; | ||||
|   //   report.lsr = 0; | ||||
|   //   report.dlsr = 0; | ||||
|  | ||||
|     rtcp_rr.SetReportBlock(report); | ||||
|   //   rtcp_rr.SetReportBlock(report); | ||||
|  | ||||
|     rtcp_rr.Encode(); | ||||
|   //   rtcp_rr.Encode(); | ||||
|  | ||||
|     // SendRtcpRR(rtcp_rr); | ||||
|   } | ||||
|   //   // SendRtcpRR(rtcp_rr); | ||||
|   // } | ||||
|  | ||||
|   if (on_receive_data_) { | ||||
|     on_receive_data_((const char*)rtp_packet.Payload(), | ||||
| @@ -74,7 +74,7 @@ void RtpAudioReceiver::SetSendDataFunc( | ||||
|   data_send_func_ = data_send_func; | ||||
| } | ||||
|  | ||||
| int RtpAudioReceiver::SendRtcpRR(RtcpReceiverReport& rtcp_rr) { | ||||
| int RtpAudioReceiver::SendRtcpRR(ReceiverReport& rtcp_rr) { | ||||
|   if (!data_send_func_) { | ||||
|     LOG_ERROR("data_send_func_ is nullptr"); | ||||
|     return -1; | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| #include <functional> | ||||
|  | ||||
| #include "io_statistics.h" | ||||
| #include "rtcp_receiver_report.h" | ||||
| #include "receiver_report.h" | ||||
| #include "rtp_packet.h" | ||||
| #include "rtp_statistics.h" | ||||
|  | ||||
| @@ -32,7 +32,7 @@ class RtpAudioReceiver { | ||||
|  | ||||
|  private: | ||||
|   bool CheckIsTimeSendRR(); | ||||
|   int SendRtcpRR(RtcpReceiverReport& rtcp_rr); | ||||
|   int SendRtcpRR(ReceiverReport& rtcp_rr); | ||||
|  | ||||
|  private: | ||||
|   std::function<void(const char*, size_t)> on_receive_data_ = nullptr; | ||||
|   | ||||
| @@ -60,49 +60,52 @@ int RtpAudioSender::SendRtpPacket(std::shared_ptr<RtpPacket> rtp_packet) { | ||||
|     io_statistics_->IncrementAudioOutboundRtpPacketCount(); | ||||
|   } | ||||
|  | ||||
|   if (CheckIsTimeSendSR()) { | ||||
|     RtcpSenderReport rtcp_sr; | ||||
|     SenderInfo sender_info; | ||||
|     RtcpReportBlock report; | ||||
|   // if (CheckIsTimeSendSR()) { | ||||
|   //   SenderReport rtcp_sr; | ||||
|   //   SenderInfo sender_info; | ||||
|   //   RtcpReportBlock report; | ||||
|  | ||||
|     auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|     auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration); | ||||
|     uint32_t seconds_u32 = static_cast<uint32_t>( | ||||
|         std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|   //   auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|   //   auto seconds = | ||||
|   //   std::chrono::duration_cast<std::chrono::seconds>(duration); uint32_t | ||||
|   //   seconds_u32 = static_cast<uint32_t>( | ||||
|   //       std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|  | ||||
|     uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|         std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds) | ||||
|             .count()); | ||||
|   //   uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|   //       std::chrono::duration_cast<std::chrono::nanoseconds>(duration - | ||||
|   //       seconds) | ||||
|   //           .count()); | ||||
|  | ||||
|     sender_info.sender_ssrc = 0x00; | ||||
|     sender_info.ntp_ts_msw = (uint32_t)seconds_u32; | ||||
|     sender_info.ntp_ts_lsw = (uint32_t)fraction_u32; | ||||
|     sender_info.rtp_ts = | ||||
|         std::chrono::system_clock::now().time_since_epoch().count() * 1000000; | ||||
|     sender_info.sender_packet_count = total_rtp_packets_sent_; | ||||
|     sender_info.sender_octet_count = total_rtp_payload_sent_; | ||||
|   //   sender_info.sender_ssrc = 0x00; | ||||
|   //   sender_info.ntp_ts_msw = (uint32_t)seconds_u32; | ||||
|   //   sender_info.ntp_ts_lsw = (uint32_t)fraction_u32; | ||||
|   //   sender_info.rtp_ts = | ||||
|   //       std::chrono::system_clock::now().time_since_epoch().count() * | ||||
|   //       1000000; | ||||
|   //   sender_info.sender_packet_count = total_rtp_packets_sent_; | ||||
|   //   sender_info.sender_octet_count = total_rtp_payload_sent_; | ||||
|  | ||||
|     rtcp_sr.SetSenderInfo(sender_info); | ||||
|   //   rtcp_sr.SetSenderInfo(sender_info); | ||||
|  | ||||
|     report.source_ssrc = 0x00; | ||||
|     report.fraction_lost = 0; | ||||
|     report.cumulative_lost = 0; | ||||
|     report.extended_high_seq_num = 0; | ||||
|     report.jitter = 0; | ||||
|     report.lsr = 0; | ||||
|     report.dlsr = 0; | ||||
|   //   report.source_ssrc = 0x00; | ||||
|   //   report.fraction_lost = 0; | ||||
|   //   report.cumulative_lost = 0; | ||||
|   //   report.extended_high_seq_num = 0; | ||||
|   //   report.jitter = 0; | ||||
|   //   report.lsr = 0; | ||||
|   //   report.dlsr = 0; | ||||
|  | ||||
|     rtcp_sr.SetReportBlock(report); | ||||
|   //   rtcp_sr.SetReportBlock(report); | ||||
|  | ||||
|     rtcp_sr.Encode(); | ||||
|   //   rtcp_sr.Encode(); | ||||
|  | ||||
|     // SendRtcpSR(rtcp_sr); | ||||
|   } | ||||
|   //   // SendRtcpSR(rtcp_sr); | ||||
|   // } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int RtpAudioSender::SendRtcpSR(RtcpSenderReport& rtcp_sr) { | ||||
| int RtpAudioSender::SendRtcpSR(SenderReport& rtcp_sr) { | ||||
|   if (!data_send_func_) { | ||||
|     LOG_ERROR("data_send_func_ is nullptr"); | ||||
|     return -1; | ||||
|   | ||||
| @@ -11,9 +11,9 @@ | ||||
|  | ||||
| #include "io_statistics.h" | ||||
| #include "ringbuffer.h" | ||||
| #include "rtcp_sender_report.h" | ||||
| #include "rtp_packet.h" | ||||
| #include "rtp_statistics.h" | ||||
| #include "sender_report.h" | ||||
| #include "thread_base.h" | ||||
|  | ||||
| class RtpAudioSender : public ThreadBase { | ||||
| @@ -29,7 +29,7 @@ class RtpAudioSender : public ThreadBase { | ||||
|  | ||||
|  private: | ||||
|   int SendRtpPacket(std::shared_ptr<RtpPacket> rtp_packet); | ||||
|   int SendRtcpSR(RtcpSenderReport &rtcp_sr); | ||||
|   int SendRtcpSR(SenderReport &rtcp_sr); | ||||
|  | ||||
|   bool CheckIsTimeSendSR(); | ||||
|  | ||||
|   | ||||
| @@ -33,40 +33,40 @@ void RtpDataReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { | ||||
|     io_statistics_->UpdateDataPacketLossCount(rtp_packet.SequenceNumber()); | ||||
|   } | ||||
|  | ||||
|   if (CheckIsTimeSendRR()) { | ||||
|     RtcpReceiverReport rtcp_rr; | ||||
|     RtcpReportBlock report; | ||||
|   //   if (CheckIsTimeSendRR()) { | ||||
|   //     ReceiverReport rtcp_rr; | ||||
|   //     RtcpReportBlock report; | ||||
|  | ||||
|     // auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|     // auto seconds = | ||||
|     // std::chrono::duration_cast<std::chrono::seconds>(duration); uint32_t | ||||
|     // seconds_u32 = static_cast<uint32_t>( | ||||
|     //     std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|   //     // auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|   //     // auto seconds = | ||||
|   //     // std::chrono::duration_cast<std::chrono::seconds>(duration); uint32_t | ||||
|   //     // seconds_u32 = static_cast<uint32_t>( | ||||
|   //     // std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|  | ||||
|     // uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|     //     std::chrono::duration_cast<std::chrono::nanoseconds>(duration - | ||||
|     //     seconds) | ||||
|     //         .count()); | ||||
|   //     // uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|   //     //     std::chrono::duration_cast<std::chrono::nanoseconds>(duration - | ||||
|   //     //     seconds) | ||||
|   //     //         .count()); | ||||
|  | ||||
|     report.source_ssrc = 0x00; | ||||
|     report.fraction_lost = 0; | ||||
|     report.cumulative_lost = 0; | ||||
|     report.extended_high_seq_num = 0; | ||||
|     report.jitter = 0; | ||||
|     report.lsr = 0; | ||||
|     report.dlsr = 0; | ||||
|   //     report.source_ssrc = 0x00; | ||||
|   //     report.fraction_lost = 0; | ||||
|   //     report.cumulative_lost = 0; | ||||
|   //     report.extended_high_seq_num = 0; | ||||
|   //     report.jitter = 0; | ||||
|   //     report.lsr = 0; | ||||
|   //     report.dlsr = 0; | ||||
|  | ||||
|     rtcp_rr.SetReportBlock(report); | ||||
|   //     rtcp_rr.SetReportBlock(report); | ||||
|  | ||||
|     rtcp_rr.Encode(); | ||||
|   //     rtcp_rr.Encode(); | ||||
|  | ||||
|     // SendRtcpRR(rtcp_rr); | ||||
|   } | ||||
|   //     // SendRtcpRR(rtcp_rr); | ||||
|   //   } | ||||
|  | ||||
|   if (on_receive_data_) { | ||||
|     on_receive_data_((const char*)rtp_packet.Payload(), | ||||
|                      rtp_packet.PayloadSize()); | ||||
|   } | ||||
|   //   if (on_receive_data_) { | ||||
|   //     on_receive_data_((const char*)rtp_packet.Payload(), | ||||
|   //                      rtp_packet.PayloadSize()); | ||||
|   //   } | ||||
| } | ||||
|  | ||||
| void RtpDataReceiver::SetSendDataFunc( | ||||
| @@ -74,7 +74,7 @@ void RtpDataReceiver::SetSendDataFunc( | ||||
|   data_send_func_ = data_send_func; | ||||
| } | ||||
|  | ||||
| int RtpDataReceiver::SendRtcpRR(RtcpReceiverReport& rtcp_rr) { | ||||
| int RtpDataReceiver::SendRtcpRR(ReceiverReport& rtcp_rr) { | ||||
|   if (!data_send_func_) { | ||||
|     LOG_ERROR("data_send_func_ is nullptr"); | ||||
|     return -1; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| #include <functional> | ||||
|  | ||||
| #include "io_statistics.h" | ||||
| #include "rtcp_receiver_report.h" | ||||
| #include "receiver_report.h" | ||||
| #include "rtp_packet.h" | ||||
| #include "rtp_statistics.h" | ||||
|  | ||||
| @@ -26,7 +26,7 @@ class RtpDataReceiver { | ||||
|  | ||||
|  private: | ||||
|   bool CheckIsTimeSendRR(); | ||||
|   int SendRtcpRR(RtcpReceiverReport& rtcp_rr); | ||||
|   int SendRtcpRR(ReceiverReport& rtcp_rr); | ||||
|  | ||||
|  private: | ||||
|   std::function<void(const char*, size_t)> on_receive_data_ = nullptr; | ||||
|   | ||||
| @@ -60,49 +60,52 @@ int RtpDataSender::SendRtpPacket(std::shared_ptr<RtpPacket> rtp_packet) { | ||||
|     io_statistics_->IncrementDataOutboundRtpPacketCount(); | ||||
|   } | ||||
|  | ||||
|   if (CheckIsTimeSendSR()) { | ||||
|     RtcpSenderReport rtcp_sr; | ||||
|     SenderInfo sender_info; | ||||
|     RtcpReportBlock report; | ||||
|   // if (CheckIsTimeSendSR()) { | ||||
|   //   SenderReport rtcp_sr; | ||||
|   //   SenderInfo sender_info; | ||||
|   //   RtcpReportBlock report; | ||||
|  | ||||
|     auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|     auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration); | ||||
|     uint32_t seconds_u32 = static_cast<uint32_t>( | ||||
|         std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|   //   auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|   //   auto seconds = | ||||
|   //   std::chrono::duration_cast<std::chrono::seconds>(duration); uint32_t | ||||
|   //   seconds_u32 = static_cast<uint32_t>( | ||||
|   //       std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|  | ||||
|     uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|         std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds) | ||||
|             .count()); | ||||
|   //   uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|   //       std::chrono::duration_cast<std::chrono::nanoseconds>(duration - | ||||
|   //       seconds) | ||||
|   //           .count()); | ||||
|  | ||||
|     sender_info.sender_ssrc = 0x00; | ||||
|     sender_info.ntp_ts_msw = (uint32_t)seconds_u32; | ||||
|     sender_info.ntp_ts_lsw = (uint32_t)fraction_u32; | ||||
|     sender_info.rtp_ts = | ||||
|         std::chrono::system_clock::now().time_since_epoch().count() * 1000000; | ||||
|     sender_info.sender_packet_count = total_rtp_packets_sent_; | ||||
|     sender_info.sender_octet_count = total_rtp_payload_sent_; | ||||
|   //   sender_info.sender_ssrc = 0x00; | ||||
|   //   sender_info.ntp_ts_msw = (uint32_t)seconds_u32; | ||||
|   //   sender_info.ntp_ts_lsw = (uint32_t)fraction_u32; | ||||
|   //   sender_info.rtp_ts = | ||||
|   //       std::chrono::system_clock::now().time_since_epoch().count() * | ||||
|   //       1000000; | ||||
|   //   sender_info.sender_packet_count = total_rtp_packets_sent_; | ||||
|   //   sender_info.sender_octet_count = total_rtp_payload_sent_; | ||||
|  | ||||
|     rtcp_sr.SetSenderInfo(sender_info); | ||||
|   //   rtcp_sr.SetSenderInfo(sender_info); | ||||
|  | ||||
|     report.source_ssrc = 0x00; | ||||
|     report.fraction_lost = 0; | ||||
|     report.cumulative_lost = 0; | ||||
|     report.extended_high_seq_num = 0; | ||||
|     report.jitter = 0; | ||||
|     report.lsr = 0; | ||||
|     report.dlsr = 0; | ||||
|   //   report.source_ssrc = 0x00; | ||||
|   //   report.fraction_lost = 0; | ||||
|   //   report.cumulative_lost = 0; | ||||
|   //   report.extended_high_seq_num = 0; | ||||
|   //   report.jitter = 0; | ||||
|   //   report.lsr = 0; | ||||
|   //   report.dlsr = 0; | ||||
|  | ||||
|     rtcp_sr.SetReportBlock(report); | ||||
|   //   rtcp_sr.SetReportBlock(report); | ||||
|  | ||||
|     rtcp_sr.Encode(); | ||||
|   //   rtcp_sr.Encode(); | ||||
|  | ||||
|     // SendRtcpSR(rtcp_sr); | ||||
|   } | ||||
|   //   // SendRtcpSR(rtcp_sr); | ||||
|   // } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int RtpDataSender::SendRtcpSR(RtcpSenderReport& rtcp_sr) { | ||||
| int RtpDataSender::SendRtcpSR(SenderReport& rtcp_sr) { | ||||
|   if (!data_send_func_) { | ||||
|     LOG_ERROR("data_send_func_ is nullptr"); | ||||
|     return -1; | ||||
|   | ||||
| @@ -11,9 +11,9 @@ | ||||
|  | ||||
| #include "io_statistics.h" | ||||
| #include "ringbuffer.h" | ||||
| #include "rtcp_sender_report.h" | ||||
| #include "rtp_packet.h" | ||||
| #include "rtp_statistics.h" | ||||
| #include "sender_report.h" | ||||
| #include "thread_base.h" | ||||
|  | ||||
| class RtpDataSender : public ThreadBase { | ||||
| @@ -30,7 +30,7 @@ class RtpDataSender : public ThreadBase { | ||||
|  private: | ||||
|  private: | ||||
|   int SendRtpPacket(std::shared_ptr<RtpPacket> rtp_packet); | ||||
|   int SendRtcpSR(RtcpSenderReport &rtcp_sr); | ||||
|   int SendRtcpSR(SenderReport &rtcp_sr); | ||||
|  | ||||
|   bool CheckIsTimeSendSR(); | ||||
|  | ||||
|   | ||||
| @@ -122,35 +122,36 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { | ||||
|     io_statistics_->UpdateVideoPacketLossCount(rtp_packet.SequenceNumber()); | ||||
|   } | ||||
|  | ||||
|   if (CheckIsTimeSendRR()) { | ||||
|     RtcpReceiverReport rtcp_rr; | ||||
|     RtcpReportBlock report; | ||||
|   // if (CheckIsTimeSendRR()) { | ||||
|   //   ReceiverReport rtcp_rr; | ||||
|   //   RtcpReportBlock report; | ||||
|  | ||||
|     // auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|     // auto seconds = | ||||
|     // std::chrono::duration_cast<std::chrono::seconds>(duration); uint32_t | ||||
|     // seconds_u32 = static_cast<uint32_t>( | ||||
|     //     std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|   //   // auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|   //   // auto seconds = | ||||
|   //   // std::chrono::duration_cast<std::chrono::seconds>(duration); uint32_t | ||||
|   //   // seconds_u32 = static_cast<uint32_t>( | ||||
|   //   // std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|  | ||||
|     // uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|     //     std::chrono::duration_cast<std::chrono::nanoseconds>(duration - | ||||
|     //     seconds) | ||||
|     //         .count()); | ||||
|   //   // uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|   //   //     std::chrono::duration_cast<std::chrono::nanoseconds>(duration - | ||||
|   //   //     seconds) | ||||
|   //   //         .count()); | ||||
|  | ||||
|     report.source_ssrc = 0x00; | ||||
|     report.fraction_lost = 0; | ||||
|     report.cumulative_lost = 0; | ||||
|     report.extended_high_seq_num = 0; | ||||
|     report.jitter = 0; | ||||
|     report.lsr = 0; | ||||
|     report.dlsr = 0; | ||||
|   //   report.source_ssrc = 0x00; | ||||
|   //   report.fraction_lost = 0; | ||||
|   //   report.cumulative_lost = 0; | ||||
|   //   report.extended_high_seq_num = 0; | ||||
|   //   report.jitter = 0; | ||||
|   //   report.lsr = 0; | ||||
|   //   report.dlsr = 0; | ||||
|  | ||||
|     rtcp_rr.SetReportBlock(report); | ||||
|   //   rtcp_rr.SetReportBlock(report); | ||||
|  | ||||
|     rtcp_rr.Encode(); | ||||
|   //   rtcp_rr.Encode(); | ||||
|  | ||||
|   //   // SendRtcpRR(rtcp_rr); | ||||
|   // } | ||||
|  | ||||
|     // SendRtcpRR(rtcp_rr); | ||||
|   } | ||||
|   if (rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::AV1) { | ||||
|     RtpPacketAv1 rtp_packet_av1; | ||||
|     rtp_packet_av1.Build(rtp_packet.Buffer().data(), rtp_packet.Size()); | ||||
| @@ -407,7 +408,7 @@ void RtpVideoReceiver::SetSendDataFunc( | ||||
|   data_send_func_ = data_send_func; | ||||
| } | ||||
|  | ||||
| int RtpVideoReceiver::SendRtcpRR(RtcpReceiverReport& rtcp_rr) { | ||||
| int RtpVideoReceiver::SendRtcpRR(ReceiverReport& rtcp_rr) { | ||||
|   if (!data_send_func_) { | ||||
|     LOG_ERROR("data_send_func_ is nullptr"); | ||||
|     return -1; | ||||
|   | ||||
| @@ -11,8 +11,8 @@ | ||||
| #include "io_statistics.h" | ||||
| #include "nack_requester.h" | ||||
| #include "receive_side_congestion_controller.h" | ||||
| #include "receiver_report.h" | ||||
| #include "ringbuffer.h" | ||||
| #include "rtcp_receiver_report.h" | ||||
| #include "rtcp_sender.h" | ||||
| #include "rtp_packet_av1.h" | ||||
| #include "rtp_packet_h264.h" | ||||
| @@ -53,7 +53,7 @@ class RtpVideoReceiver : public ThreadBase, | ||||
|  | ||||
|  private: | ||||
|   bool CheckIsTimeSendRR(); | ||||
|   int SendRtcpRR(RtcpReceiverReport& rtcp_rr); | ||||
|   int SendRtcpRR(ReceiverReport& rtcp_rr); | ||||
|  | ||||
|   void SendCombinedRtcpPacket( | ||||
|       std::vector<std::unique_ptr<RtcpPacket>> rtcp_packets); | ||||
|   | ||||
| @@ -100,40 +100,25 @@ int RtpVideoSender::SendRtpPacket(std::shared_ptr<RtpPacket> rtp_packet) { | ||||
|   } | ||||
|  | ||||
|   if (CheckIsTimeSendSR()) { | ||||
|     RtcpSenderReport rtcp_sr; | ||||
|     SenderInfo sender_info; | ||||
|     SenderReport rtcp_sr; | ||||
|     rtcp_sr.SetSenderSsrc(ssrc_); | ||||
|     rtcp_sr.SetTimestamp(0); | ||||
|     rtcp_sr.SetNtpTimestamp(0); | ||||
|     rtcp_sr.SetSenderPacketCount(total_rtp_packets_sent_); | ||||
|     rtcp_sr.SetSenderOctetCount(total_rtp_payload_sent_); | ||||
|  | ||||
|     RtcpReportBlock report; | ||||
|  | ||||
|     auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||||
|     auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration); | ||||
|     uint32_t seconds_u32 = static_cast<uint32_t>( | ||||
|         std::chrono::duration_cast<std::chrono::seconds>(duration).count()); | ||||
|     report.SetMediaSsrc(ssrc_); | ||||
|     report.SetFractionLost(0); | ||||
|     report.SetCumulativeLost(0); | ||||
|     report.SetJitter(0); | ||||
|     report.SetLastSr(0); | ||||
|     report.SetExtHighestSeqNum(0); | ||||
|     report.SetDelayLastSr(0); | ||||
|  | ||||
|     uint32_t fraction_u32 = static_cast<uint32_t>( | ||||
|         std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds) | ||||
|             .count()); | ||||
|  | ||||
|     sender_info.sender_ssrc = 0x00; | ||||
|     sender_info.ntp_ts_msw = (uint32_t)seconds_u32; | ||||
|     sender_info.ntp_ts_lsw = (uint32_t)fraction_u32; | ||||
|     sender_info.rtp_ts = | ||||
|         std::chrono::system_clock::now().time_since_epoch().count() * 1000000; | ||||
|     sender_info.sender_packet_count = total_rtp_packets_sent_; | ||||
|     sender_info.sender_octet_count = total_rtp_payload_sent_; | ||||
|  | ||||
|     rtcp_sr.SetSenderInfo(sender_info); | ||||
|  | ||||
|     report.source_ssrc = 0x00; | ||||
|     report.fraction_lost = 0; | ||||
|     report.cumulative_lost = 0; | ||||
|     report.extended_high_seq_num = 0; | ||||
|     report.jitter = 0; | ||||
|     report.lsr = 0; | ||||
|     report.dlsr = 0; | ||||
|  | ||||
|     // rtcp_sr.SetReportBlock(report); | ||||
|  | ||||
|     rtcp_sr.Encode(); | ||||
|     rtcp_sr.SetReportBlock(report); | ||||
|     rtcp_sr.Create(); | ||||
|  | ||||
|     SendRtcpSR(rtcp_sr); | ||||
|   } | ||||
| @@ -141,7 +126,7 @@ int RtpVideoSender::SendRtpPacket(std::shared_ptr<RtpPacket> rtp_packet) { | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int RtpVideoSender::SendRtcpSR(RtcpSenderReport& rtcp_sr) { | ||||
| int RtpVideoSender::SendRtcpSR(SenderReport& rtcp_sr) { | ||||
|   if (!data_send_func_) { | ||||
|     LOG_ERROR("data_send_func_ is nullptr"); | ||||
|     return -1; | ||||
|   | ||||
| @@ -5,11 +5,11 @@ | ||||
|  | ||||
| #include "io_statistics.h" | ||||
| #include "ringbuffer.h" | ||||
| #include "rtcp_sender_report.h" | ||||
| #include "rtp_packet.h" | ||||
| #include "rtp_packet_history.h" | ||||
| #include "rtp_packet_to_send.h" | ||||
| #include "rtp_statistics.h" | ||||
| #include "sender_report.h" | ||||
| #include "thread_base.h" | ||||
|  | ||||
| class RtpVideoSender : public ThreadBase { | ||||
| @@ -28,7 +28,7 @@ class RtpVideoSender : public ThreadBase { | ||||
|  | ||||
|  private: | ||||
|   int SendRtpPacket(std::shared_ptr<RtpPacket> rtp_packet); | ||||
|   int SendRtcpSR(RtcpSenderReport &rtcp_sr); | ||||
|   int SendRtcpSR(SenderReport &rtcp_sr); | ||||
|  | ||||
|   bool CheckIsTimeSendSR(); | ||||
|  | ||||
|   | ||||
| @@ -234,7 +234,7 @@ int NvidiaVideoEncoder::SetTargetBitrate(int bitrate) { | ||||
|   encoder_->GetInitializeParams(&init_params); | ||||
|   init_params.frameRateDen = 1; | ||||
|   init_params.frameRateNum = init_params.frameRateDen * fps_; | ||||
|   init_params.encodeConfig->rcParams.averageBitRate = average_bitrate_; | ||||
|   init_params.encodeConfig->rcParams.averageBitRate = bitrate; | ||||
|   init_params.encodeConfig->rcParams.maxBitRate = bitrate; | ||||
|   reconfig_params.reInitEncodeParams = init_params; | ||||
|   return encoder_->Reconfigure(&reconfig_params) ? 0 : -1; | ||||
|   | ||||
| @@ -1,96 +1,55 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "receiver_report.h" | ||||
|  | ||||
| #include <utility> | ||||
| ReceiverReport::ReceiverReport() : buffer_(nullptr), size_(0) {} | ||||
|  | ||||
| #include "byte_io.h" | ||||
| #include "common_header.h" | ||||
| #include "log.h" | ||||
|  | ||||
| // RTCP receiver report (RFC 3550). | ||||
| // | ||||
| //   0                   1                   2                   3 | ||||
| //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| //  |V=2|P|    RC   |   PT=RR=201   |             length            | | ||||
| //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| //  |                     SSRC of packet sender                     | | ||||
| //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| //  |                         report block(s)                       | | ||||
| //  |                            ....                               | | ||||
|  | ||||
| ReceiverReport::ReceiverReport() = default; | ||||
|  | ||||
| ReceiverReport::ReceiverReport(const ReceiverReport& rhs) = default; | ||||
|  | ||||
| ReceiverReport::~ReceiverReport() = default; | ||||
|  | ||||
| bool ReceiverReport::Parse(const CommonHeader& packet) { | ||||
|   const uint8_t report_blocks_count = packet.count(); | ||||
|  | ||||
|   if (packet.payload_size_bytes() < | ||||
|       kRrBaseLength + report_blocks_count * ReportBlock::kLength) { | ||||
|     LOG_WARN("Packet is too small to contain all the data."); | ||||
|     return false; | ||||
| ReceiverReport::~ReceiverReport() { | ||||
|   if (buffer_) { | ||||
|     delete[] buffer_; | ||||
|     buffer_ = nullptr; | ||||
|   } | ||||
|  | ||||
|   SetSenderSsrc(ByteReader<uint32_t>::ReadBigEndian(packet.payload())); | ||||
|  | ||||
|   const uint8_t* next_report_block = packet.payload() + kRrBaseLength; | ||||
|  | ||||
|   report_blocks_.resize(report_blocks_count); | ||||
|   for (ReportBlock& block : report_blocks_) { | ||||
|     block.Parse(next_report_block, ReportBlock::kLength); | ||||
|     next_report_block += ReportBlock::kLength; | ||||
|   } | ||||
|  | ||||
|   return true; | ||||
|   size_ = 0; | ||||
| } | ||||
|  | ||||
| size_t ReceiverReport::BlockLength() const { | ||||
|   return kHeaderLength + kRrBaseLength + | ||||
|          report_blocks_.size() * ReportBlock::kLength; | ||||
| void ReceiverReport::SetReportBlock(RtcpReportBlock &rtcp_report_block) { | ||||
|   reports_.push_back(std::move(rtcp_report_block)); | ||||
| } | ||||
|  | ||||
| bool ReceiverReport::Create(uint8_t* packet, size_t* index, size_t max_length, | ||||
|                             PacketReadyCallback callback) const { | ||||
|   while (*index + BlockLength() > max_length) { | ||||
|     if (!OnBufferFull(packet, index, callback)) return false; | ||||
|   } | ||||
|   CreateHeader(report_blocks_.size(), kPacketType, HeaderLength(), packet, | ||||
|                index); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(packet + *index, sender_ssrc()); | ||||
|   *index += kRrBaseLength; | ||||
|   for (const ReportBlock& block : report_blocks_) { | ||||
|     block.Create(packet + *index); | ||||
|     *index += ReportBlock::kLength; | ||||
|   } | ||||
|   return true; | ||||
| void ReceiverReport::SetReportBlocks( | ||||
|     std::vector<RtcpReportBlock> &rtcp_report_blocks) { | ||||
|   reports_ = std::move(rtcp_report_blocks); | ||||
| } | ||||
|  | ||||
| bool ReceiverReport::AddReportBlock(const ReportBlock& block) { | ||||
|   if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { | ||||
|     LOG_WARN("Max report blocks reached."); | ||||
|     return false; | ||||
| const uint8_t *ReceiverReport::Create() { | ||||
|   size_t buffer_size = | ||||
|       DEFAULT_SR_SIZE + reports_.size() * RtcpReportBlock::kLength; | ||||
|   if (!buffer_ || buffer_size != size_) { | ||||
|     delete[] buffer_; | ||||
|     buffer_ = nullptr; | ||||
|   } | ||||
|   report_blocks_.push_back(block); | ||||
|   return true; | ||||
|  | ||||
|   buffer_ = new uint8_t[buffer_size]; | ||||
|   size_ = buffer_size; | ||||
|  | ||||
|   int pos = | ||||
|       rtcp_common_header_.Create(DEFAULT_RTCP_VERSION, 0, DEFAULT_RR_BLOCK_NUM, | ||||
|                                  RTCP_TYPE::RR, DEFAULT_RR_SIZE, buffer_); | ||||
|  | ||||
|   for (const auto &report : reports_) { | ||||
|     pos += report.Create(buffer_ + pos); | ||||
|   } | ||||
|  | ||||
|   return buffer_; | ||||
| } | ||||
|  | ||||
| bool ReceiverReport::SetReportBlocks(std::vector<ReportBlock> blocks) { | ||||
|   if (blocks.size() > kMaxNumberOfReportBlocks) { | ||||
|     LOG_WARN("Too many report blocks ({}) for receiver report.", blocks.size()); | ||||
|     return false; | ||||
| size_t ReceiverReport::Parse(const uint8_t *buffer) { | ||||
|   reports_.clear(); | ||||
|   size_t pos = rtcp_common_header_.Parse(buffer); | ||||
|  | ||||
|   for (int i = 0; i < rtcp_common_header_.CountOrFormat(); i++) { | ||||
|     RtcpReportBlock report; | ||||
|     pos += report.Parse(buffer + pos); | ||||
|     reports_.emplace_back(std::move(report)); | ||||
|   } | ||||
|   report_blocks_ = std::move(blocks); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
|   return pos; | ||||
| } | ||||
| @@ -1,50 +1,66 @@ | ||||
| /* | ||||
|  * @Author: DI JUNKUN | ||||
|  * @Date: 2025-02-17 | ||||
|  * @Date: 2025-02-18 | ||||
|  * Copyright (c) 2025 by DI JUNKUN, All Rights Reserved. | ||||
|  */ | ||||
|  | ||||
| #ifndef _RECEIVER_REPORT_H_ | ||||
| #define _RECEIVER_REPORT_H_ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
| // RR | ||||
| //  0                   1                   2                   3 | ||||
| //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |V=2|P|   RC    |   PT=SR=200   |            length             | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                     SSRC of packet sender                     | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                 SSRC_1 (SSRC of first source)                 | report | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | ||||
| // | fraction lost |       cumulative number of packets lost       | 1 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |           extended highest sequence number received           | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                      interarrival jitter                      | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                         last SR (LSR)                         | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                   delay since last SR (DLSR)                  | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                 SSRC_2 (SSRC of second source)                | report | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | ||||
| // :                               ...                             : 2 | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                  profile-specific extensions                  | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #include "report_block.h" | ||||
| #include "rtcp_packet.h" | ||||
| #include "rtcp_common_header.h" | ||||
| #include "rtcp_report_block.h" | ||||
|  | ||||
| class CommonHeader; | ||||
|  | ||||
| class ReceiverReport : public RtcpPacket { | ||||
| class ReceiverReport { | ||||
|  public: | ||||
|   static constexpr uint8_t kPacketType = 201; | ||||
|   static constexpr size_t kMaxNumberOfReportBlocks = 0x1f; | ||||
|  | ||||
|   ReceiverReport(); | ||||
|   ReceiverReport(const ReceiverReport&); | ||||
|   ~ReceiverReport() override; | ||||
|   ~ReceiverReport(); | ||||
|  | ||||
|   // Parse assumes header is already parsed and validated. | ||||
|   bool Parse(const CommonHeader& packet); | ||||
|  public: | ||||
|   void SetReportBlock(RtcpReportBlock &rtcp_report_block); | ||||
|   void SetReportBlocks(std::vector<RtcpReportBlock> &rtcp_report_blocks); | ||||
|  | ||||
|   bool AddReportBlock(const ReportBlock& block); | ||||
|   bool SetReportBlocks(std::vector<ReportBlock> blocks); | ||||
|   const uint8_t *Create(); | ||||
|   size_t Parse(const uint8_t *buffer); | ||||
|  | ||||
|   const std::vector<ReportBlock>& report_blocks() const { | ||||
|     return report_blocks_; | ||||
|   } | ||||
|  | ||||
|   size_t BlockLength() const override; | ||||
|  | ||||
|   bool Create(uint8_t* packet, size_t* index, size_t max_length, | ||||
|               PacketReadyCallback callback) const override; | ||||
|   const uint8_t *Buffer() const { return buffer_; } | ||||
|   size_t Size() const { return size_; } | ||||
|  | ||||
|  private: | ||||
|   static constexpr size_t kRrBaseLength = 4; | ||||
|   RtcpCommonHeader rtcp_common_header_; | ||||
|   std::vector<RtcpReportBlock> reports_; | ||||
|  | ||||
|   std::vector<ReportBlock> report_blocks_; | ||||
|   // Entire RTCP buffer | ||||
|   uint8_t *buffer_ = nullptr; | ||||
|   size_t size_ = 0; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -1,79 +0,0 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "report_block.h" | ||||
|  | ||||
| #include "byte_io.h" | ||||
| #include "log.h" | ||||
|  | ||||
| // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications. | ||||
| // | ||||
| // RTCP report block (RFC 3550). | ||||
| // | ||||
| //     0                   1                   2                   3 | ||||
| //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| //    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| //  0 |                 SSRC_1 (SSRC of first source)                 | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| //  4 | fraction lost |       cumulative number of packets lost       | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| //  8 |           extended highest sequence number received           | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // 12 |                      interarrival jitter                      | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // 16 |                         last SR (LSR)                         | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // 20 |                   delay since last SR (DLSR)                  | | ||||
| // 24 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| ReportBlock::ReportBlock() | ||||
|     : source_ssrc_(0), | ||||
|       fraction_lost_(0), | ||||
|       cumulative_lost_(0), | ||||
|       extended_high_seq_num_(0), | ||||
|       jitter_(0), | ||||
|       last_sr_(0), | ||||
|       delay_since_last_sr_(0) {} | ||||
|  | ||||
| bool ReportBlock::Parse(const uint8_t* buffer, size_t length) { | ||||
|   if (length < ReportBlock::kLength) { | ||||
|     LOG_ERROR("Report Block should be 24 bytes long"); | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   source_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[0]); | ||||
|   fraction_lost_ = buffer[4]; | ||||
|   cumulative_lost_ = ByteReader<int32_t, 3>::ReadBigEndian(&buffer[5]); | ||||
|   extended_high_seq_num_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[8]); | ||||
|   jitter_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[12]); | ||||
|   last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[16]); | ||||
|   delay_since_last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[20]); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void ReportBlock::Create(uint8_t* buffer) const { | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&buffer[0], source_ssrc()); | ||||
|   ByteWriter<uint8_t>::WriteBigEndian(&buffer[4], fraction_lost()); | ||||
|   ByteWriter<int32_t, 3>::WriteBigEndian(&buffer[5], cumulative_lost()); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&buffer[8], extended_high_seq_num()); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&buffer[12], jitter()); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&buffer[16], last_sr()); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&buffer[20], delay_since_last_sr()); | ||||
| } | ||||
|  | ||||
| bool ReportBlock::SetCumulativeLost(int32_t cumulative_lost) { | ||||
|   // We have only 3 bytes to store it, and it's a signed value. | ||||
|   if (cumulative_lost >= (1 << 23) || cumulative_lost < -(1 << 23)) { | ||||
|     LOG_WARN("Cumulative lost is too big to fit into Report Block"); | ||||
|     return false; | ||||
|   } | ||||
|   cumulative_lost_ = cumulative_lost; | ||||
|   return true; | ||||
| } | ||||
| @@ -1,13 +1,15 @@ | ||||
| #include "rtcp_header.h" | ||||
| #include "rtcp_common_header.h" | ||||
| 
 | ||||
| RtcpHeader::RtcpHeader() | ||||
| #include "log.h" | ||||
| 
 | ||||
| RtcpCommonHeader::RtcpCommonHeader() | ||||
|     : version_(0), | ||||
|       padding_(0), | ||||
|       count_or_format_(0), | ||||
|       payload_type_(PAYLOAD_TYPE::UNKNOWN), | ||||
|       length_(0) {} | ||||
| 
 | ||||
| RtcpHeader::RtcpHeader(const uint8_t* buffer, uint32_t size) { | ||||
| RtcpCommonHeader::RtcpCommonHeader(const uint8_t* buffer, uint32_t size) { | ||||
|   if (size < 4) { | ||||
|     version_ = 2; | ||||
|     padding_ = 0; | ||||
| @@ -23,11 +25,11 @@ RtcpHeader::RtcpHeader(const uint8_t* buffer, uint32_t size) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| RtcpHeader::~RtcpHeader() {} | ||||
| RtcpCommonHeader::~RtcpCommonHeader() {} | ||||
| 
 | ||||
| int RtcpHeader::Encode(uint8_t version, uint8_t padding, | ||||
|                        uint8_t count_or_format, uint8_t payload_type, | ||||
|                        uint16_t length, uint8_t* buffer) { | ||||
| int RtcpCommonHeader::Create(uint8_t version, uint8_t padding, | ||||
|                              uint8_t count_or_format, uint8_t payload_type, | ||||
|                              uint16_t length, uint8_t* buffer) { | ||||
|   if (!buffer) { | ||||
|     return 0; | ||||
|   } | ||||
| @@ -37,4 +39,13 @@ int RtcpHeader::Encode(uint8_t version, uint8_t padding, | ||||
|   buffer[2] = length >> 8 & 0xFF; | ||||
|   buffer[3] = length & 0xFF; | ||||
|   return 4; | ||||
| } | ||||
| 
 | ||||
| size_t RtcpCommonHeader::Parse(const uint8_t* buffer) { | ||||
|   version_ = buffer[0] >> 6; | ||||
|   padding_ = buffer[0] >> 5 & 0x01; | ||||
|   count_or_format_ = buffer[0] & 0x1F; | ||||
|   payload_type_ = PAYLOAD_TYPE(buffer[1]); | ||||
|   length_ = (buffer[2] << 8) + buffer[3]; | ||||
|   return 4; | ||||
| } | ||||
| @@ -4,8 +4,6 @@ | ||||
| #include <cstddef> | ||||
| #include <cstdint> | ||||
| 
 | ||||
| #include "log.h" | ||||
| 
 | ||||
| // RTCP header
 | ||||
| //  0                   1                   2                   3
 | ||||
| //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 | ||||
| @@ -15,7 +13,7 @@ | ||||
| 
 | ||||
| #include "rtcp_typedef.h" | ||||
| 
 | ||||
| class RtcpHeader { | ||||
| class RtcpCommonHeader { | ||||
|  public: | ||||
|   typedef enum { | ||||
|     UNKNOWN = 0, | ||||
| @@ -27,9 +25,9 @@ class RtcpHeader { | ||||
|   } PAYLOAD_TYPE; | ||||
| 
 | ||||
|  public: | ||||
|   RtcpHeader(); | ||||
|   RtcpHeader(const uint8_t* buffer, uint32_t size); | ||||
|   ~RtcpHeader(); | ||||
|   RtcpCommonHeader(); | ||||
|   RtcpCommonHeader(const uint8_t* buffer, uint32_t size); | ||||
|   ~RtcpCommonHeader(); | ||||
| 
 | ||||
|  public: | ||||
|   void SetVerion(uint8_t version) { version_ = version; } | ||||
| @@ -51,9 +49,11 @@ class RtcpHeader { | ||||
|   } | ||||
|   uint16_t Length() const { return length_; } | ||||
| 
 | ||||
|   int Encode(uint8_t version, uint8_t padding, uint8_t count_or_format, | ||||
|   int Create(uint8_t version, uint8_t padding, uint8_t count_or_format, | ||||
|              uint8_t payload_type, uint16_t length, uint8_t* buffer); | ||||
| 
 | ||||
|   size_t Parse(const uint8_t* buffer); | ||||
| 
 | ||||
|  private: | ||||
|   uint8_t version_ : 2; | ||||
|   uint8_t padding_ : 1; | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
| class RtcpPacket { | ||||
|  public: | ||||
|   typedef enum { SR = 200, RR = 201, TCC = 11, NACK = 1 } PAYLOAD_TYPE; | ||||
|   typedef enum { SR = 200, RR = 201, TCC = 11, NACK = 1 } RtcpPayloadType; | ||||
|   // Callback used to signal that an RTCP packet is ready. Note that this may | ||||
|   // not contain all data in this RtcpPacket; if a packet cannot fit in | ||||
|   // max_length bytes, it will be fragmented and multiple calls to this | ||||
|   | ||||
							
								
								
									
										87
									
								
								src/rtcp/rtcp_packet/rtcp_report_block.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/rtcp/rtcp_packet/rtcp_report_block.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| #include "rtcp_report_block.h" | ||||
|  | ||||
| #include "byte_io.h" | ||||
| #include "log.h" | ||||
|  | ||||
| // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications. | ||||
| // | ||||
| // RTCP report block (RFC 3550). | ||||
| // | ||||
| //     0                   1                   2                   3 | ||||
| //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| //    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| //  0 |                 SSRC_1 (SSRC of first source)                 | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| //  4 | fraction lost |       cumulative number of packets lost       | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| //  8 |           extended highest sequence number received           | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // 12 |                      interarrival jitter                      | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // 16 |                         last SR (LSR)                         | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // 20 |                   delay since last SR (DLSR)                  | | ||||
| // 24 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
|  | ||||
| RtcpReportBlock::RtcpReportBlock() | ||||
|     : source_ssrc_(0), | ||||
|       fraction_lost_(0), | ||||
|       cumulative_lost_(0), | ||||
|       extended_high_seq_num_(0), | ||||
|       jitter_(0), | ||||
|       last_sr_(0), | ||||
|       delay_since_last_sr_(0) {} | ||||
|  | ||||
| size_t RtcpReportBlock::Create(uint8_t* buffer) const { | ||||
|   buffer[0] = (source_ssrc_ >> 24) & 0xFF; | ||||
|   buffer[1] = (source_ssrc_ >> 16) & 0xFF; | ||||
|   buffer[2] = (source_ssrc_ >> 8) & 0xFF; | ||||
|   buffer[3] = source_ssrc_ & 0xFF; | ||||
|  | ||||
|   buffer[4] = fraction_lost_; | ||||
|  | ||||
|   buffer[5] = (cumulative_lost_ >> 16) & 0xFF; | ||||
|   buffer[6] = (cumulative_lost_ >> 8) & 0xFF; | ||||
|   buffer[7] = cumulative_lost_ & 0xFF; | ||||
|  | ||||
|   buffer[8] = (extended_high_seq_num_ >> 24) & 0xFF; | ||||
|   buffer[9] = (extended_high_seq_num_ >> 16) & 0xFF; | ||||
|   buffer[10] = (extended_high_seq_num_ >> 8) & 0xFF; | ||||
|   buffer[11] = extended_high_seq_num_ & 0xFF; | ||||
|  | ||||
|   buffer[12] = (jitter_ >> 24) & 0xFF; | ||||
|   buffer[13] = (jitter_ >> 16) & 0xFF; | ||||
|   buffer[14] = (jitter_ >> 8) & 0xFF; | ||||
|   buffer[15] = jitter_ & 0xFF; | ||||
|  | ||||
|   buffer[16] = (last_sr_ >> 24) & 0xFF; | ||||
|   buffer[17] = (last_sr_ >> 16) & 0xFF; | ||||
|   buffer[18] = (last_sr_ >> 8) & 0xFF; | ||||
|   buffer[19] = last_sr_ & 0xFF; | ||||
|  | ||||
|   buffer[20] = (delay_since_last_sr_ >> 24) & 0xFF; | ||||
|   buffer[21] = (delay_since_last_sr_ >> 16) & 0xFF; | ||||
|   buffer[22] = (delay_since_last_sr_ >> 8) & 0xFF; | ||||
|   buffer[23] = delay_since_last_sr_ & 0xFF; | ||||
|  | ||||
|   return RtcpReportBlock::kLength; | ||||
| } | ||||
|  | ||||
| size_t RtcpReportBlock::Parse(const uint8_t* buffer) { | ||||
|   source_ssrc_ = | ||||
|       (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; | ||||
|   fraction_lost_ = buffer[4]; | ||||
|   cumulative_lost_ = (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; | ||||
|   if (cumulative_lost_ & 0x800000) {  // Check if the sign bit is set | ||||
|     cumulative_lost_ |= 0xFF000000;   // Sign extend to 32 bits | ||||
|   } | ||||
|   extended_high_seq_num_ = | ||||
|       (buffer[8] << 24) | (buffer[9] << 16) | (buffer[10] << 8) | buffer[11]; | ||||
|   jitter_ = | ||||
|       (buffer[12] << 24) | (buffer[13] << 16) | (buffer[14] << 8) | buffer[15]; | ||||
|   last_sr_ = | ||||
|       (buffer[16] << 24) | (buffer[17] << 16) | (buffer[18] << 8) | buffer[19]; | ||||
|   delay_since_last_sr_ = | ||||
|       (buffer[20] << 24) | (buffer[21] << 16) | (buffer[22] << 8) | buffer[23]; | ||||
|   return RtcpReportBlock::kLength; | ||||
| } | ||||
| @@ -1,35 +1,38 @@ | ||||
| /*
 | ||||
|  * @Author: DI JUNKUN | ||||
|  * @Date: 2025-02-17 | ||||
|  * @Date: 2025-02-18 | ||||
|  * Copyright (c) 2025 by DI JUNKUN, All Rights Reserved. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _REPORT_BLOCK_H_ | ||||
| #define _REPORT_BLOCK_H_ | ||||
| #ifndef _RTCP_REPORT_BLOCK_H_ | ||||
| #define _RTCP_REPORT_BLOCK_H_ | ||||
| 
 | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| // A ReportBlock represents the Sender Report packet from
 | ||||
| // RFC 3550 section 6.4.1.
 | ||||
| class ReportBlock { | ||||
| #include "log.h" | ||||
| 
 | ||||
| class RtcpReportBlock { | ||||
|  public: | ||||
|   static constexpr size_t kLength = 24; | ||||
| 
 | ||||
|   ReportBlock(); | ||||
|   ~ReportBlock() {} | ||||
| 
 | ||||
|   bool Parse(const uint8_t* buffer, size_t length); | ||||
| 
 | ||||
|   // Fills buffer with the ReportBlock.
 | ||||
|   // Consumes ReportBlock::kLength bytes.
 | ||||
|   void Create(uint8_t* buffer) const; | ||||
|   RtcpReportBlock(); | ||||
|   ~RtcpReportBlock() {} | ||||
| 
 | ||||
|  public: | ||||
|   void SetMediaSsrc(uint32_t ssrc) { source_ssrc_ = ssrc; } | ||||
|   void SetFractionLost(uint8_t fraction_lost) { | ||||
|     fraction_lost_ = fraction_lost; | ||||
|   } | ||||
|   bool SetCumulativeLost(int32_t cumulative_lost); | ||||
|   bool SetCumulativeLost(int32_t cumulative_lost) { | ||||
|     // We have only 3 bytes to store it, and it's a signed value.
 | ||||
|     if (cumulative_lost >= (1 << 23) || cumulative_lost < -(1 << 23)) { | ||||
|       LOG_WARN("Cumulative lost is too big to fit into Report Block"); | ||||
|       return false; | ||||
|     } | ||||
|     cumulative_lost_ = cumulative_lost; | ||||
|     return true; | ||||
|   } | ||||
|   void SetExtHighestSeqNum(uint32_t ext_highest_seq_num) { | ||||
|     extended_high_seq_num_ = ext_highest_seq_num; | ||||
|   } | ||||
| @@ -39,13 +42,18 @@ class ReportBlock { | ||||
|     delay_since_last_sr_ = delay_last_sr; | ||||
|   } | ||||
| 
 | ||||
|   uint32_t source_ssrc() const { return source_ssrc_; } | ||||
|   uint8_t fraction_lost() const { return fraction_lost_; } | ||||
|   int32_t cumulative_lost() const { return cumulative_lost_; } | ||||
|   uint32_t extended_high_seq_num() const { return extended_high_seq_num_; } | ||||
|   uint32_t jitter() const { return jitter_; } | ||||
|   uint32_t last_sr() const { return last_sr_; } | ||||
|   uint32_t delay_since_last_sr() const { return delay_since_last_sr_; } | ||||
|  public: | ||||
|   size_t Create(uint8_t* buffer) const; | ||||
|   size_t Parse(const uint8_t* buffer); | ||||
| 
 | ||||
|  public: | ||||
|   uint32_t SourceSsrc() const { return source_ssrc_; } | ||||
|   uint8_t FractionLost() const { return fraction_lost_; } | ||||
|   int32_t CumulativeLost() const { return cumulative_lost_; } | ||||
|   uint32_t ExtendedHighSeqNum() const { return extended_high_seq_num_; } | ||||
|   uint32_t Jitter() const { return jitter_; } | ||||
|   uint32_t LastSr() const { return last_sr_; } | ||||
|   uint32_t DelaySinceLastSr() const { return delay_since_last_sr_; } | ||||
| 
 | ||||
|  private: | ||||
|   uint32_t source_ssrc_;     // 32 bits
 | ||||
							
								
								
									
										24
									
								
								src/rtcp/rtcp_packet/rtcp_typedef.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/rtcp/rtcp_packet/rtcp_typedef.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| #ifndef _RTCP_TYPEDEF_H_ | ||||
| #define _RTCP_TYPEDEF_H_ | ||||
|  | ||||
| #include <cstddef> | ||||
| #include <cstdint> | ||||
|  | ||||
| #define DEFAULT_RTCP_VERSION 2 | ||||
| #define DEFAULT_RTCP_HEADER_SIZE 4 | ||||
|  | ||||
| #define DEFAULT_SR_BLOCK_NUM 1 | ||||
| #define DEFAULT_SR_SIZE 52 | ||||
| #define DEFAULT_RR_BLOCK_NUM 1 | ||||
| #define DEFAULT_RR_SIZE 32 | ||||
|  | ||||
| typedef enum { | ||||
|   UNKNOWN = 0, | ||||
|   SR = 200, | ||||
|   RR = 201, | ||||
|   SDES = 202, | ||||
|   BYE = 203, | ||||
|   APP = 204 | ||||
| } RTCP_TYPE; | ||||
|  | ||||
| #endif | ||||
| @@ -1,120 +1,106 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "sender_report.h" | ||||
|  | ||||
| #include <utility> | ||||
| SenderReport::SenderReport() : buffer_(nullptr), size_(0) {} | ||||
|  | ||||
| #include "byte_io.h" | ||||
| #include "common_header.h" | ||||
| #include "log.h" | ||||
|  | ||||
| //    Sender report (SR) (RFC 3550). | ||||
| //     0                   1                   2                   3 | ||||
| //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| //    |V=2|P|    RC   |   PT=SR=200   |             length            | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| //  0 |                         SSRC of sender                        | | ||||
| //    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| //  4 |              NTP timestamp, most significant word             | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| //  8 |             NTP timestamp, least significant word             | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // 12 |                         RTP timestamp                         | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // 16 |                     sender's packet count                     | | ||||
| //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // 20 |                      sender's octet count                     | | ||||
| // 24 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
|  | ||||
| SenderReport::SenderReport() | ||||
|     : rtp_timestamp_(0), sender_packet_count_(0), sender_octet_count_(0) {} | ||||
|  | ||||
| SenderReport::SenderReport(const SenderReport&) = default; | ||||
| SenderReport::SenderReport(SenderReport&&) = default; | ||||
| SenderReport& SenderReport::operator=(const SenderReport&) = default; | ||||
| SenderReport& SenderReport::operator=(SenderReport&&) = default; | ||||
| SenderReport::~SenderReport() = default; | ||||
|  | ||||
| bool SenderReport::Parse(const CommonHeader& packet) { | ||||
|   const uint8_t report_block_count = packet.count(); | ||||
|   if (packet.payload_size_bytes() < | ||||
|       kSenderBaseLength + report_block_count * ReportBlock::kLength) { | ||||
|     LOG_WARN("Packet is too small to contain all the data."); | ||||
|     return false; | ||||
| SenderReport::~SenderReport() { | ||||
|   if (buffer_) { | ||||
|     delete[] buffer_; | ||||
|     buffer_ = nullptr; | ||||
|   } | ||||
|   // Read SenderReport header. | ||||
|   const uint8_t* const payload = packet.payload(); | ||||
|   SetSenderSsrc(ByteReader<uint32_t>::ReadBigEndian(&payload[0])); | ||||
|   uint32_t secs = ByteReader<uint32_t>::ReadBigEndian(&payload[4]); | ||||
|   uint32_t frac = ByteReader<uint32_t>::ReadBigEndian(&payload[8]); | ||||
|   ntp_.Set(secs, frac); | ||||
|   rtp_timestamp_ = ByteReader<uint32_t>::ReadBigEndian(&payload[12]); | ||||
|   sender_packet_count_ = ByteReader<uint32_t>::ReadBigEndian(&payload[16]); | ||||
|   sender_octet_count_ = ByteReader<uint32_t>::ReadBigEndian(&payload[20]); | ||||
|   report_blocks_.resize(report_block_count); | ||||
|   const uint8_t* next_block = payload + kSenderBaseLength; | ||||
|   for (ReportBlock& block : report_blocks_) { | ||||
|     bool block_parsed = block.Parse(next_block, ReportBlock::kLength); | ||||
|     next_block += ReportBlock::kLength; | ||||
|   } | ||||
|   return true; | ||||
|  | ||||
|   size_ = 0; | ||||
| } | ||||
|  | ||||
| size_t SenderReport::BlockLength() const { | ||||
|   return kHeaderLength + kSenderBaseLength + | ||||
|          report_blocks_.size() * ReportBlock::kLength; | ||||
| void SenderReport::SetReportBlock(RtcpReportBlock &rtcp_report_block) { | ||||
|   reports_.push_back(std::move(rtcp_report_block)); | ||||
| } | ||||
|  | ||||
| bool SenderReport::Create(uint8_t* packet, size_t* index, size_t max_length, | ||||
|                           PacketReadyCallback callback) const { | ||||
|   while (*index + BlockLength() > max_length) { | ||||
|     if (!OnBufferFull(packet, index, callback)) return false; | ||||
|   } | ||||
|   const size_t index_end = *index + BlockLength(); | ||||
|  | ||||
|   CreateHeader(report_blocks_.size(), kPacketType, HeaderLength(), packet, | ||||
|                index); | ||||
|   // Write SenderReport header. | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 0], sender_ssrc()); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 4], ntp_.seconds()); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 8], ntp_.fractions()); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 12], rtp_timestamp_); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 16], | ||||
|                                        sender_packet_count_); | ||||
|   ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 20], | ||||
|                                        sender_octet_count_); | ||||
|   *index += kSenderBaseLength; | ||||
|   // Write report blocks. | ||||
|   for (const ReportBlock& block : report_blocks_) { | ||||
|     block.Create(packet + *index); | ||||
|     *index += ReportBlock::kLength; | ||||
|   } | ||||
|   return true; | ||||
| void SenderReport::SetReportBlocks( | ||||
|     std::vector<RtcpReportBlock> &rtcp_report_blocks) { | ||||
|   reports_ = std::move(rtcp_report_blocks); | ||||
| } | ||||
|  | ||||
| bool SenderReport::AddReportBlock(const ReportBlock& block) { | ||||
|   if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { | ||||
|     LOG_WARN("Max report blocks reached."); | ||||
|     return false; | ||||
| const uint8_t *SenderReport::Create() { | ||||
|   size_t buffer_size = | ||||
|       DEFAULT_SR_SIZE + reports_.size() * RtcpReportBlock::kLength; | ||||
|   if (!buffer_ || buffer_size != size_) { | ||||
|     delete[] buffer_; | ||||
|     buffer_ = nullptr; | ||||
|   } | ||||
|   report_blocks_.push_back(block); | ||||
|   return true; | ||||
|  | ||||
|   buffer_ = new uint8_t[buffer_size]; | ||||
|   size_ = buffer_size; | ||||
|  | ||||
|   int pos = | ||||
|       rtcp_common_header_.Create(DEFAULT_RTCP_VERSION, 0, DEFAULT_SR_BLOCK_NUM, | ||||
|                                  RTCP_TYPE::SR, buffer_size, buffer_); | ||||
|  | ||||
|   buffer_[pos++] = sender_info_.sender_ssrc >> 24 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.sender_ssrc >> 16 & 0xFF; | ||||
|   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_lsw >> 24 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.ntp_ts_lsw >> 16 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.ntp_ts_lsw >> 8 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.ntp_ts_lsw & 0xFF; | ||||
|  | ||||
|   buffer_[pos++] = sender_info_.rtp_ts >> 24 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.rtp_ts >> 16 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.rtp_ts >> 8 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.rtp_ts & 0xFF; | ||||
|  | ||||
|   buffer_[pos++] = sender_info_.sender_packet_count >> 24 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.sender_packet_count >> 16 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.sender_packet_count >> 8 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.sender_packet_count & 0xFF; | ||||
|  | ||||
|   buffer_[pos++] = sender_info_.sender_octet_count >> 24 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.sender_octet_count >> 16 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.sender_octet_count >> 8 & 0xFF; | ||||
|   buffer_[pos++] = sender_info_.sender_octet_count & 0xFF; | ||||
|  | ||||
|   for (auto &report : reports_) { | ||||
|     pos += report.Create(buffer_ + pos); | ||||
|   } | ||||
|  | ||||
|   return buffer_; | ||||
| } | ||||
|  | ||||
| bool SenderReport::SetReportBlocks(std::vector<ReportBlock> blocks) { | ||||
|   if (blocks.size() > kMaxNumberOfReportBlocks) { | ||||
|     LOG_WARN("Too many report blocks ({}) for sender report.", blocks.size()); | ||||
|     return false; | ||||
| size_t SenderReport::Parse() { | ||||
|   reports_.clear(); | ||||
|   size_t pos = rtcp_common_header_.Parse(buffer_); | ||||
|  | ||||
|   sender_info_.sender_ssrc = (buffer_[pos] << 24) + (buffer_[pos + 1] << 16) + | ||||
|                              (buffer_[pos + 2] << 8) + buffer_[pos + 3]; | ||||
|   pos += 4; | ||||
|   sender_info_.ntp_ts_msw = (buffer_[pos] << 24) + (buffer_[pos + 1] << 16) + | ||||
|                             (buffer_[pos + 2] << 8) + buffer_[pos + 3]; | ||||
|   pos += 4; | ||||
|   sender_info_.ntp_ts_lsw = (buffer_[pos] << 24) + (buffer_[pos + 1] << 16) + | ||||
|                             (buffer_[pos + 2] << 8) + buffer_[pos + 3]; | ||||
|   pos += 4; | ||||
|   sender_info_.rtp_ts = (buffer_[pos] << 24) + (buffer_[pos + 1] << 16) + | ||||
|                         (buffer_[pos + 2] << 8) + buffer_[pos + 3]; | ||||
|   pos += 4; | ||||
|   sender_info_.sender_packet_count = (buffer_[pos] << 24) + | ||||
|                                      (buffer_[pos + 1] << 16) + | ||||
|                                      (buffer_[pos + 2] << 8) + buffer_[pos + 3]; | ||||
|   pos += 4; | ||||
|   sender_info_.sender_octet_count = (buffer_[pos] << 24) + | ||||
|                                     (buffer_[pos + 1] << 16) + | ||||
|                                     (buffer_[pos + 2] << 8) + buffer_[pos + 3]; | ||||
|   pos += 4; | ||||
|  | ||||
|   for (int i = 0; i < rtcp_common_header_.CountOrFormat(); i++) { | ||||
|     RtcpReportBlock report; | ||||
|     pos += report.Parse(buffer_ + pos); | ||||
|     reports_.emplace_back(std::move(report)); | ||||
|   } | ||||
|   report_blocks_ = std::move(blocks); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
|   return pos; | ||||
| } | ||||
| @@ -1,71 +1,99 @@ | ||||
| /* | ||||
|  * @Author: DI JUNKUN | ||||
|  * @Date: 2025-02-17 | ||||
|  * @Date: 2025-02-18 | ||||
|  * Copyright (c) 2025 by DI JUNKUN, All Rights Reserved. | ||||
|  */ | ||||
|  | ||||
| #ifndef _SENDER_REPORT_H_ | ||||
| #define _SENDER_REPORT_H_ | ||||
|  | ||||
| // SR | ||||
| //  0                   1                   2                   3 | ||||
| //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |V=2|P|   RC    |   PT=SR=200   |            length             | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                        SSRC of sender                         | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |              NTP timestamp, most significant word             | sender | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ info | ||||
| // |             NTP timestamp, least significant word             | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                         RTP timestamp                         | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                     sender's packet count                     | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                      sender's octet count                     | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                 SSRC_1 (SSRC of first source)                 | report | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | ||||
| // | fraction lost |       cumulative number of packets lost       | 1 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |           extended highest sequence number received           | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                      interarrival jitter                      | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                         last SR (LSR)                         | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                   delay since last SR (DLSR)                  | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                 SSRC_2 (SSRC of second source)                | report | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | ||||
| // :                               ...                             : 2 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #include "api/ntp/ntp_time.h" | ||||
| #include "report_block.h" | ||||
| #include "rtcp_packet.h" | ||||
| #include "rtcp_common_header.h" | ||||
| #include "rtcp_report_block.h" | ||||
|  | ||||
| class CommonHeader; | ||||
|  | ||||
| class SenderReport : public RtcpPacket { | ||||
| class SenderReport { | ||||
|  public: | ||||
|   static constexpr uint8_t kPacketType = 200; | ||||
|   static constexpr size_t kMaxNumberOfReportBlocks = 0x1f; | ||||
|   typedef struct { | ||||
|     uint32_t sender_ssrc : 32; | ||||
|     uint64_t ntp_ts_msw : 64; | ||||
|     uint64_t ntp_ts_lsw : 64; | ||||
|     uint32_t rtp_ts : 32; | ||||
|     uint32_t sender_packet_count : 32; | ||||
|     uint32_t sender_octet_count : 32; | ||||
|   } SenderInfo; | ||||
|  | ||||
|  public: | ||||
|   SenderReport(); | ||||
|   SenderReport(const SenderReport&); | ||||
|   SenderReport(SenderReport&&); | ||||
|   SenderReport& operator=(const SenderReport&); | ||||
|   SenderReport& operator=(SenderReport&&); | ||||
|   ~SenderReport() override; | ||||
|   ~SenderReport(); | ||||
|  | ||||
|   // Parse assumes header is already parsed and validated. | ||||
|   bool Parse(const CommonHeader& packet); | ||||
|  | ||||
|   void SetNtp(webrtc::NtpTime ntp) { ntp_ = ntp; } | ||||
|   void SetRtpTimestamp(uint32_t rtp_timestamp) { | ||||
|     rtp_timestamp_ = rtp_timestamp; | ||||
|  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; | ||||
|   } | ||||
|   void SetPacketCount(uint32_t packet_count) { | ||||
|     sender_packet_count_ = packet_count; | ||||
|   void SetTimestamp(uint32_t timestamp) { sender_info_.rtp_ts = timestamp; } | ||||
|   void SetSenderPacketCount(uint32_t packet_count) { | ||||
|     sender_info_.sender_packet_count = packet_count; | ||||
|   } | ||||
|   void SetOctetCount(uint32_t octet_count) { | ||||
|     sender_octet_count_ = octet_count; | ||||
|   void SetSenderOctetCount(uint32_t octet_count) { | ||||
|     sender_info_.sender_octet_count = octet_count; | ||||
|   } | ||||
|   bool AddReportBlock(const ReportBlock& block); | ||||
|   bool SetReportBlocks(std::vector<ReportBlock> blocks); | ||||
|   void ClearReportBlocks() { report_blocks_.clear(); } | ||||
|   void SetReportBlock(RtcpReportBlock &rtcp_report_block); | ||||
|   void SetReportBlocks(std::vector<RtcpReportBlock> &rtcp_report_blocks); | ||||
|  | ||||
|   webrtc::NtpTime ntp() const { return ntp_; } | ||||
|   uint32_t rtp_timestamp() const { return rtp_timestamp_; } | ||||
|   uint32_t sender_packet_count() const { return sender_packet_count_; } | ||||
|   uint32_t sender_octet_count() const { return sender_octet_count_; } | ||||
|  public: | ||||
|   const uint8_t *Create(); | ||||
|   size_t Parse(); | ||||
|  | ||||
|   const std::vector<ReportBlock>& report_blocks() const { | ||||
|     return report_blocks_; | ||||
|   } | ||||
|  | ||||
|   size_t BlockLength() const override; | ||||
|  | ||||
|   bool Create(uint8_t* packet, size_t* index, size_t max_length, | ||||
|               PacketReadyCallback callback) const override; | ||||
|   // Entire RTP buffer | ||||
|   const uint8_t *Buffer() const { return buffer_; } | ||||
|   size_t Size() const { return size_; } | ||||
|  | ||||
|  private: | ||||
|   static constexpr size_t kSenderBaseLength = 24; | ||||
|   RtcpCommonHeader rtcp_common_header_; | ||||
|   SenderInfo sender_info_; | ||||
|   std::vector<RtcpReportBlock> reports_; | ||||
|  | ||||
|   webrtc::NtpTime ntp_; | ||||
|   uint32_t rtp_timestamp_; | ||||
|   uint32_t sender_packet_count_; | ||||
|   uint32_t sender_octet_count_; | ||||
|   std::vector<ReportBlock> report_blocks_; | ||||
|   // Entire RTCP buffer | ||||
|   uint8_t *buffer_; | ||||
|   size_t size_; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -1,31 +0,0 @@ | ||||
| #include "rtcp_receiver_report.h" | ||||
|  | ||||
| RtcpReceiverReport::RtcpReceiverReport() { | ||||
|   buffer_ = new uint8_t[DEFAULT_RR_SIZE]; | ||||
|   size_ = DEFAULT_RR_SIZE; | ||||
| } | ||||
|  | ||||
| RtcpReceiverReport::~RtcpReceiverReport() { | ||||
|   if (buffer_) { | ||||
|     delete buffer_; | ||||
|     buffer_ = nullptr; | ||||
|   } | ||||
|  | ||||
|   size_ = 0; | ||||
| } | ||||
|  | ||||
| void RtcpReceiverReport::SetReportBlock(RtcpReportBlock &rtcp_report_block) { | ||||
|   reports_.push_back(rtcp_report_block); | ||||
| } | ||||
|  | ||||
| void RtcpReceiverReport::SetReportBlock( | ||||
|     std::vector<RtcpReportBlock> &rtcp_report_blocks) { | ||||
|   reports_ = rtcp_report_blocks; | ||||
| } | ||||
|  | ||||
| const uint8_t *RtcpReceiverReport::Encode() { | ||||
|   rtcp_header_.Encode(DEFAULT_RTCP_VERSION, 0, DEFAULT_RR_BLOCK_NUM, | ||||
|                       RTCP_TYPE::RR, DEFAULT_RR_SIZE, buffer_); | ||||
|  | ||||
|   return buffer_; | ||||
| } | ||||
| @@ -1,62 +0,0 @@ | ||||
| #ifndef _RTCP_RECEIVER_REPORT_H_ | ||||
| #define _RTCP_RECEIVER_REPORT_H_ | ||||
|  | ||||
| // RR | ||||
| //  0                   1                   2                   3 | ||||
| //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |V=2|P|   RC    |   PT=SR=200   |            length             | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                     SSRC of packet sender                     | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                 SSRC_1 (SSRC of first source)                 | report | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | ||||
| // | fraction lost |       cumulative number of packets lost       | 1 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |           extended highest sequence number received           | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                      interarrival jitter                      | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                         last SR (LSR)                         | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                   delay since last SR (DLSR)                  | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                 SSRC_2 (SSRC of second source)                | report | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | ||||
| // :                               ...                             : 2 | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                  profile-specific extensions                  | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #include "rtcp_header.h" | ||||
| #include "rtcp_typedef.h" | ||||
|  | ||||
| class RtcpReceiverReport { | ||||
|  public: | ||||
|   RtcpReceiverReport(); | ||||
|   ~RtcpReceiverReport(); | ||||
|  | ||||
|  public: | ||||
|   void SetReportBlock(RtcpReportBlock &rtcp_report_block); | ||||
|   void SetReportBlock(std::vector<RtcpReportBlock> &rtcp_report_blocks); | ||||
|  | ||||
|  public: | ||||
|   const uint8_t *Encode(); | ||||
|   size_t Decode(); | ||||
|  | ||||
|   // Entire RTP buffer | ||||
|   const uint8_t *Buffer() const { return buffer_; } | ||||
|   size_t Size() const { return size_; } | ||||
|  | ||||
|  private: | ||||
|   RtcpHeader rtcp_header_; | ||||
|   std::vector<RtcpReportBlock> reports_; | ||||
|  | ||||
|   // Entire RTCP buffer | ||||
|   uint8_t *buffer_ = nullptr; | ||||
|   size_t size_ = 0; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -1,69 +0,0 @@ | ||||
| #include "rtcp_sender_report.h" | ||||
|  | ||||
| RtcpSenderReport::RtcpSenderReport() { | ||||
|   buffer_ = new uint8_t[DEFAULT_SR_SIZE]; | ||||
|   size_ = DEFAULT_SR_SIZE; | ||||
| } | ||||
|  | ||||
| RtcpSenderReport::~RtcpSenderReport() { | ||||
|   if (buffer_) { | ||||
|     delete buffer_; | ||||
|     buffer_ = nullptr; | ||||
|   } | ||||
|  | ||||
|   size_ = 0; | ||||
| } | ||||
|  | ||||
| void RtcpSenderReport::SetSenderInfo(SenderInfo &sender_info) { | ||||
|   sender_info_.sender_ssrc = sender_info.sender_ssrc; | ||||
|   sender_info_.ntp_ts_msw = sender_info.ntp_ts_msw; | ||||
|   sender_info_.ntp_ts_lsw = sender_info.ntp_ts_lsw; | ||||
|   sender_info_.rtp_ts = sender_info.rtp_ts; | ||||
|   sender_info_.sender_packet_count = sender_info.sender_packet_count; | ||||
|   sender_info_.sender_octet_count = sender_info.sender_octet_count; | ||||
| } | ||||
|  | ||||
| void RtcpSenderReport::SetReportBlock(RtcpReportBlock &rtcp_report_block) { | ||||
|   reports_.push_back(rtcp_report_block); | ||||
| } | ||||
|  | ||||
| void RtcpSenderReport::SetReportBlock( | ||||
|     std::vector<RtcpReportBlock> &rtcp_report_blocks) { | ||||
|   reports_ = rtcp_report_blocks; | ||||
| } | ||||
|  | ||||
| const uint8_t *RtcpSenderReport::Encode() { | ||||
|   int pos = rtcp_header_.Encode(DEFAULT_RTCP_VERSION, 0, DEFAULT_SR_BLOCK_NUM, | ||||
|                                 RTCP_TYPE::SR, DEFAULT_SR_SIZE, buffer_); | ||||
|  | ||||
|   buffer_[pos] = sender_info_.sender_ssrc >> 24 & 0xFF; | ||||
|   buffer_[pos + 1] = sender_info_.sender_ssrc >> 16 & 0xFF; | ||||
|   buffer_[pos + 2] = sender_info_.sender_ssrc >> 8 & 0xFF; | ||||
|   buffer_[pos + 3] = sender_info_.sender_ssrc & 0xFF; | ||||
|  | ||||
|   buffer_[pos + 4] = sender_info_.ntp_ts_msw >> 56 & 0xFF; | ||||
|   buffer_[pos + 5] = sender_info_.ntp_ts_msw >> 48 & 0xFF; | ||||
|   buffer_[pos + 6] = sender_info_.ntp_ts_msw >> 40 & 0xFF; | ||||
|   buffer_[pos + 7] = sender_info_.ntp_ts_msw >> 32 & 0xFF; | ||||
|   buffer_[pos + 8] = sender_info_.ntp_ts_lsw >> 24 & 0xFF; | ||||
|   buffer_[pos + 9] = sender_info_.ntp_ts_lsw >> 16 & 0xFF; | ||||
|   buffer_[pos + 10] = sender_info_.ntp_ts_lsw >> 8 & 0xFF; | ||||
|   buffer_[pos + 11] = sender_info_.ntp_ts_lsw & 0xFF; | ||||
|  | ||||
|   buffer_[pos + 12] = sender_info_.rtp_ts >> 24 & 0xFF; | ||||
|   buffer_[pos + 13] = sender_info_.rtp_ts >> 16 & 0xFF; | ||||
|   buffer_[pos + 14] = sender_info_.rtp_ts >> 8 & 0xFF; | ||||
|   buffer_[pos + 15] = sender_info_.rtp_ts & 0xFF; | ||||
|  | ||||
|   buffer_[pos + 16] = sender_info_.sender_packet_count >> 24 & 0xFF; | ||||
|   buffer_[pos + 17] = sender_info_.sender_packet_count >> 16 & 0xFF; | ||||
|   buffer_[pos + 18] = sender_info_.sender_packet_count >> 8 & 0xFF; | ||||
|   buffer_[pos + 19] = sender_info_.sender_packet_count & 0xFF; | ||||
|  | ||||
|   buffer_[pos + 20] = sender_info_.sender_octet_count >> 24 & 0xFF; | ||||
|   buffer_[pos + 21] = sender_info_.sender_octet_count >> 16 & 0xFF; | ||||
|   buffer_[pos + 22] = sender_info_.sender_octet_count >> 8 & 0xFF; | ||||
|   buffer_[pos + 23] = sender_info_.sender_octet_count & 0xFF; | ||||
|  | ||||
|   return buffer_; | ||||
| } | ||||
| @@ -1,72 +0,0 @@ | ||||
| #ifndef _RTCP_SENDER_REPORT_H_ | ||||
| #define _RTCP_SENDER_REPORT_H_ | ||||
|  | ||||
| // SR | ||||
| //  0                   1                   2                   3 | ||||
| //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |V=2|P|   RC    |   PT=SR=200   |            length             | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                        SSRC of sender                         | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |              NTP timestamp, most significant word             | sender | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ info | ||||
| // |             NTP timestamp, least significant word             | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                         RTP timestamp                         | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                     sender's packet count                     | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                      sender's octet count                     | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                 SSRC_1 (SSRC of first source)                 | report | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | ||||
| // | fraction lost |       cumulative number of packets lost       | 1 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |           extended highest sequence number received           | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                      interarrival jitter                      | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                         last SR (LSR)                         | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |                   delay since last SR (DLSR)                  | | ||||
| // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | ||||
| // |                 SSRC_2 (SSRC of second source)                | report | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block | ||||
| // :                               ...                             : 2 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #include "rtcp_header.h" | ||||
| #include "rtcp_typedef.h" | ||||
|  | ||||
| class RtcpSenderReport { | ||||
|  public: | ||||
|   RtcpSenderReport(); | ||||
|   ~RtcpSenderReport(); | ||||
|  | ||||
|  public: | ||||
|   void SetSenderInfo(SenderInfo &sender_info); | ||||
|   void SetReportBlock(RtcpReportBlock &rtcp_report_block); | ||||
|   void SetReportBlock(std::vector<RtcpReportBlock> &rtcp_report_blocks); | ||||
|  | ||||
|  public: | ||||
|   const uint8_t *Encode(); | ||||
|   size_t Decode(); | ||||
|  | ||||
|   // Entire RTP buffer | ||||
|   const uint8_t *Buffer() const { return buffer_; } | ||||
|   size_t Size() const { return size_; } | ||||
|  | ||||
|  private: | ||||
|   RtcpHeader rtcp_header_; | ||||
|   SenderInfo sender_info_; | ||||
|   std::vector<RtcpReportBlock> reports_; | ||||
|  | ||||
|   // Entire RTCP buffer | ||||
|   uint8_t *buffer_ = nullptr; | ||||
|   size_t size_ = 0; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -1,43 +0,0 @@ | ||||
| #ifndef _RTCP_TYPEDEF_H_ | ||||
| #define _RTCP_TYPEDEF_H_ | ||||
|  | ||||
| #include <cstddef> | ||||
| #include <cstdint> | ||||
|  | ||||
| #define DEFAULT_RTCP_VERSION 2 | ||||
| #define DEFAULT_RTCP_HEADER_SIZE 4 | ||||
|  | ||||
| #define DEFAULT_SR_BLOCK_NUM 1 | ||||
| #define DEFAULT_SR_SIZE 52 | ||||
| #define DEFAULT_RR_BLOCK_NUM 1 | ||||
| #define DEFAULT_RR_SIZE 32 | ||||
|  | ||||
| typedef enum { | ||||
|   UNKNOWN = 0, | ||||
|   SR = 200, | ||||
|   RR = 201, | ||||
|   SDES = 202, | ||||
|   BYE = 203, | ||||
|   APP = 204 | ||||
| } RTCP_TYPE; | ||||
|  | ||||
| typedef struct { | ||||
|   uint32_t sender_ssrc : 32; | ||||
|   uint64_t ntp_ts_msw : 64; | ||||
|   uint64_t ntp_ts_lsw : 64; | ||||
|   uint32_t rtp_ts : 32; | ||||
|   uint32_t sender_packet_count : 32; | ||||
|   uint32_t sender_octet_count : 32; | ||||
| } SenderInfo; | ||||
|  | ||||
| typedef struct { | ||||
|   uint32_t source_ssrc : 32; | ||||
|   uint8_t fraction_lost : 8; | ||||
|   uint32_t cumulative_lost : 24; | ||||
|   uint32_t extended_high_seq_num : 32; | ||||
|   uint32_t jitter : 32; | ||||
|   uint32_t lsr : 32; | ||||
|   uint32_t dlsr : 32; | ||||
| } RtcpReportBlock; | ||||
|  | ||||
| #endif | ||||
| @@ -223,12 +223,12 @@ bool IceTransport::ParseRtcpPacket(const uint8_t *buffer, size_t size, | ||||
|   } | ||||
|  | ||||
|   switch (rtcp_block.type()) { | ||||
|     case RtcpPacket::PAYLOAD_TYPE::SR: | ||||
|     case RtcpPacket::RtcpPayloadType::SR: | ||||
|       LOG_INFO("Sender report"); | ||||
|       // valid = HandleSenderReport(rtcp_block, rtcp_packet_info); | ||||
|       // received_blocks[rtcp_packet_info->remote_ssrc].sender_report = true; | ||||
|       break; | ||||
|     case RtcpPacket::PAYLOAD_TYPE::RR: | ||||
|     case RtcpPacket::RtcpPayloadType::RR: | ||||
|       LOG_INFO("Receiver report"); | ||||
|       // valid = HandleReceiverReport(rtcp_block, rtcp_packet_info); | ||||
|       break; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user