Implement createImageBitmap(HTMLVideoElement)
authorMs2ger@igalia.com <Ms2ger@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Feb 2018 10:24:57 +0000 (10:24 +0000)
committerMs2ger@igalia.com <Ms2ger@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Feb 2018 10:24:57 +0000 (10:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=182388

Reviewed by Žan Doberšek.

LayoutTests/imported/w3c:

* web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage-expected.txt:
* web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage.html:
  Update from upstream to make the test pass on macOS.
* web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt:

Source/WebCore:

The implementation is inspired by CanvasRenderingContext2DBase::drawImage().

Tests:

- web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage.html
- web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args.html

* html/ImageBitmap.cpp:
(WebCore::taintsOrigin): Add function to help with the implementation.
(WebCore::ImageBitmap::createPromise): Fill in implementation.

LayoutTests:

* platform/gtk/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt:
* platform/ios/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt:
* platform/wpe/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@228092 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage-expected.txt
LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage.html
LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt
LayoutTests/platform/gtk/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt
LayoutTests/platform/ios/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt
LayoutTests/platform/wpe/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/html/ImageBitmap.cpp

index 2e41180..a3d664a 100644 (file)
@@ -1,3 +1,14 @@
+2018-02-05  Ms2ger  <Ms2ger@igalia.com>
+
+        Implement createImageBitmap(HTMLVideoElement)
+        https://bugs.webkit.org/show_bug.cgi?id=182388
+
+        Reviewed by Žan Doberšek.
+
+        * platform/gtk/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt:
+        * platform/ios/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt:
+        * platform/wpe/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt:
+
 2018-02-02  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed test gardening, skip fast/visual-viewport/resize-event-fired.html on iOS.
index ba52a97..5f9cfa6 100644 (file)
@@ -1,3 +1,15 @@
+2018-02-05  Ms2ger  <Ms2ger@igalia.com>
+
+        Implement createImageBitmap(HTMLVideoElement)
+        https://bugs.webkit.org/show_bug.cgi?id=182388
+
+        Reviewed by Žan Doberšek.
+
+        * web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage-expected.txt:
+        * web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage.html:
+          Update from upstream to make the test pass on macOS.
+        * web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args-expected.txt:
+
 2018-02-02  Chris Dumez  <cdumez@apple.com>
 
         Clearing a registration should null out its workers before setting their state to "redundant"
index 376da8d..6dfdec9 100644 (file)
@@ -4,15 +4,15 @@ PASS createImageBitmap from an HTMLCanvasElement scaled down, and drawImage on t
 PASS createImageBitmap from an HTMLCanvasElement scaled up, and drawImage on the created ImageBitmap 
 PASS createImageBitmap from an HTMLCanvasElement resized, and drawImage on the created ImageBitmap 
 FAIL createImageBitmap from an HTMLCanvasElement with negative sw/sh, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "RangeError: Cannot create ImageBitmap with a negative width or height"
-FAIL createImageBitmap from an HTMLVideoElement, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: createImageBitmap with HTMLVideoElement is not implemented"
-FAIL createImageBitmap from an HTMLVideoElement scaled down, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: createImageBitmap with HTMLVideoElement is not implemented"
-FAIL createImageBitmap from an HTMLVideoElement scaled up, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: createImageBitmap with HTMLVideoElement is not implemented"
-FAIL createImageBitmap from an HTMLVideoElement resized, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: createImageBitmap with HTMLVideoElement is not implemented"
+PASS createImageBitmap from an HTMLVideoElement, and drawImage on the created ImageBitmap 
+PASS createImageBitmap from an HTMLVideoElement scaled down, and drawImage on the created ImageBitmap 
+PASS createImageBitmap from an HTMLVideoElement scaled up, and drawImage on the created ImageBitmap 
+PASS createImageBitmap from an HTMLVideoElement resized, and drawImage on the created ImageBitmap 
 FAIL createImageBitmap from an HTMLVideoElement with negative sw/sh, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "RangeError: Cannot create ImageBitmap with a negative width or height"
-FAIL createImageBitmap from an HTMLVideoElement from a data URL, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: createImageBitmap with HTMLVideoElement is not implemented"
-FAIL createImageBitmap from an HTMLVideoElement from a data URL scaled down, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: createImageBitmap with HTMLVideoElement is not implemented"
-FAIL createImageBitmap from an HTMLVideoElement from a data URL scaled up, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: createImageBitmap with HTMLVideoElement is not implemented"
-FAIL createImageBitmap from an HTMLVideoElement from a data URL resized, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: createImageBitmap with HTMLVideoElement is not implemented"
+PASS createImageBitmap from an HTMLVideoElement from a data URL, and drawImage on the created ImageBitmap 
+PASS createImageBitmap from an HTMLVideoElement from a data URL scaled down, and drawImage on the created ImageBitmap 
+PASS createImageBitmap from an HTMLVideoElement from a data URL scaled up, and drawImage on the created ImageBitmap 
+PASS createImageBitmap from an HTMLVideoElement from a data URL resized, and drawImage on the created ImageBitmap 
 FAIL createImageBitmap from an HTMLVideoElement from a data URL with negative sw/sh, and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "RangeError: Cannot create ImageBitmap with a negative width or height"
 PASS createImageBitmap from a bitmap HTMLImageElement, and drawImage on the created ImageBitmap 
 PASS createImageBitmap from a bitmap HTMLImageElement scaled down, and drawImage on the created ImageBitmap 
index ce6c90e..9146a37 100644 (file)
@@ -12,7 +12,7 @@
 <script>
 function testCanvasDisplayingPattern(canvas, width, height)
 {
-    var tolerance = 5; // for creating ImageBitmap from a video, the tolerance needs to be high
+    var tolerance = 10; // for creating ImageBitmap from a video, the tolerance needs to be high
     const check = (x, y, r, g, b, a) =>
         _assertPixelApprox(canvas, x,y, r,g,b,a, `${x},${y}`, `${r},${g},${b},${a}`, tolerance);
     check(1 * width / 4, 1 * height / 4, 255,0,0,255);
index 5a966ff..62c3af2 100644 (file)
@@ -5,10 +5,10 @@ PASS createImageBitmap with a an HTMLCanvasElement source and sh set to 0
 FAIL createImageBitmap with a an HTMLCanvasElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a an HTMLVideoElement source and sw set to 0 
 PASS createImageBitmap with a an HTMLVideoElement source and sh set to 0 
-FAIL createImageBitmap with a an HTMLVideoElement source and oversized (unallocatable) crop region assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" ("TypeError") expected object "InvalidStateError" ("InvalidStateError")
+FAIL createImageBitmap with a an HTMLVideoElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a an HTMLVideoElement from a data URL source and sw set to 0 
 PASS createImageBitmap with a an HTMLVideoElement from a data URL source and sh set to 0 
-FAIL createImageBitmap with a an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" ("TypeError") expected object "InvalidStateError" ("InvalidStateError")
+FAIL createImageBitmap with a an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a a bitmap HTMLImageElement source and sw set to 0 
 PASS createImageBitmap with a a bitmap HTMLImageElement source and sh set to 0 
 FAIL createImageBitmap with a a bitmap HTMLImageElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -40,7 +40,7 @@ PASS createImageBitmap with WebGLRenderingContext image source.
 PASS createImageBitmap with Uint8Array image source. 
 PASS createImageBitmap with ArrayBuffer image source. 
 PASS createImageBitmap with empty image source. 
-FAIL createImageBitmap with empty video source. assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
+PASS createImageBitmap with empty video source. 
 PASS createImageBitmap with an oversized canvas source. 
 FAIL createImageBitmap with an invalid OffscreenCanvas source. assert_throws: function "function () { throw e }" threw object "TypeError: Type error" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
 FAIL createImageBitmap with an undecodable blob source. assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with ArrayBuffer or Blob is not implemented" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
index e3be46f..1c7aa96 100644 (file)
@@ -5,10 +5,10 @@ PASS createImageBitmap with a an HTMLCanvasElement source and sh set to 0
 FAIL createImageBitmap with a an HTMLCanvasElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a an HTMLVideoElement source and sw set to 0 
 PASS createImageBitmap with a an HTMLVideoElement source and sh set to 0 
-FAIL createImageBitmap with a an HTMLVideoElement source and oversized (unallocatable) crop region assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" ("TypeError") expected object "InvalidStateError" ("InvalidStateError")
+FAIL createImageBitmap with a an HTMLVideoElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a an HTMLVideoElement from a data URL source and sw set to 0 
 PASS createImageBitmap with a an HTMLVideoElement from a data URL source and sh set to 0 
-FAIL createImageBitmap with a an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" ("TypeError") expected object "InvalidStateError" ("InvalidStateError")
+FAIL createImageBitmap with a an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a a bitmap HTMLImageElement source and sw set to 0 
 PASS createImageBitmap with a a bitmap HTMLImageElement source and sh set to 0 
 FAIL createImageBitmap with a a bitmap HTMLImageElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -40,7 +40,7 @@ PASS createImageBitmap with WebGLRenderingContext image source.
 PASS createImageBitmap with Uint8Array image source. 
 PASS createImageBitmap with ArrayBuffer image source. 
 PASS createImageBitmap with empty image source. 
-FAIL createImageBitmap with empty video source. assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
+PASS createImageBitmap with empty video source. 
 PASS createImageBitmap with an oversized canvas source. 
 FAIL createImageBitmap with an invalid OffscreenCanvas source. assert_throws: function "function () { throw e }" threw object "TypeError: Type error" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
 FAIL createImageBitmap with an undecodable blob source. assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with ArrayBuffer or Blob is not implemented" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
index 9ef3e65..7c35e9b 100644 (file)
@@ -5,10 +5,10 @@ PASS createImageBitmap with a an HTMLCanvasElement source and sh set to 0
 FAIL createImageBitmap with a an HTMLCanvasElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a an HTMLVideoElement source and sw set to 0 
 PASS createImageBitmap with a an HTMLVideoElement source and sh set to 0 
-FAIL createImageBitmap with a an HTMLVideoElement source and oversized (unallocatable) crop region assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" ("TypeError") expected object "InvalidStateError" ("InvalidStateError")
+FAIL createImageBitmap with a an HTMLVideoElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a an HTMLVideoElement from a data URL source and sw set to 0 
 PASS createImageBitmap with a an HTMLVideoElement from a data URL source and sh set to 0 
-FAIL createImageBitmap with a an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" ("TypeError") expected object "InvalidStateError" ("InvalidStateError")
+FAIL createImageBitmap with a an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a a bitmap HTMLImageElement source and sw set to 0 
 PASS createImageBitmap with a a bitmap HTMLImageElement source and sh set to 0 
 FAIL createImageBitmap with a a bitmap HTMLImageElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -40,7 +40,7 @@ PASS createImageBitmap with WebGLRenderingContext image source.
 PASS createImageBitmap with Uint8Array image source. 
 PASS createImageBitmap with ArrayBuffer image source. 
 PASS createImageBitmap with empty image source. 
-FAIL createImageBitmap with empty video source. assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
+PASS createImageBitmap with empty video source. 
 PASS createImageBitmap with an oversized canvas source. 
 FAIL createImageBitmap with an invalid OffscreenCanvas source. assert_throws: function "function () { throw e }" threw object "TypeError: Type error" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
 FAIL createImageBitmap with an undecodable blob source. assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with ArrayBuffer or Blob is not implemented" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
index e3be46f..1c7aa96 100644 (file)
@@ -5,10 +5,10 @@ PASS createImageBitmap with a an HTMLCanvasElement source and sh set to 0
 FAIL createImageBitmap with a an HTMLCanvasElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a an HTMLVideoElement source and sw set to 0 
 PASS createImageBitmap with a an HTMLVideoElement source and sh set to 0 
-FAIL createImageBitmap with a an HTMLVideoElement source and oversized (unallocatable) crop region assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" ("TypeError") expected object "InvalidStateError" ("InvalidStateError")
+FAIL createImageBitmap with a an HTMLVideoElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a an HTMLVideoElement from a data URL source and sw set to 0 
 PASS createImageBitmap with a an HTMLVideoElement from a data URL source and sh set to 0 
-FAIL createImageBitmap with a an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" ("TypeError") expected object "InvalidStateError" ("InvalidStateError")
+FAIL createImageBitmap with a an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS createImageBitmap with a a bitmap HTMLImageElement source and sw set to 0 
 PASS createImageBitmap with a a bitmap HTMLImageElement source and sh set to 0 
 FAIL createImageBitmap with a a bitmap HTMLImageElement source and oversized (unallocatable) crop region assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -40,7 +40,7 @@ PASS createImageBitmap with WebGLRenderingContext image source.
 PASS createImageBitmap with Uint8Array image source. 
 PASS createImageBitmap with ArrayBuffer image source. 
 PASS createImageBitmap with empty image source. 
-FAIL createImageBitmap with empty video source. assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with HTMLVideoElement is not implemented" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
+PASS createImageBitmap with empty video source. 
 PASS createImageBitmap with an oversized canvas source. 
 FAIL createImageBitmap with an invalid OffscreenCanvas source. assert_throws: function "function () { throw e }" threw object "TypeError: Type error" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
 FAIL createImageBitmap with an undecodable blob source. assert_throws: function "function () { throw e }" threw object "TypeError: createImageBitmap with ArrayBuffer or Blob is not implemented" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
index 0d86aa3..4459f1c 100644 (file)
@@ -1,3 +1,22 @@
+2018-02-05  Ms2ger  <Ms2ger@igalia.com>
+
+        Implement createImageBitmap(HTMLVideoElement)
+        https://bugs.webkit.org/show_bug.cgi?id=182388
+
+        Reviewed by Žan Doberšek.
+
+        The implementation is inspired by CanvasRenderingContext2DBase::drawImage().
+
+        Tests:
+
+        - web-platform-tests/2dcontext/imagebitmap/createImageBitmap-drawImage.html
+        - web-platform-tests/2dcontext/imagebitmap/createImageBitmap-invalid-args.html
+
+
+        * html/ImageBitmap.cpp:
+        (WebCore::taintsOrigin): Add function to help with the implementation.
+        (WebCore::ImageBitmap::createPromise): Fill in implementation.
+
 2018-02-05  Zan Dobersek  <zdobersek@igalia.com>
 
         Unreviewed, rolling out r228085.
index 72d9339..1111d34 100644 (file)
@@ -114,6 +114,21 @@ static bool taintsOrigin(CachedImage& cachedImage)
     return false;
 }
 
+static bool taintsOrigin(SecurityOrigin* origin, HTMLVideoElement& video)
+{
+    if (!video.hasSingleSecurityOrigin())
+        return true;
+
+    if (video.player()->didPassCORSAccessCheck())
+        return false;
+
+    auto url = video.currentSrc();
+    if (url.protocolIsData())
+        return false;
+
+    return !origin->canRequest(url);
+}
+
 // https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#cropped-to-the-source-rectangle-with-formatting
 static ExceptionOr<IntRect> croppedSourceRectangleWithFormatting(IntSize inputSize, ImageBitmapOptions& options, std::optional<IntRect> rect)
 {
@@ -363,35 +378,66 @@ void ImageBitmap::createPromise(ScriptExecutionContext&, RefPtr<HTMLCanvasElemen
 }
 
 #if ENABLE(VIDEO)
-void ImageBitmap::createPromise(ScriptExecutionContext&, RefPtr<HTMLVideoElement>& videoElement, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
+void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, RefPtr<HTMLVideoElement>& video, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
 {
-    UNUSED_PARAM(videoElement);
-    UNUSED_PARAM(options);
-    UNUSED_PARAM(rect);
+    // https://html.spec.whatwg.org/multipage/#dom-createimagebitmap
+    // WHATWG HTML 2102913b313078cd8eeac7e81e6a8756cbd3e773
+    // Steps 3-7.
+    // (Step 3 is handled in croppedSourceRectangleWithFormatting.)
+
+    // 4. Check the usability of the image argument. If this throws an exception
+    //    or returns bad, then return p rejected with an "InvalidStateError"
+    //    DOMException.
+    if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readyState() == HTMLMediaElement::HAVE_METADATA) {
+        promise.reject(InvalidStateError, "Cannot create ImageBitmap before the HTMLVideoElement has data");
+        return;
+    }
 
-    // 2. If the video element's networkState attribute is NETWORK_EMPTY, then return
-    //    a promise rejected with an "InvalidStateError" DOMException and abort these
-    //    steps.
+    // 5. Let imageBitmap be a new ImageBitmap object.
+    auto imageBitmap = create();
 
-    // 3. If the video element's readyState attribute is either HAVE_NOTHING or
-    //    HAVE_METADATA, then return a promise rejected with an "InvalidStateError"
-    //    DOMException and abort these steps.
+    // 6.1. If image's networkState attribute is NETWORK_EMPTY, then return p
+    //      rejected with an "InvalidStateError" DOMException.
+    if (video->networkState() == HTMLMediaElement::NETWORK_EMPTY) {
+        promise.reject(InvalidStateError, "Cannot create ImageBitmap before the HTMLVideoElement has data");
+        return;
+    }
+
+    // 6.2. Set imageBitmap's bitmap data to a copy of the frame at the current
+    //      playback position, at the media resource's intrinsic width and
+    //      intrinsic height (i.e., after any aspect-ratio correction has been
+    //      applied), cropped to the source rectangle with formatting.
+    auto size = video->player() ? roundedIntSize(video->player()->naturalSize()) : IntSize();
+    auto maybeSourceRectangle = croppedSourceRectangleWithFormatting(size, options, WTFMove(rect));
+    if (maybeSourceRectangle.hasException()) {
+        promise.reject(maybeSourceRectangle.releaseException());
+        return;
+    }
+    auto sourceRectangle = maybeSourceRectangle.releaseReturnValue();
 
-    // 4. Create a new ImageBitmap object.
+    auto outputSize = outputSizeForSourceRectangle(sourceRectangle, options);
+    auto bitmapData = ImageBuffer::create(FloatSize(outputSize.width(), outputSize.height()), bufferRenderingMode);
 
-    // 5. Let the ImageBitmap object's bitmap data be a copy of the frame at the current
-    //    playback position, at the media resource's intrinsic width and intrinsic height
-    //    (i.e. after any aspect-ratio correction has been applied), cropped to the source
-    //    rectangle with formatting.
+    {
+        GraphicsContext& c = bitmapData->context();
+        GraphicsContextStateSaver stateSaver(c);
+        c.clip(FloatRect(FloatPoint(), outputSize));
+        auto scaleX = float(outputSize.width()) / float(sourceRectangle.width());
+        auto scaleY = float(outputSize.height()) / float(sourceRectangle.height());
+        c.scale(FloatSize(scaleX, scaleY));
+        c.translate(-sourceRectangle.location());
+        video->paintCurrentFrameInContext(c, FloatRect(FloatPoint(), size));
+    }
 
-    // 6. If the origin of the video element is not the same origin as the origin specified
-    //    by the entry settings object, then set the origin-clean flag of the ImageBitmap
-    //    object's bitmap to false.
+    imageBitmap->m_bitmapData = WTFMove(bitmapData);
 
-    // 7. Return a new promise, but continue running these steps in parallel.
+    // 6.3. If the origin of image's video is not same origin with entry
+    //      settings object's origin, then set the origin-clean flag of
+    //      image's bitmap to false.
+    imageBitmap->m_originClean = !taintsOrigin(scriptExecutionContext.securityOrigin(), *video);
 
-    // 8. Resolve the promise with the new ImageBitmap object as the value.
-    promise.reject(TypeError, "createImageBitmap with HTMLVideoElement is not implemented");
+    // 6.4.1. Resolve p with imageBitmap.
+    promise.resolve(WTFMove(imageBitmap));
 }
 #endif