mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-24 10:10:05 -06:00
M-HW: NVENC on top of the shared hardware-encoding setting (#183); never-crash fixes
Merge origin/main into the NVENC branch. #183 already provides the HardwareEncoding enum, ExportSettings.hardware_encoding, the hardwareEncoding export param and the Export > Video > Hardware Encoding checkbox, so the duplicates from this branch are dropped and NVENC uses them. filmcraft-export is now an all-platform dependency of filmcraft-platform (VideoToolbox and NVENC both register encoders). Never-crash fixes in the NVENC backend: - submit() rejects a driver input pitch narrower than a row (and unlocks the buffer); fill_nv12 uses get_mut instead of slicing rows. - composition offsets use saturating math and i32::try_from; frame-rate, size and timestamp casts are checked; sizes above u16::MAX decline. - Annex B scanning and NAL type checks use get()/first(). - A failed nvEncOpenEncodeSessionEx that returns a handle destroys it. ffi.rs carries NVIDIA's MIT notice for nvEncodeAPI.h, listed in ATTRIBUTION.md under a new "Third-party source code" section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+16
-2
@@ -72,7 +72,7 @@ and `filmcraft-cli`.
|
||||
| `engine` | L4 | `Session`, command registry, undo history, media pool, jobs, interchange glue |
|
||||
| `ui-egui` | L5 | the egui frontend: docking, panels, timeline, monitors, playback, control-channel handlers |
|
||||
| `automation` | L5 | MCP server (`rmcp`, stdio), headless or bridged to the running app |
|
||||
| `platform` | L5 | OS media FFI only: hardware video decoding (VideoToolbox H.264 / HEVC on macOS; Media Foundation / Direct3D 11 H.264 / HEVC on Windows; a no-op elsewhere) behind `codecs::VideoDecoder`, with transparent fallback to our decoders; NVIDIA NVENC H.264 encoding behind the Export encoder registry (Windows). The one crate allowed `unsafe` ([ADR 0001](adr/0001-platform-ffi.md), [README](../crates/platform/README.md)) |
|
||||
| `platform` | L5 | OS media FFI only: hardware video decoding (VideoToolbox H.264 / HEVC on macOS; Media Foundation / Direct3D 11 H.264 / HEVC on Windows; a no-op elsewhere) behind `codecs::VideoDecoder`, with transparent fallback to our decoders, and hardware H.264 encoding (VideoToolbox, opt-in) and H.265 encoding (VideoToolbox, the only H.265 encoder; the format exists only where a hardware encoder does) and NVIDIA NVENC H.264 encoding (Windows, opt-in) behind `export::VideoEncoder`; H.264 declines to the built-in encoder for what the hardware does not take. The one crate allowed `unsafe` ([ADR 0001](adr/0001-platform-ffi.md), [README](../crates/platform/README.md)) |
|
||||
| `filmcraft` | L6 | desktop binary: eframe/wgpu window, cpal audio output, file dialogs, native macOS menu, TCP control server |
|
||||
| `filmcraft-cli` | L6 | headless CLI: `exec`, `run`, `inspect`, `describe`, `commands`, `import`, `export`, `render`, `probe`, `mcp`; `--bridge` targets the running app |
|
||||
| `filmcraft-web` | L6 | the browser app (wasm32): eframe web runner on WebGPU/WebGL2, Blob-backed services, OPFS recovery, WebAudio, WebCodecs, `window.filmcraft` API ([web.md](web.md)) |
|
||||
@@ -254,7 +254,8 @@ file ──► codecs (MP4/MOV, MKV, audio) demux + decode, GOP-aware see
|
||||
samples): the `avcC` / `hvcC` sample becomes Annex B, the MFT is given the process's Direct3D 11
|
||||
video device through an `IMFDXGIDeviceManager` so it decodes with DXVA, and its NV12 (8-bit) /
|
||||
P010 (10-bit) texture is read back through a staging texture (the one GPU to CPU copy) into
|
||||
planar `Yuv8` / `Yuv16`. H.264 Baseline / Main / High and HEVC Main / Main 10, 4:2:0, progressive;
|
||||
planar `Yuv8` / `Yuv16`. H.264 Baseline / Main / High, HEVC Main / Main 10, VP9 profiles 0 / 2 and AV1 main
|
||||
(8- and 10-bit), 4:2:0, progressive (VP9 / AV1 samples go in as they are, not as Annex B);
|
||||
everything else, and any stream the GPU's DXVA decoder does not list, is declined. A decoder that
|
||||
would hand back system-memory pictures (Microsoft's decoder MFTs do that when DXVA is not
|
||||
available) fails the stream, so the hybrid continues with our decoder and Windows' software
|
||||
@@ -295,6 +296,19 @@ file ──► codecs (MP4/MOV, MKV, audio) demux + decode, GOP-aware see
|
||||
and handed to the GPU as an image (a layer image keeps its clip's blend mode), so both paths
|
||||
give the same picture. Setting `FILMCRAFT_CPU_COMPOSITE=1`
|
||||
forces the CPU path in the desktop app.
|
||||
- **CPU compositor shortcuts.** The CPU compositor, which is what export runs, works on
|
||||
premultiplied linear `f32` images, 33 MB at 1080p, so what it does not allocate, convert or mix
|
||||
is time saved. Three shortcuts, each of which gives the general path's bits (compared bit for
|
||||
bit, with every blend mode, in `render/src/region_tests.rs`): the canvas stays unallocated
|
||||
until a layer needs it, and an opaque bottom layer (an 8-bit or 16-bit Y'CbCr frame without an
|
||||
alpha plane, opacity 100 %, Normal) simply becomes the canvas; a plain media frame with an alpha
|
||||
plane (a ProRes 4444 banner) is converted and mixed only inside the rectangle where its alpha is
|
||||
not zero (`VideoFrame::alpha_region`, `to_linear_f32_region`, `blend::composite_at`), the rest
|
||||
being transparent anyway; and working images are recycled through `filmcraft_frame::pool`
|
||||
(`take_f32_overwritten` / `recycle_f32`: the buffer comes back with its old contents, so there is
|
||||
no zero-fill) by the export pipeline once a frame is converted to 8 bits. A clip with effects,
|
||||
opacity masks, frame blending, colour management, or a picture that is not placed one to one on
|
||||
the output takes the general path.
|
||||
- **Frame scheduling.** `crates/ui-egui/src/frames.rs` runs a small pool of worker threads with
|
||||
prioritised jobs: the frame on screen first, then playback prefetch, then thumbnails. The UI never
|
||||
decodes. It shows the exact frame when it is ready and holds the nearest cached frame meanwhile.
|
||||
|
||||
Reference in New Issue
Block a user