Skip to content

Commit 4829102

Browse files
authored
Merge pull request #185 from w3c/videoframe_from_canvasimagesource
Construct VideoFrame from CanvasImageSource (including VideoFrame)
2 parents c47a145 + 3602251 commit 4829102

File tree

1 file changed

+140
-68
lines changed

1 file changed

+140
-68
lines changed

index.src.html

Lines changed: 140 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,16 @@
4545
type: attribute; text: resizeWidth; url:#dom-imagebitmapoptions-resizewidth
4646
type: attribute; text: resizeHeight; url:#dom-imagebitmapoptions-resizeheight
4747
type: dfn; text: cropped to the source rectangle with formatting; url: imagebitmap-and-animations.html#cropped-to-the-source-rectangle-with-formatting
48-
type: dfn; text: global object; url: webappapis.html#global-object
48+
type: dfn; text: bitmap data; url: imagebitmap-and-animations.html#concept-imagebitmap-bitmap-data
49+
for: Canvas;
50+
type: dfn; text: Check the usability of the image argument; url: canvas.html#check-the-usability-of-the-image-argument
51+
for: origin;
52+
type: dfn; text: origin; url: origin.html#concept-origin
53+
for: webappapis;
54+
type: dfn; text: global object; url: webappapis.html#global-object
55+
type: dfn; text: entry settings object; url: webappapis.html#entry-settings-object
56+
for: media;
57+
type: dfn; text: current playback position; url: media.html#current-playback-position
4958
type: dfn; text: live; url: infrastructure.html#live
5059

5160
spec: mediacapture-streams; urlPrefix: https://www.w3.org/TR/mediacapture-streams/
@@ -77,6 +86,11 @@
7786
spec: media-capabilities; urlPrefix: https://w3c.github.io/media-capabilities/#
7887
type: method; text: decodingInfo(); url: dom-mediacapabilities-decodinginfo
7988
type: attribute; text: powerEfficient; url: dom-mediacapabilitiesinfo-powerefficient
89+
90+
spec: css-images-3; urlPrefix: https://www.w3.org/TR/css-images-3/
91+
type: dfn; text: natural dimensions; url: #natural-dimensions
92+
type: dfn; text: natural width; url: #natural-width
93+
type: dfn; text: natural height; url: #natural-height
8094
</pre>
8195

8296
<style>
@@ -152,14 +166,16 @@
152166
The <dfn>control thread</dfn> is the thread from which authors will construct
153167
a [=codec=] and invoke its methods. Invoking a codec's methods will typically
154168
result in the creation of [=control messages=] which are later executed on the
155-
[=codec thread=]. Each [=global object=] has a separate control thread.
169+
[=codec thread=]. Each [=webappapis/global object=] has a separate control
170+
thread.
156171

157172
The <dfn>codec thread</dfn> is the thread from which a [=codec=] will
158173
[=dequeue=] [=control messages=] and execute their steps. Each [=codec=]
159174
instance has a separate codec thread. The lifetime of a codec thread matches
160175
that of its associated [=codec=] instance.
161176

162-
The [=control thread=] uses a traditional event loop, as described in [[!HTML]].
177+
The [=control thread=] uses a traditional event loop, as described in
178+
[[!HTML]].
163179

164180
The [=codec thread=] uses a specialized [=codec processing loop=].
165181

@@ -1034,7 +1050,7 @@
10341050
2. Set {{VideoEncoder/[[active encoder config]]}} to `config`.
10351051
</dd>
10361052

1037-
<dt><dfn method for=VideoEncoder>encode(frame, options)</dfn></dt>
1053+
<dt><dfn method for=VideoEncoder>encode(|frame|, |options|)</dfn></dt>
10381054
<dd>
10391055
[=Enqueues a control message=] to encode the given |frame|.
10401056

@@ -2129,10 +2145,14 @@
21292145
VideoFrame Interface {#videoframe-interface}
21302146
--------------------------------------------
21312147

2148+
NOTE: {{VideoFrame}} is a {{CanvasImageSource}}. A {{VideoFrame}} may be
2149+
passed to any method accepting a {{CanvasImageSource}}, including
2150+
{{CanvasDrawImage}}'s {{CanvasDrawImage/drawImage()}}.
2151+
21322152
<xmp class='idl'>
21332153
[Exposed=(Window,DedicatedWorker)]
21342154
interface VideoFrame {
2135-
constructor(ImageBitmap imageBitmap, optional VideoFrameInit init = {});
2155+
constructor(CanvasImageSource image, optional VideoFrameInit init = {});
21362156
constructor(sequence<(Plane or PlaneInit)> planes,
21372157
VideoFramePlaneInit init);
21382158

@@ -2151,10 +2171,6 @@
21512171

21522172
VideoFrame clone();
21532173
undefined close();
2154-
2155-
Promise<ImageBitmap> createImageBitmap(
2156-
optional ImageBitmapOptions options = {});
2157-
21582174
};
21592175

21602176
dictionary VideoFrameInit {
@@ -2235,48 +2251,65 @@
22352251

22362252
### Constructors ###{#videoframe-constructors}
22372253

2238-
<dfn constructor for=VideoFrame title="VideoFrame(imageBitmap, init)">
2239-
VideoFrame(imageBitmap, init)
2254+
<dfn constructor for=VideoFrame title="VideoFrame(image, init)">
2255+
VideoFrame(image, init)
22402256
</dfn>
2241-
1. If the value of |imageBitmap|'s' {{PlatformObject/[[Detached]]}} internal
2242-
slot is `true`, then throw an {{InvalidStateError}}
2257+
1. [=Canvas/Check the usability of the image argument=]. If this throws an
2258+
exception or returns <var ignore=''>bad</var>, then throw an {{InvalidStateError}} {{DOMException}}.
2259+
2. If the [=origin/origin=] of |image|'s image data is not [=same origin=]
2260+
with the [=webappapis/entry settings object=]'s
2261+
[=origin/origin=], then throw a {{SecurityError}}
22432262
{{DOMException}}.
2244-
2. Let |resource| be the [=media resource=] containing the bitmap data for
2245-
|imageBitmap|.
2246-
3. Let |resourceReference| be a reference to |resource|.
2247-
4. Let |frame| be a new {{VideoFrame}}, initialized as follows:
2248-
1. Assign |resourceReference| to
2249-
{{VideoFrame/[[resource reference]]}}.
2250-
2. If |resource| uses a recognized {{PixelFormat}}:
2251-
1. Assign the {{PixelFormat}} of |resource| to
2252-
{{VideoFrame/[[format]]}}.
2253-
2. Let |planes| be a list of {{Plane}}s describing the
2254-
[=media resource=] in accordance with the
2255-
{{VideoFrame/[[format]]}}.
2263+
3. Let |frame| be a new {{VideoFrame}}.
2264+
5. Switch on |image|:
2265+
- {{HTMLImageElement}}
2266+
- {{SVGImageElement}}
2267+
1. If {{VideoFrameInit/timestamp}} does not [=map/exist=] in
2268+
|init|, throw a {{TypeError}}.
2269+
2. If |image|'s media data has no [=natural dimensions=]
2270+
(e.g., it's a vector graphic with no specified content size), then
2271+
throw an {{InvalidStateError}} {{DOMException}}.
2272+
3. Let |resource| be a new [=media resource=] containing a copy of
2273+
|image|'s media data. If this is an animated image, |image|'s
2274+
[=bitmap data=] must only be taken from the default image of the
2275+
animation (the one that the format defines is to be used when
2276+
animation is not supported or is disabled), or, if there is no
2277+
such image, the first frame of the animation.
2278+
4. Let |width| and |height| be the [=natural width=] and
2279+
[=natural height=] of |image|.
2280+
5. Run the [=VideoFrame/Initialize Frame With Resource and Size=]
2281+
algorithm with |init|, |frame|, |resource|, |width|, and |height|
2282+
2283+
- {{HTMLVideoElement}}
2284+
1. If |image|'s {{HTMLMediaElement/networkState}} attribute is
2285+
{{HTMLMediaElement/NETWORK_EMPTY}}, then throw an
2286+
{{InvalidStateError}} {{DOMException}}.
2287+
2. Let |currentPlaybackFrame| be the {{VideoFrame}} at the [=current
2288+
playback position=].
2289+
3. Run the [=VideoFrame/Initialize Frame From Other Frame=] algorithm
2290+
with |init|, |frame|, and |currentPlaybackFrame|.
2291+
2292+
- {{HTMLCanvasElement}}
2293+
- {{ImageBitmap}}
2294+
- {{OffscreenCanvas}}
2295+
1. If {{VideoFrameInit/timestamp}} does not [=map/exist=] in
2296+
|init|, throw a {{TypeError}}.
2297+
2. Let |resource| be a new [=media resource=] containing a copy of
2298+
|image|'s [=bitmap data=].
2299+
2300+
NOTE: Implementers are should avoid a deep copy by using reference
2301+
coutning where feasible.
2302+
2303+
3. Let |width| be `image.width` and |height| be `image.height`.
2304+
4. Run the [=VideoFrame/Initialize Frame With Resource and Size=]
2305+
algorithm with |init|, |frame|, |resource|, |width|, and |height|.
2306+
2307+
- {{VideoFrame}}
2308+
1. Run the [=VideoFrame/Initialize Frame From Other Frame=] algorithm
2309+
with |init|, |frame|, and |image|.
22562310

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

2261-
3. Assign |planes| to {{VideoFrame/[[planes]]}}.
2262-
3. Otherwise (|resource| does not use a recognized {{PixelFormat}}):
2263-
1. Assign `""` to {{VideoFrame/[[format]]}}.
2264-
2. Assign `null` to {{VideoFrame/[[planes]]}}.
2265-
4. Assign |imageBitmap|.{{ImageBitmap/width}} to
2266-
{{VideoFrame/[[coded width]]}},
2267-
{{VideoFrame/[[crop width]]}}, and {{VideoFrame/[[display width]]}}.
2268-
5. Assign |imageBitmap|.{{ImageBitmap/height}} to
2269-
{{VideoFrame/[[coded height]]}}, {{VideoFrame/[[crop height]]}}, and
2270-
{{VideoFrame/[[display height]]}}.
2271-
6. Assign `0` to {{VideoFrame/[[crop top]]}} and
2272-
{{VideoFrame/[[crop left]]}}.
2273-
7. If {{VideoFrameInit/timestamp}} [=map/exists=] in |init|, assign
2274-
`init.timestamp` to {{VideoFrame/[[timestamp]]}}. Otherwise, assign
2275-
`null` to {{VideoFrame/[[timestamp]]}}.
2276-
8. If {{VideoFrameInit/duration}} [=map/exists=] in |init|, assign
2277-
`init.duration` to {{VideoFrame/[[duration]]}}. Otherwise, assign
2278-
`null` to {{VideoFrame/[[duration]]}}.
2279-
5. Return |frame|.
22802313

22812314
<dfn constructor for=VideoFrame title="VideoFrame(planes, init)">
22822315
VideoFrame(planes, init)
@@ -2474,27 +2507,6 @@
24742507
{{VideoFrame/displayWidth}}, and {{VideoFrame/displayHeight}}.
24752508
6. Assign `null` to {{VideoFrame/duration}} and {{VideoFrame/timestamp}}.
24762509

2477-
: <dfn method for=VideoFrame>createImageBitmap(options)</dfn>
2478-
:: Creates an ImageBitmap from this {{VideoFrame}}.
2479-
2480-
When invoked, run these steps:
2481-
1. Let |p| be a new Promise.
2482-
2. If either |options|'s {{ImageBitmapOptions/resizeWidth}} or
2483-
{{ImageBitmap/resizeHeight}} is present and is 0, then return |p|
2484-
rejected with an {{InvalidStateError}} {{DOMException}}.
2485-
3. If the <a>this'</a> {{VideoFrame/[[detached]]}} is `true`, then return
2486-
|p| rejected with an {{InvalidStateError}} {{DOMException}}.
2487-
4. Let |imageBitmap| be a new {{ImageBitmap}} object.
2488-
5. Set |imageBitmap|'s bitmap data to a copy of the {{VideoFrame}} pixel
2489-
data, at the frame's intrinsic width and intrinsic height (`i.e`.,
2490-
after any aspect-ratio correction has been applied),
2491-
[=ImageBitmap/cropped to the source rectangle with formatting=].
2492-
6. If the origin of |imageBitmap|'s image is not same origin with entry
2493-
settings object's origin, then set the origin-clean flag of
2494-
|imageBitmap|'s bitmap to `false`.
2495-
7. Run this step in parallel:
2496-
1. Resolve p with imageBitmap.
2497-
24982510
### Algorithms ###{#videoframe-algorithms}
24992511
: To check if a {{VideoFramePlaneInit}} is a
25002512
<dfn>valid VideoFramePlaneInit</dfn>, run these steps:
@@ -2512,6 +2524,66 @@
25122524
{{VideoFramePlaneInit/displayHeight}} = 0, return `false`.
25132525
6. Return `true`.
25142526

2527+
: <dfn for=VideoFrame>Initialize Frame From Other Frame</dfn> (with |init|,
2528+
|frame|, and |otherFrame|)
2529+
:: 1. Let |resource| be the [=media resource=] referenced by |otherFrame|'s
2530+
{{VideoFrame/[[resource reference]]}}.
2531+
2. Assign a new reference for |resource| to |frame|'s
2532+
{{VideoFrame/[[resource reference]]}}.
2533+
3. Assign the following attributes from |otherFrame| to |frame|:
2534+
{{VideoFrame/format}}, {{VideoFrame/codedWidth}},
2535+
{{VideoFrame/codedHeight}}, {{VideoFrame/cropLeft}},
2536+
{{VideoFrame/cropTop}}, {{VideoFrame/cropWidth}},
2537+
{{VideoFrame/cropHeight}}, {{VideoFrame/displayWidth}},
2538+
{{VideoFrame/displayHeight}}.
2539+
4. Let |planes| be a new [=list=].
2540+
5. For each |otherPlane| in |otherFrame|.{{VideoFrame/planes}}:
2541+
1. Let |plane| be a new {{Plane}}.
2542+
2. Assign a reference for |frame| to |plane|'s
2543+
{{Plane/[[parent frame]]}}.
2544+
3. Assign the following attributes from |otherPlane| to |plane|:
2545+
{{Plane/stride}}, {{Plane/rows}}, {{Plane/length}}.
2546+
4. Append |plane| to |planes|.
2547+
6. Assign |planes| to |frame|.{{VideoFrame/planes}}.
2548+
7. If {{VideoFrameInit/duration}} [=map/exists=] in |init|, assign it to
2549+
|frame|.{{VideoFrame/duration}}. Otherwise, assign
2550+
|otherFrame|.{{VideoFrame/duration}} to
2551+
|frame|.{{VideoFrame/duration}}.
2552+
8. If {{VideoFrameInit/timestamp}} [=map/exists=] in |init|, assign it to
2553+
|frame|.{{VideoFrame/timestamp}}. Otherwise, assign
2554+
|otherFrame|.{{VideoFrame/timestamp}} to
2555+
|frame|.{{VideoFrame/timestamp}}.
2556+
2557+
: <dfn for=VideoFrame>Initialize Frame With Resource and Size</dfn> (with
2558+
|init|, |frame|, |resource|, |width| and |height|)
2559+
:: 1. Assign a new reference for |resource| to |frame|'s
2560+
{{VideoFrame/[[resource reference]]}}.
2561+
2. If |resource| uses a recognized {{PixelFormat}}:
2562+
1. Assign the {{PixelFormat}} of |resource| to {{VideoFrame/format}}.
2563+
2. Let |planes| be a list of {{Plane}}s describing the
2564+
[=media resource=] in accordance with the {{VideoFrame/format}}.
2565+
2566+
ISSUE: The spec should define explicit rules for each
2567+
{{PixelFormat}} and reference them in the step above. See
2568+
[#165](https://github.com/w3c/webcodecs/issues/165).
2569+
2570+
3. Assign |planes| to {{VideoFrame/planes}}.
2571+
3. Otherwise (|resource| does not use a recognized {{PixelFormat}}):
2572+
1. Assign `""` to {{VideoFrame/format}}.
2573+
2. Assign `null` to {{VideoFrame/planes}}.
2574+
4. Assign |width| to the following attributes of |frame|:
2575+
{{VideoFrame/codedWidth}}, {{VideoFrame/cropWidth}},
2576+
{{VideoFrame/displayWidth}}.
2577+
5. Assign |height| to the following attributes of |frame|:
2578+
{{VideoFrame/codedHeight}}, {{VideoFrame/cropHeight}},
2579+
{{VideoFrame/displayHeight}}.
2580+
6. Assign `0` to frame's {{VideoFrame/cropTop}} and
2581+
{{VideoFrame/cropLeft}}.
2582+
7. Assign `init`.{{VideoFrameInit/duration}} to
2583+
|frame|.{{VideoFrame/duration}}.
2584+
8. Assign `init`.{{VideoFrameInit/timestamp}} to
2585+
|frame|.{{VideoFrame/timestamp}}.
2586+
25152587
: <dfn>Clone VideoFrame</dfn> (with |frame|)
25162588
:: 1. Let |clone| be a new {{VideoFrame}} initialized as follows:
25172589
1. Assign |frame|.{{VideoFrame/[[resource reference]]}} to

0 commit comments

Comments
 (0)