ffcine
GPU video finishing in Rust. ffcine decodes camera footage, grades it (HDR tone mapping, camera LUTs, crop/scale, 3D LUTs, denoise, stabilization, user shaders) and encodes it with the frames kept in VRAM end to end: libav* (ffmpeg) for demux/decode/encode/mux on NVDEC/NVENC, libplacebo on Vulkan for the processing. Around that it renders whole timelines (OTIO, imported from DaVinci Resolve, Final Cut Pro, Kdenlive/Shotcut, CapCut or EDL) with a content-keyed segment cache (animated effect parameters take keyframes or ffmpeg-style expressions), mixes audio to EBU R128, and handles the jobs before and after the edit: card offload, clip catalog, triage with transcripts, chapters and stills.
It is a set of library crates (ffcine is the facade) with the ffcine CLI on top. Design:
docs/design.md.
Requirements
- Linux with an NVIDIA GPU and driver: CUDA, NVDEC/NVENC, Vulkan, and optical flow (NVOFA, Turing or newer) for stabilization and temporal denoise.
- ffmpeg 9 (libav*) built with CUDA, NVENC/NVDEC and Vulkan, and libplacebo >= 7.365 (API 375).
- Nix with flakes is the supported way to get all of the above: the flake pins libplacebo and builds a matching ffmpeg.
Ingest and catalog need no GPU and build on macOS too
(cargo install ffcine-cli --no-default-features).
Install
Or with the system libraries above installed: cargo install ffcine-cli.
ffcine doctor checks the GPU path (CUDA, Vulkan, NVENC, NVDEC, NVOF, the linked libav and
libplacebo) and exits non-zero if anything is missing.
Quickstart
grade defaults: bt.2390 tone mapping, perceptual gamut mapping, lanczos scaling in gamma light,
10-bit HEVC NVENC (p6, hq, qp=12, main10, p010le, GOP 24). --preview switches to
8-bit libx264; --hdr pq (or hlg) makes a BT.2020 HDR10 / HLG master instead.
Commands
probe, doctor |
inspect a clip; check the GPU path |
grade, batch, looks |
grade one shot, many shots on one warm pipeline, or compare looks |
stabilize, jitter |
optical-flow or gyro stabilization; measure residual jitter |
import, subs, title |
other editors' projects to an ffcine timeline; .ass subtitles as text clips; title sequences and end screens |
render, diff, comp |
render a timeline or a comp (video, still, text and nested-comp layers with keyframes, expressions, time remaps and libavfilter graphs) to a master with a segment cache; what changed between renders; check a comp, write out its template, or start one from the story template |
audio, sync, beats |
the timeline's audio mix (R128, buses, ducking); line up recorder WAVs; a song's tempo and beats |
ingest, catalog, fetch-luts, bake |
verified card offload; clip catalog with picture profiles; camera LUTs; camera LUT + LUT + look baked to one .cube |
triage, search, snap |
index a card (strips, scene cuts, transcripts); find words; snap cuts to words |
breakdown |
shot list of a reference video: cuts, keyframes, camera motion, beat, colour, speech, contact sheet |
chapters, tag, credits, still, publish |
YouTube chapters, chapters and cover art in the MP4, music credits, stills, upload to Immich |
ffcine <command> --help has every flag with its default, examples and the docs page to read
next (-h is the brief form); docs/ has one page per area.
skills/ has agent skills: shot-breakdown turns a
TikTok, reel or YouTube link into a shot list to recreate it.
Rust library quickstart
For timeline manipulation, LUT parsing, and pipeline construction without native libraries, disable the default GPU features:
[]
= { = "0.4", = false }
use ;
let rate: Rational = "24000/1001".parse?;
assert_eq!;
let pipeline = new;
assert!;
let timeline = new;
let json = timeline.to_json?;
assert_eq!;
# Ok::
This constructs values and serializes JSON; it does not open media or use a GPU. To run a render, enable default features and install the native requirements above:
#
#
The API reference describes the portable API; docs.rs
builds without default features because its builders lack the matching native
libraries. Generate the complete backend docs locally with
nix develop --command cargo doc --workspace --no-deps --open.
See CONTRIBUTING.md
for checks, examples, native dependencies, and release instructions.
Workspace packages
All crates share a version. The published release may lag behind master;
use the Git repository when you need changes that have not reached crates.io.
| Crate | crates.io | rustdoc |
|---|---|---|
ffcine |
package | API docs |
ffcine-assembly |
package | API docs |
ffcine-audio |
package | API docs |
ffcine-breakdown |
package | API docs |
ffcine-cli |
package | API docs |
ffcine-comp |
package | API docs |
ffcine-core |
package | API docs |
ffcine-delivery |
package | API docs |
ffcine-filters |
package | API docs |
ffcine-hooks |
package | API docs |
ffcine-import |
package | API docs |
ffcine-ingest |
package | API docs |
ffcine-reframe |
package | API docs |
ffcine-render |
package | API docs |
ffcine-stabilize |
package | API docs |
ffcine-text |
package | API docs |
ffcine-timeline |
package | API docs |
ffcine-triage |
package | API docs |
ffcine-libplacebo-sys |
package | API docs |
Development
&& &&
Tests that need a GPU skip themselves when there is none, so cargo nextest run passes on CI runners.
Security
Report vulnerabilities privately using the instructions in SECURITY.md. Use GitHub Issues for other bugs and feature requests, with the command, native library versions, and a minimal example.
License
ffcine is licensed under the Apache License, Version 2.0.
No binaries are distributed; build from source. A built ffcine links ffmpeg, so its licence
terms follow the ffmpeg you link: the flake's ffmpeg is configured with --enable-gpl --enable-version3 (GPL-3.0). If you build ffmpeg with --enable-nonfree (e.g. for libnpp or
libfdk-aac), the result can't be redistributed at all. NVENC/NVDEC, CUDA and optical flow come
from the proprietary NVIDIA driver at run time and are not part of ffcine.