Context
The native Rust rewrite (RFC 0001) requires a decode/encode binding for the render engine. This decision must be made before any Epic 1 (Native Render Engine) issues are written — the binding choice determines every subsequent API call in the compositor. Deciding mid-epic would force a rewrite of already-written code.
This spike runs in the current repo under spike/rust-decode-spike/ on its own branch. The findings port to the new repo; the spike code does not.
Question to answer
Is a native FFmpeg Rust binding or gstreamer-rs the better foundation for the render engine on the target hardware matrix?
FFmpeg candidate: test ffmpeg-the-third as the primary candidate, not ffmpeg-next. Per community discussion (source), ffmpeg-next is now maintenance-only (upstream compat patches, no meaningful feature work), while ffmpeg-the-third is the actively-developed fork of the same lineage. If ffmpeg-the-third fails the evaluation criteria below, fall back to testing ffmpeg-next or ac-ffmpeg (smaller community, more actively maintained per the same thread) before ruling out the FFmpeg-binding approach entirely.
Target hardware:
- Mac M2 (VideoToolbox)
- Mac M3 (VideoToolbox)
- Windows x64 with NVIDIA GPU (NVENC/NVDEC)
Evaluation criteria
For each candidate binding, test and document:
- Hardware codec access — can it reach VideoToolbox on Mac and NVENC/NVDEC on Windows without extra shims or a non-Rust native layer?
- Seek/decode accuracy — frame-accurate seek to an arbitrary timestamp on a real
.mp4 fixture (required for jump-cut editing; off-by-one-frame seek is a disqualifier)
- Build complexity — does it cross-compile cleanly on all three target platforms? Are system dependencies (FFmpeg libs, GStreamer plugins) manageable in CI?
- Crate maturity — update frequency, known unsoundness issues, community size
- Redistribution/licensing risk (gstreamer-rs only) — do the codec paths needed (H.264/HEVC decode via VideoToolbox/NVDEC) require any GStreamer plugin that bundles proprietary or non-permissively-licensed codec code? Document any constraint that would affect distributing the compiled app.
Spike scope
Write the minimum Rust code needed to answer the criteria above — not a working compositor, just enough to test the decision surface:
Considered and deferred
- Shelling out to the FFmpeg CLI instead of binding to it (e.g. via
ffmpeg-sidecar) was raised repeatedly in the source discussion as a lower-risk alternative to fighting binding maturity issues. Deferred for this spike: the render engine's jump-cut compositing needs frame-accurate, in-process seek/decode that subprocess piping can't cleanly provide. Worth one line in FINDINGS.md noting this was considered, in case both binding candidates prove too fragile and this needs revisiting.
Output
A findings doc committed to the spike branch at spike/rust-decode-spike/FINDINGS.md containing:
- Which binding is recommended and why
- The test results for each evaluation criterion on each platform tested
- Any caveats or open questions for the Epic 1 implementation
- The chosen binding becomes the
encoderProfile design decision that Epic 1 is built against
Acceptance criteria
Related
Context
The native Rust rewrite (RFC 0001) requires a decode/encode binding for the render engine. This decision must be made before any Epic 1 (Native Render Engine) issues are written — the binding choice determines every subsequent API call in the compositor. Deciding mid-epic would force a rewrite of already-written code.
This spike runs in the current repo under
spike/rust-decode-spike/on its own branch. The findings port to the new repo; the spike code does not.Question to answer
Is a native FFmpeg Rust binding or
gstreamer-rsthe better foundation for the render engine on the target hardware matrix?FFmpeg candidate: test
ffmpeg-the-thirdas the primary candidate, notffmpeg-next. Per community discussion (source),ffmpeg-nextis now maintenance-only (upstream compat patches, no meaningful feature work), whileffmpeg-the-thirdis the actively-developed fork of the same lineage. Ifffmpeg-the-thirdfails the evaluation criteria below, fall back to testingffmpeg-nextorac-ffmpeg(smaller community, more actively maintained per the same thread) before ruling out the FFmpeg-binding approach entirely.Target hardware:
Evaluation criteria
For each candidate binding, test and document:
.mp4fixture (required for jump-cut editing; off-by-one-frame seek is a disqualifier)Spike scope
Write the minimum Rust code needed to answer the criteria above — not a working compositor, just enough to test the decision surface:
.mp4file using each candidateffprobe/ffmpegCLI)Considered and deferred
ffmpeg-sidecar) was raised repeatedly in the source discussion as a lower-risk alternative to fighting binding maturity issues. Deferred for this spike: the render engine's jump-cut compositing needs frame-accurate, in-process seek/decode that subprocess piping can't cleanly provide. Worth one line inFINDINGS.mdnoting this was considered, in case both binding candidates prove too fragile and this needs revisiting.Output
A findings doc committed to the spike branch at
spike/rust-decode-spike/FINDINGS.mdcontaining:encoderProfiledesign decision that Epic 1 is built againstAcceptance criteria
spike/rust-decode-spike/FINDINGS.mdexists and addresses all five evaluation criteria.mp4episode fixture on MacRelated