Repository navigation
Conversation
All filmcraft-* git dependencies move from 2c5ba7a (2026-10-03) to FilmCraft main 4e2d0bc2 (2026-10-10), the first revision with filmcraft-platform. Fixes for what changed: - MediaInfo.audio became audio_streams (audio() / has_audio()); VideoStreamInfo gained hdr. - FilmCraft now rounds a frame request to the track's nearest timestamp unit (halves up), so the media pool's mid-frame request landed on the next frame when the timescale equals the frame rate (our own MP4 / MOV exports at 10 fps): it asks a quarter into the frame instead. - filmcraft_vp9::Decoder::new() decodes on frame threads and may return a picture from a later call; the VP9 round-trip tests that expect one picture per call use with_threads(1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The desktop app registers FilmCraft's hardware decoders (VideoToolbox on macOS, Media Foundation / DXVA on Windows, NVDEC and VA-API on Linux) in front of the software decoders, on a background thread (probing the drivers takes 0.3-0.6 s). filmcraft-platform is a dependency of the app binary only: all OS FFI stays in that FilmCraft crate, our crates stay unsafe-free and the L0-L4 / wasm32 builds are unchanged. - Settings > Import > Enable Hardware Accelerated Decoding (import.hardwareDecoding, on by default; automation id settings.import.hardwareDecoding; prefs.set): flips FilmCraft's switch through FootageSource::set_hardware_decoding; a change closes the media pool's open decoders, so footage already open follows it. - GPU Information and the System Compatibility Report show the backend in use and its counters. - Streams the hardware does not take, decoders that fail mid-stream, other codecs, the CLI and the web app decode in software. - tests/hardware_decoding.rs: off decodes in software, VP9 stays in software, and a hardware smoke test (skips without a device) matches the software frames and follows the switch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Real-world evidence for this PR from the community Discord (#artcraft-bugs / #effectcraft): two users report H.264 10-bit 4:2:2 footage (brdn, Apple silicon; Cullen, Sony A6700 S-Log) showing as a black frame in EffectCraft 0.8, while the same file plays in FilmCraft. The pinned FilmCraft software decoder only handles 8-bit 4:2:0, and FilmCraft's |
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
FilmCraft 4e2d0bc turns pure-rotation MP4/MOV frames itself and hands AAC 3.0-5.1 over in WAV order; keep only our own turn for headers it leaves as stored, and the matching downmix gains. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Updated against current main (merge of upstream/main, plus a follow-up commit). Conflicts: Because this branch carries the FilmCraft bump, two upstream tests failed against it, so I adapted the code. FilmCraft now rotates pure-rotation MP4/MOV frames itself, so Checks run: The one failure is 🤖 Generated with Claude Code |
Conflicts only in the Japanese/Chinese/Ukrainian i18n tables (kept both sides) and docs/gaps.md, docs/hardware-parity.md (upstream's rows with the hardware decode status from this branch). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
@echelon, @bflatastic: this is ready for review now, and it needs two yes/no decisions from you. Everything else is done and tested.
Why it matters: two Discord users get a black frame for H.264 10-bit 4:2:2 footage (see my comment above), because the pinned software decoder only handles 8-bit 4:2:0. With this PR EffectCraft takes the same hardware path as FilmCraft. On my machine hardware decoding cuts the CPU cost of a frame by 5–31x, bit-exact with the software decoder. If you would rather not take the dependency, a "no" on (2) is useful too: I can then land only the pin bump and the black-frame notice. 🤖 Generated with Claude Code |
|
The pin bump is now also its own PR: #1603. |
Keep the PR's newer FilmCraft pin (4e2d0bc, with filmcraft-platform) and main's symphonia aiff entry. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Fixes #804.
Draft: this needs two maintainer decisions (see the last section): bumping the FilmCraft pin, and adding
filmcraft-platform, a dependency that contains OS FFI.Why
Gap #15 (
docs/gaps.md,docs/hardware-parity.md): After Effects decodes H.264 / HEVC in hardware, while EffectCraft decodes every frame in software on every platform. FilmCraft already has the hardware path infilmcraft-platform: VideoToolbox, Media Foundation / DXVA, NVDEC and VA-API, with automatic software fallback. On this Linux machine (RTX 5090 for NVDEC, Radeon 610M iGPU for VA-API), decoding H.264 / HEVC in hardware cuts the CPU cost of a frame by 5–31× and the time of a random jump in a long-GOP file by 1.6–4×. The output is bit-exact with the software decoder. Full numbers are under Measurements.Pin bump
All
filmcraft-*git deps move from2c5ba7a(2026-10-03) to FilmCraftmain4e2d0bc2(2026-10-10, 1078 commits later), the first revision that hasfilmcraft-platform. That change is its own commit (Bump FilmCraft to 4e2d0bc2). What broke, and the fixes:MediaInfo.audio→audio_streams(audio()/has_audio());VideoStreamInfogainedhdr. These were mechanical fixes ininterchange,mediaand two tests.qa::kinetic): FilmCraft now rounds a frame request to the track's nearest timestamp unit, halves up (FilmCraft 2b49201e, for 1 ms WebM timescales). The media pool asked for the middle of frame i. When the timescale equals the frame rate (our own 10 fps MP4 / MOV exports), that request rounds onto frame i+1. The pool now asks a quarter of the way into the frame. That still tolerates timestamps rounded either way, and it is a one-line change inpool.rs.filmcraft_vp9::Decoder::new()now uses frame threads, so a picture can come out of a later call. The tests expect one picture per call, so they now useDecoder::with_threads(1). Only test code uses the VP9 decoder.effectcraft-gpu's unit tests all passed (203/203), then the process segfaulted at exit during GPU teardown, the same class as the knownui_gpusegfault. It did not recur on the final run.filmcraft-exportpulls inrender,text,captions,audio-dsp) and the macOS-onlyobjc2-core-media/-video/-video-toolbox.windowsandlibloadingwere already in the lockfile.Fix
apps/effectcraft(L6) is the only crate that depends onfilmcraft-platform, and only on non-wasm targets. At startup it callsfilmcraft_platform::register()on a background thread, because probing the drivers takes 0.3–0.6 s. Allunsafe/ FFI stays inside FilmCraft's crate.unsafe_code = "forbid"is unchanged for our workspace, and L0–L4, the web app and the CLI are untouched.cargo xtask layersneeded no change, since its rules only covereffectcraft-*edges and UI crates.import.hardwareDecoding, on by default like After Effects; automation idsettings.import.hardwareDecoding;prefs.set; i18n rows in all four catalogs). Through a newFootageSource::set_hardware_decodingit flipsfilmcraft_codecs::hw::set_hardware_decoding. When the value changes, the media pool closes its open decoders, so footage that is already open follows the setting without a restart. Cached frames stay valid.videoDecoding) show the backend and its counters, e.g.NVDEC (on; 1200 frames decoded in hardware).HybridDecoder) and other codecs decode in software.render/src/lib.rsagainst #329: scrubbing a long movie: superseded viewer frames call off their decodes #784, is a union of trait methods, plus forwarding the two new methods inCancellableFootage, and is recorded. #794: open movies in place instead of reading them whole #796'sopen_reader/reader_openersexist at the new pin. On a local merge of all three, the media / render / engine / host tests pass (805), as do the new tests. The #329: scrubbing a long movie: superseded viewer frames call off their decodes #784 scrub harness with cancellation also works with hardware decoders: a drag (one far frame every 16 ms) has its last frame 161 ms after the request in software, 67 ms with NVDEC and 77 ms with VA-API, and nothing stale keeps decoding.Measurements
These are headless runs of a release build through EffectCraft's
MediaPooland FilmCraft's sources, on a Ryzen with 16 threads that other jobs were also loading. The fixtures are ffmpeg-madetestsrc2+ noise clips with long GOPs (250). "CPU" is process CPU time per decoded frame. "Jump" is the mean of 12 random seeks. The bench is not committed.Determinism
Over the first 60 frames of every fixture above, the hardware output was 60/60 frames bit-exact with the software decoder (max diff 0, PSNR ∞) for NVDEC and VA-API, H.264 and HEVC, 1080p and 2160p. That is expected: H.264 / HEVC decoding is exactly specified, and FilmCraft's hardware path reuses the software decoder's parsers and DPB. The only documented difference is concealment of leading pictures after a seek into an open GOP, which neither decoder reconstructs correctly. So final renders don't need to force software decoding for determinism, and this PR doesn't do it. FilmCraft has no per-source switch in its media API anyway:
make_video_decoderasks the process-wide registry. The CLI never registers hardware decoders, so headless renders stay software-only.Tests
apps/effectcraft/tests/hardware_decoding.rs(its own binary, because the switch is process-wide; the fixtures are ffmpeg-made and the test skips without ffmpeg):off_decodes_everything_in_software: with the setting off,register()runs (twice, harmlessly) and no frame comes from the hardware.codecs_the_hardware_does_not_take_stay_in_software: VP9 with the setting on uses no hardware and gives the same pixels as with it off.hardware_decode_smoke: skips when no hardware decoder is present. Otherwise the stream is taken by the hardware, all 48 frames are > 60 dB against software (they are exact here), and switching off closes the decoders so new frames come from software.Gates
cargo fmt --checkcargo clippy --workspace --all-targets -D warningscargo test --workspace --no-fail-fast: 2832 passed, 0 failed (25 ignored)cargo xtask layersokcargo xtask wasmok (32 crates)cargo xtask assetsokLinux only: the macOS and Windows paths compile inside FilmCraft's crate but were not built or run here.
Needs maintainer decision
2c5ba7a→4e2d0bc2). It is a large jump. Everything above passes, but you may prefer another revision or to bump it yourselves; the second commit rebases onto any revision that hasfilmcraft-platform.filmcraft-platformcontainsunsafefor VideoToolbox / Media Foundation / CUDA-NVDEC / libva (with// SAFETY:comments,unsafe_code = "deny"outside its FFI modules; FilmCraft ADR 0001). On Suggestion: optional Nvidia CUDA / NVENC fast lane #498, CUDA/NVENC was declined because of the pure-Rust / no-unsaferules. This PR keeps our own codeunsafe-free and links no SDK: libva and the NVIDIA driver aredlopened at run time and nothing is needed at build time. Still, the shipped binary would call the OS and GPU drivers' video APIs. If that isn't acceptable, the pin bump (commit 1) can land on its own.🤖 Generated with Claude Code