Bug 1659206 [wpt PR 25022] - [webcodecs] Implement planar access to VideoFrames., a=testonly
authorDan Sanders <sandersd@chromium.org>
Wed, 26 Aug 2020 08:48:57 +0000
changeset 546425 f5934c6c3e419ce1a380ff01969105f1af9fc63a
parent 546424 7209704dc0418dbcaefdf360a53ae458852af68b
child 546426 5bade268cf9fb93b7ecb6e0ab4efd189612a470c
push id37735
push userabutkovits@mozilla.com
push dateThu, 27 Aug 2020 21:29:40 +0000
treeherdermozilla-central@109f3a4de567 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1659206, 25022, 1096722, 2355390, 799773
milestone82.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1659206 [wpt PR 25022] - [webcodecs] Implement planar access to VideoFrames., a=testonly Automatic update from web-platform-tests [webcodecs] Implement planar access to VideoFrames. This initial version supports only I420. We'll want to implement explicit conversion and probably color space metadata before adding many more formats. Bug: 1096722 Change-Id: I42949e2a7e9e2135fab260e73da2f2aa420eb424 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2355390 Commit-Queue: Dan Sanders <sandersd@chromium.org> Reviewed-by: Chrome Cunningham <chcunningham@chromium.org> Cr-Commit-Position: refs/heads/master@{#799773} -- wpt-commits: 41118b0c44a293c8096501d4950e99962ce16350 wpt-pr: 25022
testing/web-platform/tests/webcodecs/video-frame.html
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webcodecs/video-frame.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html>
+<title>Test the VideoFrame API.</title>
+<body></body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+function makeImageBitmap(width, height) {
+  let canvas = new OffscreenCanvas(width, height);
+
+  let ctx = canvas.getContext('2d');
+  ctx.fillStyle = 'rgba(50, 100, 150, 255)';
+  ctx.fillRect(0, 0, width, height);
+
+  return canvas.transferToImageBitmap();
+}
+
+test(t => {
+  let image = makeImageBitmap(32, 16);
+  let frame = new VideoFrame(image, {timestamp: 10});
+
+  assert_equals(frame.timestamp, 10, "timestamp");
+  assert_equals(frame.duration, null, "duration");
+  assert_equals(frame.cropWidth, 32, "cropWidth");
+  assert_equals(frame.cropHeight, 16, "cropHeight");
+  assert_equals(frame.cropWidth, 32, "displayWidth");
+  assert_equals(frame.cropHeight, 16, "displayHeight");
+
+  frame.destroy();
+}, 'Test we can construct a VideoFrame.');
+
+test(t => {
+  let image = makeImageBitmap(1, 1);
+  let frame = new VideoFrame(image, {timestamp: 10});
+
+  assert_equals(frame.cropWidth, 1, "cropWidth");
+  assert_equals(frame.cropHeight, 1, "cropHeight");
+  assert_equals(frame.cropWidth, 1, "displayWidth");
+  assert_equals(frame.cropHeight, 1, "displayHeight");
+
+  frame.destroy();
+}, 'Test we can construct an odd-sized VideoFrame.');
+
+test(t => {
+  let image = makeImageBitmap(32, 16);
+  let frame = new VideoFrame(image, {timestamp: 0});
+
+  // TODO(sandersd): This would be more clear as RGBA, but conversion has
+  // not be specified (or implemented) yet.
+  if (frame.format !== "I420") {
+    return;
+  }
+  assert_equals(frame.planes.length, 3, "number of planes");
+
+  // Validate Y plane metadata.
+  let yPlane = frame.planes[0];
+  let yStride = yPlane.stride;
+  let yRows = yPlane.rows;
+  let yLength = yPlane.length;
+
+  // Required minimums to contain the visible data.
+  assert_greater_than_equal(yRows, 16, "Y plane rows");
+  assert_greater_than_equal(yStride, 32, "Y plane stride");
+  assert_greater_than_equal(yLength, 32 * 16, "Y plane length");
+
+  // Not required by spec, but sets limit at 50% padding per dimension.
+  assert_less_than_equal(yRows, 32, "Y plane rows");
+  assert_less_than_equal(yStride, 64, "Y plane stride");
+  assert_less_than_equal(yLength, 32 * 64, "Y plane length");
+
+  // Validate Y plane data.
+  let buffer = new ArrayBuffer(yLength);
+  let view = new Uint8Array(buffer);
+  frame.planes[0].readInto(view);
+
+  // TODO(sandersd): This probably needs to be fuzzy unless we can make
+  // guarantees about the color space.
+  assert_equals(view[0], 94, "Y value at (0, 0)");
+
+  frame.destroy();
+}, 'Test we can read planar data from a VideoFrame.');
+
+test(t => {
+  let image = makeImageBitmap(32, 16);
+  let frame = new VideoFrame(image, {timestamp: 0});
+
+  // TODO(sandersd): This would be more clear as RGBA, but conversion has
+  // not be specified (or implemented) yet.
+  if (frame.format !== "I420") {
+    return;
+  }
+
+  assert_equals(frame.planes.length, 3, "number of planes");
+
+  // Attempt to read Y plane data, but destroy the frame first.
+  let yPlane = frame.planes[0];
+  let yLength = yPlane.length;
+  frame.destroy();
+
+  let buffer = new ArrayBuffer(yLength);
+  let view = new Uint8Array(buffer);
+  assert_throws_dom("InvalidStateError", () => yPlane.readInto(view));
+}, 'Test we cannot read planar data from a destroyed VideoFrame.');
+</script>
+</html>