| <!DOCTYPE html> | |
| <html> | |
| <title>Test the VideoFrame API.</title> | |
| <body></body> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="/webcodecs/utils.js"></script> | |
| <script> | |
| 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.'); | |
| test(t => { | |
| let image = makeImageBitmap(32, 16); | |
| image.close(); | |
| assert_throws_dom("InvalidStateError", () => { | |
| let frame = new VideoFrame(image, {timestamp: 10}); | |
| }) | |
| }, 'Test constructing VideoFrames from closed ImageBitmap throws.'); | |
| </script> | |
| </html> |