Skip to content

Commit 105250f

Browse files
committed
Construct VideoFrame from CanvasImageSource (including VideoFrame)
Replaces the ImageBitmap constructor with more generic constructor for CanvasImageSource. VideoFrame is itself a CanvasImageSource. Fixes #158
1 parent 763f629 commit 105250f

File tree

1 file changed

+136
-65
lines changed

1 file changed

+136
-65
lines changed

index.src.html

Lines changed: 136 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,16 @@
3939
type: attribute; text: resizeWidth; url:#dom-imagebitmapoptions-resizewidth
4040
type: attribute; text: resizeHeight; url:#dom-imagebitmapoptions-resizeheight
4141
type: dfn; text: cropped to the source rectangle with formatting; url: imagebitmap-and-animations.html#cropped-to-the-source-rectangle-with-formatting
42-
type: dfn; text: global object; url: webappapis.html#global-object
42+
type: dfn; text: bitmap data; url: imagebitmap-and-animations.html#concept-imagebitmap-bitmap-data
43+
for: Canvas;
44+
type: dfn; text: Check the usability of the image argument; url: canvas.html#check-the-usability-of-the-image-argument
45+
for: origin;
46+
type: dfn; text: origin; url: origin.html#concept-origin
47+
for: webappapis;
48+
type: dfn; text: global object; url: webappapis.html#global-object
49+
type: dfn; text: entry settings object; url: webappapis.html#entry-settings-object
50+
for: media;
51+
type: dfn; text: current playback position; url: media.html#current-playback-position
4352

4453
spec: mediacapture-streams; urlPrefix: https://www.w3.org/TR/mediacapture-streams/
4554
for: mediaDevices;
@@ -74,6 +83,11 @@
7483
type: dfn; text: acquire the content; url: #acquire-the-content
7584
for: AudioBuffer
7685
type: method; text: copyToChannel(); url: #dom-audiobuffer-copytochannel
86+
87+
spec: css-images-3; urlPrefix: https://www.w3.org/TR/css-images-3/
88+
type: dfn; text: natural dimensions; url: #natural-dimensions
89+
type: dfn; text: natural width; url: #natural-width
90+
type: dfn; text: natural height; url: #natural-height
7791
</pre>
7892

7993
<pre class='biblio'>
@@ -139,14 +153,16 @@
139153
The <dfn>control thread</dfn> is the thread from which authors will construct
140154
a [=codec=] and invoke its methods. Invoking a codec's methods will typically
141155
result in the creation of [=control messages=] which are later executed on the
142-
[=codec thread=]. Each [=global object=] has a separate control thread.
156+
[=codec thread=]. Each [=webappapis/global object=] has a separate control
157+
thread.
143158

144159
The <dfn>codec thread</dfn> is the thread from which a [=codec=] will
145160
[=dequeue=] [=control messages=] and execute their steps. Each [=codec=]
146161
instance has a separate codec thread. The lifetime of a codec thread matches
147162
that of its associated [=codec=] instance.
148163

149-
The [=control thread=] uses a traditional event loop, as described in [[!HTML]].
164+
The [=control thread=] uses a traditional event loop, as described in
165+
[[!HTML]].
150166

151167
The [=codec thread=] uses a specialized [=codec processing loop=].
152168

@@ -1017,7 +1033,7 @@
10171033
2. Set {{VideoEncoder/[[active encoder config]]}} to `config`.
10181034
</dd>
10191035

1020-
<dt><dfn method for=VideoEncoder>encode(frame, options)</dfn></dt>
1036+
<dt><dfn method for=VideoEncoder>encode(|frame|, |options|)</dfn></dt>
10211037
<dd>
10221038
[=Enqueues a control message=] to encode the given |frame|.
10231039

@@ -2021,11 +2037,15 @@
20212037
VideoFrame Interface {#videoframe-interface}
20222038
--------------------------------------------
20232039

2040+
NOTE: {{VideoFrame}} is a {{CanvasImageSource}}. A {{VideoFrame}} may be
2041+
passed to any method accepting a {{CanvasImageSource}}, including
2042+
{{CanvasDrawImage}}'s {{CanvasDrawImage/drawImage()}}.
2043+
20242044
<pre class='idl'>
20252045
<xmp>
20262046
[Exposed=(Window,DedicatedWorker)]
20272047
interface VideoFrame {
2028-
constructor(ImageBitmap imageBitmap, optional VideoFrameInit init = {});
2048+
constructor(CanvasImageSource image, optional VideoFrameInit init = {});
20292049
constructor(sequence<(Plane or PlaneInit)> planes,
20302050
VideoFramePlaneInit init);
20312051

@@ -2044,10 +2064,6 @@
20442064

20452065
VideoFrame clone();
20462066
undefined close();
2047-
2048-
Promise<ImageBitmap> createImageBitmap(
2049-
optional ImageBitmapOptions options = {});
2050-
20512067
};
20522068

20532069
dictionary VideoFrameInit {
@@ -2081,44 +2097,61 @@
20812097

20822098
### Constructors ###{#videoframe-constructors}
20832099

2084-
<dfn constructor for=VideoFrame title="VideoFrame(imageBitmap, init)">
2085-
VideoFrame(imageBitmap, init)
2100+
<dfn constructor for=VideoFrame title="VideoFrame(image, init)">
2101+
VideoFrame(image, init)
20862102
</dfn>
2087-
1. If the value of |imageBitmap|'s' {{PlatformObject/[[Detached]]}} internal
2088-
slot is `true`, then throw an {{InvalidStateError}}
2103+
1. [=Canvas/Check the usability of the image argument=]. If this throws an
2104+
exception or returns <var ignore=''>bad</var>, then throw an {{InvalidStateError}} {{DOMException}}.
2105+
2. If the [=origin/origin=] of |image|'s image data is not [=same origin=]
2106+
with the [=webappapis/entry settings object=]'s
2107+
[=origin/origin=], then throw a {{SecurityError}}
20892108
{{DOMException}}.
2090-
2. Let |resource| be the [=frame resource=] containing the bitmap data for
2091-
|imageBitmap|.
2092-
3. Let |resourceReference| be a reference to |resource|.
2093-
4. Let |frame| be a new {{VideoFrame}}, initialized as follows:
2094-
1. Assign |resourceReference| to
2095-
{{VideoFrame/[[resource reference]]}}.
2096-
2. If |resource| uses a recognized {{PixelFormat}}:
2097-
1. Assign the {{PixelFormat}} of |resource| to {{VideoFrame/format}}.
2098-
2. Let |planes| be a list of {{Plane}}s describing the
2099-
[=frame resource=] in accordance with the {{VideoFrame/format}}.
2109+
3. Let |frame| be a new {{VideoFrame}}.
2110+
5. Switch on |image|:
2111+
- {{HTMLImageElement}}
2112+
- {{SVGImageElement}}
2113+
1. If {{VideoFramePlaneInit/timestamp}} does not [=map/exist=] in
2114+
|init|, throw a {{TypeError}}.
2115+
2. If image's media data has no [=natural dimensions=]
2116+
(e.g., it's a vector graphic with no specified content size), then
2117+
throw an {{InvalidStateError}} {{DOMException}}.
2118+
3. Let |resource| be a new [=frame resource=] containing a copy of
2119+
|image|'s media data. If this is an animated image, |image|'s
2120+
[=bitmap data=] must only be taken from the default image of the
2121+
animation (the one that the format defines is to be used when
2122+
animation is not supported or is disabled), or, if there is no
2123+
such image, the first frame of the animation.
2124+
4. Let |width| and |height| be the [=natural width=] and
2125+
[=natural height=] of |image|.
2126+
5. Run the [=VideoFrame/Initialize Frame With Resource and Size=]
2127+
algorithm with |init|, |frame|, |resource|, |width|, and |height|
2128+
2129+
- {{HTMLVideoElement}}
2130+
1. If |image|'s {{HTMLMediaElement/networkState}} attribute is
2131+
{{HTMLMediaElement/NETWORK_EMPTY}}, then throw an
2132+
{{InvalidStateError}} {{DOMException}}.
2133+
2. Let |currentPlaybackFrame| be the {{VideoFrame}} at the [=current
2134+
playback position=].
2135+
3. Run the [=VideoFrame/Initialize Frame From Other Frame=] algoirhtm
2136+
with |init|, |frame|, and |currentPlaybackFrame|.
2137+
2138+
- {{HTMLCanvasElement}}
2139+
- {{ImageBitmap}}
2140+
- {{OffscreenCanvas}}
2141+
1. If {{VideoFramePlaneInit/timestamp}} does not [=map/exist=] in
2142+
|init|, throw a {{TypeError}}.
2143+
2. Let |resource| be a new [=frame resource=] containing a copy of
2144+
|image|'s [=bitmap data=].
2145+
3. Let |width| be `image.width` and |height| be `image.height`.
2146+
4. Run the [=VideoFrame/Initialize Frame With Resource and Size=]
2147+
algorithm with |init|, |frame|, |resource|, |width|, and |height|.
2148+
2149+
- {{VideoFrame}}
2150+
1. Run the [=VideoFrame/Initialize Frame From Other Frame=] algorithm
2151+
with |init|, |frame|, and |image|.
21002152

2101-
ISSUE: The spec should define explicit rules for each
2102-
{{PixelFormat}} and reference them in the step above. See
2103-
[#165](https://github.com/w3c/webcodecs/issues/165).
2153+
6. Return |frame|.
21042154

2105-
3. Assign |planes| to {{VideoFrame/planes}}.
2106-
3. Otherwise (|resource| does not use a recognized {{PixelFormat}}):
2107-
1. Assign `""` to {{VideoFrame/format}}.
2108-
2. Assign `null` to {{VideoFrame/planes}}.
2109-
4. Assign |imageBitmap|.{{ImageBitmap/width}} to {{VideoFrame/codedWidth}},
2110-
{{VideoFrame/cropWidth}}, and {{VideoFrame/displayWidth}}.
2111-
5. Assign |imageBitmap|.{{ImageBitmap/height}} to
2112-
{{VideoFrame/codedHeight}}, {{VideoFrame/cropHeight}}, and
2113-
{{VideoFrame/displayHeight}}.
2114-
6. Assign `0` to {{VideoFrame/cropTop}} and {{VideoFrame/cropLeft}}.
2115-
7. If {{VideoFrameInit/timestamp}} [=map/exists=] in |init|, assign
2116-
`init.timestamp` to {{VideoFrame/timestamp}}. Otherwise, assign
2117-
`null` to {{VideoFrame/timestamp}}.
2118-
8. If {{VideoFrameInit/duration}} [=map/exists=] in |init|, assign
2119-
`init.duration` to {{VideoFrame/duration}}. Otherwise, assign
2120-
`null` to {{VideoFrame/duration}}.
2121-
5. Return |frame|.
21222155

21232156
<dfn constructor for=VideoFrame title="VideoFrame(planes, init)">
21242157
VideoFrame(planes, init)
@@ -2286,28 +2319,6 @@
22862319
{{VideoFrame/displayWidth}}, and {{VideoFrame/displayHeight}}.
22872320
6. Assign `null` to {{VideoFrame/duration}} and {{VideoFrame/timestamp}}.
22882321

2289-
: <dfn method for=VideoFrame>createImageBitmap(options)</dfn>
2290-
:: Creates an ImageBitmap from this {{VideoFrame}}.
2291-
2292-
When invoked, run these steps:
2293-
1. Let |p| be a new Promise.
2294-
2. If either |options|'s {{ImageBitmapOptions/resizeWidth}} or
2295-
{{ImageBitmap/resizeHeight}} is present and is 0, then return |p|
2296-
rejected with an {{InvalidStateError}} {{DOMException}}.
2297-
3. If the <a>this'</a> {{VideoFrame/[[detached]]}} internal slot is set to
2298-
`true`, then return |p| rejected with an {{InvalidStateError}}
2299-
{{DOMException}}.
2300-
4. Let |imageBitmap| be a new {{ImageBitmap}} object.
2301-
5. Set |imageBitmap|'s bitmap data to a copy of the {{VideoFrame}} pixel
2302-
data, at the frame's intrinsic width and intrinsic height (`i.e`.,
2303-
after any aspect-ratio correction has been applied),
2304-
[=ImageBitmap/cropped to the source rectangle with formatting=].
2305-
6. If the origin of |imageBitmap|'s image is not same origin with entry
2306-
settings object's origin, then set the origin-clean flag of
2307-
|imageBitmap|'s bitmap to `false`.
2308-
7. Run this step in parallel:
2309-
1. Resolve p with imageBitmap.
2310-
23112322
### Algorithms ###{#videoframe-algorithms}
23122323
: To check if a {{VideoFramePlaneInit}} is a
23132324
<dfn>valid VideoFramePlaneInit</dfn>, run these steps:
@@ -2325,6 +2336,66 @@
23252336
{{VideoFramePlaneInit/displayHeight}} = 0, return `false`.
23262337
6. Return `true`.
23272338

2339+
: <dfn for=VideoFrame>Initialize Frame From Other Frame</dfn> (with |init|,
2340+
|frame|, and |otherFrame|)
2341+
:: 1. Let |resource| be the [=frame resource=] referenced by |otherFrame|'s
2342+
{{VideoFrame/[[resource reference]]}}.
2343+
2. Assign a new reference for |resource| to |frame|'s
2344+
{{VideoFrame/[[resource reference]]}}.
2345+
3. Assign the following attributes from |otherFrame| to |frame|:
2346+
{{VideoFrame/format}}, {{VideoFrame/codedWidth}},
2347+
{{VideoFrame/codedHeight}}, {{VideoFrame/cropLeft}},
2348+
{{VideoFrame/cropTop}}, {{VideoFrame/cropWidth}},
2349+
{{VideoFrame/cropHeight}}, {{VideoFrame/displayWidth}},
2350+
{{VideoFrame/displayHeight}}.
2351+
4. Let |planes| be a new [=list=].
2352+
5. For each |otherPlane| in |otherFrame|.{{VideoFrame/planes}}:
2353+
1. Let |plane| be a new {{Plane}}.
2354+
2. Assign a reference for |frame| to |plane|'s
2355+
{{Plane/[[parent frame]]}}.
2356+
3. Assign the following attributes from |otherPlane| to |plane|:
2357+
{{Plane/stride}}, {{Plane/rows}}, {{Plane/length}}.
2358+
4. Append |plane| to |planes|.
2359+
6. Assign |planes| to |frame|.{{VideoFrame/planes}}.
2360+
7. If {{VideoFrameInit/duration}} [=map/exists=] in |init|, assign it to
2361+
|frame|.{{VideoFrame/duration}}. Otherwise, assign
2362+
|otherFrame|.{{VideoFrame/duration}} to
2363+
|frame|.{{VideoFrame/duration}}.
2364+
8. If {{VideoFrameInit/timestamp}} [=map/exists=] in |init|, assign it to
2365+
|frame|.{{VideoFrame/timestamp}}. Otherwise, assign
2366+
|otherFrame|.{{VideoFrame/timestamp}} to
2367+
|frame|.{{VideoFrame/timestamp}}.
2368+
2369+
: <dfn for=VideoFrame>Initialize Frame With Resource and Size</dfn> (with
2370+
|init|, |frame|, |resource|, |width| and |height|)
2371+
:: 1. Assign a new reference for |resource| to |frame|'s
2372+
{{VideoFrame/[[resource reference]]}}.
2373+
2. If |resource| uses a recognized {{PixelFormat}}:
2374+
1. Assign the {{PixelFormat}} of |resource| to {{VideoFrame/format}}.
2375+
2. Let |planes| be a list of {{Plane}}s describing the
2376+
[=frame resource=] in accordance with the {{VideoFrame/format}}.
2377+
2378+
ISSUE: The spec should define explicit rules for each
2379+
{{PixelFormat}} and reference them in the step above. See
2380+
[#165](https://github.com/w3c/webcodecs/issues/165).
2381+
2382+
3. Assign |planes| to {{VideoFrame/planes}}.
2383+
3. Otherwise (|resource| does not use a recognized {{PixelFormat}}):
2384+
1. Assign `""` to {{VideoFrame/format}}.
2385+
2. Assign `null` to {{VideoFrame/planes}}.
2386+
4. Assign |width| to the following attributes of |frame|:
2387+
{{VideoFrame/codedWidth}}, {{VideoFrame/cropWidth}},
2388+
{{VideoFrame/displayWidth}}.
2389+
5. Assign |height| to the following attributes of |frame|:
2390+
{{VideoFrame/codedHeight}}, {{VideoFrame/cropHeight}},
2391+
{{VideoFrame/displayHeight}}.
2392+
6. Assign `0` to frame's {{VideoFrame/cropTop}} and
2393+
{{VideoFrame/cropLeft}}.
2394+
7. Assign `init`.{{VideoFrameInit/duration}} to
2395+
|frame|.{{VideoFrame/duration}}.
2396+
8. Assign `init`.{{VideoFrameInit/timestamp}} to
2397+
|frame|.{{VideoFrame/timestamp}}.
2398+
23282399
: <dfn>Clone VideoFrame</dfn> (with |frame|)
23292400
:: 1. Let |clone| be a new {{VideoFrame}} initialized as follows:
23302401
1. Assign |frame|.{{VideoFrame/[[resource reference]]}} to

0 commit comments

Comments
 (0)