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
constructor(any worker, optional object options); // worker as DedicatedWorker.
137
+
};
138
+
139
+
typedef (SFrameTransform or RTCRtpScriptTransform) RTCRtpTransform;
140
+
118
141
// New methods for RTCRtpSender and RTCRtpReceiver
119
142
partial interface RTCRtpSender {
120
143
RTCInsertableStreams createEncodedStreams();
144
+
attribute RTCRtpTransform? transform;
121
145
};
122
146
123
147
partial interface RTCRtpReceiver {
124
148
RTCInsertableStreams createEncodedStreams();
149
+
attribute RTCRtpTransform? transform;
125
150
};
126
151
</pre>
127
152
@@ -134,31 +159,120 @@ argument, ensure that the codec is disabled and produces no output.
134
159
135
160
### Stream creation ### {#stream-creation}
136
161
137
-
Let the {{RTCRtpSender}} or {{RTCRtpReceiver}} have an internal slot,
138
-
`[[Streams]]`, initialized to null.
162
+
At construction of each {{RTCRtpSender}} or {{RTCRtpReceiver}}, run the following steps:
163
+
1. Initialize `[[Streams]]` to null.
164
+
2. Initialize `[[transform]]` to null.
165
+
3. Initialize `[[readable]]` to the result of <a href="https://streams.spec.whatwg.org/#readablestream-create">creating a</a>{{ReadableStream}}. `[[readable]]` is provided frames using the [=readEncodedData=] algorithm given |this| as parameter.
166
+
4. Set `[[readable]]`.`[[owner]]` to |this|.
167
+
5. Initialize `[[writable]]` to the result of <a href="https://streams.spec.whatwg.org/#writablestream-create">creating a</a>{{WritableStream}}, its <a href="https://streams.spec.whatwg.org/#writablestream-create-writealgorithm">writeAlgorithm</a> set to [=writeEncodedData=] given |this| as parameter.
168
+
6. Set `[[writable]]`.`[[owner]]` to |this|.
169
+
7. Initialize `[[pipeToController]]` to null.
170
+
8. Initialize `[[lastReceivedFrameTimestamp]]` to zero.
171
+
9. If the {{RTCPeerConnection}}'s configuration does not have {{RTCConfiguration/encodedInsertableStreams}} set to "true", queue a task to run the following steps:
172
+
1. If `[[pipeToController]]` is not null, abort these steps.
173
+
2. Call <a href="https://streams.spec.whatwg.org/#readable-stream-pipe-to">pipeTo</a> with `[[readable]]`, `[[writable]]`, preventClose equal to true, preventAbort equal to true, preventCancel equal to true and `[[pipeToController]]`.signal.
139
174
140
175
When {{RTCRtpSender/createEncodedStreams}}() is
141
176
called, run the following steps:
142
177
143
-
* If the {{RTCPeerConnection}}'s configuration does not have {{RTCConfiguration/encodedInsertableStreams}} set to "true", throw an {{InvalidStateError}} and abort these steps.
144
-
* If the data source does not permit access, throw an {{InvalidAccessError}} and abort these steps.
145
-
* If `[[Streams]]` is not null, throw an {{InvalidStateError}}.
146
-
* Create an {{RTCInsertableStreams}} object |s|.
147
-
* Set |s|.{{RTCInsertableStreams/readable}} to a {{ReadableStream}} representing the encoded data source.
148
-
* Set |s|.{{RTCInsertableStreams/writable}} to a {{WritableStream}} representing the encoded data sink.
149
-
* Enable the encoded data source.
150
-
* Store |s| in the internal slot `[[Streams]]`.
151
-
* Return |s|
178
+
1. If the {{RTCPeerConnection}}'s configuration does not have {{RTCConfiguration/encodedInsertableStreams}} set to "true", throw an {{InvalidStateError}} and abort these steps.
179
+
2. If the data source does not permit access, throw an {{InvalidAccessError}} and abort these steps.
180
+
3. If `[[Streams]]` is not null, throw an {{InvalidStateError}}.
181
+
4. If `[[pipeToController]]` is not null, throw an {{InvalidStateError}}.
182
+
5. Create an {{RTCInsertableStreams}} object |s|.
183
+
6. Set |s|.{{RTCInsertableStreams/readable}} to `[[readable]]`.
184
+
7. Set |s|.{{RTCInsertableStreams/writable}} to `[[writable]]`.
185
+
8. Enable the encoded data source.
186
+
9. Store |s| in the internal slot `[[Streams]]`.
187
+
10. Return |s|
152
188
153
189
### Stream processing ### {#stream-processing}
154
190
155
-
When a frame is produced from the encoded data source, place it on the
156
-
`[[Streams]]`.{{RTCInsertableStreams/readable}}.
157
-
158
-
When a frame appears on the `[[Streams]]`.{{RTCInsertableStreams/writable}}, do the following:
159
-
* Check that the frame is a a valid frame that has been created by the encoded data source; if it is not, discard it. A processor cannot create frames, or move frames between streams.
160
-
* Check that the frame's {{RTCEncodedVideoFrame/timestamp}} is equal to or larger than any previously received frame. A processor cannot reorder frames, although it may delay them or drop them.
161
-
* Process the frame as if it came directly from the encoded data source.
191
+
The <dfn>readEncodedData</dfn> algorithm is given a |rtcObject| as parameter. It is defined by running the following steps:
192
+
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}}.
193
+
2. Let |frame| be the newly produced frame.
194
+
3. Set |frame|.`[[owner]]` to |rtcObject|.
195
+
4. <a href="https://streams.spec.whatwg.org/#readablestream-enqueue">Enqueue</a> |frame| in |rtcObject|.`[[readable]]`.
196
+
197
+
The <dfn>writeEncodedData</dfn> algorithm is given a |rtcObject| as parameter and a |frame| as input. It is defined by running the following steps:
198
+
1. If |frame|.`[[owner]]` is not equal to |rtcObject|, abort these steps. A processor cannot create frames, or move frames between streams.
199
+
2. If the |frame|'s {{RTCEncodedVideoFrame/timestamp}} is equal to or larger than |rtcObject|.`[[lastReceivedFrameTimestamp]]`, abort these steps. A processor cannot reorder frames, although it may delay them or drop them.
200
+
3. Set |rtcObject|.`[[lastReceivedFrameTimestamp]]` to the |frame|'s {{RTCEncodedVideoFrame/timestamp}}.
201
+
4. Process the frame as if it came directly from the encoded data source:
202
+
* If |rtcObject| is a {{RTCRtpSender}}, enqueue it |rtcObject|'s packetizer.
203
+
* If |rtcObject| is a {{RTCRtpReceiver}}, enqueue it to |rtcObject|'s decoder.
204
+
205
+
## Extension attribute ## {#attribute}
206
+
207
+
A RTCRtpTransform has two private slots called `[[readable]]` and `[[writable]]`.
208
+
209
+
On getting the transform attribute, the user agent MUST run the following steps:
210
+
1. Let |rtcObject| be the {{RTCRtpReceiver}} or {{RTCRtpSender}} on which the getter is invoked.
211
+
2. Return |rtcObject|.`[[transform]]`.
212
+
213
+
On setting the transform attribute, the user agent MUST run the following steps:
214
+
1. Let |rtcObject| be the {{RTCRtpReceiver}} or {{RTCRtpSender}} on which the setter is invoked.
215
+
2. Let |transform| be the argument to the setter.
216
+
3. Let |checkedTransform| set to |transform| if it is not null or to an <a href="https://streams.spec.whatwg.org/#identity-transform-stream">identity transform</a> otherwise.
217
+
3. Let |reader| be the result of <a href="https://streams.spec.whatwg.org/#readablestream-get-a-reader">getting a reader</a> for |checkedTransform|.`[[readable]]`.
218
+
4. Let |writer| be the result of <a href="https://streams.spec.whatwg.org/#writablestream-get-a-writer">getting a writer</a> for |checkedTransform|.`[[writable]]`.
219
+
5. Initialize |newPipeToController| to a new AbortController.
220
+
6. If |rtcObject|.`[[pipeToController]]` is not null, run the following steps:
221
+
1. <a href="https://dom.spec.whatwg.org/#abortsignal-add">Add</a> the [=chain transform algorithm=] to |rtcObject|.`[[pipeToController]]`:
222
+
2. Call <a href="https://dom.spec.whatwg.org/#abortsignal-signal-abort">abort</a> on |rtcObject|.`[[pipeToController]]`.
223
+
7. Else, run the [=chain transform algorithm=] steps.
224
+
8. Set |rtcObject|.`[[pipeToController]]` to |newPipeToController|.
225
+
9. Set |rtcObject|.`[[transform]]` to |transform|.
226
+
227
+
The <dfn>chain transform algorithm</dfn> steps are defined as:
228
+
1. If |newPipeToController| <a href="https://dom.spec.whatwg.org/#abortsignal-aborted-flag">aborted flag</a> is true, abort these steps.
229
+
2. Call <a href="https://streams.spec.whatwg.org/#readablestreamdefaultreader-release">release</a> with |reader|.
230
+
3. Call <a href="https://streams.spec.whatwg.org/#writablestreamdefaultwriter-release">release</a> with |writer|.
231
+
4. Assert that |newPipeToController| is the same object as |rtcObject|.`[[pipeToController]]`.
232
+
5. Call <a href="https://streams.spec.whatwg.org/#readable-stream-pipe-to">pipeTo</a> with |rtcObject|.`[[readable]]`, |checkedTransform|.`[[writable]]`, preventClose equal to false, preventAbort equal to false, preventCancel equal to true and |newPipeToController|.signal.
233
+
6. Call <a href="https://streams.spec.whatwg.org/#readable-stream-pipe-to">pipeTo</a> with |checkedTransform|.`[[readable]]`, |rtcObject|.`[[writable]]`, preventClose equal to true, preventAbort equal to true, preventCancel equal to false and |newPipeToController|.signal.
234
+
235
+
This algorithm is defined so that transforms can be updated dynamically.
236
+
There is no guarantee on which frame will happen the switch from the previous transform to the new transform.
237
+
238
+
If a web application sets the transform synchronously at creation of the {{RTCRtpSender}} (for instance when calling addTrack), the transform will receive the first frame generated by the {{RTCRtpSender}}'s encoder.
239
+
Similarly, if a web application sets the transform synchronously at creation of the {{RTCRtpReceiver}} (for instance when calling addTrack, or at track event handler), the transform will receive the first full frame generated by the {{RTCRtpReceiver}}'s packetizer.
240
+
241
+
# SFrameTransform # {#sframe}
242
+
243
+
When the SFrameTransform.constructor() is invoked, run the following steps:
244
+
1. Let |transformAlgorithm| be an algorithm which takes a |frame| as input and runs the <a href="#sframe-transform-algorithm">SFrame transform algorithm</a> with |this| and |frame|.
245
+
2. Set |this|.<a href="https://streams.spec.whatwg.org/#generictransformstream-transform">`[[transform]]`</a> to the result of <a href="https://streams.spec.whatwg.org/#transformstream-create">creating a TransformStream</a>, its <a href="https://streams.spec.whatwg.org/#transformstream-create-transformalgorithm">transformAlgorithm</a> set to |transformAlgorithm|.
246
+
3. Let |options| be the method's first argument.
247
+
4. Set |this|.`[[role]]` to |options|.role.
248
+
5. Set |this|.`[[readable]]` to |this|.<a href="https://streams.spec.whatwg.org/#generictransformstream-transform">`[[transform]]`</a>.`[[readable]]`.
249
+
6. Set |this|.`[[writable]]` to |this|.<a href="https://streams.spec.whatwg.org/#generictransformstream-transform">`[[transform]]`</a>.`[[writable]]`.
The SFrame transform algorithm, given |sframe| as a SFrameTransform object and |frame|, runs these steps:
254
+
1. Let |role| be |sframe|.`[[role]]`.
255
+
2. If |frame|.`[[rtcObject]]` is a {{RTCRtpSender}}, set |role| to 'encrypt'.
256
+
3. If |frame|.`[[rtcObject]]` is a {{RTCRtpReceiver}}, set |role| to 'decrypt'.
257
+
4. Let |data| be undefined.
258
+
5. If |frame| is an ArrayBuffer, set |data| to |frame|. // FIXME Support BufferSource
259
+
6. If |frame| is an {{RTCEncodedAudioFrame}}, set |data| to |frame|.{{RTCEncodedAudioFrame/data}}
260
+
7. If |frame| is an {{RTCEncodedVideoFrame}}, set |data| to |frame|.{{RTCEncodedVideoFrame/data}}
261
+
8. If |data| is undefined, abort these steps.
262
+
9. Let |buffer| be the result of running the SFrame algorithm with |data| and |role| as parameters. This algorithm is defined by the <a href="https://datatracker.ietf.org/doc/draft-omara-sframe/">SFrame specification</a>.
263
+
10. If |frame| is an ArrayBuffer, set |frame| to |buffer|.
264
+
11. If |frame| is an {{RTCEncodedAudioFrame}}, set |frame|.{{RTCEncodedAudioFrame/data}} to |buffer|.
265
+
12. If |frame| is an {{RTCEncodedVideoFrame}}, set |frame|.{{RTCEncodedVideoFrame/data}} to |buffer|.
266
+
13. <a href="https://streams.spec.whatwg.org/#transformstream-enqueue">Enqueue</a> |frame| in |sframe|.`[[transform]]`.
267
+
268
+
# RTCRtpScriptTransform # {#scriptTransform}
269
+
270
+
When the RTCRtpScriptTransform.constructor() is invoked, run the following steps:
271
+
1. Create two <a href="https://streams.spec.whatwg.org/#identity-transform-stream">identity transforms</a> named |t1| and |t2|.
272
+
2. Set |this|.`[[writable]]` to |t1|.`[[writable]]`.
273
+
3. Set |this|.`[[readable]]` to |t2|.`[[readable]]`.
274
+
4. FIXME: transfer |t1|.`[[readable]]` and |t2|.`[[writable]]` to the dedicated worker.
275
+
5. FIXME: Create counterpart of |this| in dedicated worker, for instance expose transfered |t1|.`[[readable]]` and |t2|.`[[writable]]`.
162
276
163
277
# Privacy and security considerations # {#privacy}
0 commit comments