Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] Added SRTO_MININPUTBW #1791

Merged
merged 4 commits into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/socketoptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ const SocketOption srt_options [] {
{ "ipttl", 0, SRTO_IPTTL, SocketOption::PRE, SocketOption::INT, nullptr},
{ "iptos", 0, SRTO_IPTOS, SocketOption::PRE, SocketOption::INT, nullptr},
{ "inputbw", 0, SRTO_INPUTBW, SocketOption::POST, SocketOption::INT64, nullptr},
{ "mininputbw", 0, SRTO_MININPUTBW, SocketOption::POST, SocketOption::INT64, nullptr},
{ "oheadbw", 0, SRTO_OHEADBW, SocketOption::POST, SocketOption::INT, nullptr},
{ "latency", 0, SRTO_LATENCY, SocketOption::PRE, SocketOption::INT, nullptr},
{ "tsbpdmode", 0, SRTO_TSBPDMODE, SocketOption::PRE, SocketOption::BOOL, nullptr},
Expand Down
23 changes: 20 additions & 3 deletions docs/APISocketOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ The following table lists SRT socket options in alphabetical order. Option detai
| [`SRTO_GROUPSTABTIMEO`](#SRTO_GROUPSTABTIMEO) | 1.5.0 | pre | `int32_t` | ms | 80 | 10-... | W | GSD+ |
| [`SRTO_GROUPTYPE`](#SRTO_GROUPTYPE) | 1.5.0 | | `int32_t` | enum | | | R | S |
| [`SRTO_INPUTBW`](#SRTO_INPUTBW) | 1.0.5 | post | `int64_t` | B/s | 0 | 0.. | RW | GSD |
| [`SRTO_MININPUTBW`](#SRTO_MININPUTBW) | 1.4.3 | post | `int64_t` | B/s | 0 | 0.. | RW | GSD |
| [`SRTO_IPTOS`](#SRTO_IPTOS) | 1.0.5 | pre-bind | `int32_t` | | (system) | 0..255 | RW | GSD |
| [`SRTO_IPTTL`](#SRTO_IPTTL) | 1.0.5 | pre-bind | `int32_t` | hops | (system) | 1..255 | RW | GSD |
| [`SRTO_IPV6ONLY`](#SRTO_IPV6ONLY) | 1.4.0 | pre-bind | `int32_t` | | (system) | -1..1 | RW | GSD |
Expand Down Expand Up @@ -501,12 +502,13 @@ context than inside the listener callback handler, the value is undefined.
| ---------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ |
| `SRTO_INPUTBW` | 1.0.5 | post | `int64_t` | B/s | 0 | 0.. | RW | GSD |

This option is effective only if `SRTO_MAXBW` is set to 0 (relative). It
controls the maximum bandwidth together with `SRTO_OHEADBW` option according
This option is effective only if [`SRTO_MAXBW`](#SRTO_MAXBW) is set to 0 (relative). It
controls the maximum bandwidth together with [`SRTO_OHEADBW`](#SRTO_OHEADBW) option according
to the formula: `MAXBW = INPUTBW * (100 + OHEADBW) / 100`. When this option
is set to 0 (automatic) then the real INPUTBW value will be estimated from
the rate of the input (cases when the application calls the `srt_send*`
function) during transmission.
function) during transmission. The minimum allowed estimate value is restricted
by [`SRTO_MININPUTBW`](#SRTO_MININPUTBW), meaning `INPUTBW = MAX(INPUTBW_ESTIMATE; MININPUTBW)`.

*Recommended: set this option to the anticipated bitrate of your live stream
and keep the default 25% value for `SRTO_OHEADBW`*.
Expand All @@ -515,6 +517,21 @@ and keep the default 25% value for `SRTO_OHEADBW`*.

---

#### SRTO_MININPUTBW

| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity |
| ----------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ |
| `SRTO_MININPUTBW` | 1.4.3 | post | `int64_t` | B/s | 0 | 0.. | RW | GSD |

This option is effective only if both `SRTO_MAXBW` and `SRTO_INPUTBW` are set to 0.
It controls the minimum allowed value of the input butrate estimate.

See [`SRTO_INPUTBW`](#SRTO_INPUTBW).

[Return to list](#list-of-options)

---

#### SRTO_IPTOS

| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity |
Expand Down
1 change: 1 addition & 0 deletions docs/srt-live-transmit.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ All other parameters are SRT socket options. The following have the following va
| `linger` | 0.. | `SRTO_LINGER` | Link linger value |
| `lossmaxttl` | 0.. | `SRTO_LOSSMAXTTL` | Packet reorder tolerance. |
| `maxbw` | 0.. | `SRTO_MAXBW` | Bandwidth limit in bytes |
| `mininputbw` | 0.. | `SRTO_MININPUTBW` | Minimum allowed estimate of `SRTO_INPUTBW` |
| `messageapi` | `bool` | `SRTO_MESSAGEAPI` | Enable SRT message mode. |
| `minversion` | maj.min.rev | `SRTO_MINVERSION` | Minimum SRT library version of a peer. |
| `mss` | 76.. | `SRTO_MSS` | MTU size |
Expand Down
26 changes: 20 additions & 6 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ extern const SRT_SOCKOPT srt_post_opt_list [SRT_SOCKOPT_NPOST] = {
SRTO_RCVTIMEO,
SRTO_MAXBW,
SRTO_INPUTBW,
SRTO_MININPUTBW,
SRTO_OHEADBW,
SRTO_SNDDROPDELAY,
SRTO_CONNTIMEO,
Expand Down Expand Up @@ -263,6 +264,7 @@ struct SrtOptionAction
flags[SRTO_TSBPDMODE] = SRTO_R_PRE;
flags[SRTO_LATENCY] = SRTO_R_PRE;
flags[SRTO_INPUTBW] = 0 | SRTO_POST_SPEC;
flags[SRTO_MININPUTBW] = 0 | SRTO_POST_SPEC;
flags[SRTO_OHEADBW] = 0 | SRTO_POST_SPEC;
flags[SRTO_PASSPHRASE] = SRTO_R_PRE;
flags[SRTO_PBKEYLEN] = SRTO_R_PRE;
Expand Down Expand Up @@ -305,7 +307,7 @@ void CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen)
throw CUDTException(MJ_NOTSUP, MN_INVAL, 0);

// Restriction check
int oflags = srt_options_action.flags[optName];
const int oflags = srt_options_action.flags[optName];

ScopedLock cg (m_ConnectionLock);
ScopedLock sendguard (m_SendLock);
Expand All @@ -321,7 +323,7 @@ void CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen)
throw CUDTException(MJ_NOTSUP, MN_ISCONNECTED, 0);

// Option execution. If this returns -1, there's no such option.
int status = m_config.set(optName, optval, optlen);
const int status = m_config.set(optName, optval, optlen);
if (status == -1)
{
LOGC(aclog.Error, log << CONID() << "OPTION: #" << optName << " UNKNOWN");
Expand All @@ -338,6 +340,7 @@ void CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen)
break;

case SRTO_INPUTBW:
case SRTO_MININPUTBW:
updateCC(TEV_INIT, EventVariant(TEV_INIT_INPUTBW));
break;

Expand Down Expand Up @@ -433,15 +436,26 @@ void CUDT::getOpt(SRT_SOCKOPT optName, void *optval, int &optlen)
break;

case SRTO_MAXBW:
if (optlen < sizeof(m_config.m_llMaxBW))
throw CUDTException(MJ_NOTSUP, MN_INVAL, 0);
*(int64_t *)optval = m_config.m_llMaxBW;
optlen = sizeof(int64_t);
break;

case SRTO_INPUTBW:
if (optlen < sizeof(m_config.m_llInputBW))
throw CUDTException(MJ_NOTSUP, MN_INVAL, 0);
*(int64_t*)optval = m_config.m_llInputBW;
optlen = sizeof(int64_t);
optlen = sizeof(int64_t);
break;

case SRTO_MININPUTBW:
if (optlen < sizeof (m_config.m_llMinInputBW))
throw CUDTException(MJ_NOTSUP, MN_INVAL, 0);
*(int64_t*)optval = m_config.m_llMinInputBW;
optlen = sizeof(int64_t);
break;

case SRTO_OHEADBW:
*(int32_t *)optval = m_config.m_iOverheadBW;
optlen = sizeof(int32_t);
Expand Down Expand Up @@ -7085,7 +7099,7 @@ bool CUDT::updateCC(ETransmissionEvent evt, const EventVariant arg)
}
else
{
// No need to calculate input reate if the bandwidth is set
// No need to calculate input rate if the bandwidth is set
const bool disable_in_rate_calc = (bw != 0);
m_pSndBuffer->resetInputRateSmpPeriod(disable_in_rate_calc);
}
Expand Down Expand Up @@ -7116,8 +7130,8 @@ bool CUDT::updateCC(ETransmissionEvent evt, const EventVariant arg)
* and sendrate skyrockets for retransmission.
* Keep previously set maximum in that case (inputbw == 0).
*/
if (inputbw != 0)
m_CongCtl->updateBandwidth(0, withOverhead(inputbw)); // Bytes/sec
if (inputbw >= 0)
m_CongCtl->updateBandwidth(0, withOverhead(std::max(m_config.m_llMinInputBW, inputbw))); // Bytes/sec
}
}

Expand Down
2 changes: 1 addition & 1 deletion srtcore/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ enum AckDataItem
};
const size_t ACKD_FIELD_SIZE = sizeof(int32_t);

static const size_t SRT_SOCKOPT_NPOST = 12;
static const size_t SRT_SOCKOPT_NPOST = 13;
extern const SRT_SOCKOPT srt_post_opt_list [];

enum GroupDataItem
Expand Down
3 changes: 2 additions & 1 deletion srtcore/group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ void CUDTGroup::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen)
{
// There's at least one socket in the group, so only
// post-options are allowed.
if (!std::binary_search(srt_post_opt_list, srt_post_opt_list + SRT_SOCKOPT_NPOST, optName))
if (!binary_search(srt_post_opt_list, srt_post_opt_list + SRT_SOCKOPT_NPOST, optName))
{
LOGC(gmlog.Error, log << "setsockopt(group): Group is connected, this option can't be altered");
throw CUDTException(MJ_NOTSUP, MN_ISCONNECTED, 0);
Expand Down Expand Up @@ -567,6 +567,7 @@ void CUDTGroup::deriveSettings(CUDT* u)
// Reuseaddr: true by default and should only be true.
IM(SRTO_MAXBW, m_llMaxBW);
IM(SRTO_INPUTBW, m_llInputBW);
IM(SRTO_MININPUTBW, m_llMinInputBW);
IM(SRTO_OHEADBW, m_iOverheadBW);
IM(SRTO_IPTOS, m_iIpToS);
IM(SRTO_IPTTL, m_iIpTTL);
Expand Down
97 changes: 49 additions & 48 deletions srtcore/socketconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,58 +64,59 @@ static struct SrtConfigSetter

#define DISPATCH(optname) fn[optname] = &CSrtConfigSetter<optname>::set;

DISPATCH(SRTO_MSS);
DISPATCH(SRTO_FC);
DISPATCH(SRTO_SNDBUF);
DISPATCH(SRTO_RCVBUF);
DISPATCH(SRTO_LINGER);
DISPATCH(SRTO_UDP_SNDBUF);
DISPATCH(SRTO_UDP_RCVBUF);
DISPATCH(SRTO_RENDEZVOUS);
DISPATCH(SRTO_SNDTIMEO);
DISPATCH(SRTO_RCVTIMEO);
DISPATCH(SRTO_SNDSYN);
DISPATCH(SRTO_RCVSYN);
DISPATCH(SRTO_REUSEADDR);
DISPATCH(SRTO_MAXBW);
DISPATCH(SRTO_IPTTL);
DISPATCH(SRTO_IPTOS);
DISPATCH(SRTO_BINDTODEVICE);
DISPATCH(SRTO_INPUTBW);
DISPATCH(SRTO_OHEADBW);
DISPATCH(SRTO_SENDER);
DISPATCH(SRTO_TSBPDMODE);
DISPATCH(SRTO_LATENCY);
DISPATCH(SRTO_RCVLATENCY);
DISPATCH(SRTO_PEERLATENCY);
DISPATCH(SRTO_TLPKTDROP);
DISPATCH(SRTO_SNDDROPDELAY);
DISPATCH(SRTO_PASSPHRASE);
DISPATCH(SRTO_PBKEYLEN);
DISPATCH(SRTO_NAKREPORT);
DISPATCH(SRTO_CONNTIMEO);
DISPATCH(SRTO_DRIFTTRACER);
DISPATCH(SRTO_LOSSMAXTTL);
DISPATCH(SRTO_VERSION);
DISPATCH(SRTO_MINVERSION);
DISPATCH(SRTO_STREAMID);
DISPATCH(SRTO_CONGESTION);
DISPATCH(SRTO_MESSAGEAPI);
DISPATCH(SRTO_PAYLOADSIZE);
DISPATCH(SRTO_TRANSTYPE);
DISPATCH(SRTO_MSS);
DISPATCH(SRTO_FC);
DISPATCH(SRTO_SNDBUF);
DISPATCH(SRTO_RCVBUF);
DISPATCH(SRTO_LINGER);
DISPATCH(SRTO_UDP_SNDBUF);
DISPATCH(SRTO_UDP_RCVBUF);
DISPATCH(SRTO_RENDEZVOUS);
DISPATCH(SRTO_SNDTIMEO);
DISPATCH(SRTO_RCVTIMEO);
DISPATCH(SRTO_SNDSYN);
DISPATCH(SRTO_RCVSYN);
DISPATCH(SRTO_REUSEADDR);
DISPATCH(SRTO_MAXBW);
DISPATCH(SRTO_IPTTL);
DISPATCH(SRTO_IPTOS);
DISPATCH(SRTO_BINDTODEVICE);
DISPATCH(SRTO_INPUTBW);
DISPATCH(SRTO_MININPUTBW);
DISPATCH(SRTO_OHEADBW);
DISPATCH(SRTO_SENDER);
DISPATCH(SRTO_TSBPDMODE);
DISPATCH(SRTO_LATENCY);
DISPATCH(SRTO_RCVLATENCY);
DISPATCH(SRTO_PEERLATENCY);
DISPATCH(SRTO_TLPKTDROP);
DISPATCH(SRTO_SNDDROPDELAY);
DISPATCH(SRTO_PASSPHRASE);
DISPATCH(SRTO_PBKEYLEN);
DISPATCH(SRTO_NAKREPORT);
DISPATCH(SRTO_CONNTIMEO);
DISPATCH(SRTO_DRIFTTRACER);
DISPATCH(SRTO_LOSSMAXTTL);
DISPATCH(SRTO_VERSION);
DISPATCH(SRTO_MINVERSION);
DISPATCH(SRTO_STREAMID);
DISPATCH(SRTO_CONGESTION);
DISPATCH(SRTO_MESSAGEAPI);
DISPATCH(SRTO_PAYLOADSIZE);
DISPATCH(SRTO_TRANSTYPE);
#if ENABLE_EXPERIMENTAL_BONDING
DISPATCH(SRTO_GROUPCONNECT);
DISPATCH(SRTO_GROUPCONNECT);
#endif
DISPATCH(SRTO_KMREFRESHRATE);
DISPATCH(SRTO_KMPREANNOUNCE);
DISPATCH(SRTO_ENFORCEDENCRYPTION);
DISPATCH(SRTO_PEERIDLETIMEO);
DISPATCH(SRTO_IPV6ONLY);
DISPATCH(SRTO_PACKETFILTER);
DISPATCH(SRTO_KMREFRESHRATE);
DISPATCH(SRTO_KMPREANNOUNCE);
DISPATCH(SRTO_ENFORCEDENCRYPTION);
DISPATCH(SRTO_PEERIDLETIMEO);
DISPATCH(SRTO_IPV6ONLY);
DISPATCH(SRTO_PACKETFILTER);
#if ENABLE_EXPERIMENTAL_BONDING
DISPATCH(SRTO_GROUPSTABTIMEO);
DISPATCH(SRTO_GROUPSTABTIMEO);
#endif
DISPATCH(SRTO_RETRANSMITALGO);
DISPATCH(SRTO_RETRANSMITALGO);

#undef DISPATCH
}
Expand Down
29 changes: 24 additions & 5 deletions srtcore/socketconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ struct CSrtConfig: CSrtMuxerConfig
uint32_t m_uStabilityTimeout;
int m_iRetransmitAlgo;

int64_t m_llInputBW; // Input stream rate (bytes/sec)
// 0: use internally estimated input bandwidth
int64_t m_llInputBW; // Input stream rate (bytes/sec). 0: use internally estimated input bandwidth
int64_t m_llMinInputBW; // Minimum input stream rate estimate (bytes/sec)
int m_iOverheadBW; // Percent above input stream rate (applies if m_llMaxBW == 0)
bool m_bRcvNakReport; // Enable Receiver Periodic NAK Reports
int m_iMaxReorderTolerance; //< Maximum allowed value for dynamic reorder tolerance
Expand Down Expand Up @@ -298,6 +298,7 @@ struct CSrtConfig: CSrtMuxerConfig
, m_uStabilityTimeout(COMM_DEF_STABILITY_TIMEOUT_US)
, m_iRetransmitAlgo(0)
, m_llInputBW(0)
, m_llMinInputBW(0)
, m_iOverheadBW(25)
, m_bRcvNakReport(true)
, m_iMaxReorderTolerance(0) // Sensible optimal value is 10, 0 preserves old behavior
Expand Down Expand Up @@ -559,7 +560,11 @@ struct CSrtConfigSetter<SRTO_MAXBW>
{
static void set(CSrtConfig& co, const void* optval, int optlen)
{
co.m_llMaxBW = cast_optval<int64_t>(optval, optlen);
const int64_t val = cast_optval<int64_t>(optval, optlen);
if (val < -1)
throw CUDTException(MJ_NOTSUP, MN_INVAL, 0);

co.m_llMaxBW = val;
}
};

Expand Down Expand Up @@ -620,15 +625,29 @@ struct CSrtConfigSetter<SRTO_INPUTBW>
{
static void set(CSrtConfig& co, const void* optval, int optlen)
{
co.m_llInputBW = cast_optval<int64_t>(optval, optlen);
const int64_t val = cast_optval<int64_t>(optval, optlen);
if (val < 0)
throw CUDTException(MJ_NOTSUP, MN_INVAL, 0);
co.m_llInputBW = val;
}
};
template<>
struct CSrtConfigSetter<SRTO_MININPUTBW>
{
static void set(CSrtConfig& co, const void* optval, int optlen)
{
const int64_t val = cast_optval<int64_t>(optval, optlen);
if (val < 0)
throw CUDTException(MJ_NOTSUP, MN_INVAL, 0);
co.m_llMinInputBW = val;
}
};
template<>
struct CSrtConfigSetter<SRTO_OHEADBW>
{
static void set(CSrtConfig& co, const void* optval, int optlen)
{
int32_t val = cast_optval<int32_t>(optval, optlen);
const int32_t val = cast_optval<int32_t>(optval, optlen);
if (val < 5 || val > 100)
throw CUDTException(MJ_NOTSUP, MN_INVAL, 0);
co.m_iOverheadBW = val;
Expand Down
1 change: 1 addition & 0 deletions srtcore/srt.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ typedef enum SRT_SOCKOPT {
SRTO_PEERVERSION, // Peer SRT Version (from SRT Handshake)
SRTO_CONNTIMEO = 36, // Connect timeout in msec. Caller default: 3000, rendezvous (x 10)
SRTO_DRIFTTRACER = 37, // Enable or disable drift tracer
SRTO_MININPUTBW = 38, // Minimum estimate of input stream rate.
// (some space left)
SRTO_SNDKMSTATE = 40, // (GET) the current state of the encryption at the peer side
SRTO_RCVKMSTATE, // (GET) the current state of the encryption at the agent side
Expand Down
Loading