From 0bea9e7a11f02e71bfa84172acbe10e4d76a39ab Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 10 Sep 2024 10:08:28 +0200 Subject: [PATCH] Fix WebGL renderer failing to display video (#7381) ### What * Fixes #7328 This is obviously a brittle hack, but allows us to move on without having to wait on a wgpu release containing https://github.com/gfx-rs/wgpu/pull/6170 :) Tested using `pixi run rerun-web /Users/andreas/Desktop/sample\ videos/Big_Buck_Bunny_720_10s_30MB_av1.mp4` (insert video of your choice) and then running `http://localhost:9090/?url=ws%3A%2F%2Flocalhost%3A9877&renderer=webgl` in Chrome (on Mac. shouldn't matter much as long as the browser has webcodec support and draws video) ### Checklist * [x] I have read and agree to [Contributor Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and the [Code of Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md) * [x] I've included a screenshot or gif (if applicable) * [x] I have tested the web demo (if applicable): * Using examples from latest `main` build: [rerun.io/viewer](https://rerun.io/viewer/pr/7381?manifest_url=https://app.rerun.io/version/main/examples_manifest.json) * Using full set of examples from `nightly` build: [rerun.io/viewer](https://rerun.io/viewer/pr/7381?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json) * [x] The PR title and labels are set such as to maximize their usefulness for the next release's CHANGELOG * [x] If applicable, add a new check to the [release checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)! * [x] If have noted any breaking changes to the log API in `CHANGELOG.md` and the migration guide - [PR Build Summary](https://build.rerun.io/pr/7381) - [Recent benchmark results](https://build.rerun.io/graphs/crates.html) - [Wasm size tracking](https://build.rerun.io/graphs/sizes.html) To run all checks from `main`, comment on the PR with `@rerun-bot full-check`. --- .../src/renderer/video/decoder/web.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/crates/viewer/re_renderer/src/renderer/video/decoder/web.rs b/crates/viewer/re_renderer/src/renderer/video/decoder/web.rs index c25bd788a4fe..6eeacc9de8b5 100644 --- a/crates/viewer/re_renderer/src/renderer/video/decoder/web.rs +++ b/crates/viewer/re_renderer/src/renderer/video/decoder/web.rs @@ -315,7 +315,9 @@ fn copy_video_frame_to_texture( depth_or_array_layers: 1, }; let source = { - // TODO(jan): Remove this unsafe code when https://github.com/gfx-rs/wgpu/pull/6170 ships. + // TODO(jan): The wgpu version we're using doesn't support `VideoFrame` yet. + // This got fixed in https://github.com/gfx-rs/wgpu/pull/6170 but hasn't shipped yet. + // So instead, we just pretend this is a `HtmlVideoElement` instead. // SAFETY: Depends on the fact that `wgpu` passes the object through as-is, // and doesn't actually inspect it in any way. The browser then does its own // typecheck that doesn't care what kind of image source wgpu gave it. @@ -325,6 +327,19 @@ fn copy_video_frame_to_texture( frame.clone().expect("Failed to clone the video frame"), ) }; + // Fake width & height to work around wgpu validating this as if it was a `HtmlVideoElement`. + // Since it thinks this is a `HtmlVideoElement`, it will want to call `videoWidth` and `videoHeight` + // on it to validate the size. + // We simply redirect `displayWidth`/`displayHeight` to `videoWidth`/`videoHeight` to make it work! + let display_width = js_sys::Reflect::get(&frame, &"displayWidth".into()) + .expect("Failed to get displayWidth property from VideoFrame."); + js_sys::Reflect::set(&frame, &"videoWidth".into(), &display_width) + .expect("Failed to set videoWidth property."); + let display_height = js_sys::Reflect::get(&frame, &"displayHeight".into()) + .expect("Failed to get displayHeight property from VideoFrame."); + js_sys::Reflect::set(&frame, &"videoHeight".into(), &display_height) + .expect("Failed to set videoHeight property."); + wgpu_types::ImageCopyExternalImage { source: wgpu_types::ExternalImageSource::HTMLVideoElement(frame), origin: wgpu_types::Origin2d { x: 0, y: 0 },