1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

SRT: Upgrade libsrt from 1.4.1 to 1.5.1. v6.0.12 (#3362)

Co-authored-by: winlin <winlin@vip.126.com>
This commit is contained in:
john 2023-01-04 19:56:33 +08:00 committed by GitHub
parent 7a56208f2f
commit fe086dfc31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
143 changed files with 38185 additions and 15108 deletions

View file

@ -12,7 +12,7 @@
// This is a controversial thing, so temporarily blocking
//#define SRT_ENABLE_SYSTEMBUFFER_TRACE
#include "platform_sys.h"
#ifdef SRT_ENABLE_SYSTEMBUFFER_TRACE
@ -34,8 +34,11 @@
#include "logging.h"
using namespace std;
using namespace srt::sync;
using namespace srt_logging;
namespace srt {
SrtCongestionControlBase::SrtCongestionControlBase(CUDT* parent)
{
m_parent = parent;
@ -58,7 +61,7 @@ void SrtCongestion::Check()
class LiveCC: public SrtCongestionControlBase
{
int64_t m_llSndMaxBW; //Max bandwidth (bytes/sec)
size_t m_zSndAvgPayloadSize; //Average Payload Size of packets to xmit
srt::sync::atomic<size_t> m_zSndAvgPayloadSize; //Average Payload Size of packets to xmit
size_t m_zMaxPayloadSize;
// NAKREPORT stuff.
@ -74,12 +77,12 @@ public:
{
m_llSndMaxBW = BW_INFINITE; // 1 Gbbps in Bytes/sec BW_INFINITE
m_zMaxPayloadSize = parent->OPT_PayloadSize();
if ( m_zMaxPayloadSize == 0 )
if (m_zMaxPayloadSize == 0)
m_zMaxPayloadSize = parent->maxPayloadSize();
m_zSndAvgPayloadSize = m_zMaxPayloadSize;
m_iMinNakInterval_us = 20000; //Minimum NAK Report Period (usec)
m_iNakReportAccel = 2; //Default NAK Report Period (RTT) accelerator
m_iNakReportAccel = 2; //Default NAK Report Period (RTT) accelerator (send periodic NAK every RTT/2)
HLOGC(cclog.Debug, log << "Creating LiveCC: bw=" << m_llSndMaxBW << " avgplsize=" << m_zSndAvgPayloadSize);
@ -90,11 +93,11 @@ public:
// from receiving thread.
parent->ConnectSignal(TEV_SEND, SSLOT(updatePayloadSize));
/*
* Readjust the max SndPeriod onACK (and onTimeout)
*/
parent->ConnectSignal(TEV_CHECKTIMER, SSLOT(updatePktSndPeriod_onTimer));
parent->ConnectSignal(TEV_ACK, SSLOT(updatePktSndPeriod_onAck));
//
// Adjust the max SndPeriod onACK and onTimeout.
//
parent->ConnectSignal(TEV_CHECKTIMER, SSLOT(onRTO));
parent->ConnectSignal(TEV_ACK, SSLOT(onAck));
}
bool checkTransArgs(SrtCongestion::TransAPI api, SrtCongestion::TransDir dir, const char* , size_t size, int , bool ) ATR_OVERRIDE
@ -151,24 +154,30 @@ private:
HLOGC(cclog.Debug, log << "LiveCC: avg payload size updated: " << m_zSndAvgPayloadSize);
}
void updatePktSndPeriod_onTimer(ETransmissionEvent , EventVariant var)
/// @brief On RTO event update an inter-packet send interval.
/// @param arg EventVariant::STAGE to distinguish between INIT and actual RTO.
void onRTO(ETransmissionEvent , EventVariant var)
{
if ( var.get<EventVariant::STAGE>() != TEV_CHT_INIT )
if (var.get<EventVariant::STAGE>() != TEV_CHT_INIT )
updatePktSndPeriod();
}
void updatePktSndPeriod_onAck(ETransmissionEvent , EventVariant )
/// @brief Handle an incoming ACK event.
/// Mainly updates a send interval between packets relying on the maximum BW limit.
void onAck(ETransmissionEvent, EventVariant )
{
updatePktSndPeriod();
}
/// @brief Updates a send interval between packets relying on the maximum BW limit.
void updatePktSndPeriod()
{
// packet = payload + header
const double pktsize = (double) m_zSndAvgPayloadSize + CPacket::SRT_DATA_HDR_SIZE;
const double pktsize = (double) m_zSndAvgPayloadSize.load() + CPacket::SRT_DATA_HDR_SIZE;
m_dPktSndPeriod = 1000 * 1000.0 * (pktsize / m_llSndMaxBW);
HLOGC(cclog.Debug, log << "LiveCC: sending period updated: " << m_dPktSndPeriod
<< " (pktsize=" << pktsize << ", bw=" << m_llSndMaxBW);
<< " by avg pktsize=" << m_zSndAvgPayloadSize
<< ", bw=" << m_llSndMaxBW);
}
void setMaxBW(int64_t maxbw)
@ -176,7 +185,6 @@ private:
m_llSndMaxBW = maxbw > 0 ? maxbw : BW_INFINITE;
updatePktSndPeriod();
#ifdef SRT_ENABLE_NOCWND
/*
* UDT default flow control should not trigger under normal SRT operation
* UDT stops sending if the number of packets in transit (not acknowledged)
@ -186,9 +194,6 @@ private:
*/
// XXX Consider making this a socket option.
m_dCWndSize = m_dMaxCWndSize;
#else
m_dCWndSize = 1000;
#endif
}
void updateBandwidth(int64_t maxbw, int64_t bw) ATR_OVERRIDE
@ -215,7 +220,7 @@ private:
return SrtCongestion::SRM_FASTREXMIT;
}
uint64_t updateNAKInterval(uint64_t nakint_tk, int /*rcv_speed*/, size_t /*loss_length*/) ATR_OVERRIDE
int64_t updateNAKInterval(int64_t nakint_us, int /*rcv_speed*/, size_t /*loss_length*/) ATR_OVERRIDE
{
/*
* duB:
@ -233,12 +238,12 @@ private:
// Note: this value will still be reshaped to defined minimum,
// as per minNAKInterval.
return nakint_tk / m_iNakReportAccel;
return nakint_us / m_iNakReportAccel;
}
uint64_t minNAKInterval() ATR_OVERRIDE
int64_t minNAKInterval() ATR_OVERRIDE
{
return m_iMinNakInterval_us * CTimer::getCPUFrequency();
return m_iMinNakInterval_us;
}
};
@ -250,7 +255,7 @@ class FileCC : public SrtCongestionControlBase
// Fields from CUDTCC
int m_iRCInterval; // UDT Rate control interval
uint64_t m_LastRCTime; // last rate increase time
steady_clock::time_point m_LastRCTime; // last rate increase time
bool m_bSlowStart; // if in slow start phase
int32_t m_iLastAck; // last ACKed seq no
bool m_bLoss; // if loss happened since last rate increase
@ -268,7 +273,7 @@ public:
FileCC(CUDT* parent)
: SrtCongestionControlBase(parent)
, m_iRCInterval(CUDT::COMM_SYN_INTERVAL_US)
, m_LastRCTime(CTimer::getTime())
, m_LastRCTime(steady_clock::now())
, m_bSlowStart(true)
, m_iLastAck(parent->sndSeqNo())
, m_bLoss(false)
@ -290,9 +295,9 @@ public:
m_dCWndSize = 16;
m_dPktSndPeriod = 1;
parent->ConnectSignal(TEV_ACK, SSLOT(updateSndPeriod));
parent->ConnectSignal(TEV_LOSSREPORT, SSLOT(slowdownSndPeriod));
parent->ConnectSignal(TEV_CHECKTIMER, SSLOT(speedupToWindowSize));
parent->ConnectSignal(TEV_ACK, SSLOT(onACK));
parent->ConnectSignal(TEV_LOSSREPORT, SSLOT(onLossReport));
parent->ConnectSignal(TEV_CHECKTIMER, SSLOT(onRTO));
HLOGC(cclog.Debug, log << "Creating FileCC");
}
@ -306,10 +311,11 @@ public:
return true;
}
/// Tells if an early ACK is needed (before the next Full ACK happening every 10ms).
/// In FileCC, treat non-full-payload as an end-of-message (stream)
/// and request ACK to be sent immediately.
bool needsQuickACK(const CPacket& pkt) ATR_OVERRIDE
{
// For FileCC, treat non-full-buffer situation as an end-of-message situation;
// request ACK to be sent immediately.
if (pkt.getLength() < m_parent->maxPayloadSize())
{
// This is not a regular fixed size packet...
@ -330,14 +336,15 @@ public:
}
private:
// SLOTS
void updateSndPeriod(ETransmissionEvent, EventVariant arg)
/// Handle icoming ACK event.
/// In slow start stage increase CWND. Leave slow start once maximum CWND is reached.
/// In congestion avoidance stage adjust inter packet send interval value to achieve maximum rate.
void onACK(ETransmissionEvent, EventVariant arg)
{
const int ack = arg.get<EventVariant::ACK>();
const uint64_t currtime = CTimer::getTime();
if (currtime - m_LastRCTime < (uint64_t)m_iRCInterval)
const steady_clock::time_point currtime = steady_clock::now();
if (count_microseconds(currtime - m_LastRCTime) < m_iRCInterval)
return;
m_LastRCTime = currtime;
@ -360,11 +367,11 @@ private:
}
else
{
m_dPktSndPeriod = m_dCWndSize / (m_parent->RTT() + m_iRCInterval);
m_dPktSndPeriod = m_dCWndSize / (m_parent->SRTT() + m_iRCInterval);
HLOGC(cclog.Debug, log << "FileCC: UPD (slowstart:ENDED) wndsize="
<< m_dCWndSize << "/" << m_dMaxCWndSize
<< " sndperiod=" << m_dPktSndPeriod << "us = wndsize/(RTT+RCIV) RTT="
<< m_parent->RTT() << " RCIV=" << m_iRCInterval);
<< m_parent->SRTT() << " RCIV=" << m_iRCInterval);
}
}
else
@ -376,9 +383,9 @@ private:
}
else
{
m_dCWndSize = m_parent->deliveryRate() / 1000000.0 * (m_parent->RTT() + m_iRCInterval) + 16;
m_dCWndSize = m_parent->deliveryRate() / 1000000.0 * (m_parent->SRTT() + m_iRCInterval) + 16;
HLOGC(cclog.Debug, log << "FileCC: UPD (speed mode) wndsize="
<< m_dCWndSize << "/" << m_dMaxCWndSize << " RTT = " << m_parent->RTT()
<< m_dCWndSize << "/" << m_dMaxCWndSize << " RTT = " << m_parent->SRTT()
<< " sndperiod=" << m_dPktSndPeriod << "us. deliverRate = "
<< m_parent->deliveryRate() << " pkts/s)");
}
@ -393,7 +400,7 @@ private:
else
{
double inc = 0;
const int loss_bw = 2 * (1000000 / m_dLastDecPeriod); // 2 times last loss point
const int loss_bw = static_cast<int>(2 * (1000000 / m_dLastDecPeriod)); // 2 times last loss point
const int bw_pktps = min(loss_bw, m_parent->bandwidth());
int64_t B = (int64_t)(bw_pktps - 1000000.0 / m_dPktSndPeriod);
@ -456,9 +463,10 @@ private:
}
// When a lossreport has been received, it might be due to having
// reached the available bandwidth limit. Slowdown to avoid further losses.
void slowdownSndPeriod(ETransmissionEvent, EventVariant arg)
/// When a lossreport has been received, it might be due to having
/// reached the available bandwidth limit. Slowdown to avoid further losses.
/// Leave the slow start stage if it was active.
void onLossReport(ETransmissionEvent, EventVariant arg)
{
const int32_t* losslist = arg.get_ptr();
size_t losslist_size = arg.get_len();
@ -483,9 +491,9 @@ private:
}
else
{
m_dPktSndPeriod = m_dCWndSize / (m_parent->RTT() + m_iRCInterval);
m_dPktSndPeriod = m_dCWndSize / (m_parent->SRTT() + m_iRCInterval);
HLOGC(cclog.Debug, log << "FileCC: LOSS, SLOWSTART:OFF, sndperiod=" << m_dPktSndPeriod << "us AS wndsize/(RTT+RCIV) (RTT="
<< m_parent->RTT() << " RCIV=" << m_iRCInterval << ")");
<< m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")");
}
}
@ -493,14 +501,14 @@ private:
m_bLoss = true;
// TODO: const int pktsInFlight = CSeqNo::seqoff(m_iLastAck, m_parent->sndSeqNo());
const int pktsInFlight = m_parent->RTT() / m_dPktSndPeriod;
const int pktsInFlight = static_cast<int>(m_parent->SRTT() / m_dPktSndPeriod);
const int numPktsLost = m_parent->sndLossLength();
const int lost_pcent_x10 = pktsInFlight > 0 ? (numPktsLost * 1000) / pktsInFlight : 0;
HLOGC(cclog.Debug, log << "FileCC: LOSS: "
<< "sent=" << CSeqNo::seqlen(m_iLastAck, m_parent->sndSeqNo()) << ", inFlight=" << pktsInFlight
<< ", lost=" << numPktsLost << " ("
<< lost_pcent_x10 / 10 << "." << lost_pcent_x10 % 10 << "\%)");
<< lost_pcent_x10 / 10 << "." << lost_pcent_x10 % 10 << "%)");
if (lost_pcent_x10 < 20) // 2.0%
{
HLOGC(cclog.Debug, log << "FileCC: LOSS: m_dLastDecPeriod=" << m_dLastDecPeriod << "->" << m_dPktSndPeriod);
@ -527,11 +535,8 @@ private:
m_iLastDecSeq = m_parent->sndSeqNo();
// remove global synchronization using randomization
srand(m_iLastDecSeq);
m_iDecRandom = (int)ceil(m_iAvgNAKNum * (double(rand()) / RAND_MAX));
if (m_iDecRandom < 1)
m_iDecRandom = 1;
m_iDecRandom = m_iAvgNAKNum > 1 ? genRandomInt(1, m_iAvgNAKNum) : 1;
SRT_ASSERT(m_iDecRandom >= 1);
HLOGC(cclog.Debug, log << "FileCC: LOSS:NEW lseqno=" << lossbegin
<< ", lastsentseqno=" << m_iLastDecSeq
<< ", seqdiff=" << CSeqNo::seqoff(m_iLastDecSeq, lossbegin)
@ -562,7 +567,9 @@ private:
}
}
void speedupToWindowSize(ETransmissionEvent, EventVariant arg)
/// @brief On retransmission timeout leave slow start stage if it was active.
/// @param arg EventVariant::STAGE to distinguish between INIT and actual RTO.
void onRTO(ETransmissionEvent, EventVariant arg)
{
ECheckTimerStage stg = arg.get<EventVariant::STAGE>();
@ -583,9 +590,9 @@ private:
}
else
{
m_dPktSndPeriod = m_dCWndSize / (m_parent->RTT() + m_iRCInterval);
m_dPktSndPeriod = m_dCWndSize / (m_parent->SRTT() + m_iRCInterval);
HLOGC(cclog.Debug, log << "FileCC: CHKTIMER, SLOWSTART:OFF, sndperiod=" << m_dPktSndPeriod << "us AS wndsize/(RTT+RCIV) (wndsize="
<< setprecision(6) << m_dCWndSize << " RTT=" << m_parent->RTT() << " RCIV=" << m_iRCInterval << ")");
<< setprecision(6) << m_dCWndSize << " RTT=" << m_parent->SRTT() << " RCIV=" << m_iRCInterval << ")");
}
}
else
@ -636,8 +643,18 @@ bool SrtCongestion::configure(CUDT* parent)
return !!congctl;
}
void SrtCongestion::dispose()
{
if (congctl)
{
delete congctl;
congctl = 0;
}
}
SrtCongestion::~SrtCongestion()
{
delete congctl;
congctl = 0;
dispose();
}
} // namespace srt