Skip to content

Commit

Permalink
Add "Use Case 2"
Browse files Browse the repository at this point in the history
  • Loading branch information
pthatcher committed Mar 26, 2024
1 parent e69abff commit 91c4935
Showing 1 changed file with 118 additions and 0 deletions.
118 changes: 118 additions & 0 deletions explainer-use-case-2.md
@@ -0,0 +1,118 @@
# Custom Congestion Control Use Case

## Use case description

In this use case, congestion control can be done by the application, but by doing custom bandwidth estimation and custom pacing and probing.

## Goals

Enable applications to do custom bandwidth estimation by enabling them to:
- Have access to information about when RTP packets are sent and how large they are.
- Have access to information about when congestion control feedback (ack messages) are received, which per-packet information about when they were received.
- Have access to information used by L4S.
- Know when a packet sent by the application is not sent, and why.
- Efficiently control when packets are sent, in order to do custom pacing and probing.

## Key use-cases


## API Outline


```javascript
partial interface RtpSendStream {
Promise<RtpSendResult> sendRtp(RtpPacketInit packet, RtpSendOptions options);
}

dictionary RtpSendOptions {
DOMHighResTimeStamp sendTime;
}

interface RtpSendResult {
readonly attribute RtpSent sent?;
readonly attribute RtpUnsentReason unsent?;
}


interface RtpSent {
readonly attribute DOMHighResTimeStamp time;

// Can be correlated with acks
readonly attribute unsigned long long ackId?;
readonly attribute unsigned long long size;
}

enum RtpUnsentReason {
"overuse",
"transport-unavailable",
};

partial interface RtpTransport {
attribute EventHandler onrtpsent; // RtpSent
attribute EventHandler onrtpacksreceived; // RtpAcks
}


// RFC 8888 or Transport-cc feedback
interface RtpAcks {
readonly attribute sequence<RtpAck> acks;
readonly attribute unsigned long long remoteSendTimestamp;
readonly attribute DOMHighResTimeStamp receivedTime;
readonly attribute ExplicitCongestionNotification explicitCongestionNotification; // AKA "ECN"
}

interface RtpAck {
// Correlated with RtpSent.ackId
readonly attribute unsigned long long ackId;
readonly attribute unsigned long long remoteReceiveTimestamp;
}

// See RFC 3991 and RFC 3168
enum ExplicitCongestionNotification {
"unset", // AKA "Not-ECT"; Bits: 00
"scalable-congestion-not-experienced", // AKA "ECT(1)" or "Scalable" or "L4S" ; Bits: 01
"classic-congestion-not-experienced", // AKA "ECT(0)" or "Classic" or "not L4S"; Bits: 10
"congestion-experienced" // AKA "CE" or "ECN-marked" or "marked"; Bits: 11
}
```
## Proposed solutions
## Example: Custom BWE
```javascript
const [pc, rtpTransport] = setupPeerConnectionWithRtpTransport(); // Custom
const estimator = createBandwidthEstimator(); // Custom
rtpTransport.onrtpsent = (rtpSent) => {
if (rtpSent.ackId) {
estimator.rememberRtpSent(rtpSent);
}
}
rtpTransport.onrtpacksreceived = (rtpAcks) => {
for (const rtpAck in rtpAcks.acks) {
const bwe = estimator.processReceivedAcks(rtpAck);
doBitrateAllocationAndUpdateEncoders(bwe); // Custom
}
}

```
## Example: Custom Pacing and Probing
```javascript
const [pc, rtpSender1, rtpSender2] = setupPeerConnectionWithRtpSenders(); // Custom
const pacer = createPacer(); // Custom
while (true) {
// Packets are queued by using pacer.sendRtp(rtpSender, rtpPacket) instead of rtpSender.sendRtp(rtpPacket)
const [rtpSender, packet, sendTime] = await pacer.dequeue(); // Custom
const rtpSent = rtpSender.sendRtp(packet, {sendTime: sendTime});
(async () => {
pacer.handleSent(await rtpSent);
})();
}
```
## Alternative designs considered

0 comments on commit 91c4935

Please sign in to comment.