<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.29 (Ruby 3.4.4) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ageneau-ccwg-ndtc-00" category="info" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.31.0 -->
  <front>
    <title abbrev="NDTC">Network Delivery Time Control</title>
    <seriesInfo name="Internet-Draft" value="draft-ageneau-ccwg-ndtc-00"/>
    <author fullname="Paul-Louis Ageneau">
      <organization>Netflix</organization>
      <address>
        <email>pageneau@netflix.com</email>
      </address>
    </author>
    <author fullname="Grenville Armitage">
      <organization>Netflix</organization>
      <address>
        <email>garmitage@netflix.com</email>
      </address>
    </author>
    <author fullname="Scott Danahy">
      <organization>Netflix</organization>
      <address>
        <email>sdanahy@netflix.com</email>
      </address>
    </author>
    <date year="2025" month="October" day="18"/>
    <area>Web and Internet Transport</area>
    <workgroup>Congestion Control Working Group</workgroup>
    <keyword>rate adaptation</keyword>
    <keyword>real-time</keyword>
    <keyword>low-latency video</keyword>
    <abstract>
      <?line 85?>

<t>This document describes Network Delivery Time Control (NDTC), a rate
adaptation algorithm for real-time video streaming suited for
interactive applications like cloud gaming. NDTC leverages the Frame
Dithering Available Capacity Estimation (FDACE) heuristic, which
estimates available path capacity without inducing congestion.
The algorithm dynamically adjusts frame sizes and transmission
times to ensure timely delivery, while also responding to
conventional congestion signals.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://paullouisageneau.github.io/draft-ageneau-ccwg-ndtc/draft-ageneau-ccwg-ndtc.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ageneau-ccwg-ndtc/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Congestion Control Working Group Working Group mailing list (<eref target="mailto:ccwg@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/ccwg/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/ccwg/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/paullouisageneau/draft-ageneau-ccwg-ndtc"/>.</t>
    </note>
  </front>
  <middle>
    <?line 96?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>This document specifies implementation details and considerations for
Network Delivery Time Control (NDTC) <xref target="NDTC-LCN"/>, a rate
adaptation and congestion control algorithm for real-time, interactive video flows
which adapts the target frame size to fit within the available
path capacity, proactively minimizing self-induced congestion.
NDTC also reacts to traditional packet loss signals and is compatible
with networks that implement the Low Latency, Low Loss, and Scalable Throughput (L4S)
Internet Service.</t>
      <t>NDTC's characteristics make it ideal for high-bitrate, real-time,
interactive applications:</t>
      <ul spacing="normal">
        <li>
          <t>It does not self-induce congestion, keeping queueing delays and
packet loss to a minimum,</t>
        </li>
        <li>
          <t>Ramp up is fast with no risk of overshoot, even at high bitrates,</t>
        </li>
        <li>
          <t>The encoded video is not required to closely follow the target bitrate,
and there is no need to send filler data.</t>
        </li>
      </ul>
      <t>These properties make it particularly suited for interactive
cloud gaming applications, and (potentially) for bitrate ladder rung
selection in low-latency video applications.</t>
      <t>At a very high level, when NDTC is applied to cloud gaming it continuously
runs the following loop:</t>
      <ul spacing="normal">
        <li>
          <t>Pace out each video frame at between 1x and (on average) 2x our current
estimate of available path capacity, in order to probe the network path for
additional capacity while minimising burst load on network bottlenecks.</t>
        </li>
        <li>
          <t>Set the target frame size of the video encoder to a fraction of the
available capacity estimate, thus keeping frame delivery latencies low.</t>
        </li>
      </ul>
      <t>Each frame's paced packet train is a probe to test and update our
estimate of available capacity, and thus continuously update our
upper bound on the next encoded video frame's size.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

</section>
    <section anchor="general-principle">
      <name>General Principle</name>
      <t>A key requirement for real-time video is ensuring
each frame arrives on time to be presented. Consequently,
NDTC focuses on timely frame delivery rather than attempting to maximise throughput.
NDTC aims to ensure each frame reception duration is shorter than a frame period,
providing sufficient headroom to ensure high probability of each frame arriving in time.
In practice, the control loop of the algorithm stabilizes the frame reception
duration by dynamically setting the target frame size to a fraction of the
estimated path capacity.</t>
      <t>NDTC introduces and relies on Frame Dithering Available Capacity Estimation (FDACE),
a heuristic that paces packetized frames over a dithered send duration and
estimates available path capacity from the relationship between send
durations and observed receive durations. Beneficially, capacity estimation is performed
without injecting additional traffic (beyond the video stream we wish to deliver)
or filling the path bottleneck to capacity. We then ensure that the flow uses only a
fraction of the measured capacity to prevent risks of self-induced congestion.</t>
      <t>This process is combined with an
AIMD (Additive Increase Multiplicative Decrease) congestion control process
for compatibility with both packet loss congestion signals and ECN (Explicit
Congestion Notification) <xref target="RFC9331"/> for the L4S (Low Latency, Low Loss, and
Scalable Throughput) Internet Service <xref target="RFC9330"/>.</t>
      <t>For the rest of this document we describe NDTC based on the following mental model:</t>
      <ul spacing="normal">
        <li>
          <t>The server is encoding video on-the-fly at a frame rate <tt>1/TFRAME</tt> (where <tt>TFRAME</tt>
is the frame period), while capping each frame to a video frame size target <tt>TARGET</tt>.</t>
        </li>
        <li>
          <t>The server forms a path capacity probe by pacing the frame's constituent packets
out over target send duration <tt>TSEND</tt>.</t>
        </li>
        <li>
          <t>The path's estimated available capacity <tt>AVAILABLE</tt> is continuously updated using
each frame's actual send and receive durations (<tt>SEND</tt> and <tt>RECV</tt> respectively).</t>
        </li>
        <li>
          <t><tt>TARGET</tt> is recalculated whenever <tt>AVAILABLE</tt> changes to ensure the next <tt>RECV</tt> is
stabilized around target reception duration <tt>TRECV</tt>.</t>
        </li>
        <li>
          <t>Additionally, <tt>TARGET</tt> is capped by a combined AIMD process reacting to congestion
signals like packet loss and ECN.</t>
        </li>
      </ul>
      <t>To properly probe the path, <tt>TSEND</tt> <bcp14>MUST</bcp14> be a fraction of <tt>TRECV</tt>, and to minimise on-path
congestion, <tt>TRECV</tt> <bcp14>MUST</bcp14> be a fraction of <tt>TFRAME</tt>.
We RECOMMEND that <tt>TRECV = 0.6 * TFRAME</tt> and <tt>TSEND = 0.5 * TRECV</tt>.
(For example, sending at 30fps would result in <tt>TFRAME = 33ms</tt>, <tt>TRECV = 20ms</tt>
and <tt>TSEND = 10ms</tt>.)</t>
      <t>Note: NDTC focuses on uncovering <em>enough</em> available capacity to meet the application's
needs, it is not trying to instantly discover <em>all</em> the available
capacity on a path. Specifically, choosing <tt>TSEND = 0.5 * TRECV</tt> limits FDACE to
probing up to <tt>2.0 * AVAILABLE</tt> in any single iteration of the FDACE heuristic.</t>
      <t>NDTC initializes <tt>TARGET</tt> to <tt>INIT_TARGET</tt>, and whenever <tt>TARGET</tt> is recalculated
the result is constrained to <tt>MIN_TARGET &lt;= TARGET &lt;= MAX_TARGET</tt>. Actual values
for the <tt>INIT_TARGET</tt>, <tt>MIN_TARGET</tt> and <tt>MAX_TARGET</tt> parameters are application-specific.</t>
    </section>
    <section anchor="algorithm-overview">
      <name>Algorithm Overview</name>
      <t>This section details implementation of the whole NDTC feedback loop
using variable and parameter names summarized
in section <xref target="variables-and-parameters"/> (rather than the more
mathematically-oriented names used in NDTC's conference paper <xref target="NDTC-LCN"/>).</t>
      <section anchor="illustrating-using-rtprtcp">
        <name>Illustrating using RTP/RTCP</name>
        <t>Although NDTC can be implemented for various real-time video transport
protocols, this document illustrates the use of NDTC to support
applications using RTP/RTCP <xref target="RFC3550"/>.</t>
        <t>In particular, NDTC operates on a single video stream and it is frame-oriented.
References to a "frame" in the rest of this document means a sequence of
consecutive RTP packets having the same RTP timestamp and ending with a packet
whose RTP header Mark bit is set.</t>
        <t>Defining a frame when NDTC is used for non-RTP flows
is currently outside the scope of this document.</t>
      </section>
      <section anchor="architecture-considerations">
        <name>Architecture considerations</name>
        <t>NDTC can be implemented both sender-side or receiver-side depending of the
application's needs.</t>
        <t>In the following discussion, the "agent" refers to the entity running the NDTC algorithm.
A core requirement to execute FDACE is that, for every frame, the agent
learns the precise durations over which a given frame was sent (<tt>SEND</tt>)
and received (<tt>RECV</tt>). Recommendations for transmitting this timing information between
senders and receivers is discussed in subsequent sections.</t>
        <t>If the agent is the sender, the algorithm runs on every frame feedback. If the
agent is the receiver, the algorithm runs as soon as a frame is received and
sends the updated target frame size (<tt>TARGET</tt>) to the server.</t>
        <section anchor="sender-side-agent">
          <name>Sender-side Agent</name>
          <t>Sender-side NDTC can be instantiated by having receivers
pass <tt>RECV</tt> back to the sender inside existing
RTCP-based Feedback for Congestion Control <xref target="RFC8888"/> or
Transport-wide Congestion Control (TWCC) <xref target="draft-holmer-rmcat-transport-wide-cc-extensions"/>
reports. Alternatively, an implementor might introduce application-specific
RTCP feedback to make messages smaller and achieve better precision.</t>
          <t>The receiver is also required to report which packets have not been received
(as decribed in <xref target="loss"/>) and <bcp14>SHOULD</bcp14> also reflect Explicit Congestion Notification (ECN)
markings of received packets (if support for L4S is desired).</t>
          <t>In this scenario, the agent has local control of the underlying
packet pacer and video encoder.</t>
        </section>
        <section anchor="receiver-side-agent">
          <name>Receiver-side Agent</name>
          <t>Receiver-side NDTC requires the receiver to regularly pass back updates
to <tt>TARGET</tt> (to properly control the video encoder) and <tt>SLOPE</tt>
(section <xref target="fdace"/>) to properly control the packet pacer. This may
be achieved with e.g. RTCP messages like Receiver Estimated Maximum Bitrate (REMB)
<xref target="draft-alvestrand-rmcat-remb"/>.</t>
          <t>Note: if the receiver agent cannot pass back <tt>SLOPE</tt> information, the sender's
pacing heuristic <bcp14>SHOULD</bcp14> assume <tt>SLOPE = 1</tt>.</t>
        </section>
        <section anchor="timing-and-timestamping">
          <name>Timing and Timestamping</name>
          <t>The precision with which <tt>SEND</tt> and <tt>RECV</tt> are measured and reported
<bcp14>MUST</bcp14> be 1ms or better. Indeed, the durations are typically around a few
milliseconds only, so a lower precision would not be sufficient to obtain a
consistent estimate, even by averaging multiple samples.
We RECOMMEND a precision of 0.1ms.</t>
          <t>If the agent is implemented sender-side, we assume the agent derives <tt>SEND</tt>
from local knowledge (e.g. timestamps generated low in the networking stack),
and learns <tt>RECV</tt> from reports passed back by the receiver.</t>
          <t>If the agent is implemented receiver-side, we assume the agent derives <tt>RECV</tt>
from local knowledge (e.g. kernel timestamps from the underlying network
interface) and learns <tt>SEND</tt> via in-band messages from the sender. For instance,
the sender can write the effective send time on each packet just before it goes
out using the <xref target="abs-send-time"/> RTP extension.</t>
        </section>
      </section>
      <section anchor="fdace">
        <name>Frame Dithering Available Capacity Estimation (FDACE)</name>
        <t>FDACE calculates an estimated available capacity <tt>AVAILABLE</tt> and a slope <tt>SLOPE</tt>
given send and receive durations for a frame.</t>
        <t>Frame size <tt>LENGTH</tt> is calculated by summing up packet payload sizes for the frame
according to <xref target="framesize"/>.
Therefore <tt>AVAILABLE</tt> will actually refer to application-layer
capacity expressed in terms of video bitrate.</t>
        <t>If the frame consists of a single packet, if <tt>LENGTH</tt> is strictly less than
<tt>MIN_TARGET</tt>, or if the frame suffered packet loss in the sense of <xref target="loss"/>,
the agent does not run FDACE.
Instead, it sets <tt>TARGET</tt> and <tt>SLOPE</tt> to the values calculated for the last
frame without packet loss and immediately jumps to the AIMD congestion control
described in <xref target="congestion"/>.</t>
        <t>If the frame was packetized as 2 packets or more and suffered no packet loss,
the agent first calculates the normalized send duration <tt>NSEND</tt> and the
normalized reception duration <tt>NRECV</tt> for the frame by respectively dividing
frame send duration <tt>SEND</tt> and frame receive duration <tt>RECV</tt> by frame size
<tt>LENGTH</tt>.</t>
        <artwork><![CDATA[
NSEND = SEND / LENGTH
NRECV = RECV / LENGTH
]]></artwork>
        <t>Send duration <tt>SEND</tt> corresponds to the elapsed time between sending the first
packet and sending the last packet of the frame (i.e. the one with the RTP marker).
It <bcp14>MUST NOT</bcp14> be the calculated send duration in <xref target="pacer"/> if different from the
actual duration over which the pacer did send the frame.
Packet send times <bcp14>SHOULD</bcp14> be measured as close as socket send calls as possible.</t>
        <t>Receive duration <tt>RECV</tt> corresponds to the elapsed time between reception of
the first packet and reception of the last packet of the frame (i.e. the one
with the RTP marker). Note there is no need for sender and receiver clock
synchronization.
In practice, packet reception times <bcp14>SHOULD</bcp14> be measured using kernel timestamps
for enhanced precision, as the application might take significant time to
receive packets in userspace.
The agent <bcp14>SHOULD</bcp14> cap <tt>RECV</tt> to a small multiple of the frame period in order to
mitigate outliers caused by transient adverse network events while still
allowing the value to grow large enough to capture bursts of cross-traffic
and reflect sudden path capacity reductions.
The <bcp14>RECOMMENDED</bcp14> maximum value for <tt>RECV</tt> is <tt>3*TFRAME</tt>.</t>
        <t>A dual-variable EWMA process is updated with the new sample <tt>(NSEND, NRECV)</tt>.
The process calculates the averages <tt>AVG_NSEND</tt>, <tt>AVG_NRECV</tt>, the variances
<tt>VAR_NSEND</tt> and <tt>VAR_NRECV</tt>, and the covariance <tt>COVAR</tt>.
The <bcp14>RECOMMENDED</bcp14> weight is <tt>LAMBDA = 0.04</tt>.
A suitable implementation of the dual-variable EWMA process is detailed
in <xref target="ewma-implementation"/>.</t>
        <t>The agent now derives the linear regression parameters from the output of the
EWMA process. The slope <tt>SLOPE</tt> and y-intercept <tt>INTERCEPT</tt> of the linear
equation <tt>NRECV = SLOPE * NSEND + INTERCEPT</tt> are calculated as follows:</t>
        <artwork><![CDATA[
if (VAR_NSEND > 0.0) {
    SLOPE = min(COVAR / VAR_NSEND, 1.0)
} else {
    SLOPE = 0.0
}
INTERCEPT = max(AVG_NRECV - SLOPE * AVG_NSEND, 0.0)
]]></artwork>
        <t><tt>SLOPE</tt> reflects how pacing frames changes their reception as they go through
the path bottleneck and intercept more or less cross-traffic. The relationship
is locally linear because we observe normalized times and not rates, and network
path components behave linearly in terms of processing time per byte to a good
approximation.</t>
        <t>If the path is not constraining, for instance during ramp-up, receive duration
is always equal to send duration, and <tt>SLOPE = 1</tt>, which can be interpreted as
the path capacity looking infinite.</t>
        <t>If there is no visible cross-traffic and the flow is alone at
bottleneck, the slope <tt>SLOPE</tt> is 0, the send rate does not matter as we always
receive at bottleneck rate.
If cross-traffic takes most of the bottlneck capacity, <tt>SLOPE</tt> is close to 1.
More generally, we can calculate that in a single FIFO bottleneck scenario
with constant-rate cross traffic, <tt>SLOPE</tt> is the fraction of the bottleneck
capacity occupied by cross-traffic. However, this statement does not hold
true in all scenarios. FDACE does not require such a simple scenario and
performs correctly in more complex network setups, for instance with more
advanced AQM (Active Queue Management) disciplines (see <xref target="aqm"/>).</t>
        <t>The y-intercept <tt>INTERCEPT</tt> reflects the normalized receive duration that we
would measure if the frame was sent as an unpaced burst, reflecting total path
capacity.</t>
        <t>The agent extrapolates <tt>ESTIMATE</tt>, the normalized reception duration that we
would measure if the frame was sent at receive rate, reflecting available
capacity on the path. It corresponds to the ordinate of intersection with
the identity line <tt>NRECV = NSEND</tt>.</t>
        <t>In order to be robust when <tt>SLOPE</tt> is close or equal to 1, <tt>ESTIMATE</tt> is
approximated with successive iterations from <tt>AVG_NRECV</tt> and converging to the
intersection.
The <bcp14>RECOMMENDED</bcp14> number of iterations is <tt>ITERATIONS = 3</tt>. If <tt>ITERATIONS</tt> is
too low, NDTC will overestimate the available capacity in the presence of
cross-traffic. If <tt>ITERATIONS</tt> is higher, NDTC yields more easily against
elastic cross-traffic.</t>
        <artwork><![CDATA[
ESTIMATE = AVG_NRECV
for (i = 0; i < ITERATIONS; i++) {
    ESTIMATE = SLOPE * ESTIMATE + INTERCEPT
}
]]></artwork>
        <t>This means that when the flow is not contrained and <tt>SLOPE = 1</tt>,
<tt>ESTIMATE = AVG_NRECV</tt>, which is a conservative estimate for the capacity.</t>
        <t>For increased simplicity and performance in CPU-constrained environments,
the loop <bcp14>MAY</bcp14> be unrolled as noted in <xref target="estimate-implementation"/>.</t>
        <t>The agent <bcp14>SHOULD</bcp14> add a conservative margin <tt>MARGIN</tt> to <tt>ESTIMATE</tt>, increasing
with the linear regression error. The <bcp14>RECOMMENDED</bcp14> formula to calculate <tt>MARGIN</tt>
is to multiply a constant <tt>KMARGIN</tt> by the standard deviation of <tt>NRECV</tt> and to
<tt>1-R2</tt> where <tt>R2</tt> is the coefficient of determination representing the proportion
of variation in <tt>NRECV</tt> explained by the linear regression. The <bcp14>RECOMMENDED</bcp14> value
for <tt>KMARGIN</tt> is 0.25. A value to close to 0 makes the algorithm react slower to
abrupt changes. A value too high for k makes the algorithm significantly
underestimate the capacity in the presence of bursty cross traffic.</t>
        <artwork><![CDATA[
if (VAR_NSEND > 0.0 && VAR_NRECV > 0.0) {
    R2 = COVAR^2 / (VAR_NSEND * VAR_NRECV)
    MARGIN = KMARGIN * sqrt(VAR_NRECV) * (1-R2)
} else {
    MARGIN = 0.0
}
]]></artwork>
        <t>Available capacity <tt>AVAILABLE</tt> is calculated by taking the reciprocal of
<tt>ESTIMATE</tt> plus <tt>MARGIN</tt>:</t>
        <artwork><![CDATA[
AVAILABLE = 1.0 / (ESTIMATE + MARGIN)
]]></artwork>
      </section>
      <section anchor="target">
        <name>Target Frame Size from Available Capacity</name>
        <t>Before FDACE and the combined congestion control run for the first time,
<tt>TARGET</tt> is initialized to <tt>INIT_TARGET</tt> and <tt>SLOPE</tt> is initialized to 1.0.</t>
        <t>Each time FDACE runs and updates the available capacity, the agent now derives
the new target frame size <tt>TARGET</tt> from <tt>TRECV</tt> and <tt>AVAILABLE</tt> and caps it to
<tt>MAX_TARGET</tt>.</t>
        <artwork><![CDATA[
TARGET = min(TRECV * AVAILABLE, MAX_TARGET)
]]></artwork>
        <t>The agent <bcp14>MUST</bcp14> cap <tt>TARGET</tt> to <tt>MAX_TARGET</tt> even if the encoder has its own internal
maximum frame size to prevent a runaway feedback loop in case the path capacity
is very large. Without capping, NDTC would continue increasing the target frame
size until it matches the available path capacity even if the encoded video can't
follow it, pacing over shorter and shorter durations in the process.
Frames would be sent as very short bursts, increasing the risk of packet loss.
<tt>MAX_TARGET</tt> <bcp14>SHOULD</bcp14> be a sensible frame size that the video content can
realistically reach.</t>
      </section>
      <section anchor="congestion">
        <name>Combined AIMD Congestion Control</name>
        <t>Even if FDAC can successfully run on its own most of the time, it doesn't react
to conventional indications of network congestion, in particular packet loss,
whereas reacting to packet loss is essential in the presence of a policer on the
path. Therefore, NDTC combines an AIMD (Additive Increase Multiplicative
Decrease) process with FDAC to also adjust the frame size and send duration in
response to conventional congestion feedback. It allows the algorithm to
seamlessly transition between capacity estimation and congestion signals,
following the path evolution.</t>
        <t>The AIMD process computes a congestion target frame size <tt>CTARGET</tt> and a
pseudo-slope <tt>CSLOPE</tt> to respectively cap <tt>TARGET</tt> and <tt>SLOPE</tt>, in order to limit
the effective pacer rate. See <xref target="pacer"/> for details about how the pacer adapts
the sending duration according to the slope.</t>
        <ul spacing="normal">
          <li>
            <t>When <tt>CTARGET &lt; TARGET</tt>, the flow is congestion-limited, therefore <tt>TARGET</tt>
is set to <tt>CTARGET</tt> and <tt>CSLOPE</tt> is set to 0.0 so the pacer sends at rate
<tt>CTARGET / TRECV</tt>.</t>
          </li>
          <li>
            <t>When <tt>CTARGET &gt;= TARGET</tt>, the flow is not congestion limited, therefore
<tt>TARGET</tt> is unchanged and <tt>CSLOPE</tt> is set so that the pacer send duration
results in a send rate around <tt>CTARGET / TRECV</tt>.</t>
          </li>
          <li>
            <t>When <tt>CTARGET</tt> reaches <tt>TARGET * TRECV / TSEND</tt>, <tt>CSLOPE</tt> reaches 1.0 and
the pacer reaches its minimum send duration and maximum send rate around
<tt>TARGET/TRECV</tt>.</t>
          </li>
        </ul>
        <t>Therefore, the maximum congestion frame size for the AIMD logic is defined to
correspond to the maximum send rate:</t>
        <artwork><![CDATA[
CMAX = TARGET * TRECV / TSEND
]]></artwork>
        <t>For each transmitted frame, the agent identifies whether packets of the frame were
lost as described in <xref target="loss"/>, and runs the AIMD logic to update a congestion
frame size <tt>CSIZE</tt>. <tt>CSIZE</tt> <bcp14>SHOULD</bcp14> be initialized to <tt>MAX_TARGET</tt> as in most
cases FDACE should be self-sufficient.</t>
        <t>If one or more packets were lost, the agent performs a decrease by capping
<tt>CSIZE</tt> to <tt>CMAX</tt> and multiplying it by <tt>BETA</tt>. If no packets were lost
and <tt>CSIZE</tt> is less than <tt>CMAX</tt>, the agent increases <tt>CSIZE</tt> by adding
<tt>ALPHA</tt>, then caps the result to <tt>CMAX</tt>.
The <bcp14>RECOMMENDED</bcp14> values are <tt>ALPHA=40 bytes</tt> and <tt>BETA=0.7</tt> to make increase
and decrease relatively conservative and minimize QoE redution.</t>
        <t>The AIMD logic <bcp14>SHOULD NOT</bcp14> feature a slow start phase and both decrease and
increase <bcp14>SHOULD</bcp14> be suppressed for one round-trip after a loss event.
In order to support L4S <xref target="RFC9330"/>, the agent <bcp14>SHOULD</bcp14> also react similarly
to Prague congestion control <xref target="draft-briscoe-iccrg-prague-congestion-control"/>,
which requires supporting ECN <xref target="RFC9331"/>, and if the agent is the sender, it also
requires compatible feedback like <xref target="RFC8888"/>. If the last ECN decrease is
more recent than the last packet loss event, the increase <bcp14>SHOULD</bcp14> be performed
by adding a larger <tt>EALPHA</tt> instead of <tt>ALPHA</tt> for the flow to compete more
fairly with other flows. The <bcp14>RECOMMENDED</bcp14> value is <tt>EALPHA=400 bytes</tt>.</t>
        <t>The <bcp14>RECOMMENDED</bcp14> algorithm is described in <xref target="aimd-implementation"/>.</t>
        <t>If the agent is the sender, it <bcp14>SHOULD</bcp14> also perform the decrease in case it
does not get any feedback for a significant duration after sending a frame.
In any case, the sender <bcp14>SHOULD</bcp14> implement a circuit breaker to stop sending
after it stops receiving feedback for a significant duration, following the
recommendations in <xref target="RFC8083"/>.</t>
        <t>The congestion frame size <tt>CTARGET</tt> is calculated as the minimum of
<tt>CSIZE</tt> and <tt>CMAX</tt>:</t>
        <artwork><![CDATA[
CTARGET = min(CSIZE, CMAX)
]]></artwork>
        <t>Then, <tt>CSLOPE</tt> is calculated such that the average pacing rate is
<tt>CTARGET/TRECV</tt>:</t>
        <artwork><![CDATA[
CSLOPE = max(1 - (TSEND/TRECV) * (CMAX/CTARGET), 0) / (1 - TSEND/TRECV)
]]></artwork>
      </section>
      <section anchor="encoder">
        <name>Encoder Target Frame Size</name>
        <t>The agent caps the target frame size <tt>TARGET</tt> and the slope <tt>SLOPE</tt>
with <tt>CTARGET</tt> and <tt>CSLOPE</tt> respectively to take into account the most
conservative estimate:</t>
        <artwork><![CDATA[
TARGET = min(TARGET, CTARGET)
SLOPE = min(SLOPE, CSLOPE)
]]></artwork>
        <t>The agent <bcp14>MUST</bcp14> then floor <tt>TARGET</tt> to <tt>MIN_TARGET</tt>:</t>
        <artwork><![CDATA[
TARGET = max(TARGET, MIN_TARGET)
]]></artwork>
        <t>Flooring to <tt>MIN_TARGET</tt> is required to ensure that the whole feedback loop
does not get stuck producing 1-packet frames, which do not allow the agent
to run FDACE and update <tt>TARGET</tt>.
The <bcp14>RECOMMENDED</bcp14> value for <tt>MIN_TARGET</tt> is 2000 bytes as a frame of such a size
will be packetized into 2 packets of significant size given a typical path MTU.</t>
        <t>The sender <bcp14>SHOULD</bcp14> set the encoder target frame size to <tt>TARGET</tt> as soon as possible
(i.e. the encoder target bitrate is set to <tt>TARGET/TFRAME</tt>).</t>
      </section>
      <section anchor="pacer">
        <name>Adaptive Frame Pacer</name>
        <t>When a new video frame is generated at the sender, it is first packetized
into RTP packets.
The exact packetization process depends on video codec. The sender
<bcp14>SHOULD</bcp14> first pad the frame to <tt>MIN_FRAME</tt> with codec-specific bitstream filler
data if it is smaller. A frame of size <tt>MIN_FRAME</tt> or larger <bcp14>MUST</bcp14> be packetized
in a least 2 packets. The sender <bcp14>SHOULD</bcp14> also attempt to packetize the frame
into packets of similar sizes. The sender <bcp14>MAY</bcp14> add RTP padding as specified
in <xref target="RFC3550"/> to help make packet sizes similar.</t>
        <t>The sender now calculates the desired send duration <tt>SEND</tt> for the frame.</t>
        <t>When not at bottleneck, the send duration is around target send duration <tt>TSEND</tt>.
To ensure a positive feedback loop, <tt>TSEND</tt> <bcp14>MUST</bcp14> be strictly less than
<tt>TRECV</tt>, the <bcp14>RECOMMENDED</bcp14> values is <tt>TSEND = 0.5 * TRECV = 0.3 * TFRAME</tt>.</t>
        <t>The sender first calculates the base pacing duration <tt>PACE</tt> by adding dithering of
amplitude <tt>DELTA</tt> to <tt>TSEND</tt> and interpolating with <tt>TRECV</tt> according to
<tt>SLOPE</tt>. The <bcp14>RECOMMENDED</bcp14> value for <tt>DELTA</tt> is <tt>0.5*TSEND</tt>.
With <tt>rand()</tt> a pseudo-random value in <tt>\[-1, 1\]</tt>, <tt>PACE</tt> is calculated as:</t>
        <artwork><![CDATA[
PACE = SLOPE * (TSEND + rand() * DELTA) + (1 - SLOPE) * TRECV
]]></artwork>
        <t>Adapting the duration according to <tt>SLOPE</tt> reduces how aggressively NDTC paces
packets as the flow gets closer to filling the entire bottleneck.
It makes the feedback loop run closer to the desired operating point and
minimizes transient queueing for each frame.
It also helps FDACE by probing locally in non-linear scenarios and
stabilizes competition with other NDTC flows.</t>
        <t>The sender then scales the pacing duration proportionally to <tt>LENGTH/TARGET</tt>,
where the frame size <tt>LENGTH</tt> is calculated according to <xref target="framesize"/>.
This helps sustaining the send rate when the encoder produces frames that don't
match the target frame size. For instance, the encoder may chronically
underproduce because the video is not dynamic or complex enough, and
it may temporarily overproduce on scene change.
Eventually, <tt>SEND</tt> is capped at the frame period <tt>TFRAME</tt>.</t>
        <artwork><![CDATA[
SEND = min(PACE * LENGTH/TARGET, TFRAME)
]]></artwork>
        <t>The sender also calculates a frame alignment delay as follows to reduce frame
jitter. The delay is calculated to compensate the send duration variation so
the last packets of frames are received at the frame period.</t>
        <artwork><![CDATA[
DELAY = SLOPE * max(PACE + SLOPE * DELTA - SEND, 0)
]]></artwork>
        <t>The packets of the frame are sent after <tt>DELAY</tt> over the duration <tt>SEND</tt>,
meaning that if the frame is available at <tt>t</tt>, the first packet is sent at
<tt>t + DELAY</tt> and the last packet (i.e. the one with the RTP marker) should be
sent at <tt>t + DELAY + SEND</tt>. Other packets are spread evenly over the interval.</t>
        <t>To achieve this, the sender <bcp14>SHOULD</bcp14> wait for duration <tt>DELAY</tt>, then for each packet
<tt>p</tt>, send it, then wait for an interval <tt>SEND * SIZE(p) / LENGTH</tt> where
<tt>SIZE(p)</tt> is the payload size for packet p.
The pacer <bcp14>SHOULD</bcp14> match send times with a absolute precision of at least 1ms.
It <bcp14>MUST</bcp14> prevent cummulative errors from actual wait durations being different
from expected durations.</t>
        <t>If ECN is not supported, the pacer does not need to precisely pace packets
besides the first and last one, and it <bcp14>MAY</bcp14> instead group packets in small
bursts to prevent waking up too often.</t>
        <t>In any case, the agent <bcp14>MUST</bcp14> use the actually achieved send duration, not the
calculated pacing duration, when running FDACE for the frame.</t>
        <t>If FEC is enabled, the sender <bcp14>SHOULD NOT</bcp14> send FEC packets during duration <tt>SEND</tt>
and <bcp14>SHOULD</bcp14> instead pace FEC packets after it, spreading them so that the
interval between packets is calculated similarly to the interval for video
packets.</t>
        <t>If the sender supports retransmissions, the sender <bcp14>SHOULD</bcp14> handle retransmitted
packets separately. They <bcp14>SHOULD</bcp14> be paced and sent in parallel to video frames.
If the application features an audio stream, the sender <bcp14>SHOULD</bcp14> handle audio
packets separately. They <bcp14>SHOULD</bcp14> be sent immediately after they are generated,
without adding a delay.
This means retransmissions and audio packets can be sent between two video
packets. From the point of view of FDACE, they will be accounted for as
cross-traffic sharing the same path.</t>
        <t>The pacer <bcp14>MUST</bcp14> handle the corner case where packets from the previous frame are
still waiting to be sent when the new frame is available, for instance because
the new frame is early. In this case, it is crucial to ensure that the previous
frame is fully sent before the new frame is sent. Therefore if packets from the
previous frame were to be sent after the first packet of the new frame, the
sender <bcp14>MUST</bcp14> reschedule the leftover packets to send them before the first packet
of the new frame.</t>
      </section>
    </section>
    <section anchor="implementation-details">
      <name>Implementation Details</name>
      <section anchor="variables-and-parameters">
        <name>Variables and Parameters</name>
        <t>The following table summarizes parameters used by the algorithm:</t>
        <table>
          <thead>
            <tr>
              <th align="left">Parameter</th>
              <th align="left">Description</th>
              <th align="left">Unit</th>
              <th align="left">Recommended</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">
                <tt>MIN_TARGET</tt></td>
              <td align="left">minimum target frame size</td>
              <td align="left">bytes</td>
              <td align="left">2000</td>
            </tr>
            <tr>
              <td align="left">
                <tt>MAX_TARGET</tt></td>
              <td align="left">maximum target frame size</td>
              <td align="left">bytes</td>
              <td align="left">-</td>
            </tr>
            <tr>
              <td align="left">
                <tt>INIT_TARGET</tt></td>
              <td align="left">initial target frame size</td>
              <td align="left">bytes</td>
              <td align="left">
                <tt>&lt;= MAX_TARGET/2</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>TRECV</tt></td>
              <td align="left">target receive duration</td>
              <td align="left">seconds</td>
              <td align="left">
                <tt>0.6 * TFRAME</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>TSEND</tt></td>
              <td align="left">target send duration</td>
              <td align="left">seconds</td>
              <td align="left">
                <tt>0.5 * TRECV</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>ITERATIONS</tt></td>
              <td align="left">extrapolation iterations</td>
              <td align="left">-</td>
              <td align="left">3</td>
            </tr>
            <tr>
              <td align="left">
                <tt>ALPHA</tt></td>
              <td align="left">congestion additive increase</td>
              <td align="left">bytes</td>
              <td align="left">40</td>
            </tr>
            <tr>
              <td align="left">
                <tt>EALPHA</tt></td>
              <td align="left">congestion additive increase for ECN</td>
              <td align="left">bytes</td>
              <td align="left">400</td>
            </tr>
            <tr>
              <td align="left">
                <tt>BETA</tt></td>
              <td align="left">congestion multiplicative decrease</td>
              <td align="left">-</td>
              <td align="left">0.7</td>
            </tr>
            <tr>
              <td align="left">
                <tt>DELTA</tt></td>
              <td align="left">send dithering amplitude</td>
              <td align="left">seconds</td>
              <td align="left">
                <tt>0.5 * TSEND</tt></td>
            </tr>
            <tr>
              <td align="left">
                <tt>LAMBDA</tt></td>
              <td align="left">regression EWMA weight</td>
              <td align="left">-</td>
              <td align="left">0.04</td>
            </tr>
            <tr>
              <td align="left">
                <tt>KMARGIN</tt></td>
              <td align="left">estimation margin constant</td>
              <td align="left">-</td>
              <td align="left">0.25</td>
            </tr>
          </tbody>
        </table>
        <t>The following table summarizes variables used by the algorithm:</t>
        <table>
          <thead>
            <tr>
              <th align="left">Variable</th>
              <th align="left">Description</th>
              <th align="left">Unit</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">
                <tt>AVAILABLE</tt></td>
              <td align="left">estimated available capacity</td>
              <td align="left">bytes/second</td>
            </tr>
            <tr>
              <td align="left">
                <tt>DELAY</tt></td>
              <td align="left">pacing alignment delay</td>
              <td align="left">seconds</td>
            </tr>
            <tr>
              <td align="left">
                <tt>TARGET</tt></td>
              <td align="left">target frame size from FDAC</td>
              <td align="left">bytes</td>
            </tr>
            <tr>
              <td align="left">
                <tt>CTARGET</tt></td>
              <td align="left">target frame size from AIMD</td>
              <td align="left">bytes</td>
            </tr>
            <tr>
              <td align="left">
                <tt>LENGTH</tt></td>
              <td align="left">actual frame size</td>
              <td align="left">bytes</td>
            </tr>
            <tr>
              <td align="left">
                <tt>CMAX</tt></td>
              <td align="left">AIMD maximum frame size</td>
              <td align="left">bytes</td>
            </tr>
            <tr>
              <td align="left">
                <tt>PACE</tt></td>
              <td align="left">base pacing duration</td>
              <td align="left">seconds</td>
            </tr>
            <tr>
              <td align="left">
                <tt>SEND</tt></td>
              <td align="left">send duration for the frame</td>
              <td align="left">seconds</td>
            </tr>
            <tr>
              <td align="left">
                <tt>RECV</tt></td>
              <td align="left">receive duration for the frame</td>
              <td align="left">seconds</td>
            </tr>
            <tr>
              <td align="left">
                <tt>SLOPE</tt></td>
              <td align="left">linear regression slope (a)</td>
              <td align="left">-</td>
            </tr>
            <tr>
              <td align="left">
                <tt>INTERCEPT</tt></td>
              <td align="left">linear regression y-intercept (b)</td>
              <td align="left">seconds/byte</td>
            </tr>
            <tr>
              <td align="left">
                <tt>ESTIMATE</tt></td>
              <td align="left">extrapolated estimate</td>
              <td align="left">seconds/byte</td>
            </tr>
            <tr>
              <td align="left">
                <tt>MARGIN</tt></td>
              <td align="left">estimation margin</td>
              <td align="left">seconds/byte</td>
            </tr>
            <tr>
              <td align="left">
                <tt>CSLOPE</tt></td>
              <td align="left">pseudo-slope from AIMD</td>
              <td align="left">-</td>
            </tr>
            <tr>
              <td align="left">
                <tt>NSEND</tt></td>
              <td align="left">normalized send duration</td>
              <td align="left">seconds/byte</td>
            </tr>
            <tr>
              <td align="left">
                <tt>NRECV</tt></td>
              <td align="left">normalized receive duration</td>
              <td align="left">seconds/byte</td>
            </tr>
            <tr>
              <td align="left">
                <tt>AVG_NSEND</tt></td>
              <td align="left">average of norm. send duration</td>
              <td align="left">seconds/byte</td>
            </tr>
            <tr>
              <td align="left">
                <tt>AVG_NRECV</tt></td>
              <td align="left">average of norm. receive duration</td>
              <td align="left">seconds/byte</td>
            </tr>
            <tr>
              <td align="left">
                <tt>VAR_NSEND</tt></td>
              <td align="left">variance of norm. send duration</td>
              <td align="left">(seconds/byte)^2</td>
            </tr>
            <tr>
              <td align="left">
                <tt>VAR_NRECV</tt></td>
              <td align="left">variance of norm. receive duration</td>
              <td align="left">(seconds/byte)^2</td>
            </tr>
            <tr>
              <td align="left">
                <tt>COVAR</tt></td>
              <td align="left">covariance of norm. send and receive durations</td>
              <td align="left">(seconds/byte)^2</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="framesize">
        <name>Frame Size Calculation</name>
        <t>The frame size <tt>LENGTH</tt> is used for normalizing the send and receive durations in FDACE
and calculating the pacing duration. <tt>LENGTH</tt> is calculated as the sum of RTP payloads
corresponding to the frame (i.e. sharing the same timestamp). FEC and retransmitted
packets <bcp14>MUST NOT</bcp14> be counted in <tt>LENGTH</tt>.</t>
        <t>Since frame size is calculated from payload sizes only, FDACE will estimate an
application-layer capacity, and <tt>TARGET</tt> can be set directly as encoder target.
Implementors <bcp14>MAY</bcp14> choose to take into account RTP headers, and optionally UDP/IP headers.
In that case, capacity will more closely reflect network capacity, however target frame
size <bcp14>SHOULD</bcp14> be decreased by the typical header overhead before being set as encoder target.</t>
        <t>If the frame consists of two packets or more, send and receive durations do not
account for one of the extreme packets.
When sending, since the pacer waits after sending each packet, the sender <bcp14>SHOULD</bcp14>
sum up payload sizes except the last one.
When running FDACE, the agent does not know how the path exactly handles packets,
so it can't know for sure which payload to exclude at reception.
Therefore, in the context of FDACE, the agent <bcp14>SHOULD</bcp14> calculate <tt>LENGTH</tt> as the sum
of all payloads of the frame minus the average size of the first and last one.
If the frame consists of a single packet, <tt>LENGTH</tt> is the size of the packet.</t>
        <t>Note that if the frame is packetized into packets of similar sizes as
recommended, which packet to exclude does not matter since the payload
sizes are the same.</t>
      </section>
      <section anchor="loss">
        <name>Loss Detection</name>
        <t>Packet loss is taken into account to decide if FDACE should be run for a frame
and to trigger AIMD decrease. Lost packet are detected by tracking
discontinuities in received sequence numbers.</t>
        <t>The receiver <bcp14>SHOULD</bcp14> reorder packets for the currently received frame (i.e.
timestamp) to avoid misclassifiying reordered packets as lost. As soon as the
first packet of the next frame (i.e. timestamp) is received, missing packets for
the previous frame <bcp14>MUST</bcp14> be reported as lost. The receiver <bcp14>MUST</bcp14> consider a packet
as lost in the context of this algorithm even if it can be recovered with
Forwared Error Correction or retransmission. Therefore, a frame triggering
packet loss reaction may still be successfully transmitted.</t>
      </section>
    </section>
    <section anchor="fairness">
      <name>Fairness Considerations</name>
      <t>As NDTC does not attempt to maximize throughput, it also does not attempt to
achieve throughput fairness in general. Targeting a reception duration means
that NDTC tends to yield to capacity seeking-flows, but it does not get starved.</t>
      <t>Thanks to its design, NDTC never takes more capacity than the combined AIMD
congestion control logic allows, so it is guaranteed not to starve traditional
capacity-seeking flows.</t>
    </section>
    <section anchor="aqm">
      <name>Active Queue Management Considerations</name>
      <t>As interactive flows in general, NDTC flows greatly benefit
from AQM (Active Queue Management) disciplines.</t>
      <t>In the case of NDTC, flow queueing, for instance in FQ-CoDel <xref target="RFC8290"/>
or Cake <xref target="CAKE"/>, particularly helps FDACE as cross-traffic packets are
interleaved in each frame, providing stability in addition to fairness.
As NDTC adapts the send duration to pace close to available capacity,
Cake's DRR++ scheme additionally allows NDTC to have priority over bulk traffic.</t>
      <t>NDTC can also take advantage of L4S bottlenecks if the AIMD logic
behaves as a Prague congestion controller like suggested in <xref target="aimd-implementation"/>,
providing fairness with TCP Prague and traditional TCP flows.
An essential aspect is that NDTC can seemlessly transition between L4S and
standard bottlenecks as the network path evolves.</t>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>An attacker could insert, edit, or drop messages from the connection could cause
NDTC to underutilizes the path capacity or overhsoot it, causing network
congestion. The RTP flow and RTCP feedback should be protected from message
injection and modification using SRTP.</t>
      <t>In a more sophisticated attack, an attacker could selectively delay video
packets in order to manipulate timings and make NDTC incorrectly estimate
available path capacity. However, the combined congestion control should prevent
NDTC to cause network congestion in that scenario.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-normative-references">
      <name>Normative References</name>
      <reference anchor="draft-alvestrand-rmcat-remb" target="https://datatracker.ietf.org/doc/html/draft-alvestrand-rmcat-remb-03">
        <front>
          <title>RTCP message for Receiver Estimated Maximum Bitrate</title>
          <author initials="H." surname="Alvestrand" fullname="H. Alvestrand">
            <organization/>
          </author>
          <date year="2013" month="October" day="21"/>
        </front>
      </reference>
      <reference anchor="draft-holmer-rmcat-transport-wide-cc-extensions" target="https://datatracker.ietf.org/doc/html/draft-holmer-rmcat-transport-wide-cc-extensions-01">
        <front>
          <title>RTP Extensions for Transport-wide Congestion Control</title>
          <author initials="S." surname="Holmer" fullname="S. Holmer">
            <organization/>
          </author>
          <author initials="M." surname="Flodman" fullname="M. Flodman">
            <organization/>
          </author>
          <author initials="E." surname="Sprang" fullname="E. Sprang">
            <organization/>
          </author>
          <date year="2015" month="October" day="19"/>
        </front>
      </reference>
      <reference anchor="draft-briscoe-iccrg-prague-congestion-control" target="https://datatracker.ietf.org/doc/html/draft-briscoe-iccrg-prague-congestion-control-04">
        <front>
          <title>Prague Congestion Control</title>
          <author initials="K. D." surname="Schepper" fullname="K. De Schepper">
            <organization/>
          </author>
          <author initials="O." surname="Tilmans" fullname="O. Tilmans">
            <organization/>
          </author>
          <author initials="B." surname="Briscoe" fullname="B. Briscoe">
            <organization/>
          </author>
          <author initials="V." surname="Goel" fullname="V. Goel">
            <organization/>
          </author>
          <date>n.d.</date>
        </front>
      </reference>
      <reference anchor="abs-send-time" target="http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time">
        <front>
          <title>RTP Header Extension for Absolute Sender Time</title>
          <author>
            <organization/>
          </author>
          <date>n.d.</date>
        </front>
      </reference>
      <reference anchor="NDTC-LCN" target="https://ieeexplore.ieee.org/document/11146354">
        <front>
          <title>Network Delivery Time Control: a Novel Approach to Rate Adaptation for Low-Latency Video Flows</title>
          <author initials="P.-L." surname="Ageneau" fullname="Paul-Louis Ageneau">
            <organization/>
          </author>
          <author initials="G." surname="Armitage" fullname="Grenville Armitage">
            <organization/>
          </author>
          <date year="2025" month="October" day="13"/>
        </front>
        <seriesInfo name="IEEE 50th Conference on Local Computer Networks (LCN)" value=""/>
      </reference>
      <reference anchor="CAKE" target="https://www.bufferbloat.net/projects/codel/wiki/Cake">
        <front>
          <title>Cake - Common Applications Kept Enhanced</title>
          <author>
            <organization/>
          </author>
          <date>n.d.</date>
        </front>
      </reference>
      <reference anchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="S. Bradner" initials="S." surname="Bradner"/>
          <date month="March" year="1997"/>
          <abstract>
            <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
        <seriesInfo name="DOI" value="10.17487/RFC2119"/>
      </reference>
      <reference anchor="RFC8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="B. Leiba" initials="B." surname="Leiba"/>
          <date month="May" year="2017"/>
          <abstract>
            <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
        <seriesInfo name="DOI" value="10.17487/RFC8174"/>
      </reference>
      <reference anchor="RFC9331">
        <front>
          <title>The Explicit Congestion Notification (ECN) Protocol for Low Latency, Low Loss, and Scalable Throughput (L4S)</title>
          <author fullname="K. De Schepper" initials="K." surname="De Schepper"/>
          <author fullname="B. Briscoe" initials="B." role="editor" surname="Briscoe"/>
          <date month="January" year="2023"/>
          <abstract>
            <t>This specification defines the protocol to be used for a new network service called Low Latency, Low Loss, and Scalable throughput (L4S). L4S uses an Explicit Congestion Notification (ECN) scheme at the IP layer that is similar to the original (or 'Classic') ECN approach, except as specified within. L4S uses 'Scalable' congestion control, which induces much more frequent control signals from the network, and it responds to them with much more fine-grained adjustments so that very low (typically sub-millisecond on average) and consistently low queuing delay becomes possible for L4S traffic without compromising link utilization. Thus, even capacity-seeking (TCP-like) traffic can have high bandwidth and very low delay at the same time, even during periods of high traffic load.</t>
            <t>The L4S identifier defined in this document distinguishes L4S from 'Classic' (e.g., TCP-Reno-friendly) traffic. Then, network bottlenecks can be incrementally modified to distinguish and isolate existing traffic that still follows the Classic behaviour, to prevent it from degrading the low queuing delay and low loss of L4S traffic. This Experimental specification defines the rules that L4S transports and network elements need to follow, with the intention that L4S flows neither harm each other's performance nor that of Classic traffic. It also suggests open questions to be investigated during experimentation. Examples of new Active Queue Management (AQM) marking algorithms and new transports (whether TCP-like or real time) are specified separately.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9331"/>
        <seriesInfo name="DOI" value="10.17487/RFC9331"/>
      </reference>
      <reference anchor="RFC9330">
        <front>
          <title>Low Latency, Low Loss, and Scalable Throughput (L4S) Internet Service: Architecture</title>
          <author fullname="B. Briscoe" initials="B." role="editor" surname="Briscoe"/>
          <author fullname="K. De Schepper" initials="K." surname="De Schepper"/>
          <author fullname="M. Bagnulo" initials="M." surname="Bagnulo"/>
          <author fullname="G. White" initials="G." surname="White"/>
          <date month="January" year="2023"/>
          <abstract>
            <t>This document describes the L4S architecture, which enables Internet applications to achieve low queuing latency, low congestion loss, and scalable throughput control. L4S is based on the insight that the root cause of queuing delay is in the capacity-seeking congestion controllers of senders, not in the queue itself. With the L4S architecture, all Internet applications could (but do not have to) transition away from congestion control algorithms that cause substantial queuing delay and instead adopt a new class of congestion controls that can seek capacity with very little queuing. These are aided by a modified form of Explicit Congestion Notification (ECN) from the network. With this new architecture, applications can have both low latency and high throughput.</t>
            <t>The architecture primarily concerns incremental deployment. It defines mechanisms that allow the new class of L4S congestion controls to coexist with 'Classic' congestion controls in a shared network. The aim is for L4S latency and throughput to be usually much better (and rarely worse) while typically not impacting Classic performance.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9330"/>
        <seriesInfo name="DOI" value="10.17487/RFC9330"/>
      </reference>
      <reference anchor="RFC3550">
        <front>
          <title>RTP: A Transport Protocol for Real-Time Applications</title>
          <author fullname="H. Schulzrinne" initials="H." surname="Schulzrinne"/>
          <author fullname="S. Casner" initials="S." surname="Casner"/>
          <author fullname="R. Frederick" initials="R." surname="Frederick"/>
          <author fullname="V. Jacobson" initials="V." surname="Jacobson"/>
          <date month="July" year="2003"/>
          <abstract>
            <t>This memorandum describes RTP, the real-time transport protocol. RTP provides end-to-end network transport functions suitable for applications transmitting real-time data, such as audio, video or simulation data, over multicast or unicast network services. RTP does not address resource reservation and does not guarantee quality-of- service for real-time services. The data transport is augmented by a control protocol (RTCP) to allow monitoring of the data delivery in a manner scalable to large multicast networks, and to provide minimal control and identification functionality. RTP and RTCP are designed to be independent of the underlying transport and network layers. The protocol supports the use of RTP-level translators and mixers. Most of the text in this memorandum is identical to RFC 1889 which it obsoletes. There are no changes in the packet formats on the wire, only changes to the rules and algorithms governing how the protocol is used. The biggest change is an enhancement to the scalable timer algorithm for calculating when to send RTCP packets in order to minimize transmission in excess of the intended rate when many participants join a session simultaneously. [STANDARDS-TRACK]</t>
          </abstract>
        </front>
        <seriesInfo name="STD" value="64"/>
        <seriesInfo name="RFC" value="3550"/>
        <seriesInfo name="DOI" value="10.17487/RFC3550"/>
      </reference>
      <reference anchor="RFC8888">
        <front>
          <title>RTP Control Protocol (RTCP) Feedback for Congestion Control</title>
          <author fullname="Z. Sarker" initials="Z." surname="Sarker"/>
          <author fullname="C. Perkins" initials="C." surname="Perkins"/>
          <author fullname="V. Singh" initials="V." surname="Singh"/>
          <author fullname="M. Ramalho" initials="M." surname="Ramalho"/>
          <date month="January" year="2021"/>
          <abstract>
            <t>An effective RTP congestion control algorithm requires more fine-grained feedback on packet loss, timing, and Explicit Congestion Notification (ECN) marks than is provided by the standard RTP Control Protocol (RTCP) Sender Report (SR) and Receiver Report (RR) packets. This document describes an RTCP feedback message intended to enable congestion control for interactive real-time traffic using RTP. The feedback message is designed for use with a sender-based congestion control algorithm, in which the receiver of an RTP flow sends back to the sender RTCP feedback packets containing the information the sender needs to perform congestion control.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="8888"/>
        <seriesInfo name="DOI" value="10.17487/RFC8888"/>
      </reference>
      <reference anchor="RFC8083">
        <front>
          <title>Multimedia Congestion Control: Circuit Breakers for Unicast RTP Sessions</title>
          <author fullname="C. Perkins" initials="C." surname="Perkins"/>
          <author fullname="V. Singh" initials="V." surname="Singh"/>
          <date month="March" year="2017"/>
          <abstract>
            <t>The Real-time Transport Protocol (RTP) is widely used in telephony, video conferencing, and telepresence applications. Such applications are often run on best-effort UDP/IP networks. If congestion control is not implemented in these applications, then network congestion can lead to uncontrolled packet loss and a resulting deterioration of the user's multimedia experience. The congestion control algorithm acts as a safety measure by stopping RTP flows from using excessive resources and protecting the network from overload. At the time of this writing, however, while there are several proprietary solutions, there is no standard algorithm for congestion control of interactive RTP flows.</t>
            <t>This document does not propose a congestion control algorithm. It instead defines a minimal set of RTP circuit breakers: conditions under which an RTP sender needs to stop transmitting media data to protect the network from excessive congestion. It is expected that, in the absence of long-lived excessive congestion, RTP applications running on best-effort IP networks will be able to operate without triggering these circuit breakers. To avoid triggering the RTP circuit breaker, any Standards Track congestion control algorithms defined for RTP will need to operate within the envelope set by these RTP circuit breaker algorithms.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="8083"/>
        <seriesInfo name="DOI" value="10.17487/RFC8083"/>
      </reference>
      <reference anchor="RFC8290">
        <front>
          <title>The Flow Queue CoDel Packet Scheduler and Active Queue Management Algorithm</title>
          <author fullname="T. Hoeiland-Joergensen" initials="T." surname="Hoeiland-Joergensen"/>
          <author fullname="P. McKenney" initials="P." surname="McKenney"/>
          <author fullname="D. Taht" initials="D." surname="Taht"/>
          <author fullname="J. Gettys" initials="J." surname="Gettys"/>
          <author fullname="E. Dumazet" initials="E." surname="Dumazet"/>
          <date month="January" year="2018"/>
          <abstract>
            <t>This memo presents the FQ-CoDel hybrid packet scheduler and Active Queue Management (AQM) algorithm, a powerful tool for fighting bufferbloat and reducing latency.</t>
            <t>FQ-CoDel mixes packets from multiple flows and reduces the impact of head-of-line blocking from bursty traffic. It provides isolation for low-rate traffic such as DNS, web, and videoconferencing traffic. It improves utilisation across the networking fabric, especially for bidirectional traffic, by keeping queue lengths short, and it can be implemented in a memory- and CPU-efficient fashion across a wide range of hardware.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="8290"/>
        <seriesInfo name="DOI" value="10.17487/RFC8290"/>
      </reference>
    </references>
    <?line 791?>

<section anchor="ewma-implementation">
      <name>Dual-variable EWMA Process Implementation</name>
      <t>All variables are initialized at zero. When receiving a new sample
<tt>(NSEND, NRECV)</tt>, the EWMA process <bcp14>SHOULD</bcp14> be updated as follow:</t>
      <artwork><![CDATA[
COUNT = COUNT + 1
WEIGHT = max(LAMBDA, 1.0/COUNT)
DELTA_NSEND = NSEND - AVG_NSEND
DELTA_NRECV = NRECV - AVG_NRECV
AVG_NSEND += WEIGHT * DELTA_NSEND
AVG_NRECV += WEIGHT * DELTA_NRECV
VAR_NSEND = (1 - WEIGHT) * (VAR_NSEND + WEIGHT * DELTA_NSEND^2)
VAR_NRECV = (1 - WEIGHT) * (VAR_NRECV + WEIGHT * DELTA_NRECV^2)
COVAR = (1 - WEIGHT) * (COVAR + WEIGHT * DELTA_NSEND * DELTA_NRECV)
]]></artwork>
      <t><tt>COUNT</tt> is also initialized at zero and the weight <tt>1.0/COUNT</tt> is used
at the beginning to ensure initial values get equal weights and prevent
the very first value from having an unreasonably large effect on the average.</t>
    </section>
    <section anchor="estimate-implementation">
      <name>Estimate Implementation</name>
      <t><tt>ESTIMATE</tt> is calculated step-by-step with <tt>ITERATIONS</tt> iterations, and the
<bcp14>RECOMMENDED</bcp14> value for <tt>ITERATIONS</tt> is 3. In a CPU-constrained environment,
for instance if NDTC runs for a very large number of parallel sessions,
the loop <bcp14>MAY</bcp14> therefore be unrolled, making <tt>ESTIMATE</tt> linear according to
<tt>AVG_NRECV</tt>:</t>
      <t><tt>
ESTIMATE = SLOPE^3 * AVG_NRECV + (SLOPE^2 + SLOPE + 1) * INTERCEPT
</tt></t>
    </section>
    <section anchor="aimd-implementation">
      <name>AIMD Logic Implementation</name>
      <t>On frame feedback, the agent <bcp14>SHOULD</bcp14> run the following AIMD logic to update
the congestion frame size <tt>CSIZE</tt>:</t>
      <artwork><![CDATA[
ecn_gain = 1.0 / 16.0
ecn_fraction = float(ecn_marking_count) / float(packet_count)
ecn_average = ecn_gain * (ecn_fraction - ecn_average)

// Multiplicative decrease
if (last_decrease_time > first_packet_send_time) {
    // Suppress decrease for one round-trip
} else if (packet_lost_count > 0) {
    // Loss decrease
    CSIZE = min(CSIZE, CMAX) * BETA
    last_decrease_time = now()
} else if (last_ecn_decrease_time < first_packet_send_time) {
    // Suppress ECN decrease for one round-trip
} else if (ecn_marking_count > 0) {
    // ECN decrease
    CSIZE = min(CSIZE, CMAX) * (1.0 - ecn_average * (1.0 - BETA))
    last_ecn_decrease_time = now()
}

// Additive increase (suppressed after loss but not ECN decrease)
if (last_decrease_time <= first_packet_send_time && CSIZE < CMAX) {
    if (last_ecn_decrease_time <= last_decrease_time) {
        CSIZE = min(CSIZE + ALPHA, CMAX)
    } else {
        CSIZE = min(CSIZE + EALPHA * (1.0 - ecn_fraction), CMAX)
    }
}
]]></artwork>
      <t>This algorithm uses logic close to a Prague congestion controller
<xref target="draft-briscoe-iccrg-prague-congestion-control"/>, it also uses
the recommended ECN gain 1/16. For a new flow, <tt>ecn_average</tt>
        <bcp14>SHOULD</bcp14> be initialized to 1.0.</t>
      <t>If ECN is not supported, the AIMD logic <bcp14>MAY</bcp14> be simplified to only the
multiplicative decrease on packet loss (suppressed for one round-trip)
and the additive increase otherwise.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
hZP6rp7xn7WFpIb+NtTW372HvXSG/b8/Sibx+9idpGcj/fNIgT7z6Tu20t/e
qHe+2KmJQ83Hah5h/Q8Po9tRmWe/3zJpsyo3m/kj+zdTaqDTSAa/rhrSXTNK
H93pJdXUDM4Q0GgQeyvaJEkvyRJNu4LsqPeh/8b+iE1O2XefzZY2bvEmBIIC
sWvNWbmaZeDK9800lTeKkl5wYmmzgRJou1iZnXZPWx8xCkw+2EkkDEqtvS3a
rcgpWYuxg2XL7glu2e364/2x/66Wytfr4Ob+8enrg9Pw80jaNxadGhnJNwnR
RYQLgPUrZb4jR8hID+dZSLFyT3lCND+9GhKEtI9Fa59gKP74p9fzxTsEqPQA
4+5eWLAwt/oyDe7DaYnrGw84n8umRgU4t1sGm3AkUUJNyBmgaHzmKz1gXMIg
bLcygRKHX48Vb0AH7F1KEcu9Z9kS/J+0I106c++k7qTg/0JTuyQrGznoiGZX
N2r1+jZW7cC0NX9IDaUfMow76MCk9P1IZVPcW3hWQSUskh45ozRHV0sJuOLi
fZeb79v9akL5oecQkSfAmkMxu+cJuXOaLJlN1lIl+9DZrjtv9Ct6pqXsijeT
zCzvaMPMfk/3dj7GXTFx+CyaaOYNstavKaS3WyikuMawMTqf2sStmr4P+RMp
sHh9T9KHnEVsfNsoXwYCrrHaShPCt3Bm6KWq9S1pxq8vVSt8YzzNpW7KSyQa
sLrhiXyETcQGUI3jSs+ZL+DDp5eR0cYfLeBKp5I/WFjGbrexR7nUavvQXujq
pNjUOEkqDT4LXwccmoWHGRNJYqLg4NqTq7pEIm07I8xpy4vyRvoj89RJL1xu
Ztt2IzuOSS/wafS7Pd53mfBKlkz6QQ8su9AQYY0nMD1uJ58h4Nubxs1kYJH6
N211Htuy68s9ZMoOpphw6UvEhDHIgvxhCa3KR/L7dYG/TuDgt8fSL4LDA82W
VzArG/LBNsWXpPEvI6TUK7G2eyMNpSTLOCmtSsQ6+3ieFWWzQprEcf7dWNKB
9BdCeropDg8HckoSWuSLZ7+kXzwLCbx9A0wMAIUvoPqlAFntNDLSdEBxnfb0
fGAPqmE2Il8UcNqSgQv8089MERU4UMqQo9sDO8XnrhJmLwlsBT6oxfRRrN7x
RBBDiOFfrrRea6XyWZqpNOl3R3xCcfYVmeRDLcl31JBHLmVU3AJXHJKXm4Iu
pnNO+vNw1ip2lH6eNjSlGOqBQrj+ob2jRcjuraI/CF9o+mlYnicB/iDJBrBk
sRVgAVP+sJhGmD67L0ls4c/eYf3+w0CSL3zGw5ZHFyryn4fH9VMXep8/+sPh
x4/4tBh/XPvDB3y1G5nk2VdZ0/yIYquFUhqolDhJ5Yor0V9jrgV/Uth/Wa/z
H80rV+GjaJwjotg6CnSRfM84t4hEhrlYBN9TIGxwpN+QsHnz5ssvLXy58I8n
3yzyRXf+wxncl2ndlGA2Gmadbqp3Sdl66FvPRMiaLXeU6dQARMVA8glUL4dj
oYOR7k+aQ3lnlQCat3Mafru5xE/3ppenXy0MBM9xUvTn1jX0y9vhC3TcQF6w
fLxKii4LTtb132eIjfqJMu6pQ8S5NRtG2i+kQFD9KfvMLCoPr5yQ2JkjcQiI
79BUq7+AsPiDkEA1pHlA6JfIFcZXjucI3iGu3dTrnnbGBNKVygAZKFENf+mc
ZLLpko8t5lXJtSr/JFE7DhNieNppOfn8naSH6VdBGOR5o/6oruDbLqJx8D51
10Y/FujL0ep5bIYvi57R7Bq1FU7Z1uuFFA5LWilAxN8U2IKWfvz4Sr+uXtzk
ka6s6nJZrMq1tqDiHuitVse90zb2pOyFRkzeqjR3lHVnzaLubzeg4NGAdbgh
yfvZrTQWdYGQ1GdkSWxl/HK8hUnbn3tfcGMUebMIn+TA5+JxS/y11Ke77QVf
a4rtVvDmw8O+9oKEsFWV+H+hZKYVbbTrX1xTj6TYMRZLFEkbR7PdxlEgmPU6
jBas7wcZ0oN8UcGrH1+ec+sM/PdLe2R+Pjn9/gef0i5ucm72d8Cv7Bt2vb/1
LXLlv8PYyc//7nstace/2LwnvGm//NbqYprpozPEToE9b/AcsbvHt5LFKG9x
EUT87cve6f/+aN/EJiJ3jJfVexfHeGmHuDtWnvevm8/iex0yUCfh8xo9SBCy
iTQwMQl3EXxhRmOoU3dZ6od3QoDVh7I04RZKl/SxkumEdj1NcfYcf0iGjQJN
XwUL0s+ucKcxWEk1UjBufHNUrr72PbvUvGVy89956CGLO/oNGZO11sryJzq3
Hk5JDaP/ajZu1nEqxLdCn1FzRzLuVqOqxxytLu5rpDQwuaqk39PiulYxLGN7
jKRDV0igaJ3ma+T9mLoQuk46Mw3AS/l7dhES6sjP046jo5moeTKZmO2OV39/
7JtsKkJL9cvfH4UcO6J4YG5shoVpoNhCJ3nOSvPO1fWpGca88nVWXp71uE9g
hndZUKyvHtioXO4t3+KiLGVebrZ6ix5ioSfO0W9Hh/w0NDD8FsK26PbwUD8V
85b9BchEk59ExulTHu0dNN/asAIRdzbv0CYv7htzcLD9iVrvTuBGRnDqvPVP
3nI7mz8Kkb3V5aHA8g++oxHNeKZ1qjEMuluu6lsUYRWdCsayHAc9kpL52LkS
9oWHDM6eSjY6L4Kz/E7P3r9FxcLefro2vwWY5G9+8ytOmZWO3n/SnevcOmk6
1acOugfcye4zPgQQ9vcjGHYPGEDBODDeCX/vJcXG4lxllwGMYVic6Ub370KV
b769A4poiCUn+0aPIxC470K+7blQP64XUsQjONLvixzxUtYX665RkiCQQ9gT
0H42W9aCL/pz+CukwhyiJXevWWR+bf10cJlgLf3uZsxjwe0w+R8dEGvh3HRR
wS64h+IkwZmJubM5gTSyujcPNGGD2qZPWv6huIi/wYPMXgi0u/Ijap90KOi1
d2+Ju3z0jrnzDr5yVcJ12UJ+/393XoROrZQAAA==

-->

</rfc>
