diff --git a/apps/socketoptions.hpp b/apps/socketoptions.hpp index ec5f8bfa8..8e24e9307 100644 --- a/apps/socketoptions.hpp +++ b/apps/socketoptions.hpp @@ -209,6 +209,7 @@ const SocketOption srt_options [] { { "latency", 0, SRTO_LATENCY, SocketOption::PRE, SocketOption::INT, nullptr}, { "tsbpddelay", 0, SRTO_TSBPDDELAY, SocketOption::PRE, SocketOption::INT, nullptr}, { "tlpktdrop", 0, SRTO_TLPKTDROP, SocketOption::PRE, SocketOption::BOOL, nullptr}, + { "snddropdelay", 0, SRTO_SNDDROPDELAY, SocketOption::POST, SocketOption::INT, nullptr}, { "nakreport", 0, SRTO_NAKREPORT, SocketOption::PRE, SocketOption::BOOL, nullptr}, { "conntimeo", 0, SRTO_CONNTIMEO, SocketOption::PRE, SocketOption::INT, nullptr}, { "lossmaxttl", 0, SRTO_LOSSMAXTTL, SocketOption::PRE, SocketOption::INT, nullptr}, diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 8d4112061..4381912df 100755 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -243,6 +243,7 @@ CUDT::CUDT() m_iOPT_TsbPdDelay = SRT_LIVE_DEF_LATENCY_MS; m_iOPT_PeerTsbPdDelay = 0; //Peer's TsbPd delay as receiver (here is its minimum value, if used) m_bOPT_TLPktDrop = true; + m_iOPT_SndDropDelay = 0; m_bTLPktDrop = true; //Too-late Packet Drop m_bMessageAPI = true; m_zOPT_ExpPayloadSize = SRT_LIVE_DEF_PLSIZE; @@ -303,6 +304,7 @@ CUDT::CUDT(const CUDT& ancestor) m_iOPT_TsbPdDelay = ancestor.m_iOPT_TsbPdDelay; m_iOPT_PeerTsbPdDelay = ancestor.m_iOPT_PeerTsbPdDelay; m_bOPT_TLPktDrop = ancestor.m_bOPT_TLPktDrop; + m_iOPT_SndDropDelay = ancestor.m_iOPT_SndDropDelay; m_zOPT_ExpPayloadSize = ancestor.m_zOPT_ExpPayloadSize; m_bTLPktDrop = ancestor.m_bTLPktDrop; m_bMessageAPI = ancestor.m_bMessageAPI; @@ -581,6 +583,12 @@ void CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen) m_bOPT_TLPktDrop = bool_int_value(optval, optlen); break; + case SRTO_SNDDROPDELAY: + // Surprise: you may be connected to alter this option. + // The application may manipulate this option on sender while transmitting. + m_iOPT_SndDropDelay = *(int*)optval; + break; + case SRTO_PASSPHRASE: if (m_bConnected) throw CUDTException(MJ_NOTSUP, MN_ISCONNECTED, 0); @@ -749,6 +757,7 @@ void CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen) m_iOPT_TsbPdDelay = SRT_LIVE_DEF_LATENCY_MS; m_iOPT_PeerTsbPdDelay = 0; m_bOPT_TLPktDrop = true; + m_iOPT_SndDropDelay = 0; m_bMessageAPI = true; m_bRcvNakReport = true; m_zOPT_ExpPayloadSize = SRT_LIVE_DEF_PLSIZE; @@ -765,6 +774,7 @@ void CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen) m_iOPT_TsbPdDelay = 0; m_iOPT_PeerTsbPdDelay = 0; m_bOPT_TLPktDrop = false; + m_iOPT_SndDropDelay = -1; m_bMessageAPI = false; m_bRcvNakReport = false; m_zOPT_ExpPayloadSize = 0; // use maximum @@ -985,6 +995,11 @@ void CUDT::getOpt(SRT_SOCKOPT optName, void* optval, int& optlen) optlen = sizeof(int32_t); break; + case SRTO_SNDDROPDELAY: + *(int32_t*)optval = m_iOPT_SndDropDelay; + optlen = sizeof(int32_t); + break; + case SRTO_PBKEYLEN: if (m_pCryptoControl) *(int32_t*)optval = m_pCryptoControl->KeyLen(); // Running Key length. @@ -4979,8 +4994,13 @@ void CUDT::checkNeedDrop(ref_t bCongestion) // >>using 1 sec for worse case 1 frame using all bit budget. // picture rate would be useful in auto SRT setting for min latency // XXX Make SRT_TLPKTDROP_MINTHRESHOLD_MS option-configurable - int threshold_ms = std::max(m_iPeerTsbPdDelay_ms, +SRT_TLPKTDROP_MINTHRESHOLD_MS) + (2*COMM_SYN_INTERVAL_US/1000); - if (timespan_ms > threshold_ms) + int threshold_ms = 0; + if (m_iOPT_SndDropDelay >= 0) + { + threshold_ms = std::max(m_iPeerTsbPdDelay_ms + m_iOPT_SndDropDelay, +SRT_TLPKTDROP_MINTHRESHOLD_MS) + (2*COMM_SYN_INTERVAL_US/1000); + } + + if (threshold_ms && timespan_ms > threshold_ms) { // protect packet retransmission CGuard::enterCS(m_AckLock); diff --git a/srtcore/core.h b/srtcore/core.h index 083c6f8ec..26bcb9282 100644 --- a/srtcore/core.h +++ b/srtcore/core.h @@ -557,7 +557,8 @@ class CUDT bool m_bOPT_TsbPd; // Whether AGENT will do TSBPD Rx (whether peer does, is not agent's problem) int m_iOPT_TsbPdDelay; // Agent's Rx latency int m_iOPT_PeerTsbPdDelay; // Peer's Rx latency for the traffic made by Agent's Tx. - bool m_bOPT_TLPktDrop; // Whether Agent WILL DO TLPKTDROP on Rx. + bool m_bOPT_TLPktDrop; // Whether Agent WILL DO TLPKTDROP on Rx. + int m_iOPT_SndDropDelay; // Extra delay when deciding to snd-drop for TLPKTDROP, -1 to off std::string m_sStreamName; int m_iTsbPdDelay_ms; // Rx delay to absorb burst in milliseconds diff --git a/srtcore/srt.h b/srtcore/srt.h index 9cc4c0c29..186220a29 100644 --- a/srtcore/srt.h +++ b/srtcore/srt.h @@ -158,7 +158,7 @@ typedef enum SRT_SOCKOPT { SRTO_IPTTL = 29, // IP Time To Live (passthru for system sockopt IPPROTO_IP/IP_TTL) SRTO_IPTOS, // IP Type of Service (passthru for system sockopt IPPROTO_IP/IP_TOS) SRTO_TLPKTDROP = 31, // Enable receiver pkt drop - // deprecated: SRTO_TSBPDMAXLAG (@c below) + SRTO_SNDDROPDELAY = 32, // Extra delay towards latency for sender TLPKTDROP decision (-1 to off) SRTO_NAKREPORT = 33, // Enable receiver to send periodic NAK reports SRTO_VERSION = 34, // Local SRT Version SRTO_PEERVERSION, // Peer SRT Version (from SRT Handshake) @@ -193,6 +193,7 @@ typedef enum SRT_SOCKOPT { static const SRT_SOCKOPT SRTO_TWOWAYDATA SRT_ATR_DEPRECATED = (SRT_SOCKOPT)37; // This has been deprecated a long time ago, treat this as never implemented. +// The value is also already reused for another option. static const SRT_SOCKOPT SRTO_TSBPDMAXLAG SRT_ATR_DEPRECATED = (SRT_SOCKOPT)32; // This option is a derivative from UDT; the mechanism that uses it is now