srt_protocol/options/
sender.rs

1use std::{default::Default, time::Duration};
2
3use super::*;
4
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub struct Sender {
7    // OptName	Since	Restrict	Type	Units	Default	Range	Dir	Entity
8    // SRTO_PEERLATENCY	1.3.0	pre	int32_t	ms	0	0..	RW	GSD
9    /// SRTO_PEERLATENCY
10    /// The latency value (as described in SRTO_RCVLATENCY) provided by the sender side as a minimum
11    /// value for the receiver.
12    ///
13    /// Reading the value of the option on an unconnected socket reports the configured value.
14    /// Reading the value on a connected socket reports the effective receiver buffering latency of
15    /// the peer.
16    ///
17    /// The SRTO_PEERLATENCY option in versions prior to 1.3.0 is only available as SRTO_LATENCY.
18    ///
19    /// See also SRTO_LATENCY.
20    pub peer_latency: Duration,
21
22    // OptName	Since	Restrict	Type	Units	Default	Range	Dir	Entity
23    // SRTO_SNDDROPDELAY	1.3.2	post	int32_t	ms	*	-1..	W	GSD+
24    // Special value -1: Do not drop packets on the sender at all (retransmit them always when
25    // requested).
26    // Default: 0 in Live mode, -1 in File mode.
27    /// SRTO_SNDDROPDELAY
28    /// Sets an extra delay before TLPKTDROP is triggered on the data sender. This delay is added to
29    /// the default drop delay time interval value. Keep in mind that the longer the delay, the more
30    /// probable it becomes that packets would be retransmitted uselessly because they will be
31    /// dropped by the receiver anyway.
32    ///
33    /// TLPKTDROP discards packets reported as lost if it is already too late to send them (the
34    /// receiver would discard them even if received). The delay before the TLPKTDROP mechanism is
35    /// triggered consists of the SRT latency (SRTO_PEERLATENCY), plus SRTO_SNDDROPDELAY, plus 2 *
36    /// interval between sending ACKs (where the default interval between sending ACKs is 10
37    /// milliseconds). The minimum delay is 1000 + 2 * interval between sending ACKs milliseconds.
38    ///
39    /// Default: 0
40    pub drop_delay: Duration,
41
42    /// SRTO_SNDBUF
43    /// Sender Buffer Size. See SRTO_RCVBUF for more information.
44    pub buffer_size: ByteCount,
45
46    // SRTO_OHEADBW - see LiveBandwidthMode
47    // SRTO_MAXBW - see LiveBandwidthMode
48    // SRTO_INPUTBW - see LiveBandwidthMode
49    // SRTO_MININPUTBW - see LiveBandwidthMode
50    pub bandwidth: LiveBandwidthMode,
51
52    /// SRTO_FC - Flow Control Window Size - unit: packets, default 25600, range: 32..
53    /// Flow Control limits the maximum number of packets "in flight" - payload (data) packets that
54    /// were sent but reception is not yet acknowledged with an ACK control packet. It also includes
55    /// data packets already received, but that can't be acknowledged due to loss of preceding data
56    /// packet(s). In other words, if a data packet with sequence number A was lost, then
57    /// acknowledgement of the following SRTO_FC packets is blocked until packet A is either
58    /// successfully retransmitted or dropped by the Too-Late Packet Drop mechanism. Thus the sender
59    /// will have SRTO_FC packets in flight, and will not be allowed to send further data packets.
60    /// Therefore, when establishing the value of SRTO_FC, it is recommend taking into consideration
61    /// possible delays due to packet loss and retransmission.
62    ///
63    /// There is a restriction that the receiver buffer size (SRTO_RCVBUF) must not be greater than
64    /// SRTO_FC (#700). Therefore, it is recommended to set the value of SRTO_FC first, and then the
65    /// value of SRTO_RCVBUF.
66    ///
67    /// The default flow control window size is 25600 packets. It is approximately:
68    /// - 270 Mbits of payload in the default live streaming configuration with an SRT payload size
69    ///     of 1316 bytes;
70    /// - 300 Mbits of payload with an SRT payload size of 1456 bytes.
71    ///
72    /// The minimum number of packets in flight should be (assuming max payload size):
73    /// `FCmin = bps / 8 × RTTsec / (MSS - 44)`, where:
74    /// - bps - is the payload bitrate of the stream in bits per second;
75    /// - RTTsec - RTT of the network connection in seconds;
76    /// - MSS - Maximum segment size (aka MTU), see SRTO_MSS;
77    /// - 44 - size of headers (20 bytes IPv4 + 8 bytes of UDP + 16 bytes of SRT packet header).
78    /// - To avoid blocking the sending of further packets in case of packet loss, the recommended
79    ///     flow control window is
80    /// - FC = bps / 8 × (RTTsec + latency_sec) / (MSS - 44), where latency_sec is the receiver
81    ///     buffering delay (SRTO_RCVLATENCY) in seconds.
82    pub flow_control_window_size: PacketCount,
83
84    /// SRTO_PAYLOADSIZE
85    /// Sets the maximum declared size of a single call to sending function in Live mode. When set
86    /// to 0, there's no limit for a single sending call.
87    ///
88    /// For Live mode: Default value is 1316, but can be increased up to 1456. Note that with the
89    /// SRTO_PACKETFILTER option additional header space is usually required, which decreases the
90    /// maximum possible value for SRTO_PAYLOADSIZE.
91    pub max_payload_size: PacketSize,
92
93    /// SRTO_RETRANSMITALGO - prioritize this
94    ///
95    /// An SRT sender option to choose between two retransmission algorithms:
96    ///
97    /// 0 - an intensive retransmission algorithm (default until SRT v1.4.4), and
98    /// 1 - a new efficient retransmission algorithm (introduced in SRT v1.4.2; default since
99    /// SRT v1.4.4).
100    ///
101    /// The intensive retransmission algorithm causes the SRT sender to schedule a packet for
102    /// retransmission each time it receives a negative acknowledgement (NAK). On a network
103    /// characterized by low packet loss levels and link capacity high enough to accommodate extra
104    /// retransmission overhead, this algorithm increases the chances of recovering from packet loss
105    /// with a minimum delay, and may better suit end-to-end latency constraints.
106    ///
107    /// The new efficient algorithm optimizes the bandwidth usage by producing fewer retransmissions
108    /// per lost packet. It takes SRT statistics into account to determine if a retransmitted packet
109    /// is still in flight and could reach the receiver in time, so that some of the NAK reports are
110    /// ignored by the sender. This algorithm better fits general use cases, as well as cases where
111    /// channel bandwidth is limited.
112    ///
113    /// NOTE: This option is effective only on the sending side. It influences the decision as to
114    /// whether a particular reported lost packet should be retransmitted at a certain time or not.
115    ///
116    /// NOTE: The efficient retransmission algorithm can only be used when a receiver sends Periodic
117    /// NAK reports. See SRTO_NAKREPORT.
118    pub intensive_retransmission: bool,
119}
120
121impl Default for Sender {
122    fn default() -> Self {
123        Self {
124            peer_latency: Duration::from_millis(120),
125            drop_delay: Duration::ZERO,
126            buffer_size: ByteCount(46592),
127            bandwidth: Default::default(),
128            flow_control_window_size: PacketCount(25600),
129            max_payload_size: PacketSize(1316),
130            intensive_retransmission: false,
131        }
132    }
133}
134
135impl Validation for Sender {
136    type Error = OptionsError;
137
138    fn is_valid(&self) -> Result<(), Self::Error> {
139        use OptionsError::*;
140        if self.flow_control_window_size < PacketCount(32) {
141            Err(FlowControlWindowMin(self.flow_control_window_size))
142        } else {
143            Ok(())
144        }
145    }
146}
147
148#[cfg(test)]
149mod tests {
150    use super::*;
151
152    use OptionsError::*;
153
154    #[test]
155    fn validation() {
156        let result = Sender {
157            flow_control_window_size: PacketCount(31),
158            ..Default::default()
159        };
160
161        assert_eq!(
162            result.try_validate(),
163            Err(FlowControlWindowMin(PacketCount(31)))
164        );
165    }
166}