Skip to content

Commit cc00c96

Browse files
committed
Spec optional conversion to RGB in VideoFrame.copyTo()
1 parent 871ccb3 commit cc00c96

1 file changed

Lines changed: 71 additions & 14 deletions

File tree

index.src.html

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/;
3939
for: ImageBitmap;
4040
type: dfn; text: bitmap data; url: imagebitmap-and-animations.html#concept-imagebitmap-bitmap-data
41+
for: ImageData
42+
type: dfn; text: canvas pixel data; url: canvas.html#imagedata
4143
for: Canvas;
4244
type: dfn; text: Check the usability of the image argument; url: canvas.html#check-the-usability-of-the-image-argument
4345
type: dfn; text: is not origin-clean; url: canvas.html#the-image-argument-is-not-origin-clean
@@ -3745,8 +3747,8 @@
37453747

37463748
: <dfn method for=VideoFrame>copyTo(|destination|, |options|)</dfn>
37473749
:: Asynchronously copies the planes of this frame into |destination| according
3748-
to |options|. The format of the data is the same as this {{VideoFrame}}'s
3749-
{{VideoFrame/format}}.
3750+
to |options|. The format of the data is specified by {{VideoFrameCopyToOptions/format}},
3751+
if present, or the same as {{VideoFrame/format}}.
37503752

37513753
NOTE: Promises that are returned by several calls to
37523754
{{VideoFrame/copyTo()}} are not guaranteed to resolve in the order they
@@ -3764,10 +3766,20 @@
37643766
5. If `destination.byteLength` is less than |combinedLayout|'s [=combined
37653767
buffer layout/allocationSize=], return a promise rejected with a
37663768
{{TypeError}}.
3767-
6. Let |p| be a new {{Promise}}.
3768-
7. Let |copyStepsQueue| be the result of starting a new [=parallel queue=].
3769-
8. Let |planeLayouts| be a new [=list=].
3770-
9. Enqueue the following steps to |copyStepsQueue|:
3769+
6. If `options.format` does not equal to {{VideoFrame/[[format]]}} and
3770+
`options.format` is equal to one of {{RGBA}}, {{RGBX}}, {{BGRA}}, {{BGRX}}
3771+
then:
3772+
1. Let |serializedOptions| be [$StructuredSerialize$](|options|)
3773+
2. Let |newOptions| be [$StructuredDeserialize$](|serializedOptions|, [=the current Realm=]).
3774+
3. Set |newOptions.format| to `undefined`
3775+
4. Let |rgbFrame| be the result of running the [=VideoFrame/Convert to RGB frame=]
3776+
algorithm with `options.format`, `options.rect`, and `options.colorSpace`.
3777+
5. Return the result of calling {{VideoFrame/copyTo()}} on |rgbFrame| with
3778+
|destination| and |newOptions|.
3779+
7. Let |p| be a new {{Promise}}.
3780+
8. Let |copyStepsQueue| be the result of starting a new [=parallel queue=].
3781+
9. Let |planeLayouts| be a new [=list=].
3782+
10. Enqueue the following steps to |copyStepsQueue|:
37713783
1. Let resource be the [=media resource=] referenced by
37723784
[[resource reference]].
37733785
2. Let |numPlanes| be the number of planes as defined by
@@ -3804,7 +3816,7 @@
38043816
10. Increment |planeIndex| by `1`.
38053817
11. Append |layout| to |planeLayouts|.
38063818
5. [=Queue a task=] to resolve |p| with |planeLayouts|.
3807-
10. Return |p|.
3819+
11. Return |p|.
38083820

38093821
: <dfn method for=VideoFrame>clone()</dfn>
38103822
:: Creates a new {{VideoFrame}} with a reference to the same
@@ -4048,10 +4060,17 @@
40484060
6. Let |optLayout| be `undefined`.
40494061
7. If |options|.{{VideoFrameCopyToOptions/layout}} [=map/exists=], assign
40504062
its value to |optLayout|.
4051-
8. Let |combinedLayout| be the result of running the [=VideoFrame/Compute
4052-
Layout and Allocation Size=] algorithm with |parsedRect|,
4053-
{{VideoFrame/[[format]]}}, and |optLayout|.
4054-
9. Return |combinedLayout|.
4063+
8. Let |format| be `undefined`.
4064+
9. If |options|.{{VideoFrameCopyToOptions/format}} is `undefined`,
4065+
assign {{VideoFrame/[[format]]}} to |format|.
4066+
10. Otherwise, if |options|.{{VideoFrameCopyToOptions/format}} is equal to
4067+
one of {{RGBA}}, {{RGBX}}, {{BGRA}}, {{BGRX}}, then assign
4068+
|options|.{{VideoFrameCopyToOptions/format}} to |format|,
4069+
otherwise return {{NotSupportedError}}.
4070+
11. Let |combinedLayout| be the result of running the [=VideoFrame/Compute
4071+
Layout and Allocation Size=] algorithm with |parsedRect|, |format|,
4072+
and |optLayout|.
4073+
12. Return |combinedLayout|.
40554074

40564075
: <dfn for=VideoFrame>Verify Rect Offset Alignment</dfn> (with |format| and
40574076
|rect|)
@@ -4183,10 +4202,36 @@
41834202
[=combined buffer layout/allocationSize=].
41844203
9. Return |combinedLayout|.
41854204

4205+
: <dfn for=VideoFrame>Convert to RGB frame</dfn> (with |format|, |rect| and |colorSpace|)
4206+
:: 1. Let |canvas| be a new {{OffscreenCanvas}} constructed with
4207+
|rect|.|width| and |rect|.|height|.
4208+
2. Let |canvasSettings| be a new {{CanvasRenderingContext2DSettings}} with
4209+
{{CanvasRenderingContext2DSettings/colorSpace}} set to |colorSpace|.
4210+
3. Let |context| be the result of calling {{OffscreenCanvas/getContext()}}
4211+
on |canvas| with `"2d"` and |canvasSettings|
4212+
3. Call {{CanvasDrawImage/drawImage()}} on |context| with
4213+
`rect.x`, `rect.y`, `rect.width`, `rect.height`, `0`, `0`, `rect.width`,
4214+
`rect.height`.
4215+
4. Let |imageData| be the result of calling {{CanvasImageData/getImageData()}} with
4216+
`0`, `0`, |rect.width|, |rect.height|.
4217+
5. If |format| is equal to {{BGRA}} or {{BGRX}}:
4218+
1. Let |pixelIndex| be `0`
4219+
2. While |pixelIndex| is less than `rect.width` multiplied by `rect.height`:
4220+
1. Swap items in |imageData|.{{ImageData/data}} at indexes `4 * pixelIndex`
4221+
and `4 * pixelIndex + 2`.
4222+
2. Increment |pixelIndex| by `1`
4223+
6. Let |init| be a new {{VideoFrameBufferInit}} constructed with
4224+
{{VideoFrameBufferInit/format}} = |format|,
4225+
{{VideoFrameBufferInit/codedWidth}} = `rect.width`,
4226+
{{VideoFrameBufferInit/codedHeight}} = `rect.height`
4227+
7. Let |convertedFrame| be a new {{VideoFrame}} constructed with
4228+
|imageData|.{{ImageData/data}} and |init|
4229+
8. Return |convertedFrame|
4230+
41864231
: <dfn for=VideoFrame>Copy VideoFrame metadata</dfn> (with |metadata|)
41874232
:: 1. Let |metadataCopySerialized| be [$StructuredSerialize$](|metadata|).
41884233
2. Let |metadataCopy| be [$StructuredDeserialize$](|metadataCopySerialized|, [=the current Realm=]).
4189-
3. return |metadataCopy|.
4234+
3. Return |metadataCopy|.
41904235

41914236
The goal of this algorithm is to ensure that metadata owned by a {{VideoFrame}} is immutable.
41924237

@@ -4239,13 +4284,15 @@
42394284

42404285
VideoFrame CopyTo() Options {#videoframe-copyto-options}
42414286
------------------------------------------------------------
4242-
Options to specify a rectangle of pixels to copy and the offset and stride of
4243-
planes in the destination buffer.
4287+
Options to specify a rectangle of pixels to copy, their format and the offset
4288+
and stride of planes in the destination buffer.
42444289

42454290
<xmp class='idl'>
42464291
dictionary VideoFrameCopyToOptions {
42474292
DOMRectInit rect;
42484293
sequence<PlaneLayout> layout;
4294+
VideoPixelFormat format;
4295+
PredefinedColorSpace colorSpace;
42494296
};
42504297
</xmp>
42514298

@@ -4273,6 +4320,16 @@
42734320
to specify an offset and stride for each plane in the destination
42744321
{{BufferSource}}. If unspecified, the planes will be tightly packed. It is
42754322
invalid to specify planes that overlap.
4323+
: <dfn dict-member for=VideoFrameCopyToOptions>format</dfn>
4324+
:: A {{VideoPixelFormat}} for the pixel data in the destination
4325+
{{BufferSource}}. Explicity values cab be:
4326+
{{RGBA}}, {{RGBX}}, {{BGRA}}, {{BGRX}} and the same as {{VideoFrame/format}}.
4327+
If unspecified, the {{VideoFrame/format}} is used.
4328+
: <dfn dict-member for=VideoFrameCopyToOptions>colorSpace</dfn>
4329+
:: A {{PredefinedColorSpace}} that <em class="rfc2119">SHALL</em> be used to as
4330+
a target color space for for the pixel data in the destination
4331+
{{BufferSource}}.
4332+
42764333

42774334
DOMRects in VideoFrame {#videoframe-domrect}
42784335
--------------------------------------------

0 commit comments

Comments
 (0)