<?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.39 (Ruby 3.4.9) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ageneau-ccwg-ndtc-02" category="info" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.34.0 -->
  <front>
    <title abbrev="NDTC">Network Delivery Time Control</title>
    <seriesInfo name="Internet-Draft" value="draft-ageneau-ccwg-ndtc-02"/>
    <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="July" day="06"/>
    <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 minimizing 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 maximize 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 minimize 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 SSRC and RTP timestamp and ending
with a packet whose RTP marker 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>
        <t>NDTC can be generalized to transports with multiple video streams by running
an instance of the algorithm for each video stream. This is currently outside
the scope of this document.</t>
      </section>
      <section anchor="architecture-considerations">
        <name>Architecture Considerations</name>
        <t>NDTC can be implemented either 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_LENGTH</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>Note that the flow becomes unresponsive to congestion when the target frame size
is at <tt>MIN_TARGET</tt> (at 30fps, 2000 bytes correspond to 480Kbps), therefore,
care should be taken not to set this value too high as it could harm other flows.
This is particularly a concern in an L4S context, where the consideration is
similar to the fractional window tradeoff for a Prague congestion controller
<xref target="draft-briscoe-iccrg-prague-congestion-control"/>.</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
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 sustain 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>MIN_LENGTH</tt></td>
              <td align="left">minimum frame length to run FDACE</td>
              <td align="left">bytes</td>
              <td align="left">
                <tt>MIN_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.
It means that if the frame consists in two packets, <tt>LENGTH</tt> is half the sum of
the two payloads, i.e. the average packet size. This is why <tt>MIN_LENGTH</tt> should
be set to <tt>MIN_TARGET/2</tt>.
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 with 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>
      <t>When using L4S, this draft inherits the security considerations discussed in
<xref target="RFC9330"/>. In particular, network operators might choose to restrict or police
L4S flows. Additionally, <tt>MIN_TARGET</tt> should be set low enough to ensure NDTC
flows are responsive enough not to cause a queue to build up.</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 819?>

<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 follows:</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:
H4sIAAAAAAAAA6196XYbybHm/3yKHOmca7IbAElJ7UXj9r1oiurmaW0W2e7x
+NpCAUgQZRVQcFVBFC3JzzLPMk828UVEbkCRUvuMf7jFQlUukbFvORwOTVd2
lXts771w3XXdvLVPXFW+c82NvSxXzp7W666pq3ummE4b9w7vPbk8vWdmReeu
6ubmsS3Xi9qYeT1bFysaZ94Ui25YXLm1K7bD2ez6aried7Ph8QPTbqersm1L
GvJmQ6+en10+tfa+Laq2poHL9dxtHP3furs3sPfcvOzqpiwq/HE+/o7+Uzf0
r9eXT++Z9XY1dc1jM6dlPDazet26dbttH9uu2TpDy3xoisYVNOrPbmqL9dye
rzvXrF1nL5ti3W7qprtnsN+rpt5u6D3a6JVrO1qc37P9mX4u11f2e7xyz7x1
N/TB/LGxQ9vQvLaYF5uuwCf8yBXVsCOY4Y+qvh5W9M56dmPflXNXm3duvaWl
WvvlE1orcLq393xVlBU9B3T/q3TdYlQ3V3heNLMlPV923aZ9fHSE1/CIznPk
XzvCg6NpU1+37ggDHOHDq7Jbbqf06abYVlW9LVs9waNbzhMfYYNtl8y3+/FI
hh2V9W3D3PZ8tOxWhHSm2HbLugHIaT5rFzS+oNm9VzTX8Bkms2P5+h6/Qlss
1uU/+VgeW0LqRVW+51+cQm2js/3XWn4czeoVTbU/xfeNW78rq8rZcbMqO/rs
S6e4KvSDz85xMau7zj4p1sXy5ktHb+f8+s7Y67pZ0UfvGMkUrNU7OiDC9/mw
WRHFDhu3mj7msbqiuXJ0dv7oiJAKenP21jURVYioj3AQR3cMNzx+KAMKG3l9
efrKrlwLFLALItjXbubAT+wZ4Tot0M3t8+J9udqu7HdlBzriz8NB0/+GVoDz
w8iOw5T8C5O7fXB88nB4cjx8cBJ2uqyrlWt0WZ2n8OE1kR4h1dC9J1IE42n/
/d1/8RTD45McIq/sWfiRYXKZfW33OcGtILkY2R94HdnT5yP7tKrnq2KdPT4b
2YsNTXWVw+4bwO7kdwF206ZsZ7UblrNZczWkD662tKOwJvwTa/r3IfeFEwyP
H6Vwe8Xv/RLg/Dgi4WUvZku32exA6OWIxFlFAGqzx9+N7HeyuOzxn0b2+9ph
omLaDkm0zJmx70OAAHB9fT26dtOGeBa27t7T1PTuumuPmm4zXM4bwoyjbJxd
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
H0kj3QQTmwAA

-->

</rfc>
