-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add API and algorithm to expose transform to workers #62
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,54 +62,6 @@ an additional API on {{RTCRtpSender}} and {{RTCRtpReceiver}} to | |
insert the processing into the pipeline. | ||
|
||
<pre class="idl"> | ||
// New dictionary. | ||
dictionary RTCInsertableStreams { | ||
ReadableStream readable; | ||
WritableStream writable; | ||
}; | ||
|
||
// New enum for video frame types. Will eventually re-use the equivalent defined | ||
// by WebCodecs. | ||
enum RTCEncodedVideoFrameType { | ||
"empty", | ||
"key", | ||
"delta", | ||
}; | ||
|
||
dictionary RTCEncodedVideoFrameMetadata { | ||
long long frameId; | ||
sequence<long long> dependencies; | ||
unsigned short width; | ||
unsigned short height; | ||
long spatialIndex; | ||
long temporalIndex; | ||
long synchronizationSource; | ||
sequence<long> contributingSources; | ||
}; | ||
|
||
// New interfaces to define encoded video and audio frames. Will eventually | ||
// re-use or extend the equivalent defined in WebCodecs. | ||
[Exposed=Window] | ||
interface RTCEncodedVideoFrame { | ||
readonly attribute RTCEncodedVideoFrameType type; | ||
readonly attribute unsigned long long timestamp; | ||
attribute ArrayBuffer data; | ||
RTCEncodedVideoFrameMetadata getMetadata(); | ||
}; | ||
|
||
dictionary RTCEncodedAudioFrameMetadata { | ||
long synchronizationSource; | ||
sequence<long> contributingSources; | ||
}; | ||
|
||
[Exposed=Window] | ||
interface RTCEncodedAudioFrame { | ||
readonly attribute unsigned long long timestamp; | ||
attribute ArrayBuffer data; | ||
RTCEncodedAudioFrameMetadata getMetadata(); | ||
}; | ||
|
||
|
||
// New fields in RTCConfiguration | ||
partial dictionary RTCConfiguration { | ||
boolean encodedInsertableStreams = false; | ||
|
@@ -141,13 +93,13 @@ argument, ensure that the codec is disabled and produces no output. | |
At construction of each {{RTCRtpSender}} or {{RTCRtpReceiver}}, run the following steps: | ||
1. Initialize [=this=].`[[Streams]]` to null. | ||
2. Initialize [=this=].`[[transform]]` to null. | ||
3. Initialize [=this=].`[[readable]]` to the result of <a dfn for="ReadableStream">creating</a> a {{ReadableStream}}. `[[readable]]` is provided frames using the [=readEncodedData=] algorithm given |this| as parameter. | ||
3. Initialize [=this=].`[[readable]]` to the result of <a dfn for="ReadableStream">creating</a> a {{ReadableStream}}. [=this=].`[[readable]]` is provided frames using the [=readEncodedData=] algorithm given |this| as parameter. | ||
4. Set [=this=].`[[readable]]`.`[[owner]]` to |this|. | ||
5. Initialize [=this=].`[[writable]]` to the result of [=WritableStream/creating=] a {{WritableStream}}, its [=WritableStream/create/writeAlgorithm=] set to [=writeEncodedData=] given |this| as parameter. | ||
6. Set [=this=].`[[writable]]`.`[[owner]]` to |this|. | ||
7. Initialize [=this=].`[[pipeToController]]` to null. | ||
8. Initialize [=this=].`[[lastReceivedFrameTimestamp]]` to zero. | ||
9. If the {{RTCPeerConnection}}'s configuration does not have {{RTCConfiguration/encodedInsertableStreams}} set to "true", queue a task to run the following steps: | ||
9. If the {{RTCPeerConnection}}'s configuration does not have {{RTCConfiguration/encodedInsertableStreams}} set to "true", [=queue a task=] to run the following steps: | ||
1. If [=this=].`[[pipeToController]]` is not null, abort these steps. | ||
2. Set [=this=].`[[pipeToController]]` to a new {{AbortController}}. | ||
<!-- FIXME: Use pipeTo algorithm when available. --> | ||
|
@@ -171,7 +123,7 @@ The <dfn>readEncodedData</dfn> algorithm is given a |rtcObject| as parameter. It | |
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}}. | ||
2. Let |frame| be the newly produced frame. | ||
3. Set |frame|.`[[owner]]` to |rtcObject|. | ||
4. [=ReadableStream/enqueue=] |frame| in |rtcObject|.`[[readable]]`. | ||
4. [=ReadableStream/Enqueue=] |frame| in |rtcObject|.`[[readable]]`. | ||
|
||
The <dfn>writeEncodedData</dfn> algorithm is given a |rtcObject| as parameter and a |frame| as input. It is defined by running the following steps: | ||
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. | ||
|
@@ -245,7 +197,7 @@ The <dfn constructor for="SFrameTransform" lt="SFrameTransform(options)"><code>n | |
5. Set |this|.`[[readable]]` to |this|.`[[transform]]`.`[[readable]]`. | ||
6. Set |this|.`[[writable]]` to |this|.`[[transform]]`.`[[writable]]`. | ||
|
||
## SFrame transform algorithm ## {#sframe-transform-algorithm} | ||
## Algorithm ## {#sframe-transform-algorithm} | ||
|
||
The SFrame transform algorithm, given |sframe| as a SFrameTransform object and |frame|, runs these steps: | ||
1. Let |role| be |sframe|.`[[role]]`. | ||
|
@@ -275,20 +227,112 @@ The <dfn method for="SFrameTransform">setEncryptionKey(|key|, |keyID|)</dfn> met | |
# RTCRtpScriptTransform # {#scriptTransform} | ||
|
||
<pre class="idl"> | ||
// New enum for video frame types. Will eventually re-use the equivalent defined | ||
// by WebCodecs. | ||
enum RTCEncodedVideoFrameType { | ||
"empty", | ||
"key", | ||
"delta", | ||
}; | ||
|
||
dictionary RTCEncodedVideoFrameMetadata { | ||
long long frameId; | ||
sequence<long long> dependencies; | ||
unsigned short width; | ||
unsigned short height; | ||
long spatialIndex; | ||
long temporalIndex; | ||
long synchronizationSource; | ||
sequence<long> contributingSources; | ||
}; | ||
|
||
// New interfaces to define encoded video and audio frames. Will eventually | ||
// re-use or extend the equivalent defined in WebCodecs. | ||
[Exposed=Window] | ||
interface RTCEncodedVideoFrame { | ||
readonly attribute RTCEncodedVideoFrameType type; | ||
readonly attribute unsigned long long timestamp; | ||
attribute ArrayBuffer data; | ||
RTCEncodedVideoFrameMetadata getMetadata(); | ||
}; | ||
|
||
dictionary RTCEncodedAudioFrameMetadata { | ||
long synchronizationSource; | ||
sequence<long> contributingSources; | ||
}; | ||
|
||
[Exposed=Window] | ||
interface RTCEncodedAudioFrame { | ||
readonly attribute unsigned long long timestamp; | ||
attribute ArrayBuffer data; | ||
RTCEncodedAudioFrameMetadata getMetadata(); | ||
}; | ||
|
||
|
||
// New interfaces to expose JavaScript-based transforms. | ||
|
||
[Global=(Worker,DedicatedWorker),Exposed=DedicatedWorker] | ||
interface RTCTransformEvent : Event { | ||
readonly attribute RTCRtpScriptTransformer transformer; | ||
}; | ||
|
||
[Global=(Worker,DedicatedWorker),Exposed=DedicatedWorker] | ||
partial interface DedicatedWorkerGlobalScope : WorkerGlobalScope { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With partial interfaces in Web IDL the parent interface shouldn't be specified. I've sent #71 to fix this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in #70. |
||
attribute EventHandler onrtctransform; | ||
}; | ||
|
||
[Global=(Worker,DedicatedWorker),Exposed=DedicatedWorker] | ||
interface RTCRtpScriptTransformer { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After having tried to comprehend the overall algorithm several times, I've concluded that we should rename this object to RTCRtpScriptTransformSocket. It's not a transformer itself, it's what you plug a transform (like SframeTransform) into. |
||
readonly attribute ReadableStream readable; | ||
readonly attribute WritableStream writable; | ||
readonly attribute any options; | ||
}; | ||
|
||
[Exposed=(Window)] | ||
interface RTCRtpScriptTransform { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similarly, RTCRtpScriptTransform is not a transform. I suggest we call it RTCRtpScriptTransformController. |
||
constructor(Worker worker, optional object options); | ||
constructor(Worker worker, optional any options); | ||
// FIXME: add messaging methods. | ||
}; | ||
</pre> | ||
|
||
## Operations ## {#RTCRtpScriptTransform-operations} | ||
|
||
The <dfn constructor for="RTCRtpScriptTransform" lt="RTCRtpScriptTransform(worker, options)"><code>new RTCRtpScriptTransform(<var>worker</var>, <var>options</var>)</code></dfn> constructor steps are: | ||
1. Set |t1| to an [=identity transform stream=]. | ||
2. Set |t2| to an [=identity transform stream=]. | ||
3. Set |this|.`[[writable]]` to |t1|.`[[writable]]`. | ||
4. Set |this|.`[[readable]]` to |t2|.`[[readable]]`. | ||
5. FIXME: transfer |t1|.`[[readable]]` and |t2|.`[[writable]]` to the dedicated worker. | ||
6. FIXME: Create counterpart of |this| in dedicated worker, for instance expose transfered |t1|.`[[readable]]` and |t2|.`[[writable]]`. | ||
5. Let |serializedOptions| be the result of [$StructuredSerialize$](|object|). | ||
6. Let |serializedReadable| be the result of [$StructuredSerializeWithTransfer$](|t1|.`[[readable]]`, « |t1|.`[[readable]]` »). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the << marks be square brackets? (I think the second argument to Serialize is a transfer list) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what style is best here. |
||
7. Let |serializedWritable| be the result of [$StructuredSerializeWithTransfer$](|t2|.`[[writable]]`, « |t2|.`[[writable]]` »). | ||
8. [=Queue a task=] on the DOM manipulation [=task source=] |worker|'s global scope to run the following steps: | ||
1. Let |transformerOptions| be the result of [$StructuredDeserialize$](|serializedOptions|, the current Realm). | ||
2. Let |readable| be the result of [$StructuredDeserialize$](|serializedReadable|, the current Realm). | ||
3. Let |writable| be the result of [$StructuredDeserialize$](|serializedWritable|, the current Realm). | ||
4. Let |transformer| be a new {{RTCRtpScriptTransformer}}. | ||
5. Set |transformer|.`[[options]]` to |transformerOptions|. | ||
6. Set |transformer|.`[[readable]]` to |readable|. | ||
7. Set |transformer|.`[[writable]]` to |writable|. | ||
8. Let |event| be the result of [=creating an event=] with {{RTCTransformEvent}}. | ||
9. Set |event|.type attribute to "rtctransform". | ||
10. Set |event|.transformer to |transformer|. | ||
11. Dispatch |event| on |worker|’s global scope. | ||
|
||
// FIXME: Describe error handling (worker closing flag true at RTCRtpScriptTransform creation time. And worker being terminated while transform is processing data). | ||
|
||
## Attributes ## {#RTCRtpScriptTransformer-attributes} | ||
|
||
A RTCRtpScriptTransformer has three private slots called `[[options]]`, `[[readable]]` and `[[writable]]`. | ||
|
||
The <dfn attribute for="RTCRtpScriptTransformer">options</dfn> getter steps are: | ||
1. Return [=this=].`[[options]]`. | ||
|
||
The <dfn attribute for="RTCRtpScriptTransformer">readable</dfn> getter steps are: | ||
1. Return [=this=].`[[readable]]`. | ||
|
||
The <dfn attribute for="RTCRtpScriptTransformer">writable</dfn> getter steps are: | ||
1. Return [=this=].`[[writable]]`. | ||
|
||
|
||
# Privacy and security considerations # {#privacy} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
RTCInsertableStreams
dictionary was removed here, but it's still used as the return type of two methods in https://w3c.github.io/webrtc-insertable-streams/#specification.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that is a mistake from splitting the PR, I will add it back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#73