From 2462a916307f52e80ac3f91babf97996a3632fda Mon Sep 17 00:00:00 2001 From: Chris Cunningham Date: Fri, 30 Apr 2021 01:17:36 -0700 Subject: [PATCH 1/9] Define IDL for simpler regions-based VideoFrame API --- index.src.html | 91 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 19 deletions(-) diff --git a/index.src.html b/index.src.html index c76fe2bf..26b13159 100644 --- a/index.src.html +++ b/index.src.html @@ -1381,10 +1381,7 @@ BufferSource description; unsigned long codedWidth; unsigned long codedHeight; - unsigned long cropLeft; - unsigned long cropTop; - unsigned long cropWidth; - unsigned long cropHeight; + VideoFrameRegion visibleRegion; unsigned long displayWidth; unsigned long displayHeight; HardwareAcceleration hardwareAcceleration = "allow"; @@ -2110,15 +2107,29 @@ readonly attribute FrozenArray? planes; readonly attribute unsigned long codedWidth; readonly attribute unsigned long codedHeight; - readonly attribute unsigned long cropLeft; - readonly attribute unsigned long cropTop; - readonly attribute unsigned long cropWidth; - readonly attribute unsigned long cropHeight; + + // Convenience accessor, origin is always (0, 0). + readonly attribute VideoFrameRegion codedRegion; + + // Region of this frame's pixel data that is not padding. + readonly attribute VideoFrameRegion visibleRegion; + readonly attribute unsigned long displayWidth; readonly attribute unsigned long displayHeight; readonly attribute unsigned long long? duration; readonly attribute unsigned long long? timestamp; + // Returns the minimum size (in bytes) of a buffer that readInto() could + // read this frame into with the given options. + unsigned long allocationSize( + optional VideoFrameReadIntoOptions options = {}); + + // Read the planes of this frame into |destination| according to |options|. + // The format of the data is the same as this frame's |format|. + Promise> readInto( + BufferSource destination, + optional VideoFrameReadIntoOptions options = {}); + VideoFrame clone(); undefined close(); @@ -2134,14 +2145,11 @@ dictionary VideoFramePlaneInit { required PixelFormat format; - required unsigned long codedWidth; - required unsigned long codedHeight; - unsigned long cropLeft; - unsigned long cropTop; - unsigned long cropWidth; - unsigned long cropHeight; - unsigned long displayWidth; - unsigned long displayHeight; + required [EnforceRange] unsigned long codedWidth; + required [EnforceRange] unsigned long codedHeight; + VideoFrameRegion visibleRegion; + [EnforceRange] unsigned long displayWidth; + [EnforceRange] unsigned long displayHeight; unsigned long long duration; unsigned long long timestamp; }; @@ -2499,6 +2507,38 @@ {{VideoFrame/codedWidth}}, {{VideoFrame/codedHeight}}, etc.) to those of the same name in |clone|. 2. Return |clone|. +VideoFrame ReadInto() Options {#videoframe-readinto-options} +------------------------------------------------------------ +Options to specify which {{VideoFrameRegion}} to read and the location and +padding of planes in the destination buffer. + + +dictionary VideoFrameReadIntoOptions { + // The region to read. If unspecified, the visible region will be used. The + // coded region can be easily specified by passing frame.codedRegion. + VideoFrameRegion region; + + // The layout of each plane in the buffer. This allows the offset and stride + // of each plane to be specified. If unspecified, the planes will be tightly + // packed. It is invalid to specify planes that overlap. + sequence<PlaneLayout> layout; +}; + + +VideoFrame Region {#videoframe-region} +-------------------------------------- +A dictionary specifying the position and dimensions of a region within a +{{VideoFrame}}. + + +dictionary VideoFrameRegion { + required [EnforceRange] unsigned long left; + required [EnforceRange] unsigned long top; + required [EnforceRange] unsigned long width; + required [EnforceRange] unsigned long height; +}; + + Plane Interface {#plane-interface} ---------------------------------- A {{Plane}} is solely constructed by its {{VideoFrame}}. During construction, @@ -2523,9 +2563,9 @@ }; dictionary PlaneInit { - required BufferSource src; - required unsigned long stride; - required unsigned long rows; + required BufferSource data; + required [EnforceRange] unsigned long stride; + unsigned long offset; }; @@ -2562,6 +2602,19 @@ 5. Copy the |plane bytes| into |dst|. +Plane Layout{#plane-layout} +--------------------------- +Plane layouts describe the position (offset) and padded width (stride) of a +plane within a buffer. + + +dictionary PlaneLayout { + [EnforceRange] unsigned long offset; + [EnforceRange] unsigned long stride; +}; + + + Pixel Format{#pixel-format} --------------------------- Pixel formats describe the arrangement of bytes in each plane as well as the From f8a720b15770621c1dfaa2610a41c1ac7bddc8ca Mon Sep 17 00:00:00 2001 From: Chris Cunningham Date: Fri, 30 Apr 2021 01:27:33 -0700 Subject: [PATCH 2/9] Remove crop* dfn's in favor of visibleRegion --- Makefile | 1 - index.src.html | 50 -------------------------------------------------- 2 files changed, 51 deletions(-) diff --git a/Makefile b/Makefile index 46c82d50..b5f3d7f7 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,6 @@ remote-index: index.src.html --output index.html \ --write-out "%{http_code}" \ --header "Accept: text/plain, text/html" \ - -F die-on=warning \ -F file=@index.src.html) && \ [[ "$$HTTP_STATUS" -eq "200" ]]) || ( \ echo ""; cat index.html; echo ""; \ diff --git a/index.src.html b/index.src.html index 26b13159..ee8accce 100644 --- a/index.src.html +++ b/index.src.html @@ -1429,30 +1429,6 @@ adjustments. -
cropLeft
-
- The number of pixels to remove from the left of the VideoFrame, prior to - aspect ratio adjustments. Defaults to zero if not present. -
- -
cropTop
-
- The number of pixels to remove from the top of the VideoFrame, prior to - aspect ratio adjustments. Defaults to zero if not present. -
- -
cropWidth
-
- The width in pixels to include in the crop, starting from cropLeft. - Defaults to codedWidth if not present. -
- -
cropHeight
-
- The height in pixels to include in the crop, starting from cropLeft. - Defaults to codedHeight if not present. -
-
displayWidth
Width of the VideoFrame when displayed. Defaults to cropWidth if not @@ -2371,32 +2347,6 @@ The {{VideoFrame/codedHeight}} getter steps are to return {{VideoFrame/[[coded height]]}}. -: cropLeft -:: The number of pixels to remove from the left of the VideoFrame, prior to - aspect ratio adjustments. - - The {{VideoFrame/cropLeft}} getter steps are to return - {{VideoFrame/[[crop left]]}}. - -: cropTop -:: The number of pixels to remove from the top of the VideoFrame, prior to - aspect ratio adjustments. - - The {{VideoFrame/cropTop}} getter steps are to return - {{VideoFrame/[[crop top]]}}. - -: cropWidth -:: The width of pixels to include in the crop, starting from cropLeft. - - The {{VideoFrame/cropWidth}} getter steps are to return - {{VideoFrame/[[crop width]]}}. - -: cropHeight -:: The height of pixels to include in the crop, starting from cropLeft. - - The {{VideoFrame/cropHeight}} getter steps are to return - {{VideoFrame/[[crop height]]}}. - : displayWidth :: Width of the VideoFrame when displayed after applying aspect ratio adjustments. From 1d27d0afdef66ce1da124a658ed53ec449f83ef8 Mon Sep 17 00:00:00 2001 From: Chris Cunningham Date: Thu, 3 Jun 2021 00:33:54 -0700 Subject: [PATCH 3/9] Merge fixes --- index.src.html | 80 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/index.src.html b/index.src.html index 659f535d..ca6cc84c 100644 --- a/index.src.html +++ b/index.src.html @@ -2649,13 +2649,12 @@ 2. Assign {{VideoFramePlaneInit/format}} to {{VideoFrame/[[format]]}}. 3. Assign a new [=list=] to {{VideoFrame/[[planes]]}}. 4. For each |planeInit| in |planes|: - 1. Copy |planeInit|.{{PlaneInit/src}} to |resource|. + 1. Copy |planeInit|.{{PlaneInit/data}} to |resource|. - NOTE: The user agent may use {{VideoFramePlaneInit/cropLeft}} - and {{VideoFramePlaneInit/cropTop}} to copy only the crop - region. It may also reposition the crop region within - |resource|. The final position will be reflected by - {{VideoFrame/cropLeft}} and {{VideoFrame/cropTop}}. + NOTE: The user agent may use {{VideoFramePlaneInit/visibleRegion}} + to copy only the visible region. It may also reposition the + visible region within |resource|. The final position will be + reflected by {{VideoFrame/visibleRegion}}. 2. Let |plane| be a new {{Plane}} initialized as follows: 1. Assign |frame| to {{Plane/[[parent frame]]}}. @@ -2686,13 +2685,20 @@ 9. Assign |resourceCodedWidth|, |resourceCodedHeight|, |resourceCropLeft|, and |resourceCropTop| to {{VideoFrame/[[coded width]]}}, {{VideoFrame/[[coded height]]}}, {{VideoFrame/[[crop left]]}}, and - {{VideoFrame/[[crop top]]}} respectively. - 10. If |init|.{{VideoFramePlaneInit/cropWidth}} [=map/exists=], assign - it to {{VideoFrame/[[crop width]]}}. Otherwise, assign - {{VideoFrame/[[coded width]]}} to {{VideoFrame/[[crop width]]}}. - 11. If |init|.{{VideoFramePlaneInit/cropHeight}} [=map/exists=], assign it - to {{VideoFrame/[[crop height]]}}. Otehrwise, assign - {{VideoFrame/[[coded height]]}} to {{VideoFrame/[[crop height]]}}. + {{VideoFrame/[[crop top]]}} respectively + + 10. If |init|.{{VideoFramePlaneInit/visibleRegion}} [=map/exists=]: + 1. Assign + {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/width}} to + {{VideoFrame/[[crop width]]}}. + 2. Assign + {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/height}} to + {{VideoFrame/[[crop height]]}}. + 11. Otherwise: + 1. Assign {{VideoFrame/[[coded width]]}} to + {{VideoFrame/[[crop width]]}}. + 2. Assign {{VideoFrame/[[coded height]]}} to + {{VideoFrame/[[crop height]]}}. 12. If |init|.{{VideoFramePlaneInit/displayWidth}} [=map/exists=], assign it to {{VideoFrame/[[display width]]}}. Otherwise, assign {{VideoFrame/[[crop width]]}} to {{VideoFrame/[[display width]]}}. @@ -2782,11 +2788,13 @@ 2. Assign `true` to {{VideoFrame/[[detached]]}}. 3. Assign `""` to {{VideoFrame/format}}. 4. Assign `null` to {{VideoFrame/planes}}. - 5. Assign `0` to {{VideoFrame/codedWidth}}, {{VideoFrame/codedHeight}}, - {{VideoFrame/cropLeft}}, {{VideoFrame/cropTop}}, - {{VideoFrame/cropWidth}}, {{VideoFrame/cropHeight}}, - {{VideoFrame/displayWidth}}, and {{VideoFrame/displayHeight}}. - 6. Assign `null` to {{VideoFrame/duration}} and {{VideoFrame/timestamp}}. + 5. Assign `0` to {{VideoFrame/[[coded width]]}}, + {{VideoFrame/[[coded height]]}}, {{VideoFrame/[[crop left]]}}, + {{VideoFrame/[[crop top]]}}, {{VideoFrame/[[crop width]]}}, + {{VideoFrame/[[crop height]]}}, {{VideoFrame/[[display width]]}}, + and {{VideoFrame/[[display height]]}}. + 6. Assign `null` to {{VideoFrame/[[duration]]}} and + {{VideoFrame/[[timestamp]]}}. ### Algorithms ###{#videoframe-algorithms} Create a VideoFrame (with |output|, |timestamp|, |duration|, |displayAspectWidth|, and |displayAspectHeight|) @@ -2801,11 +2809,8 @@ {{VideoFramePlaneInit/codedHeight}} be the width and height of the decoded video frame |output| in pixels, prior to any cropping or aspect ratio adjustments. - 4. Let {{VideoFramePlaneInit/cropLeft}}, - {{VideoFramePlaneInit/cropTop}}, - {{VideoFramePlaneInit/cropWidth}}, and - {{VideoFramePlaneInit/cropHeight}} - be the crop region of the decoded video frame |output| in + 4. Let {{VideoFramePlaneInit/visibleRegion}}, + be the visible region of the decoded video frame |output| in pixels, prior to any aspect ratio adjustments. 5. Let |displayWidth| and |displayHeight| be the the display size of the decoded frame in pixels. @@ -2823,13 +2828,14 @@ valid VideoFramePlaneInit, run these steps: :: 1. If {{VideoFramePlaneInit/codedWidth}} = 0 or {{VideoFramePlaneInit/codedHeight}} = 0,return `false`. - 2. If {{VideoFramePlaneInit/cropWidth}} = 0 or - {{VideoFramePlaneInit/cropHeight}} = 0, return `false`. - 3. If {{VideoFramePlaneInit/cropTop}} + - {{VideoFramePlaneInit/cropHeight}} >= + 2. If {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/width}} = 0 + or {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/height}} = + 0, return `false`. + 3. If {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/top}} + + {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/height}} >= {{VideoFramePlaneInit/codedHeight}}, return `false`. - 4. If {{VideoFramePlaneInit/cropLeft}} + - {{VideoFramePlaneInit/cropWidth}} >= + 4. If {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/left}} + + {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/width}} >= {{VideoFramePlaneInit/codedWidth}}, return `false`. 5. If {{VideoFramePlaneInit/displayWidth}} = 0 or {{VideoFramePlaneInit/displayHeight}} = 0, return `false`. @@ -2843,10 +2849,8 @@ {{VideoFrame/[[resource reference]]}}. 3. Assign the following attributes from |otherFrame| to |frame|: {{VideoFrame/format}}, {{VideoFrame/codedWidth}}, - {{VideoFrame/codedHeight}}, {{VideoFrame/cropLeft}}, - {{VideoFrame/cropTop}}, {{VideoFrame/cropWidth}}, - {{VideoFrame/cropHeight}}, {{VideoFrame/displayWidth}}, - {{VideoFrame/displayHeight}}. + {{VideoFrame/codedHeight}}, {{VideoFrame/visibleRegion}}, + {{VideoFrame/displayWidth}}, {{VideoFrame/displayHeight}}. 4. Let |planes| be a new [=list=]. 5. For each |otherPlane| in |otherFrame|.{{VideoFrame/planes}}: 1. Let |plane| be a new {{Plane}}. @@ -2883,13 +2887,11 @@ 1. Assign `""` to {{VideoFrame/format}}. 2. Assign `null` to {{VideoFrame/planes}}. 4. Assign |width| to the following attributes of |frame|: - {{VideoFrame/codedWidth}}, {{VideoFrame/cropWidth}}, - {{VideoFrame/displayWidth}}. + {{VideoFrame/codedWidth}}, {{VideoFrame/displayWidth}}. 5. Assign |height| to the following attributes of |frame|: - {{VideoFrame/codedHeight}}, {{VideoFrame/cropHeight}}, - {{VideoFrame/displayHeight}}. - 6. Assign `0` to frame's {{VideoFrame/cropTop}} and - {{VideoFrame/cropLeft}}. + {{VideoFrame/codedHeight}}, {{VideoFrame/displayHeight}}. + 6. Assign «[ "left:" → `0`, "top" → `0`, "width" → |width|, "height" → + |height| ]» to |frame|.{{VideoFrame/visibleRegion}}. 7. Assign `init`.{{VideoFrameInit/duration}} to |frame|.{{VideoFrame/duration}}. 8. Assign `init`.{{VideoFrameInit/timestamp}} to From e8ce1f4da849b1743ba1a68518952e44787243f9 Mon Sep 17 00:00:00 2001 From: Chris Cunningham Date: Thu, 3 Jun 2021 00:53:29 -0700 Subject: [PATCH 4/9] Various renames - s/crop/visbile/ - s/region/rect/ - s/readInto/copyTo/ --- index.src.html | 168 +++++++++++++++++++++++++------------------------ 1 file changed, 85 insertions(+), 83 deletions(-) diff --git a/index.src.html b/index.src.html index ca6cc84c..d556d147 100644 --- a/index.src.html +++ b/index.src.html @@ -1268,8 +1268,10 @@ 5. Let |outputConfig| be a {{VideoDecoderConfig}} that describes |output|. Initialize |outputConfig| as follows: 1. Assign `encoderConfig.codec` to `outputConfig.codec`. - 2. Assign `encoderConfig.width` to `outputConfig.cropWidth`. - 3. Assign `encoderConfig.height` to `outputConfig.cropHeight`. + 2. Assign `encoderConfig.width` to + `outputConfig.visibleRect.width`. + 3. Assign `encoderConfig.height` to + `outputConfig.visibleRect.height`. 4. Assign `encoderConfig.displayWidth` to `outputConfig.displayWidth`. 5. Assign `encoderConfig.displayHeight` to @@ -1574,14 +1576,14 @@
codedWidth
- Width of the VideoFrame in pixels, prior to any cropping or aspect ratio - adjustments. + Width of the VideoFrame in pixels, potentionally including non-visible + padding, and prior to considering potential ratio adjustments.
codedHeight
- Height of the VideoFrame in pixels, prior to any cropping or aspect ratio - adjustments. + Height of the VideoFrame in pixels, potentionally including non-visible + padding, and prior to considering potential ratio adjustments.
NOTE: {{VideoDecoderConfig/codedWidth}} and {{VideoDecoderConfig/codedHeight}} @@ -1689,7 +1691,7 @@ display aspect ratio adjustments. The encoder must scale any {{VideoFrame}} whose - {{VideoFrame/[[crop width]]}} differs from this value. + {{VideoFrame/[[visible width]]}} differs from this value.
height
@@ -1698,7 +1700,7 @@ display aspect ratio adjustments. The encoder must scale any {{VideoFrame}} whose - {{VideoFrame/[[crop height]]}} differs from this value. + {{VideoFrame/[[visible height]]}} differs from this value. @@ -2458,26 +2460,26 @@ readonly attribute unsigned long codedHeight; // Convenience accessor, origin is always (0, 0). - readonly attribute VideoFrameRegion codedRegion; + readonly attribute VideoFrameRect codedRect; - // Region of this frame's pixel data that is not padding. - readonly attribute VideoFrameRegion visibleRegion; + // Rectangle of this frame's pixel data that is not padding. + readonly attribute VideoFrameRect visibleRect; readonly attribute unsigned long displayWidth; readonly attribute unsigned long displayHeight; readonly attribute long long? duration; // microseconds readonly attribute long long? timestamp; // microseconds - // Returns the minimum size (in bytes) of a buffer that readInto() could - // read this frame into with the given options. + // Returns the minimum size (in bytes) of a buffer that copyTo() could + // copy this frame into with the given options. unsigned long allocationSize( - optional VideoFrameReadIntoOptions options = {}); + optional VideoFrameCopyToOptions options = {}); - // Read the planes of this frame into |destination| according to |options|. + // Copy the planes of this frame into |destination| according to |options|. // The format of the data is the same as this frame's |format|. - Promise> readInto( + Promise> copyTo( BufferSource destination, - optional VideoFrameReadIntoOptions options = {}); + optional VideoFrameCopyToOptions options = {}); VideoFrame clone(); undefined close(); @@ -2492,7 +2494,7 @@ required PixelFormat format; [EnforceRange] required unsigned long codedWidth; [EnforceRange] required unsigned long codedHeight; - VideoFrameRegion visibleRegion; + VideoFrameRect visibleRect; [EnforceRange] unsigned long displayWidth; [EnforceRange] unsigned long displayHeight; [EnforceRange] long long duration; // microseconds @@ -2519,26 +2521,26 @@ determined by {{VideoFrame/[[format]]}}. : [[coded width]] -:: Width of the {{VideoFrame}} in pixels, prior to any cropping or aspect - ratio adjustments. +:: Width of the {{VideoFrame}} in pixels, potentionally including non-visible + padding, and prior to considering potential ratio adjustments. : [[coded height]] -:: Height of the {{VideoFrame}} in pixels, prior to any cropping or aspect - ratio adjustments. +:: Height of the {{VideoFrame}} in pixels, potentionally including non-visible + padding, and prior to considering potential ratio adjustments. -: [[crop left]] -:: The number of pixels to remove from the left of the {{VideoFrame}}, - prior to aspect ratio adjustments. +: [[visible left]] +:: The number of pixels defining the left offset of the visible rectangle. -: [[crop top]] -:: The number of pixels to remove from the top of the {{VideoFrame}}, - prior to aspect ratio adjustments. +: [[visible top]] +:: The number of pixels defining the top offset of the visible rectangle. -: [[crop width]] -:: The width of pixels to include in the crop, starting from cropLeft. +: [[visible width]] +:: The width of pixels to include in visible rectangle, starting from + {{VideoFrame/[[visible left]]}}. -: [[crop height]] -:: The height of pixels to include in the crop, starting from cropLeft. +: [[visible height]] +:: The height of pixels to include in visible rectangle, starting from + {{VideoFrame/[[visible top]]}}. : [[display width]] :: Width of the {{VideoFrame}} when displayed after applying aspect ratio @@ -2627,7 +2629,7 @@ (e.g. wrong number of planes), throw a {{TypeError}}. ISSUE: The spec should list additional format specific validation steps ( - e.g. number and order of planes, acceptable sizing, etc...). See + e.g. number and order of planes, acceptable sizing, etc...). See [#165](https://github.com/w3c/webcodecs/issues/165). 3. Let |resource| be a new [=media resource=] allocated in accordance with @@ -2651,10 +2653,10 @@ 4. For each |planeInit| in |planes|: 1. Copy |planeInit|.{{PlaneInit/data}} to |resource|. - NOTE: The user agent may use {{VideoFramePlaneInit/visibleRegion}} - to copy only the visible region. It may also reposition the - visible region within |resource|. The final position will be - reflected by {{VideoFrame/visibleRegion}}. + NOTE: The user agent may use {{VideoFramePlaneInit/visibleRect}} + to copy only the visible rectangle. It may also reposition the + visible rectangle within |resource|. The final position will be + reflected by {{VideoFrame/visibleRect}}. 2. Let |plane| be a new {{Plane}} initialized as follows: 1. Assign |frame| to {{Plane/[[parent frame]]}}. @@ -2673,38 +2675,38 @@ 5. Let |resourceCodedWidth| be the coded width of |resource|. 6. Let |resourceCodedHeight| be the coded height of |resource|. - 7. Let |resourceCropLeft| be the left offset of the crop origin of + 7. Let |resourceVisibleLeft| be the left offset for the visible rectangle of |resource|. - 8. Let |resourceCropTop| be the top offset of the crop origin of + 8. Let |resourceVisibleTop| be the top offset for the visible rectangle of |resource|. ISSUE: The spec should provide definitions (and possibly diagrams) for - coded size, crop size, and display size. See + coded size, visible rectangle, and display size. See [#166](https://github.com/w3c/webcodecs/issues/166). - 9. Assign |resourceCodedWidth|, |resourceCodedHeight|, |resourceCropLeft|, - and |resourceCropTop| to {{VideoFrame/[[coded width]]}}, - {{VideoFrame/[[coded height]]}}, {{VideoFrame/[[crop left]]}}, and - {{VideoFrame/[[crop top]]}} respectively + 9. Assign |resourceCodedWidth|, |resourceCodedHeight|, |resourceVisibleLeft|, + and |resourceVisibleTop| to {{VideoFrame/[[coded width]]}}, + {{VideoFrame/[[coded height]]}}, {{VideoFrame/[[visible left]]}}, and + {{VideoFrame/[[visible top]]}} respectively - 10. If |init|.{{VideoFramePlaneInit/visibleRegion}} [=map/exists=]: + 10. If |init|.{{VideoFramePlaneInit/visibleRect}} [=map/exists=]: 1. Assign - {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/width}} to - {{VideoFrame/[[crop width]]}}. + {{VideoFramePlaneInit/visibleRect}}.{{VideoFrameRect/width}} to + {{VideoFrame/[[visible width]]}}. 2. Assign - {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/height}} to - {{VideoFrame/[[crop height]]}}. + {{VideoFramePlaneInit/visibleRect}}.{{VideoFrameRect/height}} to + {{VideoFrame/[[visible height]]}}. 11. Otherwise: 1. Assign {{VideoFrame/[[coded width]]}} to - {{VideoFrame/[[crop width]]}}. + {{VideoFrame/[[visible width]]}}. 2. Assign {{VideoFrame/[[coded height]]}} to - {{VideoFrame/[[crop height]]}}. + {{VideoFrame/[[visible height]]}}. 12. If |init|.{{VideoFramePlaneInit/displayWidth}} [=map/exists=], assign it to {{VideoFrame/[[display width]]}}. Otherwise, assign - {{VideoFrame/[[crop width]]}} to {{VideoFrame/[[display width]]}}. + {{VideoFrame/[[visible width]]}} to {{VideoFrame/[[display width]]}}. 13. If |init|.{{VideoFramePlaneInit/displayHeight}} [=map/exists=], assign it to {{VideoFrame/[[display height]]}}. Otherwise, assign - {{VideoFrame/[[crop height]]}} to {{VideoFrame/[[display height]]}}. + {{VideoFrame/[[visible height]]}} to {{VideoFrame/[[display height]]}}. 14. Assign |init|'s {{VideoFramePlaneInit/timestamp}} and {{VideoFramePlaneInit/duration}} to {{VideoFrame/[[timestamp]]}} and {{VideoFrame/[[duration]]}} respectively. @@ -2726,15 +2728,15 @@ {{VideoFrame/[[planes]]}}. : codedWidth -:: Width of the {{VideoFrame}} in pixels, prior to any cropping or aspect ratio - adjustments. +:: Width of the {{VideoFrame}} in pixels, potentionally including non-visible + padding, and prior to considering potential ratio adjustments. The {{VideoFrame/codedWidth}} getter steps are to return {{VideoFrame/[[coded width]]}}. : codedHeight -:: Height of the VideoFrame in pixels, prior to any cropping or aspect ratio - adjustments. +:: Height of the VideoFrame in pixels, potentionally including non-visible + padding, and prior to considering potential ratio adjustments. The {{VideoFrame/codedHeight}} getter steps are to return {{VideoFrame/[[coded height]]}}. @@ -2789,9 +2791,9 @@ 3. Assign `""` to {{VideoFrame/format}}. 4. Assign `null` to {{VideoFrame/planes}}. 5. Assign `0` to {{VideoFrame/[[coded width]]}}, - {{VideoFrame/[[coded height]]}}, {{VideoFrame/[[crop left]]}}, - {{VideoFrame/[[crop top]]}}, {{VideoFrame/[[crop width]]}}, - {{VideoFrame/[[crop height]]}}, {{VideoFrame/[[display width]]}}, + {{VideoFrame/[[coded height]]}}, {{VideoFrame/[[visible left]]}}, + {{VideoFrame/[[visible top]]}}, {{VideoFrame/[[visible width]]}}, + {{VideoFrame/[[visible height]]}}, {{VideoFrame/[[display width]]}}, and {{VideoFrame/[[display height]]}}. 6. Assign `null` to {{VideoFrame/[[duration]]}} and {{VideoFrame/[[timestamp]]}}. @@ -2808,9 +2810,10 @@ 3. Let {{VideoFramePlaneInit/codedWidth}} and {{VideoFramePlaneInit/codedHeight}} be the width and height of the decoded video frame |output| in - pixels, prior to any cropping or aspect ratio adjustments. - 4. Let {{VideoFramePlaneInit/visibleRegion}}, - be the visible region of the decoded video frame |output| in + pixels, potentionally including non-visible padding, and prior to + considering potential ratio adjustments. + 4. Let {{VideoFramePlaneInit/visibleRect}}, + be the visible rectangle of the decoded video frame |output| in pixels, prior to any aspect ratio adjustments. 5. Let |displayWidth| and |displayHeight| be the the display size of the decoded frame in pixels. @@ -2828,14 +2831,14 @@ valid VideoFramePlaneInit, run these steps: :: 1. If {{VideoFramePlaneInit/codedWidth}} = 0 or {{VideoFramePlaneInit/codedHeight}} = 0,return `false`. - 2. If {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/width}} = 0 - or {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/height}} = + 2. If {{VideoFramePlaneInit/visibleRect}}.{{VideoFrameRect/width}} = 0 + or {{VideoFramePlaneInit/visibleRect}}.{{VideoFrameRect/height}} = 0, return `false`. - 3. If {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/top}} + - {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/height}} >= + 3. If {{VideoFramePlaneInit/visibleRect}}.{{VideoFrameRect/top}} + + {{VideoFramePlaneInit/visibleRect}}.{{VideoFrameRect/height}} >= {{VideoFramePlaneInit/codedHeight}}, return `false`. - 4. If {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/left}} + - {{VideoFramePlaneInit/visibleRegion}}.{{VideoFrameRegion/width}} >= + 4. If {{VideoFramePlaneInit/visibleRect}}.{{VideoFrameRect/left}} + + {{VideoFramePlaneInit/visibleRect}}.{{VideoFrameRect/width}} >= {{VideoFramePlaneInit/codedWidth}}, return `false`. 5. If {{VideoFramePlaneInit/displayWidth}} = 0 or {{VideoFramePlaneInit/displayHeight}} = 0, return `false`. @@ -2849,7 +2852,7 @@ {{VideoFrame/[[resource reference]]}}. 3. Assign the following attributes from |otherFrame| to |frame|: {{VideoFrame/format}}, {{VideoFrame/codedWidth}}, - {{VideoFrame/codedHeight}}, {{VideoFrame/visibleRegion}}, + {{VideoFrame/codedHeight}}, {{VideoFrame/visibleRect}}, {{VideoFrame/displayWidth}}, {{VideoFrame/displayHeight}}. 4. Let |planes| be a new [=list=]. 5. For each |otherPlane| in |otherFrame|.{{VideoFrame/planes}}: @@ -2891,7 +2894,7 @@ 5. Assign |height| to the following attributes of |frame|: {{VideoFrame/codedHeight}}, {{VideoFrame/displayHeight}}. 6. Assign «[ "left:" → `0`, "top" → `0`, "width" → |width|, "height" → - |height| ]» to |frame|.{{VideoFrame/visibleRegion}}. + |height| ]» to |frame|.{{VideoFrame/visibleRect}}. 7. Assign `init`.{{VideoFrameInit/duration}} to |frame|.{{VideoFrame/duration}}. 8. Assign `init`.{{VideoFrameInit/timestamp}} to @@ -2914,16 +2917,16 @@ {{VideoFrame/codedWidth}}, {{VideoFrame/codedHeight}}, etc.) to those of the same name in |clone|. 2. Return |clone|. -VideoFrame ReadInto() Options {#videoframe-readinto-options} +VideoFrame CopyTo() Options {#videoframe-copyto-options} ------------------------------------------------------------ -Options to specify which {{VideoFrameRegion}} to read and the location and +Options to specify which {{VideoFrameRect}} to copy and the location and padding of planes in the destination buffer. -dictionary VideoFrameReadIntoOptions { - // The region to read. If unspecified, the visible region will be used. The - // coded region can be easily specified by passing frame.codedRegion. - VideoFrameRegion region; +dictionary VideoFrameCopyToOptions { + // The rectangle to copy. If unspecified, the visibleRect will be used. + // The codedRect can be easily specified by passing frame.codedRect. + VideoFrameRect rect; // The layout of each plane in the buffer. This allows the offset and stride // of each plane to be specified. If unspecified, the planes will be tightly @@ -2932,13 +2935,12 @@ }; -VideoFrame Region {#videoframe-region} +VideoFrame Rectangle (Rect) {#videoframe-rect} -------------------------------------- -A dictionary specifying the position and dimensions of a region within a -{{VideoFrame}}. +A dictionary specifying the position and dimensions of a rectangle of pixels within a {{VideoFrame}}. -dictionary VideoFrameRegion { +dictionary VideoFrameRect { required [EnforceRange] unsigned long left; required [EnforceRange] unsigned long top; required [EnforceRange] unsigned long width; @@ -2966,7 +2968,7 @@ readonly attribute unsigned long rows; readonly attribute unsigned long length; - undefined readInto(ArrayBufferView dst); + undefined copyTo(ArrayBufferView dst); }; dictionary PlaneInit { @@ -2993,7 +2995,7 @@ </dl> ### Methods ###{#plane-methods} -<dfn method for=Plane>readInto(|dst|)</dfn> +<dfn method for=Plane>copyTo(|dst|)</dfn> Copies the plane data into dst. From 0dc00be7198acf879be5189c0ea67bd0fb838431 Mon Sep 17 00:00:00 2001 From: Chris Cunningham <chcunningham@chromium.org> Date: Thu, 3 Jun 2021 00:57:44 -0700 Subject: [PATCH 5/9] Remove VideoFrame/planes --- index.src.html | 216 ++++++++++++------------------------------------- 1 file changed, 52 insertions(+), 164 deletions(-) diff --git a/index.src.html b/index.src.html index d556d147..d31e5576 100644 --- a/index.src.html +++ b/index.src.html @@ -2451,11 +2451,10 @@ [Exposed=(Window,DedicatedWorker)] interface VideoFrame { constructor(CanvasImageSource image, optional VideoFrameInit init = {}); - constructor(sequence<(Plane or PlaneInit)> planes, + constructor(sequence<PlaneInit> planes, VideoFramePlaneInit init); readonly attribute PixelFormat format; - readonly attribute FrozenArray<Plane>? planes; readonly attribute unsigned long codedWidth; readonly attribute unsigned long codedHeight; @@ -2500,6 +2499,12 @@ [EnforceRange] long long duration; // microseconds [EnforceRange] long long timestamp; // microseconds }; + +dictionary PlaneInit { + required BufferSource data; + [EnforceRange] required unsigned long rows; + [EnforceRange] required unsigned long offset; +}; ### Internal Slots ###{#videoframe-internal-slots} @@ -2515,11 +2520,6 @@ : \[[format]] :: A {{PixelFormat}} describing the pixel format of the {{VideoFrame}}. -: \[[planes]] -:: A list of {{Plane}}s describing the memory layout of the pixel data in - {{VideoFrame}}. The number of {{Plane}}s and their semantics are - determined by {{VideoFrame/[[format]]}}. - : [[coded width]] :: Width of the {{VideoFrame}} in pixels, potentionally including non-visible padding, and prior to considering potential ratio adjustments. @@ -2641,16 +2641,14 @@ NOTE: The user agent may choose to allocate resource with a larger coded size and plane strides to improve memory alignment. Increases will be - reflected by {{VideoFrame/codedWidth}}, {{VideoFrame/codedHeight}}, and - {{Plane/stride}}. + reflected by {{VideoFrame/codedWidth}} and {{VideoFrame/codedHeight}}. 4. Let |resourceReference| be a reference to |resource|. 5. Let |frame| be a new {{VideoFrame}} object initialized as follows: 1. Assign |resourceReference| to {{VideoFrame/[[resource reference]]}}. 2. Assign {{VideoFramePlaneInit/format}} to {{VideoFrame/[[format]]}}. - 3. Assign a new [=list=] to {{VideoFrame/[[planes]]}}. - 4. For each |planeInit| in |planes|: + 3. For each |planeInit| in |planes|: 1. Copy |planeInit|.{{PlaneInit/data}} to |resource|. NOTE: The user agent may use {{VideoFramePlaneInit/visibleRect}} @@ -2658,36 +2656,22 @@ visible rectangle within |resource|. The final position will be reflected by {{VideoFrame/visibleRect}}. - 2. Let |plane| be a new {{Plane}} initialized as follows: - 1. Assign |frame| to {{Plane/[[parent frame]]}}. - 2. Let |resourceStride| be the stride of the plane coresponding to - |planeInit| in |resource|. - - ISSUE: The spec should provide a definition (and possibly - diagrams) for stride. See - [#166](https://github.com/w3c/webcodecs/issues/166). - - 3. Assign |resourceStride| to {{Plane/stride}}. - 4. Assign |planeInit|.{{PlaneInit/rows}} to {{Plane/rows}}. - 5. Assign the product of ({{Plane/stride}} * {{Plane/rows}}) to - {{Plane/length}}. - 3. Append |plane| to {{VideoFrame/[[planes]]}}. - - 5. Let |resourceCodedWidth| be the coded width of |resource|. - 6. Let |resourceCodedHeight| be the coded height of |resource|. - 7. Let |resourceVisibleLeft| be the left offset for the visible rectangle of + 4. Let |resourceCodedWidth| be the coded width of |resource|. + 5. Let |resourceCodedHeight| be the coded height of |resource|. + 6. Let |resourceVisibleLeft| be the left offset for the visible rectangle of |resource|. - 8. Let |resourceVisibleTop| be the top offset for the visible rectangle of + 7. Let |resourceVisibleTop| be the top offset for the visible rectangle of |resource|. ISSUE: The spec should provide definitions (and possibly diagrams) for coded size, visible rectangle, and display size. See [#166](https://github.com/w3c/webcodecs/issues/166). - 9. Assign |resourceCodedWidth|, |resourceCodedHeight|, |resourceVisibleLeft|, - and |resourceVisibleTop| to {{VideoFrame/[[coded width]]}}, - {{VideoFrame/[[coded height]]}}, {{VideoFrame/[[visible left]]}}, and - {{VideoFrame/[[visible top]]}} respectively + 8. Assign |resourceCodedWidth|, |resourceCodedHeight|, + |resourceVisibleLeft|, and |resourceVisibleTop| to + {{VideoFrame/[[coded width]]}}, {{VideoFrame/[[coded height]]}}, + {{VideoFrame/[[visible left]]}}, and {{VideoFrame/[[visible top]]}} + respectively. 10. If |init|.{{VideoFramePlaneInit/visibleRect}} [=map/exists=]: 1. Assign @@ -2720,13 +2704,6 @@ The {{VideoFrame/format}} getter steps are to return {{VideoFrame/[[format]]}}. -: planes -:: Holds pixel data data, laid out as described by format and Plane - attributes. - - The {{VideoFrame/planes}} getter steps are to return - {{VideoFrame/[[planes]]}}. - : codedWidth :: Width of the {{VideoFrame}} in pixels, potentionally including non-visible padding, and prior to considering potential ratio adjustments. @@ -2789,43 +2766,43 @@ 1. Assign `null` to {{VideoFrame/[[resource reference]]}}. 2. Assign `true` to {{VideoFrame/[[detached]]}}. 3. Assign `""` to {{VideoFrame/format}}. - 4. Assign `null` to {{VideoFrame/planes}}. - 5. Assign `0` to {{VideoFrame/[[coded width]]}}, + 4. Assign `0` to {{VideoFrame/[[coded width]]}}, {{VideoFrame/[[coded height]]}}, {{VideoFrame/[[visible left]]}}, {{VideoFrame/[[visible top]]}}, {{VideoFrame/[[visible width]]}}, {{VideoFrame/[[visible height]]}}, {{VideoFrame/[[display width]]}}, and {{VideoFrame/[[display height]]}}. - 6. Assign `null` to {{VideoFrame/[[duration]]}} and + 5. Assign `null` to {{VideoFrame/[[duration]]}} and {{VideoFrame/[[timestamp]]}}. ### Algorithms ###{#videoframe-algorithms} Create a VideoFrame (with |output|, |timestamp|, |duration|, |displayAspectWidth|, and |displayAspectHeight|) - 1. Let |planes| be a sequence of {{Plane}}s containing the decoded - video frame data from |output|. - 2. Let |pixelFormat| be the {{PixelFormat}} of |planes|. - 3. Let |init| be a {{VideoFramePlaneInit}} with the following - keys: - 1. Assign |timestamp| to {{VideoFrameInit/timestamp}}. - 2. Assign |duration| to {{VideoFrameInit/duration}}. - 3. Let {{VideoFramePlaneInit/codedWidth}} and - {{VideoFramePlaneInit/codedHeight}} - be the width and height of the decoded video frame |output| in - pixels, potentionally including non-visible padding, and prior to - considering potential ratio adjustments. - 4. Let {{VideoFramePlaneInit/visibleRect}}, - be the visible rectangle of the decoded video frame |output| in - pixels, prior to any aspect ratio adjustments. - 5. Let |displayWidth| and |displayHeight| be the the display size of - the decoded frame in pixels. - 6. If |displayAspectWidth| and |displayAspectHeight| are provided, + 1. Let |frame| be a new {{VideoFrame}}, constructed as follows: + 1. Assign `false` to {{VideoFrame/[[detached]]}}. + 2. Let |resource| be the [=media resource=] described by |output|. + 3. Let |resourceReference| be a reference to |resource|. + 4. Assign |resourceReference| to {{VideoFrame/[[resource reference]]}}. + 5. If |output| uses a recognized {{PixelFormat}}, assign that format to + {{VideoFrame/[[format]]}}. Otherwise, assign `""` to + {{VideoFrame/[[format]]}}. + 6. Let |codedWidth| and |codedHeight| be the coded width and height of the + |output| in pixels. + 8. Let |visibleLeft|, |visibleTop|, |visibleWidth|, and |visibleHeight| be + the left, top, width and height for the visible rectangle of |output|. + 7. Let |displayWidth| and |displayHeight| be the the display size of + |output| in pixels. + 8. If |displayAspectWidth| and |displayAspectHeight| are provided, increase |displayWidth| or |displayHeight| until the ratio of |displayWidth| to |displayHeight| matches the ratio of |displayAspectWidth| to |displayAspectHeight|. - 7. Assign the value of |displayWidth| and |displayHeight| to - {{VideoFramePlaneInit/displayWidth}} and - {{VideoFramePlaneInit/displayHeight}} respectively. - 4. Return a new {{VideoFrame}}, constructed with |pixelFormat|, - |planes|, and |init|. + 9. Assign |codedWidth|, |codedHeight|, |visibleLeft|, |visibleTop|, + |visibleWidth|, |visibleHeight|, |displayWidth|, and + |displayHeight| to {{VideoFrame/[[coded width]]}}, + {{VideoFrame/[[coded height]]}}, {{VideoFrame/[[visible left]]}}, + {{VideoFrame/[[visible top]]}}, {{VideoFrame/[[visible width]]}}, + and {{VideoFrame/[[visible height]]}} respectively.. + 10. Assign |duration| and |timestamp| to {{VideoFrame/[[duration]]}} and + {{VideoFrame/[[timestamp]]}} respectively. + 2. Return |frame|. : To check if a {{VideoFramePlaneInit}} is a valid VideoFramePlaneInit, run these steps: @@ -2854,20 +2831,11 @@ {{VideoFrame/format}}, {{VideoFrame/codedWidth}}, {{VideoFrame/codedHeight}}, {{VideoFrame/visibleRect}}, {{VideoFrame/displayWidth}}, {{VideoFrame/displayHeight}}. - 4. Let |planes| be a new [=list=]. - 5. For each |otherPlane| in |otherFrame|.{{VideoFrame/planes}}: - 1. Let |plane| be a new {{Plane}}. - 2. Assign a reference for |frame| to |plane|'s - {{Plane/[[parent frame]]}}. - 3. Assign the following attributes from |otherPlane| to |plane|: - {{Plane/stride}}, {{Plane/rows}}, {{Plane/length}}. - 4. Append |plane| to |planes|. - 6. Assign |planes| to |frame|.{{VideoFrame/planes}}. - 7. If {{VideoFrameInit/duration}} [=map/exists=] in |init|, assign it to + 4. If {{VideoFrameInit/duration}} [=map/exists=] in |init|, assign it to |frame|.{{VideoFrame/duration}}. Otherwise, assign |otherFrame|.{{VideoFrame/duration}} to |frame|.{{VideoFrame/duration}}. - 8. If {{VideoFrameInit/timestamp}} [=map/exists=] in |init|, assign it to + 5. If {{VideoFrameInit/timestamp}} [=map/exists=] in |init|, assign it to |frame|.{{VideoFrame/timestamp}}. Otherwise, assign |otherFrame|.{{VideoFrame/timestamp}} to |frame|.{{VideoFrame/timestamp}}. @@ -2876,19 +2844,9 @@ |init|, |frame|, |resource|, |width| and |height|) :: 1. Assign a new reference for |resource| to |frame|'s {{VideoFrame/[[resource reference]]}}. - 2. If |resource| uses a recognized {{PixelFormat}}: - 1. Assign the {{PixelFormat}} of |resource| to {{VideoFrame/format}}. - 2. Let |planes| be a list of {{Plane}}s describing the - [=media resource=] in accordance with the {{VideoFrame/format}}. - - ISSUE: The spec should define explicit rules for each - {{PixelFormat}} and reference them in the step above. See - [#165](https://github.com/w3c/webcodecs/issues/165). - - 3. Assign |planes| to {{VideoFrame/planes}}. - 3. Otherwise (|resource| does not use a recognized {{PixelFormat}}): - 1. Assign `""` to {{VideoFrame/format}}. - 2. Assign `null` to {{VideoFrame/planes}}. + 2. If |resource| uses a recognized {{PixelFormat}}, assign the + {{PixelFormat}} of |resource| to {{VideoFrame/[[format]]}}. + 3. Otherwise, assign `""` to {{VideoFrame/[[format]]}}. 4. Assign |width| to the following attributes of |frame|: {{VideoFrame/codedWidth}}, {{VideoFrame/displayWidth}}. 5. Assign |height| to the following attributes of |frame|: @@ -2905,16 +2863,9 @@ 1. Assign |frame|.{{VideoFrame/[[resource reference]]}} to {{VideoFrame/[[resource reference]]}}. 2. Assign |frame|.{{VideoFrame/format}} to {{VideoFrame/format}}. - 3. Assign a new [=list=] to {{VideoFrame/planes}}. - 4. For each |plane| in {{VideoFrame/planes}}: - 1. Let |clonePlane| be a new {{Plane}} initialized as follows: - 1. Assign |clone| to |clonePlane|.{{Plane/[[parent frame]]}}. - 2. Assign |plane|.{{Plane/stride}} to {{Plane/stride}}. - 3. Assign |plane|.{{Plane/rows}} to {{Plane/rows}}. - 4. Assign |plane|.{{Plane/length}} to {{Plane/length}}. - 2. Append |clonePlane| to {{VideoFrame/planes}}. - 5. Assign all remaining attributes of |frame| ( - {{VideoFrame/codedWidth}}, {{VideoFrame/codedHeight}}, etc.) to those of the same name in |clone|. + 3. Assign all remaining attributes of |frame| ( + {{VideoFrame/codedWidth}}, {{VideoFrame/codedHeight}}, etc.) to + those of the same name in |clone|. 2. Return |clone|. VideoFrame CopyTo() Options {#videoframe-copyto-options} @@ -2948,69 +2899,6 @@ }; -Plane Interface {#plane-interface} ----------------------------------- -A {{Plane}} is solely constructed by its {{VideoFrame}}. During construction, - the User Agent may use knowledge of the frame’s {{PixelFormat}} to add - padding to the {{Plane}} to improve memory alignment. - -A {{Plane}} cannot be used after the {{VideoFrame}} is destroyed. A new - {{VideoFrame}} can be assembled from existing {{Plane}}s, and the new - {{VideoFrame}} will remain valid when the original is destroyed. This makes - it possible to efficiently add an alpha plane to an existing - {{VideoFrame}}. - - - -[Exposed=(Window,DedicatedWorker)] -interface Plane { - readonly attribute unsigned long stride; - readonly attribute unsigned long rows; - readonly attribute unsigned long length; - - undefined copyTo(ArrayBufferView dst); -}; - -dictionary PlaneInit { - required BufferSource data; - [EnforceRange] required unsigned long stride; - [EnforceRange] required unsigned long rows; -}; - - -### Internal Slots ###{#plane-internal-slots} -
-
[[parent frame]]
-
Refers to the {{VideoFrame}} that constructed and owns this plane.
-
- -### Attributes ###{#plane-attributes} -
-
stride
-
The width of each row including any padding.
-
rows
-
The number of rows.
-
length
-
The total byte length of the plane (stride * rows).
-
- -### Methods ###{#plane-methods} -copyTo(|dst|) - -Copies the plane data into dst. - -When invoked, run these steps: -1. If {{Plane/[[parent frame]]}} has been destroyed, throw an - {{InvalidStateError}}. -2. If {{Plane/length}} is greater than |`dst.byteLength`|, throw a - {{TypeError}}. -3. Let |resource| be the [=media resource=] refrenced by - {{Plane/[[parent frame]]}}'s {{VideoFrame/[[resource reference]]}}. -4. Let |plane bytes| be the region of bytes in [=media resource=] coresponding - to this plane. -5. Copy the |plane bytes| into |dst|. - - Plane Layout{#plane-layout} --------------------------- Plane layouts describe the position (offset) and padded width (stride) of a From 6c2dd549068b0e53423dd5eb8de8108331116b53 Mon Sep 17 00:00:00 2001 From: Chris Cunningham Date: Fri, 4 Jun 2021 00:55:03 -0700 Subject: [PATCH 6/9] Added dfns for VideoFrameRect, PlaneLayout, VFCopyToOptions, ... ... and VideoFrame codedRect and visibleRect attributes. Still TODO: define steps for copyTo and allocationSize. Probably a *big* TODO. --- index.src.html | 136 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 103 insertions(+), 33 deletions(-) diff --git a/index.src.html b/index.src.html index 13164928..a569857b 100644 --- a/index.src.html +++ b/index.src.html @@ -2455,29 +2455,17 @@ readonly attribute PixelFormat format; readonly attribute unsigned long codedWidth; readonly attribute unsigned long codedHeight; - - // Convenience accessor, origin is always (0, 0). readonly attribute VideoFrameRect codedRect; - - // Rectangle of this frame's pixel data that is not padding. readonly attribute VideoFrameRect visibleRect; - readonly attribute unsigned long displayWidth; readonly attribute unsigned long displayHeight; readonly attribute unsigned long long? duration; // microseconds readonly attribute long long? timestamp; // microseconds - - // Returns the minimum size (in bytes) of a buffer that copyTo() could - // copy this frame into with the given options. unsigned long allocationSize( optional VideoFrameCopyToOptions options = {}); - - // Copy the planes of this frame into |destination| according to |options|. - // The format of the data is the same as this frame's |format|. Promise> copyTo( - BufferSource destination, + [AllowShared] BufferSource destination, optional VideoFrameCopyToOptions options = {}); - VideoFrame clone(); undefined close(); }; @@ -2710,12 +2698,39 @@ {{VideoFrame/[[coded width]]}}. : codedHeight -:: Height of the VideoFrame in pixels, potentionally including non-visible +:: Height of the {{VideoFrame}} in pixels, potentionally including non-visible padding, and prior to considering potential ratio adjustments. The {{VideoFrame/codedHeight}} getter steps are to return {{VideoFrame/[[coded height]]}}. +: codedRect +:: A {{VideoFrameRect}} with width and height matching {{VideoFrame/codedWidth}} + and {{VideoFrame/codedHeight}} and origin always at (0,0). Offered for + convenience for use with {{VideoFrame/allocationSize()}} and + {{VideoFrame/copyTo()}}. + + The {{VideoFrame/codedRect}} getter steps are: + 1. Let |rect| be a new {{VideoFrameRect}}, initialized as follows: + 1. Assign `0` to {{VideoFrameRect/left}} and {{VideoFrameRect/top}}. + 2. Assign {{VideoFrame/[[coded width]]}} and + {{VideoFrame/[[coded height]]}} to {{VideoFrameRect/width}} and + {{VideoFrameRect/height}} respectively. + 2. Return |rect|. + +: visibleRect +:: A {{VideoFrameRect}} describing the visible rectangle of pixels for this + {{VideoFrame}}. + + The {{VideoFrame/visibleRect}} getter steps are: + 1. Let |rect| be a new {{VideoFrameRect}}, initialized as follows: + 1. Assign {{VideoFrame/[[visible left]]}}, + {{VideoFrame/[[visible top]]}}, {{VideoFrame/[[visible width]]}}, + and {{VideoFrame/[[visible height]]}} to {{VideoFrameRect/left}}, + {{VideoFrameRect/top}}, {{VideoFrameRect/width}}, and + {{VideoFrameRect/height}} respectively. + 2. Return |rect|. + : displayWidth :: Width of the VideoFrame when displayed after applying aspect ratio adjustments. @@ -2745,6 +2760,27 @@ {{VideoFrame/[[duration]]}}. ### Methods ###{#videoframe-methods} +: allocationSize(|options|) +:: Returns the minimum byte length for a valid destination {{BufferSource}} + to be used with {{VideoFrame/copyTo()}} with the given options. + + When invoked, run these steps: + 1. If {{VideoFrame/[[detached]]}} is `true`, return `0`. + 2. If {{VideoFrame/[[format]]}} is `""`, throw a {{NotSupportedError}} + {{DOMException}}. + 3. TODO + +: copyTo(|destination|, |options|) +:: Asynchronously copies the planes of this frame into |destination| according + to |options|. The format of the data is the same as this {{VideoFrame}}'s + {{VideoFrame/format}}. + + When invoked, run these steps: + 1. If {{VideoFrame/[[detached]]}} is `true`, return `0`. + 2. If {{VideoFrame/[[format]]}} is `""`, throw a {{NotSupportedError}} + {{DOMException}}. + 3. TODO + : clone() :: Creates a new {{VideoFrame}} with a reference to the same [=media resource=]. @@ -2755,7 +2791,6 @@ 2. Return the result of running the [=Clone VideoFrame=] algorithm with [=this=]. - : close() :: Clears all state and releases the reference to the [=media resource=]. Close is final. @@ -2868,47 +2903,82 @@ VideoFrame CopyTo() Options {#videoframe-copyto-options} ------------------------------------------------------------ -Options to specify which {{VideoFrameRect}} to copy and the location and -padding of planes in the destination buffer. +Options to specify which {{VideoFrameRect}} to copy and the offset and +stride of planes in the destination buffer. dictionary VideoFrameCopyToOptions { - // The rectangle to copy. If unspecified, the visibleRect will be used. - // The codedRect can be easily specified by passing frame.codedRect. VideoFrameRect rect; - - // The layout of each plane in the buffer. This allows the offset and stride - // of each plane to be specified. If unspecified, the planes will be tightly - // packed. It is invalid to specify planes that overlap. sequence<PlaneLayout> layout; }; +: rect +:: The {{VideoFrameRect}} describing the rectangle of pixels to copy from the + {{VideoFrame}}. If unspecified, the {{VideoFrame/visibleRect}} will be used. + + NOTE: The coded rectangle can be easily specified by passing + {{VideoFrame}}'s {{VideoFrame/codedRect}}. + +: layout +:: The {{PlaneLayout}} for each plane in {{VideoFrame}}, affording the option + to specify an offset and stride for each plane in the destination + {{BufferSource}}. If unspecified, the planes will be tightly packed. It is + invalid to specify planes that overlap. + VideoFrame Rectangle (Rect) {#videoframe-rect} --------------------------------------- -A dictionary specifying the position and dimensions of a rectangle of pixels within a {{VideoFrame}}. +---------------------------------------------- +A {{VideoFrameRect}} is a dictionary specifying the position and dimensions of +a rectangle of pixels within a {{VideoFrame}}. {{VideoFrameRect}} is used with +{{VideoFrame/copyTo()}} and {{VideoFrame/allocationSize()}} to describe the +dimensions of the source rectangle. {{VideoFrame}} defines +{{VideoFrame/codedRect}} and {{VideoFrame/visibleRect}} for convenient copying + of the coded size and visible region respectively. dictionary VideoFrameRect { - required [EnforceRange] unsigned long left; - required [EnforceRange] unsigned long top; - required [EnforceRange] unsigned long width; - required [EnforceRange] unsigned long height; + [EnforceRange] required unsigned long left; + [EnforceRange] required unsigned long top; + [EnforceRange] required unsigned long width; + [EnforceRange] required unsigned long height; }; +: left +:: The left offset in pixels for this {{VideoFrameRect}}. + +: top +:: The top offset in pixels for this {{VideoFrameRect}}. + +: width +:: The width in pixels for this {{VideoFrameRect}}. + +: height +:: The height in pixels for this {{VideoFrameRect}}. + Plane Layout{#plane-layout} --------------------------- -Plane layouts describe the position (offset) and padded width (stride) of a -plane within a buffer. +A {{PlaneLayout}} is a dictionary specifying the offset and stride of a +{{VideoFrame}} plane once copied to a {{BufferSource}}. A sequence of +{{PlaneLayout}}s may be provided to {{VideoFrame}}'s {{VideoFrame/copyTo()}} to +specify how the plane is laid out in the destination {{BufferSource}}}. +Alternatively, callers can inspect {{VideoFrame/copyTo()}}'s returned sequence +of {{PlaneLayout}}s to learn the the offset and stride for planes as decided by +the user agent. dictionary PlaneLayout { - [EnforceRange] unsigned long offset; - [EnforceRange] unsigned long stride; + [EnforceRange] required unsigned long offset; + [EnforceRange] required unsigned long stride; }; +: offset +:: The offset in bytes where the given plane begins within a {{BufferSource}}. + +: stride +:: The number of bytes, including padding, used by each row of the plane within + a {{BufferSource}}. Pixel Format{#pixel-format} --------------------------- From 371529f8fcd5edcabbaf629db0d2f0ee4b5b4ff7 Mon Sep 17 00:00:00 2001 From: Chris Cunningham Date: Tue, 8 Jun 2021 00:21:19 -0700 Subject: [PATCH 7/9] Fill in VideoFrame copyTo() and allocationSize() --- index.src.html | 211 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 209 insertions(+), 2 deletions(-) diff --git a/index.src.html b/index.src.html index a569857b..dc9da333 100644 --- a/index.src.html +++ b/index.src.html @@ -2759,6 +2759,25 @@ The {{VideoFrame/duration}} getter steps are to return {{VideoFrame/[[duration]]}}. +### Internal Structures ###{#videoframe-internal-structures} +A parsed copyto options is a [=struct=] that consists of: + * A allocationSize (an {{unsigned + long}}) + * A computedLayouts (a [=list=] of + [=computed plane layout=] structs). + +A computed plane layout is a [=struct=] that consists of: + * A destinationOffset (an + {{unsigned long}}) + * A destinationStride (an + {{unsigned long}}) + * A sourceTop (an {{unsigned long}}) + * A sourceHeight (an {{unsigned long}}) + * A sourceLeftBytes (an + {{unsigned long}}) + * A sourceWidthBytes (an + {{unsigned long}}) + ### Methods ###{#videoframe-methods} : allocationSize(|options|) :: Returns the minimum byte length for a valid destination {{BufferSource}} @@ -2768,7 +2787,10 @@ 1. If {{VideoFrame/[[detached]]}} is `true`, return `0`. 2. If {{VideoFrame/[[format]]}} is `""`, throw a {{NotSupportedError}} {{DOMException}}. - 3. TODO + 3. Let |parsedOptions| be the result of running the [=Parse + VideoFrameCopyToOptions=] algorithm with |options|. + 4. If |parsedOptions| is an excpetion, throw |parsedOptions|. + 5. Return |parsedOptions|' [=parsed copyto options/allocationSize=] : copyTo(|destination|, |options|) :: Asynchronously copies the planes of this frame into |destination| according @@ -2779,7 +2801,49 @@ 1. If {{VideoFrame/[[detached]]}} is `true`, return `0`. 2. If {{VideoFrame/[[format]]}} is `""`, throw a {{NotSupportedError}} {{DOMException}}. - 3. TODO + 3. Let |parsedOptions| be the result of running the [=Parse + VideoFrameCopyToOptions=] algorithm with |options|. + 4. If |parsedOptions| is an exception, return a promise rejected with + |parsedOptions|. + 5. If `destionation.byteLength` is less than |parsedOptions|' [=parsed + copyto options/allocationSize=], return a promise rejected with a + {{TypeError}}. + 6. Let |p| be a new {{Promise}}. + 7. Let |copyStepsQueue| be the result of starting a new [=parallel queue=]. + 8. Enqueue the following steps to |copyStepsQueue|: + 1. Let resource be the [=media resource=] referenced by + [[resource reference]]. + 2. Let |numPlanes| be the number of planes as defined by + {{VideoFrame/[[format]]}}. + 3. Let |planeIndex| be `0`. + 4. While |planeIndex| is less than |parsedOptions|' |numPlanes|: + 1. Let |sourceStride| be the stride of the plane in |resource| as + identified by |planeIndex|. + 2. Let |computedLayout| be the [=computed plane layout=] in + |parsedOptions|' [=parsed copyto options/computedLayouts=] at the + position of |planeIndex| + 3. Let |sourceOffset| be the product of multiplying + |computedLayout|'s [=computed plane layout/sourceTop=] by + |sourceStride| + 4. Add |computedLayout|'s [=computed plane layout/sourceLeftBytes=] to + sourceOffset. + 5. Let |destinationOffset| be |computedLayout|'s + [=computed plane layout/destinationOffset=]. + 6. Let |rowBytes| be |computedLayout|'s + [=computed plane layout/sourceWidthBytes=]. + 7. Let |row| be `0`. + 8. While |row| is less than |computedLayout|'s + [=computed plane layout/sourceHeight=]: + 1. Copy |rowBytes| bytes from |resource| starting at + |sourceOffset| to |destination| starting at + |destinationOffset|. + 2. Increment |sourceOffset| by |sourceStride|. + 3. Increment |destinationOffset| by |computedLayout|'s + [=computed plane layout/destinationStride=]. + 4. Increment |row| by `1`. + 9. Increment |planeIndex| by `1`. + 5. Queue a task on the [=control thread=] event loop to resolve |p|. + 9. Return |p|. : clone() :: Creates a new {{VideoFrame}} with a reference to the same @@ -2901,6 +2965,140 @@ those of the same name in |clone|. 2. Return |clone|. +: Parse VideoFrameCopyToOptions (with |options|) +:: 1. Let |parsedRect| be the result of running the [=VideoFrame/Parse CopyTo + Rect=] with |options|. + 2. If |parsedRect| is an exception, return |parsedRect|. + 3. Let |parsedOptions| be the result of running the [=VideoFrame/Compute + Layout and Allocation Size=] algorithm with |parsedRect| and |options|. + 6. Return |parsedOptions|. + +: Parse CopyTo Rect (with |options|) +:: 1. Let |sourceRect| be the be the result of performing the getter steps for + {{VideoFrame/visibleRect}}. + 2. If {{VideoFrameCopyToOptions/rect}} [=map/exists=] in |options|: + 1. Let |optRect| be {{VideoFrameCopyToOptions/rect}}: + 2. If either of |optRect|.{{VideoFrameRect/width}} or + {{VideoFrameRect/height}} is `0`, return a {{TypeError}}. + 3. If the sum of |optRect|.{{VideoFrameRect/left}} and + |optRect|.{{VideoFrameRect/width}} is greater than + {{VideoFrame/[[coded width]]}}, return a {{TypeError}}. + 4. If the sum of |optRect|.{{VideoFrameRect/top}} and + |optRect|.{{VideoFrameRect/height}} is greater than + {{VideoFrame/[[coded height]]}}, return a {{TypeError}}. + 5. Assign |optRect| to |sourceRect|. + 3. Let |planeIndex| be `0`. + 4. Let |numPlanes| be the number of planes as defined by + {{VideoFrame/[[format]]}} + 5. While |planeIndex| is less than |numPlanes|: + + NOTE: The following steps validate |rect| is sample-aligned for this + frame's {{VideoFrame/[[format]]}}. + + 1. Let |plane| be the Plane identified by |planeIndex| as defined by + {{VideoFrame/[[format]]}}. + 2. Let |sampleWidth| be the horizontal pixel size of each subsample + for |plane|. + 3. Let |sampleHeight| be the vertical pixel size of each subsample + for |plane|. + 4. If |sourceRect|.{{VideoFrameRect/left}} and + |sourceRect|.{{VideoFrameRect/width}} cannot be evenly divided by + |sampleWidth|, throw a {{TypeError}}. + 5. If |sourceRect|.{{VideoFrameRect/top}} and + |sourceRect|.{{VideoFrameRect/height}} cannot be evenly divided by + |sampleHeight|, throw a {{TypeError}}. + 6. Increment |planeIndex| by `1` + 6. Return |sourceRect|. + +: Compute Layout and Allocation Size (with + |parsedRect| and |options|) +:: 1. Let |numPlanes| be the number of planes as defined by + {{VideoFrame/[[format]]}} + 2. If {{VideoFrameCopyToOptions/layout}} [=map/exists=] its size does not + equal |numPlanes|, throw a {{TypeError}}. + 3. Let |minAllocationSize| be `0`. + 4. Let |computedLayouts| be a new [=list=]. + 5. Let |endOffsets| be a new [=list=]. + 6. Let |planeIndex| be `0`. + 7. While |planeIndex| < |numPlanes|: + 1. Let |plane| be the Plane identified by |planeIndex| as defined by + {{VideoFrame/[[format]]}}. + 2. Let |sampleBytes| be the number of bytes per sample for |plane|. + 3. Let |sampleWidth| be the horizontal pixel size of each subsample + for |plane|. + 4. Let |sampleHeight| be the vertical pixel size of each subsample + for |plane|. + 5. Let |sampleWidthBytes| be the product of multiplying |sampleWidth| by + |sampleBytes|. + 6. Let |computedLayout| be a new [=computed plane layout=]. + 7. Assign quotient of dividing |parsedRect|.{{VideoFrameRect/top}} by + |sampleHeight| to |computedLayout|'s [=computed plane layout/sourceTop=]. + 8. Assign quotient of dividing |parsedRect|.{{VideoFrameRect/height}} by + |sampleHeight| to |computedLayout|'s [=computed plane layout/sourceHeight=]. + 9. Assign quotient of dividing |parsedRect|.{{VideoFrameRect/left}} by + |sampleWidthBytes| to |computedLayout|'s + [=computed plane layout/sourceLeftBytes=]. + 10. Assign quotient of dividing |parsedRect|.{{VideoFrameRect/width}} + |sampleWidthBytes| to |computedLayout|'s + [=computed plane layout/sourceWidthBytes=]. + 11. If {{VideoFrameCopyToOptions/layout}} [=map/exists=]: + 1. Let |planeLayout| be the {{PlaneLayout}} in + {{VideoFrameCopyToOptions/layout}} at position |planeIndex|. + 2. If |planeLayout|.{{PlaneLayout/stride}} is less than + |computedLayout|'s [=computed plane layout/sourceWidthBytes=], return + a {{TypeError}}. + 3. Assign |planeLayout|.{{PlaneLayout/offset}} to |computedLayout|'s + [=computed plane layout/destinationOffset=]. + 4. Assign |planeLayout|.{{PlaneLayout/stride}} to |computedLayout|'s + [=computed plane layout/destinationStride=]. + 12. Otherwise: + + NOTE: If an explicit layout was not provided, the following steps + default to tight packing. + + 1. Assign |minAllocationSize| to |computedLayout|'s + [=computed plane layout/destinationOffset=]. + 2. Assign |computedLayout|'s [=computed plane layout/sourceWidthBytes=] to + |computedLayout|'s [=computed plane layout/destinationStride=]. + 13. Let |planeSize| be the product of multiplying |computedLayout|'s + [=computed plane layout/destinationStride=] and + [=computed plane layout/sourceHeight=]. + 14. Let |planeEnd| be the sum of |planeSize| and |computedLayout|'s + [=computed plane layout/destinationOffset=]. + 15. If |planeSize| or |planeEnd| is greater than maximum range of + {{unsigned long}}, return a {{TypeError}}. + 16. Append |planeEnd| to |endOffsets|. + 17. Assign the maximum of |minAllocationSize| and |planeEnd| to + |minAllocationSize|. + + NOTE: The above step uses a maximum to allow for the + possibility that user specified plane offsets may reorder + planes. + + 18. Let |earlierPlaneIndex| be `0`. + 19. While |earlierPlaneIndex| is less than |planeIndex|. + 1. Let |earlierLayout| be `computedLayouts[earlierPlaneIndex]`. + 2. If `endOffsets[planeIndex]` is less than or equal to + |earlierLayout|'s [=computed plane layout/destinationOffset=] or + if `endOffsets[earlierPlaneIndex]` is less than or equal to + |computedLayout|'s [=computed plane layout/destinationOffset=], + continue. + + NOTE: If plane A ends before plane B starts, they do not + overlap. + + 3. Otherwise, return a {{TypeError}}. + 4. Increment |earlierPlaneIndex| by `1`. + 20. Append |computedLayout| to |computedLayouts|. + 21. Increment |planeIndex| by `1`. + 8. Let |parsedOptions| be a new [=parsed copyto options=], initialized as + follows: + 1. Assign |computedLayouts| to + [=parsed copyto options/computedLayouts=]. + 2. Assign |minAllocationSize| to + [=parsed copyto options/allocationSize=]. + 9. Return |parsedOptions|. + VideoFrame CopyTo() Options {#videoframe-copyto-options} ------------------------------------------------------------ Options to specify which {{VideoFrameRect}} to copy and the offset and @@ -2913,6 +3111,15 @@ }; +
+NOTE: The steps of {{VideoFrame/copyTo()}} or {{VideoFrame/allocationSize()}} +will enforce the following requirements: + * The coordinates of {{VideoFrameCopyToOptions/rect}} must be + sample-aligned as determiend by {{VideoFrame/[[format]]}}. + * If {{VideoFrameCopyToOptions/layout}} [=map/exists=], a {{PlaneLayout}} + must be provided for all planes. +
+ : rect :: The {{VideoFrameRect}} describing the rectangle of pixels to copy from the {{VideoFrame}}. If unspecified, the {{VideoFrame/visibleRect}} will be used. From 72f69cd417200c3ea3eba8e83be3ac1241de14aa Mon Sep 17 00:00:00 2001 From: Chris Cunningham Date: Thu, 10 Jun 2021 22:42:16 -0700 Subject: [PATCH 8/9] Fix PlaneInit, remove rows, add offset --- index.src.html | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/index.src.html b/index.src.html index dc9da333..f4140edc 100644 --- a/index.src.html +++ b/index.src.html @@ -2488,8 +2488,8 @@ dictionary PlaneInit { required BufferSource data; - [EnforceRange] required unsigned long rows; - [EnforceRange] required unsigned long offset; + [EnforceRange] required unsigned long stride; + [EnforceRange] unsigned long offset = 0; }; @@ -2635,12 +2635,24 @@ {{VideoFrame/[[resource reference]]}}. 2. Assign {{VideoFramePlaneInit/format}} to {{VideoFrame/[[format]]}}. 3. For each |planeInit| in |planes|: - 1. Copy |planeInit|.{{PlaneInit/data}} to |resource|. - - NOTE: The user agent may use {{VideoFramePlaneInit/visibleRect}} - to copy only the visible rectangle. It may also reposition the - visible rectangle within |resource|. The final position will be - reflected by {{VideoFrame/visibleRect}}. + 1. Let |rows| be the number of sample rows for the Plane coresponding + to |planeInit| as defined by {{VideoFrame/[[format]]}}. + 2. Let |dataOffset| be `0`. + 3. If {{PlaneInit/offset}} [=map/exists=], assign {{PlaneInit/offset}} + to |dataOffset|. + 4. Let |row| be `0`. + 5. While |row| is less than |rows|: + 1. Copy bytes from {{PlaneInit/data}} to |resource|, starting with + the byte positioned at |dataOffset| and stopping after + {{PlaneInit/stride}} bytes have been copied. + + NOTE: The user agent may use {{VideoFramePlaneInit/visibleRect}} + to copy only the visible rectangle. It may also reposition + the visible rectangle within |resource|. The final position + will be reflected by {{VideoFrame/visibleRect}}. + + 2. Increment |dataOffset| by {{PlaneInit/stride}}. + 3. Increment |row| by `1`. 4. Let |resourceCodedWidth| be the coded width of |resource|. 5. Let |resourceCodedHeight| be the coded height of |resource|. From 9591101ca039bd21478055c74986e395f9fe48a4 Mon Sep 17 00:00:00 2001 From: Chris Cunningham Date: Fri, 11 Jun 2021 15:31:30 -0700 Subject: [PATCH 9/9] Address feedback --- Makefile | 1 + index.src.html | 38 ++++++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index b5f3d7f7..46c82d50 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ remote-index: index.src.html --output index.html \ --write-out "%{http_code}" \ --header "Accept: text/plain, text/html" \ + -F die-on=warning \ -F file=@index.src.html) && \ [[ "$$HTTP_STATUS" -eq "200" ]]) || ( \ echo ""; cat index.html; echo ""; \ diff --git a/index.src.html b/index.src.html index b0e2e747..f64a94a2 100644 --- a/index.src.html +++ b/index.src.html @@ -2907,6 +2907,10 @@ to |options|. The format of the data is the same as this {{VideoFrame}}'s {{VideoFrame/format}}. + NOTE: Promises that are returned by several calls to + {{VideoFrame/copyTo()}} are not guaranteed to resolve in the order they + were returned. + When invoked, run these steps: 1. If {{VideoFrame/[[detached]]}} is `true`, return `0`. 2. If {{VideoFrame/[[format]]}} is `""`, throw a {{NotSupportedError}} @@ -3112,10 +3116,10 @@ 3. Let |sampleHeight| be the vertical pixel size of each subsample for |plane|. 4. If |sourceRect|.{{VideoFrameRect/left}} and - |sourceRect|.{{VideoFrameRect/width}} cannot be evenly divided by + |sourceRect|.{{VideoFrameRect/width}} are not both multiples of |sampleWidth|, throw a {{TypeError}}. 5. If |sourceRect|.{{VideoFrameRect/top}} and - |sourceRect|.{{VideoFrameRect/height}} cannot be evenly divided by + |sourceRect|.{{VideoFrameRect/height}} are not both multiples of |sampleHeight|, throw a {{TypeError}}. 6. Increment |planeIndex| by `1` 6. Return |sourceRect|. @@ -3141,22 +3145,24 @@ 5. Let |sampleWidthBytes| be the product of multiplying |sampleWidth| by |sampleBytes|. 6. Let |computedLayout| be a new [=computed plane layout=]. - 7. Assign quotient of dividing |parsedRect|.{{VideoFrameRect/top}} by - |sampleHeight| to |computedLayout|'s [=computed plane layout/sourceTop=]. - 8. Assign quotient of dividing |parsedRect|.{{VideoFrameRect/height}} by - |sampleHeight| to |computedLayout|'s [=computed plane layout/sourceHeight=]. - 9. Assign quotient of dividing |parsedRect|.{{VideoFrameRect/left}} by - |sampleWidthBytes| to |computedLayout|'s - [=computed plane layout/sourceLeftBytes=]. - 10. Assign quotient of dividing |parsedRect|.{{VideoFrameRect/width}} - |sampleWidthBytes| to |computedLayout|'s - [=computed plane layout/sourceWidthBytes=]. + 7. Set |computedLayout|'s [=computed plane layout/sourceTop=] to the + result of the integer division of + |parsedRect|.{{VideoFrameRect/top}} by |sampleHeight|. + 8. Set |computedLayout|'s [=computed plane layout/sourceHeight=] to the + result of the integer division of + |parsedRect|.{{VideoFrameRect/height}} by |sampleHeight| + 9. Set |computedLayout|'s [=computed plane layout/sourceLeftBytes=] to + the result of the integer division of + |parsedRect|.{{VideoFrameRect/left}} by |sampleWidthBytes|. + 10. Set |computedLayout|'s [=computed plane layout/sourceWidthBytes=] to + the result of the integer division of + |parsedRect|.{{VideoFrameRect/width}} by |sampleWidthBytes|. 11. If {{VideoFrameCopyToOptions/layout}} [=map/exists=]: 1. Let |planeLayout| be the {{PlaneLayout}} in {{VideoFrameCopyToOptions/layout}} at position |planeIndex|. 2. If |planeLayout|.{{PlaneLayout/stride}} is less than - |computedLayout|'s [=computed plane layout/sourceWidthBytes=], return - a {{TypeError}}. + |computedLayout|'s [=computed plane layout/sourceWidthBytes=], + return a {{TypeError}}. 3. Assign |planeLayout|.{{PlaneLayout/offset}} to |computedLayout|'s [=computed plane layout/destinationOffset=]. 4. Assign |planeLayout|.{{PlaneLayout/stride}} to |computedLayout|'s @@ -3234,8 +3240,8 @@ :: The {{VideoFrameRect}} describing the rectangle of pixels to copy from the {{VideoFrame}}. If unspecified, the {{VideoFrame/visibleRect}} will be used. - NOTE: The coded rectangle can be easily specified by passing - {{VideoFrame}}'s {{VideoFrame/codedRect}}. + NOTE: The coded rectangle can be specified by passing {{VideoFrame}}'s + {{VideoFrame/codedRect}}. : layout :: The {{PlaneLayout}} for each plane in {{VideoFrame}}, affording the option