diff --git a/src/resources/README.md b/src/resources/README.md index 824f82b998f2..daa51765baa0 100644 --- a/src/resources/README.md +++ b/src/resources/README.md @@ -2,14 +2,64 @@ Always use `getResourcePath()` to get the appropriate path to these resources de on the context (WPT, standalone, worker, etc.) -The test video files were generated with the ffmpeg cmds below: -ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx -pix_fmt yuv420p -frames 500 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-vp8-bt601.webm -ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libtheora -pix_fmt yuv420p -frames 500 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-theora-bt601.ogv -ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 500 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-h264-bt601.mp4 -ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 500 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-vp9-bt601.webm -ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 500 -colorspace bt709 -color_primaries bt709 -color_trc bt709 -color_range tv -vf scale=out_color_matrix=bt709:out_range=tv four-colors-vp9-bt709.webm - -These rotation test files are copies of four-colors-h264-bt601.mp4 with metadata changes. -ffmpeg.exe -i .\four-colors-h264-bt601.mp4 -c copy -metadata:s:v rotate=90 four-colors-h264-bt601-rotate-90.mp4 -ffmpeg.exe -i .\four-colors-h264-bt601.mp4 -c copy -metadata:s:v rotate=180 four-colors-h264-bt601-rotate-180.mp4 -ffmpeg.exe -i .\four-colors-h264-bt601.mp4 -c copy -metadata:s:v rotate=270 four-colors-h264-bt601-rotate-270.mp4 \ No newline at end of file +The test video files were generated with by ffmpeg cmds below: +``` +// Generate four-colors-vp8-bt601.webm, mimeType: 'video/webm; codecs=vp8' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-vp8-bt601.webm + +// Generate four-colors-theora-bt601.ogv, mimeType: 'video/ogg; codecs=theora' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libtheora -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-theora-bt601.ogv + +// Generate four-colors-h264-bt601.mp4, mimeType: 'video/mp4; codecs=h264' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-h264-bt601.mp4 + +// Generate four-colors-vp9-bt601.webm, mimeType: 'video/webm; codecs=vp9' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-vp9-bt601.webm + +// Generate four-colors-vp9-bt709.webm, mimeType: 'video/webm; codecs=vp9' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 50 -colorspace bt709 -color_primaries bt709 -color_trc bt709 -color_range tv -vf scale=out_color_matrix=bt709:out_range=tv four-colors-vp9-bt709.webm + +// Generate four-colors-vp9-bt601.mp4, mimeType: 'video/mp4; codecs=vp9' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-vp9-bt601.mp4 +``` + +Generate video files to test rotation behaviour. +Use ffmepg to rotate video content x degrees in cw direction (by using `transpose`) and update transform matrix in metadata through `display_rotation` to x degrees to apply ccw direction rotation. + +H264 rotated video files are generated by ffmpeg cmds below: +``` +// Generate four-colors-h264-bt601-rotate-90.mp4, mimeType: 'video/mp4; codecs=h264' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv -vf transpose=2 temp.mp4 +ffmpeg -display_rotation 270 -i temp.mp4 -c copy four-colors-h264-bt601-rotate-90.mp4 +rm temp.mp4 + +// Generate four-colors-h264-bt601-rotate-180.mp4, mimeType: 'video/mp4; codecs=h264' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv -vf transpose=2,transpose=2 temp.mp4 +ffmpeg -display_rotation 180 -i temp.mp4 -c copy four-colors-h264-bt601-rotate-180.mp4 +rm temp.mp4 + +// Generate four-colors-h264-bt601-rotate-270.mp4, mimeType: 'video/mp4; codecs=h264' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv -vf transpose=1 temp.mp4 +ffmpeg -display_rotation 90 -i temp.mp4 -c copy four-colors-h264-bt601-rotate-270.mp4 +rm temp.mp4 + +``` + +Vp9 rotated video files are generated by ffmpeg cmds below: +``` +// Generate four-colors-h264-bt601-rotate-90.mp4, mimeType: 'video/mp4; codecs=vp9' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv -vf transpose=2 temp.mp4 +ffmpeg -display_rotation 270 -i temp.mp4 -c copy four-colors-vp9-bt601-rotate-90.mp4 +rm temp.mp4 + +// Generate four-colors-h264-bt601-rotate-180.mp4, mimeType: 'video/mp4; codecs=vp9' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv -vf transpose=2,transpose=2 temp.mp4 +ffmpeg -display_rotation 180 -i temp.mp4 -c copy four-colors-vp9-bt601-rotate-180.mp4 +rm temp.mp4 + +// Generate four-colors-h264-bt601-rotate-270.mp4, mimeType: 'video/mp4; codecs=vp9' +ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv -vf transpose=1 temp.mp4 +ffmpeg -display_rotation 90 -i temp.mp4 -c copy four-colors-vp9-bt601-rotate-270.mp4 +rm temp.mp4 + +``` \ No newline at end of file diff --git a/src/resources/four-colors-h264-bt601-rotate-180.mp4 b/src/resources/four-colors-h264-bt601-rotate-180.mp4 index 1f0e9094a528..6665ea900dab 100644 Binary files a/src/resources/four-colors-h264-bt601-rotate-180.mp4 and b/src/resources/four-colors-h264-bt601-rotate-180.mp4 differ diff --git a/src/resources/four-colors-h264-bt601-rotate-270.mp4 b/src/resources/four-colors-h264-bt601-rotate-270.mp4 index e0480ceff2f8..b1e32bc83a53 100644 Binary files a/src/resources/four-colors-h264-bt601-rotate-270.mp4 and b/src/resources/four-colors-h264-bt601-rotate-270.mp4 differ diff --git a/src/resources/four-colors-h264-bt601-rotate-90.mp4 b/src/resources/four-colors-h264-bt601-rotate-90.mp4 index 9a6261056e91..66a98d0ed021 100644 Binary files a/src/resources/four-colors-h264-bt601-rotate-90.mp4 and b/src/resources/four-colors-h264-bt601-rotate-90.mp4 differ diff --git a/src/resources/four-colors-h264-bt601.mp4 b/src/resources/four-colors-h264-bt601.mp4 index 81a5ade4354c..5317bbf7c682 100644 Binary files a/src/resources/four-colors-h264-bt601.mp4 and b/src/resources/four-colors-h264-bt601.mp4 differ diff --git a/src/resources/four-colors-theora-bt601.ogv b/src/resources/four-colors-theora-bt601.ogv index 79ed41163c3b..67c57d1adef3 100644 Binary files a/src/resources/four-colors-theora-bt601.ogv and b/src/resources/four-colors-theora-bt601.ogv differ diff --git a/src/resources/four-colors-vp8-bt601.webm b/src/resources/four-colors-vp8-bt601.webm index 20a2178596e9..d1504ee33220 100644 Binary files a/src/resources/four-colors-vp8-bt601.webm and b/src/resources/four-colors-vp8-bt601.webm differ diff --git a/src/resources/four-colors-vp9-bt601-rotate-180.mp4 b/src/resources/four-colors-vp9-bt601-rotate-180.mp4 new file mode 100644 index 000000000000..fc712becd78e Binary files /dev/null and b/src/resources/four-colors-vp9-bt601-rotate-180.mp4 differ diff --git a/src/resources/four-colors-vp9-bt601-rotate-270.mp4 b/src/resources/four-colors-vp9-bt601-rotate-270.mp4 new file mode 100644 index 000000000000..a83558f53cd5 Binary files /dev/null and b/src/resources/four-colors-vp9-bt601-rotate-270.mp4 differ diff --git a/src/resources/four-colors-vp9-bt601-rotate-90.mp4 b/src/resources/four-colors-vp9-bt601-rotate-90.mp4 new file mode 100644 index 000000000000..73a03795ba39 Binary files /dev/null and b/src/resources/four-colors-vp9-bt601-rotate-90.mp4 differ diff --git a/src/resources/four-colors-vp9-bt601.mp4 b/src/resources/four-colors-vp9-bt601.mp4 new file mode 100644 index 000000000000..0d8d4f829caa Binary files /dev/null and b/src/resources/four-colors-vp9-bt601.mp4 differ diff --git a/src/resources/four-colors-vp9-bt601.webm b/src/resources/four-colors-vp9-bt601.webm index a4044a920981..47a43a0695e4 100644 Binary files a/src/resources/four-colors-vp9-bt601.webm and b/src/resources/four-colors-vp9-bt601.webm differ diff --git a/src/resources/four-colors-vp9-bt709.webm b/src/resources/four-colors-vp9-bt709.webm index 189e422035c7..a9e069ee1ca6 100644 Binary files a/src/resources/four-colors-vp9-bt709.webm and b/src/resources/four-colors-vp9-bt709.webm differ diff --git a/src/webgpu/web_platform/copyToTexture/video.spec.ts b/src/webgpu/web_platform/copyToTexture/video.spec.ts index ef3860633150..f59644008c9e 100644 --- a/src/webgpu/web_platform/copyToTexture/video.spec.ts +++ b/src/webgpu/web_platform/copyToTexture/video.spec.ts @@ -17,6 +17,7 @@ import { kPredefinedColorSpace, kVideoNames, kVideoInfo, + kVideoExpectedColors, } from '../../web_platform/util.js'; const kFormat = 'rgba8unorm'; @@ -93,29 +94,33 @@ It creates HTMLVideoElement with videos under Resource folder. { width, height, depthOrArrayLayers: 1 } ); - const expect = kVideoInfo[videoName].presentColors[dstColorSpace]; + const srcColorSpace = kVideoInfo[videoName].colorSpace; + const presentColors = kVideoExpectedColors[srcColorSpace][dstColorSpace]; + + // visible rect is whole frame, no clipping. + const expect = kVideoInfo[videoName].display; if (srcDoFlipYDuringCopy) { t.expectSinglePixelComparisonsAreOkInTexture({ texture: dstTexture }, [ // Flipped top-left. { coord: { x: width * 0.25, y: height * 0.25 }, - exp: convertToUnorm8(expect.bottomLeftColor), + exp: convertToUnorm8(presentColors[expect.bottomLeftColor]), }, // Flipped top-right. { coord: { x: width * 0.75, y: height * 0.25 }, - exp: convertToUnorm8(expect.bottomRightColor), + exp: convertToUnorm8(presentColors[expect.bottomRightColor]), }, // Flipped bottom-left. { coord: { x: width * 0.25, y: height * 0.75 }, - exp: convertToUnorm8(expect.topLeftColor), + exp: convertToUnorm8(presentColors[expect.topLeftColor]), }, // Flipped bottom-right. { coord: { x: width * 0.75, y: height * 0.75 }, - exp: convertToUnorm8(expect.topRightColor), + exp: convertToUnorm8(presentColors[expect.topRightColor]), }, ]); } else { @@ -123,22 +128,22 @@ It creates HTMLVideoElement with videos under Resource folder. // Top-left. { coord: { x: width * 0.25, y: height * 0.25 }, - exp: convertToUnorm8(expect.topLeftColor), + exp: convertToUnorm8(presentColors[expect.topLeftColor]), }, // Top-right. { coord: { x: width * 0.75, y: height * 0.25 }, - exp: convertToUnorm8(expect.topRightColor), + exp: convertToUnorm8(presentColors[expect.topRightColor]), }, // Bottom-left. { coord: { x: width * 0.25, y: height * 0.75 }, - exp: convertToUnorm8(expect.bottomLeftColor), + exp: convertToUnorm8(presentColors[expect.bottomLeftColor]), }, // Bottom-right. { coord: { x: width * 0.75, y: height * 0.75 }, - exp: convertToUnorm8(expect.bottomRightColor), + exp: convertToUnorm8(presentColors[expect.bottomRightColor]), }, ]); } diff --git a/src/webgpu/web_platform/external_texture/video.spec.ts b/src/webgpu/web_platform/external_texture/video.spec.ts index 5bee668bf2ea..2b5e0bdb40a9 100644 --- a/src/webgpu/web_platform/external_texture/video.spec.ts +++ b/src/webgpu/web_platform/external_texture/video.spec.ts @@ -18,6 +18,7 @@ import { kPredefinedColorSpace, kVideoNames, kVideoInfo, + kVideoExpectedColors, } from '../../web_platform/util.js'; const kHeight = 16; @@ -194,7 +195,11 @@ for several combinations of video format, video color spaces and dst color space passEncoder.end(); t.device.queue.submit([commandEncoder.finish()]); - const expect = kVideoInfo[videoName].presentColors[dstColorSpace]; + const srcColorSpace = kVideoInfo[videoName].colorSpace; + const presentColors = kVideoExpectedColors[srcColorSpace][dstColorSpace]; + + // visible rect is whole frame, no clipping. + const expect = kVideoInfo[videoName].display; // For validation, we sample a few pixels away from the edges to avoid compression // artifacts. @@ -202,22 +207,22 @@ for several combinations of video format, video color spaces and dst color space // Top-left. { coord: { x: kWidth * 0.25, y: kHeight * 0.25 }, - exp: convertToUnorm8(expect.topLeftColor), + exp: convertToUnorm8(presentColors[expect.topLeftColor]), }, // Top-right. { coord: { x: kWidth * 0.75, y: kHeight * 0.25 }, - exp: convertToUnorm8(expect.topRightColor), + exp: convertToUnorm8(presentColors[expect.topRightColor]), }, // Bottom-left. { coord: { x: kWidth * 0.25, y: kHeight * 0.75 }, - exp: convertToUnorm8(expect.bottomLeftColor), + exp: convertToUnorm8(presentColors[expect.bottomLeftColor]), }, // Bottom-right. { coord: { x: kWidth * 0.75, y: kHeight * 0.75 }, - exp: convertToUnorm8(expect.bottomRightColor), + exp: convertToUnorm8(presentColors[expect.bottomRightColor]), }, ]); }); @@ -247,16 +252,22 @@ parameters are present. // All tested videos are derived from an image showing yellow, red, blue or green in each // quadrant. In this test we crop the video to each quadrant and check that desired color // is sampled from each corner of the cropped image. - const srcVideoHeight = 240; - const srcVideoWidth = 320; + // visible rect clip applies on raw decoded frame, which defines based on video frame coded size. + const srcVideoHeight = source.codedHeight; + const srcVideoWidth = source.codedWidth; + + const srcColorSpace = kVideoInfo[videoName].colorSpace; + const presentColors = kVideoExpectedColors[srcColorSpace][dstColorSpace]; - const expect = kVideoInfo[videoName].presentColors[dstColorSpace]; + // The test crops raw decoded videos first and then apply transform. Expectation should + // use coded colors as reference. + const expect = kVideoInfo[videoName].coded; const cropParams = [ // Top left { subRect: { x: 0, y: 0, width: srcVideoWidth / 2, height: srcVideoHeight / 2 }, - color: convertToUnorm8(expect.topLeftColor), + color: convertToUnorm8(presentColors[expect.topLeftColor]), }, // Top right { @@ -266,7 +277,7 @@ parameters are present. width: srcVideoWidth / 2, height: srcVideoHeight / 2, }, - color: convertToUnorm8(expect.topRightColor), + color: convertToUnorm8(presentColors[expect.topRightColor]), }, // Bottom left { @@ -276,7 +287,7 @@ parameters are present. width: srcVideoWidth / 2, height: srcVideoHeight / 2, }, - color: convertToUnorm8(expect.bottomLeftColor), + color: convertToUnorm8(presentColors[expect.bottomLeftColor]), }, // Bottom right { @@ -286,7 +297,7 @@ parameters are present. width: srcVideoWidth / 2, height: srcVideoHeight / 2, }, - color: convertToUnorm8(expect.bottomRightColor), + color: convertToUnorm8(presentColors[expect.bottomRightColor]), }, ]; @@ -381,29 +392,51 @@ compute shader, for several combinations of video format, video color spaces and usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.STORAGE_BINDING, }); + // Use display size of VideoFrame and video size of HTMLVideoElement as frame size. These sizes are presenting size which + // apply transformation in video metadata if any. + const pipeline = t.device.createComputePipeline({ layout: 'auto', compute: { - // Shader loads 4 pixels near each corner, and then store them in a storage texture. + // Shader loads 4 pixels, and then store them in a storage texture. module: t.device.createShaderModule({ code: ` + override frameWidth : i32 = 0; + override frameHeight : i32 = 0; @group(0) @binding(0) var t : texture_external; @group(0) @binding(1) var outImage : texture_storage_2d; @compute @workgroup_size(1) fn main() { - var yellow : vec4 = textureLoad(t, vec2(80, 60)); + let coordTopLeft = vec2(frameWidth / 4, frameHeight / 4); + let coordTopRight = vec2(frameWidth / 4 * 3, frameHeight / 4); + let coordBottomLeft = vec2(frameWidth / 4, frameHeight / 4 * 3); + let coordBottomRight = vec2(frameWidth / 4 * 3, frameHeight / 4 * 3); + var yellow : vec4 = textureLoad(t, coordTopLeft); textureStore(outImage, vec2(0, 0), yellow); - var red : vec4 = textureLoad(t, vec2(240, 60)); + var red : vec4 = textureLoad(t, coordTopRight); textureStore(outImage, vec2(0, 1), red); - var blue : vec4 = textureLoad(t, vec2(80, 180)); + var blue : vec4 = textureLoad(t, coordBottomLeft); textureStore(outImage, vec2(1, 0), blue); - var green : vec4 = textureLoad(t, vec2(240, 180)); + var green : vec4 = textureLoad(t, coordBottomRight); textureStore(outImage, vec2(1, 1), green); return; } `, }), entryPoint: 'main', + + // Use display size of VideoFrame and video size of HTMLVideoElement as frame size. These sizes are presenting size which + // apply transformation in video metadata if any. + constants: { + frameWidth: + sourceType === 'VideoFrame' + ? (source as VideoFrame).displayWidth + : (source as HTMLVideoElement).videoWidth, + frameHeight: + sourceType === 'VideoFrame' + ? (source as VideoFrame).displayHeight + : (source as HTMLVideoElement).videoHeight, + }, }, }); @@ -423,17 +456,21 @@ compute shader, for several combinations of video format, video color spaces and pass.end(); t.device.queue.submit([encoder.finish()]); - const expect = kVideoInfo[videoName].presentColors[dstColorSpace]; + const srcColorSpace = kVideoInfo[videoName].colorSpace; + const presentColors = kVideoExpectedColors[srcColorSpace][dstColorSpace]; + + // visible rect is whole frame, no clipping. + const expect = kVideoInfo[videoName].display; t.expectSinglePixelComparisonsAreOkInTexture({ texture: outputTexture }, [ // Top-left. - { coord: { x: 0, y: 0 }, exp: convertToUnorm8(expect.topLeftColor) }, + { coord: { x: 0, y: 0 }, exp: convertToUnorm8(presentColors[expect.topLeftColor]) }, // Top-right. - { coord: { x: 0, y: 1 }, exp: convertToUnorm8(expect.topRightColor) }, + { coord: { x: 0, y: 1 }, exp: convertToUnorm8(presentColors[expect.topRightColor]) }, // Bottom-left. - { coord: { x: 1, y: 0 }, exp: convertToUnorm8(expect.bottomLeftColor) }, + { coord: { x: 1, y: 0 }, exp: convertToUnorm8(presentColors[expect.bottomLeftColor]) }, // Bottom-right. - { coord: { x: 1, y: 1 }, exp: convertToUnorm8(expect.bottomRightColor) }, + { coord: { x: 1, y: 1 }, exp: convertToUnorm8(presentColors[expect.bottomRightColor]) }, ]); }); }); diff --git a/src/webgpu/web_platform/util.ts b/src/webgpu/web_platform/util.ts index dd2031891cd7..358272a37927 100644 --- a/src/webgpu/web_platform/util.ts +++ b/src/webgpu/web_platform/util.ts @@ -51,7 +51,7 @@ const kBt709PixelValue = { }, } as const; -function videoTable({ +function makeTable
({ table, }: { table: Table; @@ -66,143 +66,233 @@ function videoTable
({ ) as any; } +// Video expected pixel value table. Finding expected pixel value +// with video color space and dst color space. +export const kVideoExpectedColors = makeTable({ + table: { + bt601: { + 'display-p3': { + yellow: srgbToDisplayP3(kBt601PixelValue.srgb.yellow), + red: srgbToDisplayP3(kBt601PixelValue.srgb.red), + blue: srgbToDisplayP3(kBt601PixelValue.srgb.blue), + green: srgbToDisplayP3(kBt601PixelValue.srgb.green), + }, + srgb: { + yellow: kBt601PixelValue.srgb.yellow, + red: kBt601PixelValue.srgb.red, + blue: kBt601PixelValue.srgb.blue, + green: kBt601PixelValue.srgb.green, + }, + }, + bt709: { + 'display-p3': { + yellow: srgbToDisplayP3(kBt709PixelValue.srgb.yellow), + red: srgbToDisplayP3(kBt709PixelValue.srgb.red), + blue: srgbToDisplayP3(kBt709PixelValue.srgb.blue), + green: srgbToDisplayP3(kBt709PixelValue.srgb.green), + }, + srgb: { + yellow: kBt709PixelValue.srgb.yellow, + red: kBt709PixelValue.srgb.red, + blue: kBt709PixelValue.srgb.blue, + green: kBt709PixelValue.srgb.green, + }, + }, + }, +} as const); + // MAINTENANCE_TODO: Add BT.2020 video in table. -export const kVideoInfo = videoTable({ +// Video container and codec defines several transform ops to apply to raw decoded frame to display. +// Our test cases covers 'visible rect' and 'rotation'. +// 'visible rect' is associated with the +// video bitstream and should apply to the raw decoded frames before any transformation. +// 'rotation' is associated with the track or presentation and should transform +// the whole visible rect (e.g. 90-degree rotate makes visible rect of vertical video to horizontal) +// The order to apply these transformations is below: + +// [raw decoded frame] ----visible rect clipping ---->[visible frame] ---rotation ---> present +// ^ ^ +// | | +// coded size display size +// The table holds test videos meta infos, including mimeType to check browser compatibility +// video color space, raw frame content layout and the frame displayed layout. +export const kVideoInfo = makeTable({ table: { 'four-colors-vp8-bt601.webm': { mimeType: 'video/webm; codecs=vp8', - presentColors: { - 'display-p3': { - topLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.yellow), - topRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.red), - bottomLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.blue), - bottomRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.green), - }, - srgb: { - topLeftColor: kBt601PixelValue.srgb.yellow, - topRightColor: kBt601PixelValue.srgb.red, - bottomLeftColor: kBt601PixelValue.srgb.blue, - bottomRightColor: kBt601PixelValue.srgb.green, - }, + colorSpace: 'bt601', + coded: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', }, }, 'four-colors-theora-bt601.ogv': { mimeType: 'video/ogg; codecs=theora', - presentColors: { - 'display-p3': { - topLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.yellow), - topRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.red), - bottomLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.blue), - bottomRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.green), - }, - srgb: { - topLeftColor: kBt601PixelValue.srgb.yellow, - topRightColor: kBt601PixelValue.srgb.red, - bottomLeftColor: kBt601PixelValue.srgb.blue, - bottomRightColor: kBt601PixelValue.srgb.green, - }, + colorSpace: 'bt601', + coded: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', }, }, 'four-colors-h264-bt601.mp4': { mimeType: 'video/mp4; codecs=avc1.4d400c', - presentColors: { - 'display-p3': { - topLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.yellow), - topRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.red), - bottomLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.blue), - bottomRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.green), - }, - srgb: { - topLeftColor: kBt601PixelValue.srgb.yellow, - topRightColor: kBt601PixelValue.srgb.red, - bottomLeftColor: kBt601PixelValue.srgb.blue, - bottomRightColor: kBt601PixelValue.srgb.green, - }, + colorSpace: 'bt601', + coded: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', }, }, 'four-colors-vp9-bt601.webm': { mimeType: 'video/webm; codecs=vp9', - presentColors: { - 'display-p3': { - topLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.yellow), - topRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.red), - bottomLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.blue), - bottomRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.green), - }, - srgb: { - topLeftColor: kBt601PixelValue.srgb.yellow, - topRightColor: kBt601PixelValue.srgb.red, - bottomLeftColor: kBt601PixelValue.srgb.blue, - bottomRightColor: kBt601PixelValue.srgb.green, - }, + colorSpace: 'bt601', + coded: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', }, }, 'four-colors-vp9-bt709.webm': { mimeType: 'video/webm; codecs=vp9', - presentColors: { - 'display-p3': { - topLeftColor: srgbToDisplayP3(kBt709PixelValue.srgb.yellow), - topRightColor: srgbToDisplayP3(kBt709PixelValue.srgb.red), - bottomLeftColor: srgbToDisplayP3(kBt709PixelValue.srgb.blue), - bottomRightColor: srgbToDisplayP3(kBt709PixelValue.srgb.green), - }, - srgb: { - topLeftColor: kBt709PixelValue.srgb.yellow, - topRightColor: kBt709PixelValue.srgb.red, - bottomLeftColor: kBt709PixelValue.srgb.blue, - bottomRightColor: kBt709PixelValue.srgb.green, - }, + colorSpace: 'bt709', + coded: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', }, }, + // video coded content has been rotate 'four-colors-h264-bt601-rotate-90.mp4': { mimeType: 'video/mp4; codecs=avc1.4d400c', - presentColors: { - 'display-p3': { - topLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.red), - topRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.green), - bottomLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.yellow), - bottomRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.blue), - }, - srgb: { - topLeftColor: kBt601PixelValue.srgb.red, - topRightColor: kBt601PixelValue.srgb.green, - bottomLeftColor: kBt601PixelValue.srgb.yellow, - bottomRightColor: kBt601PixelValue.srgb.blue, - }, + colorSpace: 'bt601', + coded: { + topLeftColor: 'red', + topRightColor: 'green', + bottomLeftColor: 'yellow', + bottomRightColor: 'blue', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', }, }, 'four-colors-h264-bt601-rotate-180.mp4': { mimeType: 'video/mp4; codecs=avc1.4d400c', - presentColors: { - 'display-p3': { - topLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.green), - topRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.blue), - bottomLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.red), - bottomRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.yellow), - }, - srgb: { - topLeftColor: kBt601PixelValue.srgb.green, - topRightColor: kBt601PixelValue.srgb.blue, - bottomLeftColor: kBt601PixelValue.srgb.red, - bottomRightColor: kBt601PixelValue.srgb.yellow, - }, + colorSpace: 'bt601', + coded: { + topLeftColor: 'green', + topRightColor: 'blue', + bottomLeftColor: 'red', + bottomRightColor: 'yellow', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', }, }, 'four-colors-h264-bt601-rotate-270.mp4': { mimeType: 'video/mp4; codecs=avc1.4d400c', - presentColors: { - 'display-p3': { - topLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.blue), - topRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.yellow), - bottomLeftColor: srgbToDisplayP3(kBt601PixelValue.srgb.green), - bottomRightColor: srgbToDisplayP3(kBt601PixelValue.srgb.red), - }, - srgb: { - topLeftColor: kBt601PixelValue.srgb.blue, - topRightColor: kBt601PixelValue.srgb.yellow, - bottomLeftColor: kBt601PixelValue.srgb.green, - bottomRightColor: kBt601PixelValue.srgb.red, - }, + colorSpace: 'bt601', + coded: { + topLeftColor: 'blue', + topRightColor: 'yellow', + bottomLeftColor: 'green', + bottomRightColor: 'red', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', + }, + }, + 'four-colors-vp9-bt601-rotate-90.mp4': { + mimeType: 'video/mp4; codecs=vp09.00.10.08', + colorSpace: 'bt601', + coded: { + topLeftColor: 'red', + topRightColor: 'green', + bottomLeftColor: 'yellow', + bottomRightColor: 'blue', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', + }, + }, + 'four-colors-vp9-bt601-rotate-180.mp4': { + mimeType: 'video/mp4; codecs=vp09.00.10.08', + colorSpace: 'bt601', + coded: { + topLeftColor: 'green', + topRightColor: 'blue', + bottomLeftColor: 'red', + bottomRightColor: 'yellow', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', + }, + }, + 'four-colors-vp9-bt601-rotate-270.mp4': { + mimeType: 'video/mp4; codecs=vp09.00.10.08', + colorSpace: 'bt601', + coded: { + topLeftColor: 'blue', + topRightColor: 'yellow', + bottomLeftColor: 'green', + bottomRightColor: 'red', + }, + display: { + topLeftColor: 'yellow', + topRightColor: 'red', + bottomLeftColor: 'blue', + bottomRightColor: 'green', }, }, },