rtcp: Move rtcp header construction to rtcp packets module

This commit is contained in:
Joni Räsänen 2022-07-07 19:51:13 +03:00
parent 8581ac512a
commit 55ce9aa419
4 changed files with 63 additions and 52 deletions

View File

@ -346,10 +346,6 @@ namespace uvgrtp {
void zero_stats(uvgrtp::receiver_statistics *stats); void zero_stats(uvgrtp::receiver_statistics *stats);
/* Set the first four or eight bytes of an RTCP packet */
rtp_error_t construct_rtcp_header(size_t packet_size, uint8_t* frame,
uint16_t secondField, uvgrtp::frame::RTCP_FRAME_TYPE frame_type, bool addLocalSSRC);
/* read the header values from rtcp packet */ /* read the header values from rtcp packet */
void read_rtcp_header(const uint8_t* packet, uvgrtp::frame::rtcp_header& header); void read_rtcp_header(const uint8_t* packet, uvgrtp::frame::rtcp_header& header);
void read_reports(const uint8_t* packet, size_t size, uint8_t count, bool has_sender_block, void read_reports(const uint8_t* packet, size_t size, uint8_t count, bool has_sender_block,

View File

@ -1285,33 +1285,6 @@ rtp_error_t uvgrtp::rtcp::handle_sender_report_packet(uint8_t* packet, size_t si
return RTP_OK; return RTP_OK;
} }
rtp_error_t uvgrtp::rtcp::construct_rtcp_header(size_t packet_size,
uint8_t* frame,
uint16_t secondField,
uvgrtp::frame::RTCP_FRAME_TYPE frame_type,
bool add_local_ssrc)
{
if (packet_size > UINT16_MAX)
{
LOG_ERROR("RTCP receiver report packet size too large!");
return RTP_GENERIC_ERROR;
}
// header |V=2|P| SC | PT | length |
frame[0] = (2 << 6) | (0 << 5) | secondField;
frame[1] = frame_type;
// The RTCP header length field is measured in 32-bit words - 1
*(uint16_t*)&frame[2] = htons((uint16_t)packet_size/sizeof(uint32_t) - 1);
if (add_local_ssrc)
{
*(uint32_t*)&frame[RTCP_HEADER_SIZE] = htonl(ssrc_);
}
return RTP_OK;
}
void uvgrtp::rtcp::read_rtcp_header(const uint8_t* packet, uvgrtp::frame::rtcp_header& header) void uvgrtp::rtcp::read_rtcp_header(const uint8_t* packet, uvgrtp::frame::rtcp_header& header)
{ {
header.version = (packet[0] >> 6) & 0x3; header.version = (packet[0] >> 6) & 0x3;
@ -1430,7 +1403,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()
frame_size += SENDER_INFO_SIZE; frame_size += SENDER_INFO_SIZE;
frame = new uint8_t[frame_size]; frame = new uint8_t[frame_size];
memset(frame, 0, frame_size); memset(frame, 0, frame_size);
construct_rtcp_header(frame_size, frame, reports, uvgrtp::frame::RTCP_FT_SR, true); construct_rtcp_header(frame_size, frame, reports, uvgrtp::frame::RTCP_FT_SR, ssrc_);
// add sender info to packet // add sender info to packet
if (clock_start_ == 0) if (clock_start_ == 0)
@ -1456,7 +1429,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()
LOG_DEBUG("Generating RTCP Receiver report"); LOG_DEBUG("Generating RTCP Receiver report");
frame = new uint8_t[frame_size]; frame = new uint8_t[frame_size];
memset(frame, 0, frame_size); memset(frame, 0, frame_size);
construct_rtcp_header(frame_size, frame, reports, uvgrtp::frame::RTCP_FT_RR, true); construct_rtcp_header(frame_size, frame, reports, uvgrtp::frame::RTCP_FT_RR, ssrc_);
} }
// the report blocks for sender or receiver report. Both have same reports. // the report blocks for sender or receiver report. Both have same reports.
@ -1518,7 +1491,7 @@ rtp_error_t uvgrtp::rtcp::send_sdes_packet(const std::vector<uvgrtp::frame::rtcp
rtp_error_t ret = RTP_OK; rtp_error_t ret = RTP_OK;
// this already adds our ssrc // this already adds our ssrc
construct_rtcp_header(frame_size, frame, num_receivers_, uvgrtp::frame::RTCP_FT_SDES, true); construct_rtcp_header(frame_size, frame, num_receivers_, uvgrtp::frame::RTCP_FT_SDES, ssrc_);
int ptr = RTCP_HEADER_SIZE + SSRC_CSRC_SIZE; int ptr = RTCP_HEADER_SIZE + SSRC_CSRC_SIZE;
construct_sdes_packet(frame, ptr, items); construct_sdes_packet(frame, ptr, items);
@ -1538,8 +1511,9 @@ rtp_error_t uvgrtp::rtcp::send_bye_packet(std::vector<uint32_t> ssrcs)
memset(frame, 0, frame_size); memset(frame, 0, frame_size);
rtp_error_t ret = RTP_OK; rtp_error_t ret = RTP_OK;
// TODO: Should this be our or peer SSRC? In others, its ours
if ((ret = construct_rtcp_header(frame_size, frame, (ssrcs.size() & 0x1f), if ((ret = construct_rtcp_header(frame_size, frame, (ssrcs.size() & 0x1f),
uvgrtp::frame::RTCP_FT_BYE, false)) != RTP_OK) uvgrtp::frame::RTCP_FT_BYE, 0)) != RTP_OK)
{ {
return ret; return ret;
} }
@ -1564,7 +1538,7 @@ rtp_error_t uvgrtp::rtcp::send_app_packet(const char* name, uint8_t subtype,
memset(frame, 0, frame_size); memset(frame, 0, frame_size);
if ((ret = construct_rtcp_header(frame_size, frame, (subtype & 0x1f), if ((ret = construct_rtcp_header(frame_size, frame, (subtype & 0x1f),
uvgrtp::frame::RTCP_FT_APP, true)) != RTP_OK) uvgrtp::frame::RTCP_FT_APP, ssrc_)) != RTP_OK)
{ {
return ret; return ret;
} }

View File

@ -3,7 +3,35 @@
#include "uvgrtp/debug.hh" #include "uvgrtp/debug.hh"
size_t get_sdes_packet_size(const std::vector<uvgrtp::frame::rtcp_sdes_item>& items) {
rtp_error_t uvgrtp::construct_rtcp_header(size_t packet_size,
uint8_t* frame,
uint16_t secondField,
uvgrtp::frame::RTCP_FRAME_TYPE frame_type,
uint32_t ssrc)
{
if (packet_size > UINT16_MAX)
{
LOG_ERROR("RTCP receiver report packet size too large!");
return RTP_GENERIC_ERROR;
}
// header |V=2|P| SC | PT | length |
frame[0] = (2 << 6) | (0 << 5) | secondField;
frame[1] = frame_type;
// The RTCP header length field is measured in 32-bit words - 1
*(uint16_t*)&frame[2] = htons((uint16_t)packet_size / sizeof(uint32_t) - 1);
if (ssrc)
{
*(uint32_t*)&frame[RTCP_HEADER_SIZE] = htonl(ssrc);
}
return RTP_OK;
}
size_t uvgrtp::get_sdes_packet_size(const std::vector<uvgrtp::frame::rtcp_sdes_item>& items) {
size_t frame_size = 0; size_t frame_size = 0;
/* We currently only support having one source. If uvgRTP is used in a mixer, multiple sources /* We currently only support having one source. If uvgRTP is used in a mixer, multiple sources
@ -27,13 +55,16 @@ size_t get_sdes_packet_size(const std::vector<uvgrtp::frame::rtcp_sdes_item>& it
return frame_size; return frame_size;
} }
size_t get_app_packet_size(size_t payload_len) size_t uvgrtp::get_app_packet_size(size_t payload_len)
{ {
return RTCP_HEADER_SIZE + SSRC_CSRC_SIZE + APP_NAME_SIZE + payload_len; return RTCP_HEADER_SIZE + SSRC_CSRC_SIZE + APP_NAME_SIZE + payload_len;
} }
void construct_sdes_packet(uint8_t* frame, int& ptr, void uvgrtp::construct_sdes_packet(uint8_t* frame, int& ptr,
const std::vector<uvgrtp::frame::rtcp_sdes_item>& items) { const std::vector<uvgrtp::frame::rtcp_sdes_item>& items) {
for (auto& item : items) for (auto& item : items)
{ {
if (item.length <= 255) if (item.length <= 255)
@ -46,7 +77,7 @@ void construct_sdes_packet(uint8_t* frame, int& ptr,
} }
} }
void construct_app_packet(uint8_t* frame, int& ptr, void uvgrtp::construct_app_packet(uint8_t* frame, int& ptr,
const char* name, const uint8_t* payload, size_t payload_len) const char* name, const uint8_t* payload, size_t payload_len)
{ {
memcpy(&frame[RTCP_HEADER_SIZE + SSRC_CSRC_SIZE], name, APP_NAME_SIZE); memcpy(&frame[RTCP_HEADER_SIZE + SSRC_CSRC_SIZE], name, APP_NAME_SIZE);

View File

@ -5,16 +5,26 @@
#include <vector> #include <vector>
const uint16_t RTCP_HEADER_SIZE = 4; namespace uvgrtp
const uint16_t SSRC_CSRC_SIZE = 4; {
const uint16_t SENDER_INFO_SIZE = 20; const uint16_t RTCP_HEADER_SIZE = 4;
const uint16_t REPORT_BLOCK_SIZE = 24; const uint16_t SSRC_CSRC_SIZE = 4;
const uint16_t APP_NAME_SIZE = 4; const uint16_t SENDER_INFO_SIZE = 20;
const uint16_t REPORT_BLOCK_SIZE = 24;
const uint16_t APP_NAME_SIZE = 4;
size_t get_sdes_packet_size(const std::vector<uvgrtp::frame::rtcp_sdes_item>& items); /* Set the first four or eight bytes of an RTCP packet */
size_t get_app_packet_size(size_t payload_len); rtp_error_t construct_rtcp_header(size_t packet_size,
uint8_t* frame,
uint16_t secondField,
uvgrtp::frame::RTCP_FRAME_TYPE frame_type,
uint32_t ssrc);
void construct_sdes_packet(uint8_t* frame, int& ptr, size_t get_sdes_packet_size(const std::vector<uvgrtp::frame::rtcp_sdes_item>& items);
const std::vector<uvgrtp::frame::rtcp_sdes_item>& items); size_t get_app_packet_size(size_t payload_len);
void construct_app_packet(uint8_t* frame, int& ptr,
const char* name, const uint8_t* payload, size_t payload_len); void construct_sdes_packet(uint8_t* frame, int& ptr,
const std::vector<uvgrtp::frame::rtcp_sdes_item>& items);
void construct_app_packet(uint8_t* frame, int& ptr,
const char* name, const uint8_t* payload, size_t payload_len);
}