common: Use the correct MTU size for ring buffer

Using the new correct MTU size seems to work. This enables much more
slots in the ring buffer, which in turn helps a lot with receiver
performance.
This commit is contained in:
Joni Räsänen 2022-09-12 13:59:03 +03:00
parent 9df2d0d459
commit 21c9528a0e
8 changed files with 45 additions and 30 deletions

View File

@ -24,9 +24,12 @@ namespace uvgrtp {
// the default MTU size for ethernet, can be adjusted with rcc flags
constexpr uint16_t DEFAULT_MTU_SIZE = 1500;
constexpr uint16_t MAX_IPV4_PAYLOAD = DEFAULT_MTU_SIZE - IPV4_HDR_SIZE - UDP_HDR_SIZE;
constexpr uint16_t MAX_IPV6_PAYLOAD = DEFAULT_MTU_SIZE - IPV6_HDR_SIZE - UDP_HDR_SIZE;
// here we ignore ethernet frame header size since it is not included in MTU
constexpr uint16_t MAX_IPV4_PAYLOAD = DEFAULT_MTU_SIZE - IPV4_HDR_SIZE - UDP_HDR_SIZE - RTP_HDR_SIZE;
constexpr uint16_t MAX_IPV6_PAYLOAD = DEFAULT_MTU_SIZE - IPV6_HDR_SIZE - UDP_HDR_SIZE - RTP_HDR_SIZE;
constexpr uint16_t MAX_IPV4_MEDIA_PAYLOAD = MAX_IPV4_PAYLOAD - RTP_HDR_SIZE;
constexpr uint16_t MAX_IPV6_MEDIA_PAYLOAD = MAX_IPV6_PAYLOAD - RTP_HDR_SIZE;
constexpr int PKT_MAX_DELAY_MS = 500;
}

View File

@ -47,8 +47,8 @@ uvgrtp::frame::rtp_frame *uvgrtp::frame::alloc_rtp_frame(size_t payload_len, siz
if ((frame = uvgrtp::frame::alloc_rtp_frame()) == nullptr)
return nullptr;
frame->probation = new uint8_t[pz_size * MAX_IPV4_PAYLOAD + payload_len];
frame->probation_len = pz_size * MAX_IPV4_PAYLOAD;
frame->probation = new uint8_t[pz_size * MAX_IPV4_MEDIA_PAYLOAD + payload_len];
frame->probation_len = pz_size * MAX_IPV4_MEDIA_PAYLOAD;
frame->probation_off = 0;
frame->payload = (uint8_t *)frame->probation + frame->probation_len;

View File

@ -399,7 +399,7 @@ rtp_error_t uvgrtp::media_stream::start_components()
}
if (rce_flags_ & RCE_SRTP_AUTHENTICATE_RTP)
rtp_->set_payload_size(MAX_IPV4_PAYLOAD - UVG_AUTH_TAG_LENGTH);
rtp_->set_payload_size(MAX_IPV4_MEDIA_PAYLOAD - UVG_AUTH_TAG_LENGTH);
initialized_ = true;
return reception_flow_->start(socket_, rce_flags_);
@ -615,11 +615,11 @@ rtp_error_t uvgrtp::media_stream::configure_ctx(int rcc_flag, ssize_t value)
rtp_->set_payload_size(value - hdr);
// auth tag is always included with SRTP and RTCP has a header for each packet within a compound frame
rtcp_->set_payload_size(value - (IPV4_HDR_SIZE + UDP_HDR_SIZE));
rtcp_->set_payload_size( value - (IPV4_HDR_SIZE + UDP_HDR_SIZE));
reception_flow_->set_payload_size(value - (IPV4_HDR_SIZE + UDP_HDR_SIZE)); // largest packet we can get from socket
break;
}
case RCC_FPS_ENUMERATOR: {
fps_enumerator_ = value;
@ -630,7 +630,6 @@ rtp_error_t uvgrtp::media_stream::configure_ctx(int rcc_flag, ssize_t value)
media_->set_fps(fps_enumerator_, fps_denominator_);
break;
}
case RCC_FPS_DENOMINATOR: {
fps_denominator_ = value;

View File

@ -19,11 +19,8 @@
#include <cstring>
constexpr size_t RECV_BUFFER_SIZE = UINT16_MAX - uvgrtp::IPV4_HDR_SIZE - uvgrtp::UDP_HDR_SIZE;
constexpr size_t DEFAULT_INITIAL_BUFFER_SIZE = 4194304;
uvgrtp::reception_flow::reception_flow() :
recv_hook_arg_(nullptr),
recv_hook_(nullptr),
@ -32,7 +29,8 @@ uvgrtp::reception_flow::reception_flow() :
ring_buffer_(),
ring_read_index_(-1), // invalid first index that will increase to a valid one
last_ring_write_index_(-1),
buffer_size_kbytes_(DEFAULT_INITIAL_BUFFER_SIZE)
buffer_size_kbytes_(DEFAULT_INITIAL_BUFFER_SIZE),
payload_size_(MAX_IPV4_PAYLOAD)
{
create_ring_buffer();
}
@ -58,11 +56,11 @@ void uvgrtp::reception_flow::clear_frames()
void uvgrtp::reception_flow::create_ring_buffer()
{
destroy_ring_buffer();
size_t elements = buffer_size_kbytes_ / RECV_BUFFER_SIZE;
size_t elements = buffer_size_kbytes_ / payload_size_;
for (size_t i = 0; i < elements; ++i)
{
ring_buffer_.push_back({ new uint8_t[RECV_BUFFER_SIZE] , 0 });
ring_buffer_.push_back({ new uint8_t[payload_size_] , 0 });
}
}
@ -81,6 +79,12 @@ void uvgrtp::reception_flow::set_buffer_size(const ssize_t& value)
create_ring_buffer();
}
void uvgrtp::reception_flow::set_payload_size(const size_t& value)
{
payload_size_ = value;
create_ring_buffer();
}
rtp_error_t uvgrtp::reception_flow::start(std::shared_ptr<uvgrtp::socket> socket, int rce_flags)
{
should_stop_ = false;
@ -375,7 +379,7 @@ void uvgrtp::reception_flow::receiver(std::shared_ptr<uvgrtp::socket> socket)
rtp_error_t ret = RTP_OK;
// get the potential packet
ret = socket->recvfrom(ring_buffer_[next_write_index].data, RECV_BUFFER_SIZE,
ret = socket->recvfrom(ring_buffer_[next_write_index].data, payload_size_,
MSG_DONTWAIT, &ring_buffer_[next_write_index].read);
if (ret == RTP_INTERRUPTED)
@ -527,7 +531,7 @@ void uvgrtp::reception_flow::increase_buffer_size(ssize_t next_write_index)
ring_buffer_.size(), ring_buffer_.size() + increase);
for (unsigned int i = 0; i < increase; ++i)
{
ring_buffer_.insert(ring_buffer_.begin() + next_write_index, { new uint8_t[RECV_BUFFER_SIZE] , -1 });
ring_buffer_.insert(ring_buffer_.begin() + next_write_index, { new uint8_t[payload_size_] , -1 });
}
// this works, because we have just added increase amount of spaces

View File

@ -146,6 +146,7 @@ namespace uvgrtp {
uvgrtp::frame::rtp_frame *pull_frame(ssize_t timeout_ms);
void set_buffer_size(const ssize_t& value);
void set_payload_size(const size_t& value);
private:
/* RTP packet receiver thread */
@ -202,6 +203,7 @@ namespace uvgrtp {
std::condition_variable process_cond_;
ssize_t buffer_size_kbytes_;
size_t payload_size_;
};
}

View File

@ -60,7 +60,7 @@ uvgrtp::rtcp::rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::string cname, int rce_
interval_ms_(DEFAULT_RTCP_INTERVAL_MS),
ourItems_(),
bye_ssrcs_(false),
mtu_size_(DEFAULT_MTU_SIZE - UDP_HDR_SIZE - IPV4_HDR_SIZE)
mtu_size_(MAX_IPV4_PAYLOAD)
{
clock_rate_ = rtp->get_clock_rate();

View File

@ -18,17 +18,20 @@
#define INVALID_TS UINT64_MAX
uvgrtp::rtp::rtp(rtp_format_t fmt):
ssrc_(uvgrtp::random::generate_32()),
ts_(uvgrtp::random::generate_32()),
seq_(uvgrtp::random::generate_32() & 0xffff),
fmt_(fmt),
payload_((uint8_t)fmt),
clock_rate_(0),
wc_start_(),
wc_start_2(),
sent_pkts_(0),
timestamp_(INVALID_TS),
payload_size_(MAX_IPV4_MEDIA_PAYLOAD),
delay_(PKT_MAX_DELAY_MS)
{
seq_ = uvgrtp::random::generate_32() & 0xffff;
ts_ = uvgrtp::random::generate_32();
ssrc_ = uvgrtp::random::generate_32();
set_payload(fmt);
set_payload_size(MAX_IPV4_PAYLOAD);
set_default_clock_rate(fmt);
}
uvgrtp::rtp::~rtp()
@ -45,12 +48,9 @@ uint16_t uvgrtp::rtp::get_sequence() const
return seq_;
}
void uvgrtp::rtp::set_payload(rtp_format_t fmt)
void uvgrtp::rtp::set_default_clock_rate(rtp_format_t fmt)
{
fmt_ = fmt;
payload_ = (uint8_t)fmt;
switch (fmt_) {
switch (fmt) {
case RTP_FORMAT_PCMU:
case RTP_FORMAT_GSM:
case RTP_FORMAT_G723:
@ -169,6 +169,11 @@ void uvgrtp::rtp::set_timestamp(uint64_t timestamp)
timestamp_= timestamp;
}
void uvgrtp::rtp::set_clock_rate(size_t rate)
{
clock_rate_ = rate;
}
uint32_t uvgrtp::rtp::get_clock_rate() const
{
return clock_rate_;

View File

@ -33,7 +33,7 @@ namespace uvgrtp {
void inc_sequence();
void set_clock_rate(size_t rate);
void set_payload(rtp_format_t fmt);
void set_dynamic_payload(uint8_t payload);
void set_timestamp(uint64_t timestamp);
void set_payload_size(size_t payload_size);
@ -47,6 +47,8 @@ namespace uvgrtp {
private:
void set_default_clock_rate(rtp_format_t fmt);
uint32_t ssrc_;
uint32_t ts_;
uint16_t seq_;