From 230f64fe66f2e50700462aee6f79e362d1fe7561 Mon Sep 17 00:00:00 2001 From: philipel Date: Mon, 3 Jun 2024 11:39:58 +0200 Subject: [PATCH 1/2] Merge the API into one file --- api-outline.md | 180 ++++++++++++++++++++++++++++++++++++++++ explainer-use-case-1.md | 117 -------------------------- explainer-use-case-2.md | 75 ----------------- 3 files changed, 180 insertions(+), 192 deletions(-) create mode 100644 api-outline.md diff --git a/api-outline.md b/api-outline.md new file mode 100644 index 0000000..78b3cfc --- /dev/null +++ b/api-outline.md @@ -0,0 +1,180 @@ +# API Outline + +```javascript +interface RtpPacket { + constructor(required RtpPacketInit); + readonly attribute bool marker; + readonly attribute octet payloadType; + readonly attribute unsigned short sequenceNumber; + readonly attribute unsigned long timestamp; + readonly attribute unsigned long ssrc; + readonly attribute sequence csrcs; + readonly attribute sequence headerExtensions; + + // Write payload to the specified (Shared-)ArrayBuffer/ArrayBufferView, + // allowing for BYOB. + undefined copyPayloadTo(AllowSharedBufferSource destination); + + // OPTIONAL: Duplicate with header extensions, but conveniently parsed + readonly attribute DOMString? mid; + readonly attribute DOMString? rid; + attribute octet? audioLevel; + attribute octet? videoRotation; + readonly attribute unsigned long long? remoteSendTimestamp; + + // OPTIONAL: Extra information that may be useful to know + readonly attribute DOMHighResTimeStamp receivedTime; + readonly attribute unsigned long sequenceNumberRolloverCount; + + void setHeaderExtension(RtpHeaderExtension); +} + +interface RtpHeaderExtension { + constructor(required RtpHeaderExtensionInit); + readonly attribute DOMString uri; + readonly attribute ArrayBuffer value; + undefined copyValueTo(AllowSharedBufferSource destination); +} + +dictionary RtpPacketInit { + bool marker = false; + required octet payloadType; + required unsigned long timestamp; + sequence csrcs = []; + // Cannot be MID, RID, or congestion control sequence number + sequence headerExtensions = []; + required AllowSharedBufferSource payload; + + // Convenience for adding to headerExtensions + octet audioLevel; + octet videoRotation; +} + +dictionary RtpHeaderExtensionInit { + required DOMString uri; + required AllowSharedBufferSource value; +} + +``` +### PeerConnection, RtpSendStream, RtpReceiveStream Extensions + +```javascript +partial interface PeerConnection { + // There may be an RtpTransport with no RtpSenders and no RtpReceivers. + readonly attribute RtpTransport? rtpTransport; +} + +// Add this to RTCConfiguration +dictionary RTCConfiguration { + // Means "continue to encode and packetize packets, but don't send them. + // Instead give them to me via onpacketizedrtpavailable/readPacketizedRtp + // and I will send them." + // TODO: Think of a better name + bool customPacer; +} + +partial interface RtpSender { + // shared between RtpSenders in the same BUNDLE group + readonly attribute RtpTransport? rtpTransport; + Promise> replaceSendStreams(); +} + +partial interface RtpReceiver { + // shared between RtpSenders in the same BUNDLE group + readonly attribute RtpTransport? rtpTransport; + Promise> replaceReceiveStreams(); +} + +interface RtpTransport { + Promise addRtpSendStream(RtpSendStreamInit); + Promise addRtpReceiveStream(RtpReceiveStreamInit); + attribute EventHandler onrtpsent; // RtpSent + attribute EventHandler onrtpacksreceived; // RtpAcks + attribute EventHandler onpacketizedrtpavailable; // No payload. Call readPacketizedRtp + sequence readPacketizedRtp(maxNumberOfPackets); + + readonly attribute unsigned long bandwidthEstimate; // bps + readonly attribute unsigned long allocatedBandwidth; // bps + attribute unsigned long customAllocatedBandwidth; // writable + // Means "when doing bitrate allocation and rate control, don't use more than this" + attribute unsigned long customMaxBandwidth; + // Means "make each packet smaller by this much so I can put custom stuff in each packet" + attribute unsigned long customPerPacketOverhead; +} + +// RFC 8888 or Transport-cc feedback +interface RtpAcks { + readonly attribute sequence 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 { + // ECT = ECN-Capable Transport + "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 +} + +[Exposed=(Window,Worker), Transferable] +interface RtpSendStream { + readonly attribute DOMString mid?; // Shared among many RtpSendStreams + readonly attribute DOMString rid?; // Unique to RtpSendStream (scoped to MID) + readonly attribute unsigned long ssrc; + readonly attribute unsigned long rtxSsrc; + + attribute EventHandler onpacketizedrtp; + sequence readPacketizedRtp(long maxNumberOfPackets); + + // https://github.com/w3c/webrtc-rtptransport/issues/32 + void sendRtp(RtpPacket packet); + Promise sendRtp(RtpPacketInit packet, RtpSendOptions options); + + // Amount allocated by the browser + readonly attribute unsigned long allocatedBandwidth; +} + +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", +}; + +dictionary RtpSendOptions { + DOMHighResTimeStamp sendTime; +} + +[Exposed=(Window,Worker), Transferable] +interface RtpReceiveStream { + readonly attribute DOMString mid?; // Shared among many RtpReceivetreams + readonly attribute DOMString rid?; // Unique to RtpReceiveStream (scoped to MID) + readonly attribute sequence ssrcs; + readonly attribute sequence rtxSsrcs; + + attribute EventHandler onreceivedrtp; + sequence readReceivedRtp(long maxNumberOfPackets); + + void receiveRtp(RtpPacket packet) +} +``` \ No newline at end of file diff --git a/explainer-use-case-1.md b/explainer-use-case-1.md index fa9cf7a..dd088e0 100644 --- a/explainer-use-case-1.md +++ b/explainer-use-case-1.md @@ -34,123 +34,6 @@ Complexities of sending and receiving RTP other than these requirements are stil particular Pacing of sent packets on the wire, inclusion of padding to support bandwidth probing, and RTP Sequence Numbering taking into account such padding. -## API Outline - -### RtpPacket, RtcpPacket - -```javascript -interface RtpPacket { - constructor(required RtpPacketInit); - readonly attribute bool marker; - readonly attribute octet payloadType; - readonly attribute unsigned short sequenceNumber; - readonly attribute unsigned long timestamp; - readonly attribute unsigned long ssrc; - readonly attribute sequence csrcs; - readonly attribute sequence headerExtensions; - - // Write payload to the specified (Shared-)ArrayBuffer/ArrayBufferView, - // allowing for BYOB. - undefined copyPayloadTo(AllowSharedBufferSource destination); - - // OPTIONAL: Duplicate with header extensions, but conveniently parsed - readonly attribute DOMString? mid; - readonly attribute DOMString? rid; - attribute octet? audioLevel; - attribute octet? videoRotation; - readonly attribute unsigned long long? remoteSendTimestamp; - - // OPTIONAL: Extra information that may be useful to know - readonly attribute DOMHighResTimeStamp receivedTime; - readonly attribute unsigned long sequenceNumberRolloverCount; - - void setHeaderExtension(RtpHeaderExtension); -} - -interface RtpHeaderExtension { - constructor(required RtpHeaderExtensionInit); - readonly attribute DOMString uri; - undefined copyValueTo(AllowSharedBufferSource destination); -} - -dictionary RtpPacketInit { - bool marker = false; - required octet payloadType; - required unsigned long timestamp; - sequence csrcs = []; - // Cannot be MID, RID, or congestion control sequence number - sequence headerExtensions = []; - required AllowSharedBufferSource payload; - - // Convenience for adding to headerExtensions - octet audioLevel; - octet videoRotation; -} - -dictionary RtpHeaderExtensionInit { - required DOMString uri; - required AllowSharedBufferSource value; -} - -``` -### RTCPeerConnection, RTCRtpSender, RTCRtpReceiver Extensions - -```javascript -partial interface PeerConnection { - // There may be an RtpTransport with no RtpSenders and no RtpReceivers. - readonly attribute RtpTransport? rtpTransport; -} -partial interface RtpSender { - // shared between RtpSenders in the same BUNDLE group - readonly attribute RtpTransport? rtpTransport; - Promise> replaceSendStreams(); -} -partial interface RtpReceiver { - // shared between RtpSenders in the same BUNDLE group - readonly attribute RtpTransport? rtpTransport; - Promise> replaceReceiveStreams(); -} - -interface RtpTransport { - Promise addRtpSendStream(RtpSendStreamInit); - Promise addRtpReceiveStream(RtpReceiveStreamInit); - readonly attribute unsigned long bandwidthEstimate; // bps - readonly attribute unsigned long allocatedBandwidth; // bps - attribute unsigned long customAllocatedBandwidth; // writable -} - -[Exposed=(Window,Worker), Transferable] -interface RtpSendStream { - readonly attribute DOMString mid?; // Shared among many RtpSendStreams - readonly attribute DOMString rid?; // Unique to RtpSendStream (scoped to MID) - readonly attribute unsigned long ssrc; - readonly attribute unsigned long rtxSsrc; - - attribute EventHandler onpacketizedrtp; - sequence readPacketizedRtp(long maxNumberOfPackets); - - // Takes a synchronous copy of packet.payload and packet.headerExtensions[*].value, - // allowing the underlying buffers to be reused immediately. - void sendRtp(RtpPacket packet); - - // Amount allocated by the browser - readonly attribute unsigned long allocatedBandwidth; -} - -[Exposed=(Window,Worker), Transferable] -interface RtpReceiveStream { - readonly attribute DOMString mid?; // Shared among many RtpReceivetreams - readonly attribute DOMString rid?; // Unique to RtpReceiveStream (scoped to MID) - readonly attribute sequence ssrcs; - readonly attribute sequence rtxSsrcs; - - attribute EventHandler onreceivedrtp; - sequence readReceivedRtp(long maxNumberOfPackets); - - void receiveRtp(RtpPacket packet) -} -``` - ## Examples ### Example 1: Send customized RTP header extension (audio level) diff --git a/explainer-use-case-2.md b/explainer-use-case-2.md index 409da2c..64eff05 100644 --- a/explainer-use-case-2.md +++ b/explainer-use-case-2.md @@ -19,81 +19,6 @@ Applications can do custom bandwidth estimation via: - Knowledge of when an application packet is not sent, and why. - Efficient control of when packets are sent, in order to do custom pacing and probing. -## API Outline - - -```javascript -partial interface RtpSendStream { - Promise 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", -}; - -// Add this to RTCConfiguration -dictionary RTCConfiguration { - // Means "continue to encode and packetize packets, but don't send them. - // Instead give them to me via onpacketizedrtpavailable/readPacketizedRtp - // and I will send them." - // TODO: Think of a better name - bool customPacer; -} - -partial interface RtpTransport { - attribute EventHandler onrtpsent; // RtpSent - attribute EventHandler onrtpacksreceived; // RtpAcks - // Means "when doing bitrate allocation and rate control, don't use more than this" - attribute unsigned long customMaxBandwidth; - // Means "make each packet smaller by this much so I can put custom stuff in each packet" - attribute unsigned long customPerPacketOverhead; - - attribute EventHandler onpacketizedrtpavailable; // No payload. Call readPacketizedRtp - sequence readPacketizedRtp(maxNumberOfPackets); -} - -// RFC 8888 or Transport-cc feedback -interface RtpAcks { - readonly attribute sequence 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 { - // ECT = ECN-Capable Transport - "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 -} -``` - ## Examples ## Example 1: Custom BWE From 6e6f637202438e07463cda939f5244159549d2a0 Mon Sep 17 00:00:00 2001 From: philipel Date: Mon, 10 Jun 2024 16:52:16 +0200 Subject: [PATCH 2/2] Remove associated RTX SSRCs from RtpSendStream and RtpReceiveStream. --- api-outline.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/api-outline.md b/api-outline.md index 78b3cfc..e639887 100644 --- a/api-outline.md +++ b/api-outline.md @@ -130,7 +130,6 @@ interface RtpSendStream { readonly attribute DOMString mid?; // Shared among many RtpSendStreams readonly attribute DOMString rid?; // Unique to RtpSendStream (scoped to MID) readonly attribute unsigned long ssrc; - readonly attribute unsigned long rtxSsrc; attribute EventHandler onpacketizedrtp; sequence readPacketizedRtp(long maxNumberOfPackets); @@ -170,7 +169,6 @@ interface RtpReceiveStream { readonly attribute DOMString mid?; // Shared among many RtpReceivetreams readonly attribute DOMString rid?; // Unique to RtpReceiveStream (scoped to MID) readonly attribute sequence ssrcs; - readonly attribute sequence rtxSsrcs; attribute EventHandler onreceivedrtp; sequence readReceivedRtp(long maxNumberOfPackets);