<?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.30 (Ruby 3.4.8) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ageneau-ccwg-ndtc-01" 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-01"/>
    <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="2026" month="March" day="02"/>
    <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 each video frame's packets at a rate between 1x and 2x (on average)
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. Importantly, 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 mean 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 on 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 are 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 described 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, because the durations are typically around a few
milliseconds only, and 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 retains the <tt>TARGET</tt> and <tt>SLOPE</tt> values from the most recent frame
for which FDACE ran 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).
<tt>SEND</tt> <bcp14>MUST</bcp14> be the actual duration over which the pacer sent the frame,
not the calculated target duration from <xref target="pacer"/>.
Packet send times <bcp14>SHOULD</bcp14> be measured as close to 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 && COVAR > 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 bottleneck 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 constrained 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 idea is that when the model fits poorly,
the agent should add a higher margin as a safety buffer.
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 <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 too close to 0 makes the algorithm react slower to abrupt
changes. A value too high for <tt>KMARGIN</tt> 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
the sum <tt>ESTIMATE + 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 FDACE 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 FDACE 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 reduction.</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>. This is obtained by solving for <tt>CSLOPE</tt> in the pacer
equation in <xref target="pacer"/> such that when <tt>LENGTH = TARGET</tt>, the send
duration results in an effective send rate of <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_TARGET</tt> with codec-specific bitstream filler
data if it is smaller. A frame of size <tt>MIN_TARGET</tt> or larger <bcp14>MUST</bcp14> be packetized
in at 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> value 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
minimises 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 regular frame period intervals:</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 an absolute precision of at least 1ms.
It <bcp14>MUST</bcp14> prevent cumulative 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>
            <tr>
              <td align="left">
                <tt>TFRAME</tt></td>
              <td align="left">video frame period</td>
              <td align="left">seconds</td>
              <td align="left">application-specific</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 FDACE</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>CSIZE</tt></td>
              <td align="left">AIMD 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 packets 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 misclassifying 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
Forward 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 seamlessly transition between L4S and
standard bottlenecks as the network path evolves.</t>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>An attacker who could insert, edit, or drop messages from the connection could
cause NDTC to underutilize the path capacity or overshoot 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 from causing 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 798?>

<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>
      <artwork><![CDATA[
ESTIMATE = SLOPE^3 * AVG_NRECV + (SLOPE^2 + SLOPE + 1) * INTERCEPT
]]></artwork>
    </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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
AAA=

-->

</rfc>
