Skip to content

Commit 09f2655

Browse files
authored
Merge pull request #286 from w3c/transferable_raw_media
Make VideoFrame/AudioData Transferable and Serializable
2 parents f73dd2c + 8d259de commit 09f2655

File tree

1 file changed

+133
-39
lines changed

1 file changed

+133
-39
lines changed

index.src.html

Lines changed: 133 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@
452452
Run these steps:
453453
1. For each |output| in |outputs|:
454454
1. Let |data| be an {{AudioData}}, initialized as follows:
455-
1. Assign `false` to {{AudioData/[[detached]]}}.
455+
1. Assign `false` to {{platform object/[[Detached]]}}.
456456
2. Let |resource| be the [=media resource=] described by |output|.
457457
3. Let |resourceReference| be a reference to |resource|.
458458
4. Assign |resourceReference| to
@@ -890,7 +890,7 @@
890890
[=Enqueues a control message=] to encode the given |data|.
891891

892892
When invoked, run these steps:
893-
1. If the value of |data|'s {{AudioData/[[detached]]}} internal slot is
893+
1. If the value of |data|'s {{platform object/[[Detached]]}} internal slot is
894894
`true`, throw a {{TypeError}}.
895895
2. If {{AudioEncoder/[[state]]}} is not `"configured"`, throw an
896896
{{InvalidStateError}}.
@@ -1206,7 +1206,7 @@
12061206
[=Enqueues a control message=] to encode the given |frame|.
12071207

12081208
When invoked, run these steps:
1209-
1. If the value of |frame|'s {{VideoFrame/[[detached]]}} internal slot is
1209+
1. If the value of |frame|'s {{platform object/[[Detached]]}} internal slot is
12101210
`true`, throw a {{TypeError}}.
12111211
2. If {{VideoEncoder/[[state]]}} is not `"configured"`, throw an
12121212
{{InvalidStateError}}.
@@ -2150,11 +2150,32 @@
21502150
encouraged to destroy such resources quickly to reduce memory pressure and
21512151
facilitate resource reuse.
21522152

2153+
### Transfer and Serialization ### {#raw-media-serialization-and-transfer}
2154+
2155+
This section is non-normative.
2156+
2157+
{{AudioData}} and {{VideoFrame}} are both [=transferable objects|transferable=]
2158+
and [=serializable objects|serializable=] objects. Their transfer and
2159+
serialization steps are defined in [[#audiodata-transfer-serialization]] and
2160+
[[#videoframe-transfer-serialization]] respectively.
2161+
2162+
Transferring an {{AudioData}} or {{VideoFrame}} moves its `[[resource
2163+
reference]]` to the destination object and closes (as in {{AudioData/close()}})
2164+
the source object. Authors may use this facility
2165+
to move an {{AudioData}} or {{VideoFrame}} between realms without copying the
2166+
underlying [=media resource=].
2167+
2168+
Serializing an {{AudioData}} or {{VideoFrame}} effectively clones (as in
2169+
{{VideoFrame/clone()}}) the source object, resulting in two objects that
2170+
reference the same [=media resource=]. Authors may use this facility to clone
2171+
an {{AudioData}} or {{VideoFrame}} to another realm without copying the
2172+
underlying [=media resource=].
2173+
21532174
AudioData Interface {#audiodata-interface}
21542175
---------------------------------------------
21552176

21562177
<xmp class='idl'>
2157-
[Exposed=(Window,DedicatedWorker)]
2178+
[Exposed=(Window,DedicatedWorker), Serializable, Transferable]
21582179
interface AudioData {
21592180
constructor(AudioDataInit init);
21602181

@@ -2182,9 +2203,6 @@
21822203
</xmp>
21832204

21842205
### Internal Slots ###{#audiodata-internal-slots}
2185-
: <dfn attribute for=AudioData>\[[detached]]</dfn>
2186-
:: Boolean indicating whether {{AudioData/close()}} was invoked on this
2187-
{{AudioData}}.
21882206

21892207
: <dfn attribute for=AudioData>[[resource reference]]</dfn>
21902208
:: A reference to a [=media resource=] that stores the audio sample data for
@@ -2210,7 +2228,7 @@
22102228
AudioData(init)
22112229
</dfn>
22122230
1. Let |frame| be a new {{AudioData}} object, initialized as follows:
2213-
1. Assign `false` to {{AudioData/[[detached]]}}.
2231+
1. Assign `false` to {{platform object/[[Detached]]}}.
22142232
2. Assign |init|.{{AudioDataInit/format}} to
22152233
{{AudioData/[[format]]}}.
22162234
3. Assign |init|.{{AudioDataInit/sampleRate}} to
@@ -2286,7 +2304,7 @@
22862304
destination buffer.
22872305

22882306
When invoked, run these steps:
2289-
1. If the value of |frame|'s {{AudioData/[[detached]]}} internal slot is
2307+
1. If the value of |frame|'s {{platform object/[[Detached]]}} internal slot is
22902308
`true`, throw an {{InvalidStateError}} {{DOMException}}.
22912309
2. Let |copyElementCount| be the result of running the
22922310
[=Compute Copy Element Count=] algorithm with |options|.
@@ -2306,7 +2324,7 @@
23062324
:: Creates a new AudioData with a reference to the same [=media resource=].
23072325

23082326
When invoked, run these steps:
2309-
1. If the value of |frame|'s {{AudioData/[[detached]]}} internal slot is
2327+
1. If the value of |frame|'s {{platform object/[[Detached]]}} internal slot is
23102328
`true`, throw an {{InvalidStateError}} {{DOMException}}.
23112329
2. Return the result of running the [=Clone AudioData=] algorithm with
23122330
[=this=].
@@ -2315,9 +2333,7 @@
23152333
:: Clears all state and releases the reference to the [=media resource=].
23162334
Close is final.
23172335

2318-
When invoked, run these steps:
2319-
1. Assign `true` to the {{AudioData/[[detached]]}} internal slot.
2320-
2. Assign `null` to {{AudioData/[[resource reference]]}}.
2336+
When invoked, run the [=Close AudioData=] algorithm with [=this=].
23212337

23222338
### Algorithms ### {#audiodata-algorithms}
23232339

@@ -2347,14 +2363,55 @@
23472363
{{AudioData/[[resource reference]]}}.
23482364
2. Let |reference| be a new reference to |resource|.
23492365
3. Assign |reference| to {{AudioData/[[resource reference]]}}.
2350-
4. Assign the values of |data|'s {{AudioData/[[detached]]}},
2366+
4. Assign the values of |data|'s {{platform object/[[Detached]]}},
23512367
{{AudioData/[[format]]}}, {{AudioData/[[sample rate]]}},
23522368
{{AudioData/[[number of frames]]}},
23532369
{{AudioData/[[number of channels]]}}, and
23542370
{{AudioData/[[timestamp]]}} slots to the corresponding slots in
23552371
|clone|.
23562372
2. Return |clone|.
23572373

2374+
: <dfn>Close AudioData</dfn> (with |data|)
2375+
:: Run these steps:
2376+
1. Assign `true` to |data|'s {{platform object/[[Detached]]}} internal slot.
2377+
2. Assign `null` to |data|'s {{AudioData/[[resource reference]]}}.
2378+
2379+
### Transfer and Serialization ###{#audiodata-transfer-serialization}
2380+
2381+
: The {{AudioData}} [=transfer steps=] (with |value| and |dataHolder|) are:
2382+
:: 1. If |value|'s {{platform object/[[Detached]]}} is `true`, throw a
2383+
{{DataCloneError}} {{DOMException}}.
2384+
2. For all {{AudioData}} internal slots in |value|, assign the value of
2385+
each internal slot to a field in |dataHolder| with the same name as the
2386+
internal slot.
2387+
3. Run the [=Close AudioData=] algorithm with |value|.
2388+
2389+
: The {{AudioData}} [=transfer-receiving steps=] (with |dataHolder| and |value|)
2390+
are:
2391+
:: 1. For all named fields in |dataHolder|, assign the value of each named
2392+
field to the {{AudioData}} internal slot in |value| with the same name
2393+
as the named field.
2394+
2395+
: The {{AudioData}} [=serialization steps=] (with |value|, |serialized|, and
2396+
|forStorage|) are:
2397+
:: 1. If |value|'s {{platform object/[[Detached]]}} is `true`, throw a
2398+
{{DataCloneError}} {{DOMException}}.
2399+
2. If |forStorage| is `true`, throw a {{TypeError}}.
2400+
3. Let |resource| be the [=media resource=] referenced by
2401+
|value|'s {{AudioData/[[resource reference]]}}.
2402+
4. Let |newReference| be a new reference to |resource|.
2403+
5. Assign |newReference| to |serialized|.[[resource reference]].
2404+
6. For all remaining {{AudioData}} internal slots (excluding
2405+
{{AudioData/[[resource reference]]}}) in |value|, assign the value of
2406+
each internal slot to a field in |serialized| with the same name as the
2407+
internal slot.
2408+
2409+
: The {{AudioData}} [=deserialization steps=] (with |serialized| and |value|)
2410+
are:
2411+
:: 1. For all named fields in |serialized|, assign the value of each named
2412+
field to the {{AudioData}} internal slot in |value| with the same name
2413+
as the named field.
2414+
23582415
### AudioDataCopyToOptions ### {#audiodata-copy-to-options}
23592416

23602417
<xmp class='idl'>
@@ -2555,7 +2612,7 @@
25552612
{{CanvasDrawImage}}'s {{CanvasDrawImage/drawImage()}}.
25562613

25572614
<xmp class='idl'>
2558-
[Exposed=(Window,DedicatedWorker)]
2615+
[Exposed=(Window,DedicatedWorker), Serializable, Transferable]
25592616
interface VideoFrame {
25602617
constructor(CanvasImageSource image, optional VideoFrameInit init = {});
25612618
constructor(sequence<PlaneInit> planes,
@@ -2604,10 +2661,6 @@
26042661

26052662
### Internal Slots ###{#videoframe-internal-slots}
26062663

2607-
: <dfn attribute for=VideoFrame>\[[detached]]</dfn>
2608-
:: A boolean indicating whether {{destroy()}} was invoked and underlying
2609-
resources have been released.
2610-
26112664
: <dfn attribute for=VideoFrame>[[resource reference]]</dfn>
26122665
:: A reference to the [=media resource=] that stores the pixel data for
26132666
this frame.
@@ -2905,7 +2958,7 @@
29052958
to be used with {{VideoFrame/copyTo()}} with the given options.
29062959

29072960
When invoked, run these steps:
2908-
1. If {{VideoFrame/[[detached]]}} is `true`, return `0`.
2961+
1. If {{platform object/[[Detached]]}} is `true`, return `0`.
29092962
2. If {{VideoFrame/[[format]]}} is `""`, throw a {{NotSupportedError}}
29102963
{{DOMException}}.
29112964
3. Let |parsedOptions| be the result of running the [=Parse
@@ -2923,7 +2976,7 @@
29232976
were returned.
29242977

29252978
When invoked, run these steps:
2926-
1. If {{VideoFrame/[[detached]]}} is `true`, return `0`.
2979+
1. If {{platform object/[[Detached]]}} is `true`, return `0`.
29272980
2. If {{VideoFrame/[[format]]}} is `""`, throw a {{NotSupportedError}}
29282981
{{DOMException}}.
29292982
3. Let |parsedOptions| be the result of running the [=Parse
@@ -2975,7 +3028,7 @@
29753028
[=media resource=].
29763029

29773030
When invoked, run these steps:
2978-
1. If the value of |frame|’s {{VideoFrame/[[detached]]}} internal slot is
3031+
1. If the value of |frame|’s {{platform object/[[Detached]]}} internal slot is
29793032
`true`, throw an {{InvalidStateError}} {{DOMException}}.
29803033
2. Return the result of running the [=Clone VideoFrame=] algorithm with
29813034
[=this=].
@@ -2984,22 +3037,12 @@
29843037
:: Clears all state and releases the reference to the [=media resource=].
29853038
Close is final.
29863039

2987-
When invoked, run these steps:
2988-
1. Assign `null` to {{VideoFrame/[[resource reference]]}}.
2989-
2. Assign `true` to {{VideoFrame/[[detached]]}}.
2990-
3. Assign `""` to {{VideoFrame/format}}.
2991-
4. Assign `0` to {{VideoFrame/[[coded width]]}},
2992-
{{VideoFrame/[[coded height]]}}, {{VideoFrame/[[visible left]]}},
2993-
{{VideoFrame/[[visible top]]}}, {{VideoFrame/[[visible width]]}},
2994-
{{VideoFrame/[[visible height]]}}, {{VideoFrame/[[display width]]}},
2995-
and {{VideoFrame/[[display height]]}}.
2996-
5. Assign `null` to {{VideoFrame/[[duration]]}} and
2997-
{{VideoFrame/[[timestamp]]}}.
3040+
When invoked, run the [=Close VideoFrame=] algorithm with [=this=].
29983041

29993042
### Algorithms ###{#videoframe-algorithms}
30003043
<dfn>Create a VideoFrame</dfn> (with |output|, |timestamp|, |duration|, |displayAspectWidth|, and |displayAspectHeight|)
30013044
1. Let |frame| be a new {{VideoFrame}}, constructed as follows:
3002-
1. Assign `false` to {{VideoFrame/[[detached]]}}.
3045+
1. Assign `false` to {{platform object/[[Detached]]}}.
30033046
2. Let |resource| be the [=media resource=] described by |output|.
30043047
3. Let |resourceReference| be a reference to |resource|.
30053048
4. Assign |resourceReference| to {{VideoFrame/[[resource reference]]}}.
@@ -3082,14 +3125,28 @@
30823125

30833126
: <dfn>Clone VideoFrame</dfn> (with |frame|)
30843127
:: 1. Let |clone| be a new {{VideoFrame}} initialized as follows:
3085-
1. Assign |frame|.{{VideoFrame/[[resource reference]]}} to
3128+
1. Let |resource| be the [=media resource=] referenced by |frame|’s
3129+
[[resource reference]].
3130+
2. Let |newReference| be a new reference to |resource|.
3131+
3. Assign |newReference| to |clone|'s
30863132
{{VideoFrame/[[resource reference]]}}.
3087-
2. Assign |frame|.{{VideoFrame/format}} to {{VideoFrame/format}}.
3088-
3. Assign all remaining attributes of |frame| (
3089-
{{VideoFrame/codedWidth}}, {{VideoFrame/codedHeight}}, etc.) to
3090-
those of the same name in |clone|.
3133+
4. Assign all remaining internal slots of |frame| (excluding
3134+
{{VideoFrame/[[resource reference]]}}) to those of the same name
3135+
in |clone|.
30913136
2. Return |clone|.
30923137

3138+
: <dfn>Close VideoFrame</dfn> (with |frame|)
3139+
:: 1. Assign `null` to |frame|'s {{VideoFrame/[[resource reference]]}}.
3140+
2. Assign `true` to |frame|'s {{platform object/[[Detached]]}}.
3141+
3. Assign `""` to |frame|'s {{VideoFrame/format}}.
3142+
4. Assign `0` to |frame|'s {{VideoFrame/[[coded width]]}},
3143+
{{VideoFrame/[[coded height]]}}, {{VideoFrame/[[visible left]]}},
3144+
{{VideoFrame/[[visible top]]}}, {{VideoFrame/[[visible width]]}},
3145+
{{VideoFrame/[[visible height]]}}, {{VideoFrame/[[display width]]}},
3146+
and {{VideoFrame/[[display height]]}}.
3147+
5. Assign `null` to |frame|'s {{VideoFrame/[[duration]]}} and
3148+
{{VideoFrame/[[timestamp]]}}.
3149+
30933150
: <dfn for=VideoFrame>Parse VideoFrameCopyToOptions</dfn> (with |options|)
30943151
:: 1. Let |parsedRect| be the result of running the [=VideoFrame/Parse CopyTo
30953152
Rect=] with |options|.
@@ -3226,6 +3283,43 @@
32263283
[=parsed copyto options/allocationSize=].
32273284
9. Return |parsedOptions|.
32283285

3286+
### Transfer and Serialization ###{#videoframe-transfer-serialization}
3287+
3288+
: The {{VideoFrame}} [=transfer steps=] (with |value| and |dataHolder|) are:
3289+
:: 1. If |value|'s {{platform object/[[Detached]]}} is `true`, throw a
3290+
{{DataCloneError}} {{DOMException}}.
3291+
2. For all {{VideoFrame}} internal slots in |value|, assign the value of
3292+
each internal slot to a field in |dataHolder| with the same name as the
3293+
internal slot.
3294+
3. Run the [=Close VideoFrame=] algorithm with |value|.
3295+
3296+
: The {{VideoFrame}} [=transfer-receiving steps=] (with |dataHolder| and
3297+
|value|) are:
3298+
:: 1. For all named fields in |dataHolder|, assign the value of each named
3299+
field to the {{VideoFrame}} internal slot in |value| with the same name
3300+
as the named field.
3301+
3302+
: The {{VideoFrame}} [=serialization steps=] (with |value|, |serialized|, and
3303+
|forStorage|) are:
3304+
:: 1. If |value|'s {{platform object/[[Detached]]}} is `true`, throw a
3305+
{{DataCloneError}} {{DOMException}}.
3306+
2. If |forStorage| is `true`, throw a {{TypeError}}.
3307+
3. Let |resource| be the [=media resource=] referenced by
3308+
|value|'s {{VideoFrame/[[resource reference]]}}.
3309+
4. Let |newReference| be a new reference to |resource|.
3310+
5. Assign |newReference| to |serialized|.[[resource reference]].
3311+
6. For all remaining {{VideoFrame}} internal slots (excluding
3312+
{{VideoFrame/[[resource reference]]}}) in |value|, assign the value of
3313+
each internal slot to a field in |serialized| with the same name as the
3314+
internal slot.
3315+
3316+
: The {{VideoFrame}} [=deserialization steps=] (with |serialized| and |value|)
3317+
are:
3318+
:: 1. For all named fields in |serialized|, assign the value of each named
3319+
field to the {{VideoFrame}} internal slot in |value| with the same name
3320+
as the named field.
3321+
3322+
32293323
VideoFrame CopyTo() Options {#videoframe-copyto-options}
32303324
------------------------------------------------------------
32313325
Options to specify which {{VideoFrameRect}} to copy and the offset and

0 commit comments

Comments
 (0)