You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -138,6 +141,7 @@ The <dfn abstract-op>readEncodedData</dfn> algorithm is given a |rtcObject| as p
138
141
1. Increment |rtcObject|.`[[lastEnqueuedFrameCounter]]` by <code>1</code>.
139
142
1. Let |frame| be the newly produced frame.
140
143
1. Set |frame|.`[[owner]]` to |rtcObject|.
144
+
1. Set |this|.`[[writable]]` to |this|.`[[transform]]`.`[[writable]]`.
141
145
1. Set |frame|.`[[counter]]` to |rtcObject|.`[[lastEnqueuedFrameCounter]]`.
142
146
1. If the frame has been produced by a {{RTCRtpReceiver}}:
143
147
1. If the relevant RTP packet contains the
@@ -150,6 +154,7 @@ The <dfn abstract-op>readEncodedData</dfn> algorithm is given a |rtcObject| as p
150
154
[[RTP-EXT-CAPTURE-TIME#timestamp-interpolation|timestamp interpolation]] and set |frame|.`[[senderCaptureTimeOffset]]`
151
155
to the most recent value that was present.
152
156
1. Otherwise, set |frame|.`[[captureTime]]` to undefined and set |frame|.`[[senderCaptureTimeOffset]]` to undefined.
157
+
1. If |frame| was produced by a [=SFrame depacketizer=], set |frame|.`[[useSFrame]]` to true.
153
158
1. If the frame has been produced by a {{RTCRtpSender}}, set |frame|.`[[captureTime]]` to the capture timestamp
154
159
using the methodology described in [[RTP-EXT-CAPTURE-TIME#absolute-capture-timestamp]] and set frame.`[[senderCaptureTimeOffset]]`
155
160
to undefined.
@@ -162,8 +167,10 @@ The <dfn abstract-op>writeEncodedData</dfn> algorithm is given a |rtcObject| as
162
167
1. Let |data| be |frame|.`[[data]]`.
163
168
1. Let |serializedFrame| be [$StructuredSerializeWithTransfer$](|frame|, « |data| »).
164
169
1. Let |frameCopy| be [$StructuredDeserializeWithTransfer$](|serializedFrame|, |frame|'s [=relevant realm=]).
170
+
1. If |frame|.`[[useSFrame]]` is true, set |frameCopy|.`[[useSFrame]]` to true.
165
171
1. Enqueue |frameCopy| for processing as if it came directly from the encoded data source, by running one of the following steps:
166
172
* If |rtcObject| is a {{RTCRtpSender}}, enqueue |frameCopy| to |rtcObject|'s packetizer, to be processed [=in parallel=].
173
+
If |frameCopy|.`[[useSFrame]]` is true, |rtcObject|'s MUST use a [=SFrame packetizer=] or skip processing of |frameCopy|.
167
174
* If |rtcObject| is a {{RTCRtpReceiver}}, enqueue |frameCopy| it to |rtcObject|'s decoder, to be processed [=in parallel=].
168
175
1. Return [=a promise resolved with=] undefined.
169
176
@@ -177,26 +184,40 @@ As [$writeEncodedData$] ensures that the transform cannot reorder frames, this w
177
184
178
185
## Extension attribute ## {#attribute}
179
186
180
-
A RTCRtpTransform has two private slots called `[[readable]]` and `[[writable]]`.
187
+
A RTCRtpTransform has the following private slots:
188
+
1. `[[readable]]` of type {{ReadableStream}}.
189
+
1. `[[writable]]` of type {{WritableStream}}.
190
+
1. `[[owner]]` of type {{RTCRtpSender}} or {{RTCRtpReceiver}}.
191
+
1. `[[useSFrame]]` of type boolean.
181
192
182
193
Each RTCRtpTransform has an <dfn abstract-op for=RTCRtpTransform>association steps</dfn> set, which is empty by default.
183
194
184
195
The <dfn attribute for="RTCRtpSender,RTCRtpReceiver">transform</dfn> getter steps are:
185
196
1. Return [=this=].`[[transform]]`.
186
197
187
198
The `transform` setter steps are:
188
-
2. Let |transform| be the argument to the setter.
189
-
3. Let |checkedTransform| set to |transform| if it is not null or to an [=identity transform stream=] otherwise.
190
-
3. Let |reader| be the result of [=ReadableStream/getting a reader=] for |checkedTransform|.`[[readable]]`.
191
-
4. Let |writer| be the result of [=WritableStream/getting a writer=] for |checkedTransform|.`[[writable]]`.
192
-
5. Initialize |newPipeToController| to a new {{AbortController}}.
193
-
6. If [=this=].`[[pipeToController]]` is not null, run the following steps:
199
+
1. Let |transform| be the argument to the setter.
200
+
1. Let |checkedTransform| set to |transform| if it is not null or to an [=identity transform stream=] otherwise.
201
+
1. Let |reader| be the result of [=ReadableStream/getting a reader=] for |checkedTransform|.`[[readable]]`.
202
+
1. Let |writer| be the result of [=WritableStream/getting a writer=] for |checkedTransform|.`[[writable]]`.
203
+
1. Initialize |newPipeToController| to a new {{AbortController}}.
204
+
1. If [=this=].`[[pipeToController]]` is not null, run the following steps:
194
205
1. [=AbortSignal/Add=] the [$chain transform algorithm$] to [=this=].`[[pipeToController]]`'s [=AbortController/signal=].
195
206
2. [=AbortController/signal abort=] on [=this=].`[[pipeToController]]`.
196
-
7. Else, run the [$chain transform algorithm$] steps.
197
-
8. Set [=this=].`[[pipeToController]]` to |newPipeToController|.
198
-
9. Set [=this=].`[[transform]]` to |transform|.
199
-
10. Run the steps in the set of [$association steps$] of |transform| with [=this=].
207
+
1. Else, run the [$chain transform algorithm$] steps.
208
+
1. If [=this=] is a {{RTCRtpSender}}, run the following substeps:
209
+
1. Let |useSFrame| be true if [=this=] is configured to use a [=SFrame packetizer=] and false otherwise.
210
+
1. If |useSFrame| is equal to |checkedTransform|.`[[useSFrame]]`, abort these substeps.
211
+
1. Configure [=this=]'s packetizer to use SFrame if |checkedTransform|.`[[useSFrame]]` is true and to not use SFrame if |checkedTransform|.`[[useSFrame]]` is false.
212
+
1. [=Update the negotiation-needed flag=] for [=this=]'s connection.
213
+
1. Otherwise, run the following steps:
214
+
1. Let |useSFrame| be true if [=this=] is configured to use a [=SFrame depacketizer=] and false otherwise.
215
+
1. If |useSFrame| is equal to |checkedTransform|.`[[useSFrame]]`, abort these substeps.
216
+
1. Configure [=this=]'s depacketizer to use SFrame if |checkedTransform|.`[[useSFrame]]` is true and to not use SFrame if |checkedTransform|.`[[useSFrame]]` is false.
217
+
1. [=Update the negotiation-needed flag=] for [=this=]'s connection.
218
+
1. Set [=this=].`[[pipeToController]]` to |newPipeToController|.
219
+
1. Set [=this=].`[[transform]]` to |transform|.
220
+
1. Run the steps in the set of [$association steps$] of |transform| with [=this=].
200
221
201
222
The <dfn abstract-op>chain transform algorithm</dfn> steps are defined as:
202
223
1. If |newPipeToController|'s [=AbortController/signal=] is [=AbortSignal/aborted=], abort these steps.
@@ -243,7 +264,8 @@ SFrameTransform includes GenericTransformStream;
243
264
enum SFrameTransformErrorEventType {
244
265
"authentication",
245
266
"keyID",
246
-
"syntax"
267
+
"syntax",
268
+
"packetization"
247
269
};
248
270
249
271
[Exposed=(Window,DedicatedWorker)]
@@ -270,13 +292,19 @@ The <dfn constructor for="SFrameTransform" lt="SFrameTransform(options)"><code>n
270
292
5. Set |this|.`[[role]]` to |options|["{{SFrameTransformOptions/role}}"].
271
293
6. Set |this|.`[[readable]]` to |this|.`[[transform]]`.`[[readable]]`.
272
294
7. Set |this|.`[[writable]]` to |this|.`[[transform]]`.`[[writable]]`.
295
+
7. Set |this|.`[[useSFrame]]` to true.
273
296
274
297
## Algorithm ## {#sframe-transform-algorithm}
275
298
276
299
The SFrame transform algorithm, given |sframe| as a SFrameTransform object and |frame|, runs these steps:
277
300
1. Let |role| be |sframe|.`[[role]]`.
278
-
1. If |frame|.`[[owner]]` is a {{RTCRtpSender}}, set |role| to 'encrypt'.
279
-
1. If |frame|.`[[owner]]` is a {{RTCRtpReceiver}}, set |role| to 'decrypt'.
301
+
1. If |sframe|.`[[owner]]` is a {{RTCRtpSender}}, set |role| to 'encrypt'.
302
+
1. If |sframe|.`[[owner]]` is a {{RTCRtpReceiver}}, set |role| to 'decrypt'.
303
+
1. If |sframe|.`[[owner]]` is a {{RTCRtpReceiver}} and |frame|.`[[useSFrame]]` is not true, [=queue a task=] to run the following steps:
304
+
1. [=fire an event=] named {{SFrameTransform/onerror|error}} at |sframe|,
305
+
using the {{SFrameTransformErrorEvent}} interface with its {{SFrameTransformErrorEvent/errorType}} attribute set to {{SFrameTransformErrorEventType/packetization}}
306
+
and its {{SFrameTransformErrorEvent/frame}} attribute set to |frame|.
307
+
1. Abort these steps.
280
308
1. Let |data| be undefined.
281
309
1. If |frame| is a {{BufferSource}}, set |data| to |frame|.
282
310
1. If |frame| is a {{RTCEncodedAudioFrame}}, set |data| to |frame|.{{RTCEncodedAudioFrame/data}}
@@ -297,6 +325,7 @@ The SFrame transform algorithm, given |sframe| as a SFrameTransform object and |
297
325
1. If |frame| is a {{BufferSource}}, set |frame| to |buffer|.
298
326
1. If |frame| is a {{RTCEncodedAudioFrame}}, set |frame|.{{RTCEncodedAudioFrame/data}} to |buffer|.
299
327
1. If |frame| is a {{RTCEncodedVideoFrame}}, set |frame|.{{RTCEncodedVideoFrame/data}} to |buffer|.
328
+
1. Set |frame|.`[[useSFrame]]` to true.
300
329
1. [=ReadableStream/Enqueue=] |frame| in |sframe|.`[[transform]]`.
301
330
302
331
## Methods ## {#sframe-transform-methods}
@@ -309,6 +338,27 @@ The <dfn method for="SFrameTransform">setEncryptionKey(|key|, |keyID|)</dfn> met
0 commit comments