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