rtcp: Use session bandwidth to calculate interval

This is not full implementation of RTCP interval calculation, but it is
a step in the right direction.
This commit is contained in:
Joni Räsänen 2022-05-27 11:33:55 +03:00
parent 6f39a4e138
commit 41af90b1cf
5 changed files with 52 additions and 7 deletions

View File

@ -35,6 +35,8 @@ namespace uvgrtp {
class media;
}
// Corresponds to one RTP session in RFC 3550
class media_stream {
public:
/// \cond DO_NOT_DOCUMENT
@ -315,6 +317,8 @@ namespace uvgrtp {
rtp_error_t start_components();
int get_default_bandwidth_kbps(rtp_format_t fmt);
uint32_t key_;
std::shared_ptr<uvgrtp::srtp> srtp_;

View File

@ -189,6 +189,8 @@ namespace uvgrtp {
/* Update various session statistics */
void update_session_statistics(const uvgrtp::frame::rtp_frame *frame);
void set_session_bandwidth(int kbps);
/* Return SSRCs of all participants */
std::vector<uint32_t> get_participants() const;
/// \endcond
@ -298,7 +300,7 @@ namespace uvgrtp {
rtp_error_t handle_app_packet(uint8_t* frame, size_t size,
uvgrtp::frame::rtcp_header& header);
static void rtcp_runner(rtcp *rtcp);
static void rtcp_runner(rtcp *rtcp, int interval);
/* when we start the RTCP instance, we don't know what the SSRC of the remote is
* when an RTP packet is received, we must check if we've already received a packet
@ -463,6 +465,8 @@ namespace uvgrtp {
}
bool active_;
int interval_ms_;
};
}

View File

@ -13,6 +13,10 @@ namespace uvgrtp {
class media_stream;
class zrtp;
/* This session is not the same as RTP session. One uvgRTP session
* houses multiple RTP sessions.
*/
class session {
public:
/// \cond DO_NOT_DOCUMENT

View File

@ -343,6 +343,7 @@ rtp_error_t uvgrtp::media_stream::start_components()
if (ctx_config_.flags & RCE_RTCP) {
rtcp_->add_participant(addr_, src_port_ + 1, dst_port_ + 1, rtp_->get_clock_rate());
rtcp_->set_session_bandwidth(get_default_bandwidth_kbps(fmt_));
rtcp_->start();
}
@ -626,3 +627,29 @@ rtp_error_t uvgrtp::media_stream::init_srtp_with_zrtp(int flags, int type, std::
return ret;
}
int uvgrtp::media_stream::get_default_bandwidth_kbps(rtp_format_t fmt)
{
int bandwidth = 50;
switch (fmt) {
case RTP_FORMAT_H264:
bandwidth = 6000;
break;
case RTP_FORMAT_H265:
bandwidth = 3000;
break;
case RTP_FORMAT_H266:
bandwidth = 2000;
break;
case RTP_FORMAT_OPUS:
bandwidth = 24;
break;
default:
LOG_WARN("Unknown RTP format, setting session bandwidth to 64 kbps");
int bandwidth = 64;
break;
}
return bandwidth;
}

View File

@ -29,7 +29,7 @@ const uint32_t RTP_SEQ_MOD = 1 << 16;
const uint32_t MIN_SEQUENTIAL = 2;
const uint32_t MAX_DROPOUT = 3000;
const uint32_t MAX_MISORDER = 100;
const uint32_t MIN_TIMEOUT_MS = 5000;
const uint32_t DEFAULT_RTCP_INTERVAL_MS = 5000;
constexpr int ESTIMATED_MAX_RECEPTION_TIME_MS = 10;
@ -54,7 +54,8 @@ uvgrtp::rtcp::rtcp(std::shared_ptr<uvgrtp::rtp> rtp, int flags):
sdes_hook_u_(nullptr),
app_hook_f_(nullptr),
app_hook_u_(nullptr),
active_(false)
active_(false),
interval_ms_(DEFAULT_RTCP_INTERVAL_MS)
{
clock_rate_ = rtp->get_clock_rate();
@ -115,7 +116,7 @@ rtp_error_t uvgrtp::rtcp::start()
}
active_ = true;
report_generator_.reset(new std::thread(rtcp_runner, this));
report_generator_.reset(new std::thread(rtcp_runner, this, interval_ms_));
return RTP_OK;
}
@ -164,12 +165,10 @@ rtp_error_t uvgrtp::rtcp::stop()
return uvgrtp::rtcp::send_bye_packet({ ssrc_ });
}
void uvgrtp::rtcp::rtcp_runner(uvgrtp::rtcp* rtcp)
void uvgrtp::rtcp::rtcp_runner(rtcp* rtcp, int interval)
{
LOG_INFO("RTCP instance created!");
int interval = MIN_TIMEOUT_MS;
// RFC 3550 says to wait half interval before sending first report
std::this_thread::sleep_for(std::chrono::milliseconds(interval/2));
@ -1564,3 +1563,10 @@ rtp_error_t uvgrtp::rtcp::send_app_packet(const char* name, uint8_t subtype,
return send_rtcp_packet_to_participants(frame, frame_size);
}
void uvgrtp::rtcp::set_session_bandwidth(int kbps)
{
interval_ms_ = 1000*360 / kbps; // the reduced minimum (see section 6.2 in RFC 3550)
// TODO: This should follow the algorithm specified in RFC 3550 appendix-A.7
}