Skip to content
Permalink
Browse files
Validate width, height, x and y for I420 and NV12 video frames
https://bugs.webkit.org/show_bug.cgi?id=246394
rdar://problem/101068854

Reviewed by Eric Carlson.

* LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-construction.any-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-construction.any.worker-expected.txt:
* Source/WebCore/Modules/webcodecs/WebCodecsVideoFrame.cpp:
(WebCore::WebCodecsVideoFrame::create):

Canonical link: https://commits.webkit.org/255489@main
  • Loading branch information
youennf committed Oct 13, 2022
1 parent 7c39226 commit cc18bcb28839ac9d58a7705b6e30b28561e2fcf8
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 7 deletions.
@@ -16,7 +16,7 @@ PASS Test visibleRect metadata override where source display width = 2 * visible
PASS Test visibleRect metadata override where source display size = 2 * visible size for both width and height
FAIL Test visibleRect + display size metadata override Can't find variable: OffscreenCanvas
FAIL Test display size metadata override Can't find variable: OffscreenCanvas
FAIL Test invalid buffer constructed VideoFrames assert_throws_js: odd coded height function "() => constructFrame({timestamp: 1234, codedWidth: 4, codedHeight: 1})" did not throw
PASS Test invalid buffer constructed VideoFrames
PASS Test Uint8Array(ArrayBuffer) constructed I420 VideoFrame
PASS Test ArrayBuffer constructed I420 VideoFrame
PASS Test planar constructed I420 VideoFrame with colorSpace
@@ -16,7 +16,7 @@ PASS Test visibleRect metadata override where source display width = 2 * visible
PASS Test visibleRect metadata override where source display size = 2 * visible size for both width and height
FAIL Test visibleRect + display size metadata override Can't find variable: OffscreenCanvas
FAIL Test display size metadata override Can't find variable: OffscreenCanvas
FAIL Test invalid buffer constructed VideoFrames assert_throws_js: odd coded height function "() => constructFrame({timestamp: 1234, codedWidth: 4, codedHeight: 1})" did not throw
PASS Test invalid buffer constructed VideoFrames
PASS Test Uint8Array(ArrayBuffer) constructed I420 VideoFrame
PASS Test ArrayBuffer constructed I420 VideoFrame
PASS Test planar constructed I420 VideoFrame with colorSpace
@@ -180,17 +180,25 @@ ExceptionOr<Ref<WebCodecsVideoFrame>> WebCodecsVideoFrame::create(BufferSource&&
return Exception { TypeError, makeString("Data is too small ", data.length(), " / ", layout.allocationSize) };

RefPtr<VideoFrame> videoFrame;
if (init.format == VideoPixelFormat::NV12)
if (init.format == VideoPixelFormat::NV12) {
if (init.codedWidth % 2 || init.codedHeight % 2)
return Exception { TypeError, "coded width or height is odd"_s };
if (init.visibleRect && (static_cast<size_t>(init.visibleRect->x) % 2 || static_cast<size_t>(init.visibleRect->x) % 2))
return Exception { TypeError, "visible x or y is odd"_s };
videoFrame = VideoFrame::createNV12({ data.data(), data.length() }, parsedRect.width, parsedRect.height, layout.computedLayouts[0], layout.computedLayouts[1]);
else if (init.format == VideoPixelFormat::RGBA || init.format == VideoPixelFormat::RGBX)
} else if (init.format == VideoPixelFormat::RGBA || init.format == VideoPixelFormat::RGBX)
videoFrame = VideoFrame::createRGBA({ data.data(), data.length() }, parsedRect.width, parsedRect.height, layout.computedLayouts[0]);
else if (init.format == VideoPixelFormat::BGRA || init.format == VideoPixelFormat::BGRX)
videoFrame = VideoFrame::createBGRA({ data.data(), data.length() }, parsedRect.width, parsedRect.height, layout.computedLayouts[0]);
else if (init.format == VideoPixelFormat::I420)
else if (init.format == VideoPixelFormat::I420) {
if (init.codedWidth % 2 || init.codedHeight % 2)
return Exception { TypeError, "coded width or height is odd"_s };
if (init.visibleRect && (static_cast<size_t>(init.visibleRect->x) % 2 || static_cast<size_t>(init.visibleRect->x) % 2))
return Exception { TypeError, "visible x or y is odd"_s };
videoFrame = VideoFrame::createI420({ data.data(), data.length() }, parsedRect.width, parsedRect.height, layout.computedLayouts[0], layout.computedLayouts[1], layout.computedLayouts[2]);
else
} else
return Exception { NotSupportedError, "VideoPixelFormat is not supported"_s };

if (!videoFrame)
return Exception { TypeError, "Unable to create internal resource from data"_s };

0 comments on commit cc18bcb

Please sign in to comment.