Skip to content

Commit a09f047

Browse files
authored
Merge pull request #110 from youennf/ensure-encodder-order
Ensure receiver-side transform order is the same as sender-side transform order
2 parents f9d5d59 + 7f10c04 commit a09f047

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

index.bs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ At construction of each {{RTCRtpSender}} or {{RTCRtpReceiver}}, run the followin
100100
7. <a dfn for="WritableStream">Set up</a> [=this=].`[[writable]]` with its [=WritableStream/set up/writeAlgorithm=] set to [=writeEncodedData=] given |this| as parameter.
101101
8. Set [=this=].`[[writable]]`.`[[owner]]` to |this|.
102102
9. Initialize [=this=].`[[pipeToController]]` to null.
103-
10. Initialize [=this=].`[[lastReceivedFrameTimestamp]]` to zero.
104-
11. [=Queue a task=] to run the following steps:
103+
1. Initialize [=this=].`[[lastReceivedFrameCounter]]` to <code>0</code>.
104+
1. Initialize [=this=].`[[lastEnqueuedFrameCounter]]` to <code>0</code>.
105+
1. [=Queue a task=] to run the following steps:
105106
1. If [=this=].`[[pipeToController]]` is not null, abort these steps.
106107
2. Set [=this=].`[[pipeToController]]` to a new {{AbortController}}.
107108
<!-- FIXME: Use pipeTo algorithm when available. -->
@@ -111,19 +112,28 @@ At construction of each {{RTCRtpSender}} or {{RTCRtpReceiver}}, run the followin
111112

112113
The <dfn>readEncodedData</dfn> algorithm is given a |rtcObject| as parameter. It is defined by running the following steps:
113114
1. Wait for a frame to be produced by |rtcObject|'s encoder if it is a {{RTCRtpSender}} or |rtcObject|'s packetizer if it is a {{RTCRtpReceiver}}.
114-
2. Let |frame| be the newly produced frame.
115-
3. Set |frame|.`[[owner]]` to |rtcObject|.
116-
4. [=ReadableStream/Enqueue=] |frame| in |rtcObject|.`[[readable]]`.
115+
1. Increment |rtcObject|.`[[lastEnqueuedFrameCounter]]` by <code>1</code>.
116+
1. Let |frame| be the newly produced frame.
117+
1. Set |frame|.`[[owner]]` to |rtcObject|.
118+
1. Set |frame|.`[[counter]]` to |rtcObject|.`[[lastEnqueuedFrameCounter]]`.
119+
1. [=ReadableStream/Enqueue=] |frame| in |rtcObject|.`[[readable]]`.
117120

118121
The <dfn>writeEncodedData</dfn> algorithm is given a |rtcObject| as parameter and a |frame| as input. It is defined by running the following steps:
119122
1. If |frame|.`[[owner]]` is not equal to |rtcObject|, abort these steps and return [=a promise resolved with=] undefined. A processor cannot create frames, or move frames between streams.
120-
2. If the |frame|'s {{RTCEncodedVideoFrame/timestamp}} is equal to or larger than |rtcObject|.`[[lastReceivedFrameTimestamp]]`, abort these steps and return [=a promise resolved with=] undefined. A processor cannot reorder frames, although it may delay them or drop them.
121-
3. Set |rtcObject|.`[[lastReceivedFrameTimestamp]]` to the |frame|'s {{RTCEncodedVideoFrame/timestamp}}.
123+
1. If |frame|.`[[counter]]` is equal or smaller than |rtcObject|.`[[lastReceivedFrameCounter]]`, abort these steps and return [=a promise resolved with=] undefined. A processor cannot reorder frames, although it may delay them or drop them.
124+
1. Set |rtcObject|.`[[lastReceivedFrameCounter]]` to |frame|`[[counter]]`.
122125
4. Enqueue the frame for processing as if it came directly from the encoded data source, by running one of the following steps:
123126
* If |rtcObject| is a {{RTCRtpSender}}, enqueue it to |rtcObject|'s packetizer, to be processed [=in parallel=].
124127
* If |rtcObject| is a {{RTCRtpReceiver}}, enqueue it to |rtcObject|'s decoder, to be processed [=in parallel=].
125128
5. Return [=a promise resolved with=] undefined.
126129

130+
On sender side, as part of [=readEncodedData=], frames produced by |rtcObject|'s encoder MUST be enqueued in |rtcObject|.`[[readable]]` in the encoder's output order.
131+
As [=writeEncodedData=] ensures that the transform cannot reorder frames, the encoder's output order is also the order followed by packetizers to generate RTP packets and assign RTP packet sequence numbers.
132+
133+
On receiver side, as part of [=readEncodedData=], frames produced by |rtcObject|'s packetizer MUST be enqueued in |rtcObject|.`[[readable]]` in the same encoder's output order.
134+
To ensure the order is respected, the depacketizer will typically use RTP packet sequence numbers to reorder RTP packets as needed before enqueuing frames in |rtcObject|.`[[readable]]`.
135+
As [=writeEncodedData=] ensures that the transform cannot reorder frames, this will be the order expected by |rtcObject|'s decoder.
136+
127137
## Extension attribute ## {#attribute}
128138

129139
A RTCRtpTransform has two private slots called `[[readable]]` and `[[writable]]`.

0 commit comments

Comments
 (0)