Commit Graph

101 Commits

Author SHA1 Message Date
Brandon Thomas 234b3454ef Export: as_chunks in the float-audio oracle test (clippy manual_chunks)
Follow-up to #1245.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 00:07:17 -04:00
Claude 6c13dda2bf
export: 32-bit integer and 32-bit float audio; Sample Size lists every size and greys out the unsupported ones
- AudioSettings gains `float`; `bits` takes 16, 24 or 32. `SampleFormat` (Int16 / Int24 /
  Int32 / Float32) and `ExportSettings::supports_sample_format` decide what each codec and
  container stores: WAV, AIFF and QuickTime PCM all four, MXF integers, FLAC integers.
  `validate` refuses float without 32 bits and float in FLAC or MXF.
- WAV float is WAVE_FORMAT_IEEE_FLOAT (EXTENSIBLE for more than two channels) with a `fact`
  chunk; AIFF float is AIFF-C `fl32`; QuickTime float is `lpcm` with the float flag; MXF writes
  32-bit integers. Float keeps the mix as it is, peaks above 0 dBFS included; 16 and 24 bit
  write the same bytes as before.
- FLAC encoder: 8-32 bits. 32-bit stereo is coded independently (a side channel would need 33
  bits), the sample range check no longer overflows, and 32-bit frames point at STREAMINFO for
  the size, which symphonia 0.5 (FilmCraft's own FLAC import) and ffmpeg both read.
- Export mode: Sample Size shows 16 bit, 24 bit, 32 bit and 32 bit float like Audio Format
  does, greying out what the format cannot store with the reason on hover; a size that stops
  being available (float after switching to FLAC) becomes 32-bit integer. es, fr, pt-br, id,
  ja and zh-cn strings.
- Tests: writer layouts and ffprobe codecs for every new format, round trips through ffmpeg
  and FilmCraft's own readers in WAV, AIFF, MOV, MXF and FLAC, headroom of a +6 dB tone,
  refused combinations, full-scale 32-bit FLAC through ffmpeg (MD5 too) and symphonia, and a
  UI test of the selector.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015nzevSsTNZxHPpUngfGTAw
2026-10-12 05:42:44 +00:00
Brandon Thomas 71ceebe857 Merge main into #879 (export schema next to FLAC, catalogs, parity table)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 22:01:41 -04:00
Brandon Thomas 8ec1a36b9f Merge pull request #613 from JordyUSA/feat/flac-export
Export: FLAC (clean-room encoder; .flac files and FLAC audio in MP4/MOV)
2026-10-11 21:02:50 -04:00
Brandon Thomas 383fafea8e export: rustfmt settings tests after merging #1113
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 20:56:58 -04:00
Brandon Thomas 1b42e5b2f9 Merge pull request #957 from Ni-zav/fix/908-tiff-size-estimate-s20261011T0357Z-b83c
fix(export): estimate TIFF sequence size using the actual channel count
2026-10-11 20:34:35 -04:00
Brandon Thomas 5f922d8abe Merge pull request #872 from vangel76/fix-854-gif-frame-delays
#854: GIF frame delays add up to the sequence duration
2026-10-11 20:32:43 -04:00
JordyUSA 773e1a3c72 Merge origin/main into feat/flac-export
Keep FLAC beside main's new AAC Audio format (21 formats, both audio-only
presets), use is_mp4_with / is_mp4_video in audio_codec() and the Audio
Format picker so MP4 (incl. AV1) offers AAC or FLAC, and add flacLevel to
main's export.media params.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:32:13 +07:00
Nigel Ihza Firdausy 8859e98fb7 export: estimate RGB TIFF sequence size from written channels 2026-10-11 11:09:25 +07:00
Earl Co 5d7dc800a8 M7: correct export loudness after peak limiting
Bound post-limiter loudness correction and cover high-crest signals, infeasible targets, cancellation, and output alignment. Focused tests and lint pass; full workspace validation pending for draft review.
2026-10-11 06:09:02 +02:00
vangel76 d066f82e26 #874: compressed (RLE / ZIPS / ZIP) OpenEXR export
Problem: OpenEXR sequences (#806) were written uncompressed only, because the
workspace had no deflate encoder; the files are 2-4x larger than necessary and
Premiere offers an EXR compression choice.

Fix: a small clean-room DEFLATE (RFC 1951) encoder in a zlib (RFC 1950)
wrapper in filmcraft-export (greedy LZ77 with bounded hash chains; stored,
fixed or dynamic Huffman per block, whichever is smallest; length-limited
codes). The EXR writer gains RLE, ZIPS (1 line) and ZIP (16 lines) chunks with
the format's byte interleave + delta predictor; chunks that do not shrink are
stored raw. New ExportSettings::exr_compression (default None, as before),
`exrCompression` param on file.exportMedia, Compression combo in Export mode
(es/fr/ja/zh-cn strings).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 02:46:53 +02:00
vangel76 7625ddf4de #854: GIF frame delays add up to the sequence duration
Problem: the GIF exporter gave every frame the same delay of
1000·den/num ms, which the encoder truncates to whole centiseconds.
At 24 fps each 41.67 ms frame became 4 cs, so a 4.0 s sequence played
in 3.84 s (4 % fast); other non-integer rates drifted the same way.

Fix: each frame's delay now runs from its rounded start time to the
next frame's (gif_delay_cs), so delays alternate (4, 4, 5, 4, 4, 4 cs
at 24 fps) and add up to the exact duration. Checked i128 math also
replaces the unchecked `(1000 * den) as u32` cast.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 02:22:09 +02:00
vangel76 f8f16b6eca Merge remote-tracking branch 'upstream/main' into gap-aac-audio
# Conflicts:
#	crates/engine/src/commands.rs
#	docs/gaps.md
2026-10-11 01:09:25 +02:00
Brandon Thomas f114b5f10c Revert #783 (Linux H.265 through NVENC): intermittent heap corruption in the CLI
With NVENC registered on Linux, `filmcraft-cli --test cli` aborts in 2 of 45 runs on an RTX 3090
(`malloc(): mismatching next->prev_size`, `malloc(): unaligned fastbin chunk detected`) right
after an export finishes; 0 of 30 runs fail with this reverted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:01:15 -04:00
vangel76 b9f60842bb #814: AAC Audio export (audio-only .m4a, or ADTS .aac)
Problem: Premiere's "AAC Audio" format has no FilmCraft equivalent. AAC
was only written inside H.264 / H.265 / AV1 movies; the only audio-only
exports were Waveform Audio and AIFF.

Fix: a new `aac` export format ("AAC Audio") that encodes the sequence
mix with the existing AAC-LC encoder into an MPEG-4 audio file (.m4a,
encoder delay in an edit list), or a raw ADTS stream when the path ends
in .aac. Bitrate, sample rate, channels and loudness normalisation follow
the audio settings. Adds an "AAC Audio 48 kHz 320 kbps" Audio Only
preset, CLI extension guessing (.m4a / .aac), es/fr/ja/zh-cn strings, and
updates G13 (also noting ProRes 4444 / XQ is already in the export UI).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:56:35 +02:00
vangel76 fb5863bc8a #806: export OpenEXR image sequences
Problem: Premiere offers OpenEXR as an image-sequence export format;
FilmCraft could not write EXR at all (docs/gaps.md G13).

Fix: a new export format (id exr, "OpenEXR") writing numbered .exr stills,
with a preset, the Include Alpha Channel option, the file.exportMedia format
list and es/ja/zh-cn strings. The writer in crates/export/src/raster.rs
follows the public OpenEXR file layout: version 2 single-part scan-line
file, half-float B/G/R(/A) channels, no compression, one scan line per
chunk, Rec.709 chromaticities; values are scene-linear (the pipeline's
transfer undone) with premultiplied alpha, as EXR defines. No new
dependency. ZIP / PIZ / DWA compression stays open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:34:28 +02:00
Brandon Thomas 257d7af4ab
Merge pull request #791 from vangel76/gap-image-sequences
#779: export JPEG, Targa and DPX image sequences
2026-10-10 18:09:10 -04:00
vangel76 c673ee85b9 #779: export JPEG, Targa and DPX image sequences
Problem: Premiere offers JPEG, Targa and DPX as image-sequence export
formats; FilmCraft only wrote PNG, TIFF and BMP sequences (docs/gaps.md G13).

Fix: three new export formats (ids jpg, tga, dpx), numbered like the other
sequences, with presets, the export UI (JPEG quality slider, Targa alpha)
and es/ja/zh-cn strings. JPEG uses the image crate at the export quality;
Targa (TGA 2.0, uncompressed 24/32-bit) and DPX (SMPTE ST 268, 10-bit RGB
method A, BT.709) are written by a small hostile-input-safe writer in
crates/export/src/raster.rs. Format::is_image_sequence replaces the
hand-kept format lists. OpenEXR stays open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:51:41 +02:00
Brandon Thomas 662d9d07b1
Merge pull request #783 from SilentYeti/nvenc-hevc-linux
Linux: H.265 export through NVENC
2026-10-10 17:49:22 -04:00
SilentYeti c635d9af9e Linux: H.265 export through NVENC
The NVENC HEVC encoder (Main 8-bit SDR and Main 10 HDR PQ / HLG) was gated to
Windows. It now also runs on 64-bit Linux, on the CUDA device the H.264 encoder
already uses: the H.265 format and HDR probes are registered there and the
HEVC tests run on both systems.

NVENC registration on Linux now happens after the VA-API probe. Started beside
it, the background HEVC probe's first cuInit could deadlock with
libva-nvidia-driver, which calls cuInit from its library constructor under the
loader lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:41:04 -07:00
Brandon Thomas 36cc163b44 Merge origin/main into #739: keep #600's CRF validation, and AV1 (hardware, like H.265) has no CRF mode either
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 17:15:40 -04:00
Brandon Thomas 74963e0e7e
Merge pull request #760 from maccagnit/gpu-export-cpu-frames
GPU export: a frame planned as one CPU image skips the renderer pool (Auto was slower than Off)
2026-10-10 17:01:07 -04:00
Tommaso Maccagni 13d8e73e8e export: a frame planned as one CPU image does not take a pooled GPU renderer
With GPU rendering on, a frame the planner hands back whole (an adjustment
layer, a complex transition, an HDR / wide-gamut sequence) was still rendered
by render_sequence, but inside RendererPool::with: as many frames at a time as
there are pooled renderers (2 to 4) instead of one per export thread. A
timeline graded on an adjustment layer exported slower with Auto than with Off.

Pipeline::frame asks the planner first (plan::is_cpu_frame, the test
plan_frame itself makes) and renders such a frame on the CPU directly. It
counts as a fallback now, not as a GPU frame. The picture does not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:40:37 +02:00
vangel76 95a9a7770a Merge upstream/main into fix-342-prores-4444-export
# Conflicts:
#	crates/engine/src/commands.rs
2026-10-10 21:27:52 +02:00
Brandon Thomas 794a25fc9e
Merge pull request #658 from vbasky/fix/current-bugs
Fix silent WAV sample-rate substitution
2026-10-10 14:57:13 -04:00
Brandon Thomas 97c39725cb
Merge pull request #606 from JordyUSA/fix/pcm-large-files
Export: never crash on WAV/AIFF over 4 GiB; stream PCM to disk
2026-10-10 14:52:50 -04:00
Manuel Camacho 7f4bf2157b HW6: AV1 export format, enabled where a hardware encoder registers one (#30)
Format::Av1 in export settings and jobs, SampleEntry::av1 (av01 + av1C) in
isobmff, and the Export panel's Format list, profile and encoder rows. No
encoder ships here: like H.265, AV1 is listed greyed out until a platform
encoder registers a probe, and a job without one fails with "AV1 encoder not
available yet". Split out of #409; the VA-API AV1 encoder follows on main's
vaapi::va design.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 10:46:43 -07:00
vangel76 4b67c44dbe #342: ProRes 4444 and 4444 XQ export, with alpha
Problem: the ProRes encoder already codes 4444 / 4444 XQ (optionally
with alpha), but export only knew the four 422 flavours: any other
proresProfile fell back to HQ and the encoder was always fed a 4:2:2
frame, so graphics could not round-trip with their alpha.

Fix: proresProfile accepts 4444 and 4444xq. The ProRes export encoder
builds a 4:4:4 frame for them and, with Include Alpha Channel, codes
the straight alpha of the unflattened picture (ExportSettings::
supports_alpha / keeps_alpha). Export Settings offers both profiles and
the alpha checkbox for them; new presets Apple ProRes 4444, 4444 with
Alpha and 4444 XQ; summary text and the MXF coding label name the
profile (and the MXF descriptor keeps its 12-bit 4:4:4 depth).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:12:54 +02:00
Vikram Bhaskaran 170852d8db
#533: Preserve explicit export sample rates to avoid silent substitution. 2026-10-11 02:00:58 +11:00
JordyUSA 8ea94a8541 Merge main into feat/flac-export
No conflicts. main's new Chinese catalog requires every tl! string:
added zh-CN for the FLAC labels (format, preset, Audio Format entry,
Compression Level and its hint).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:53:52 +07:00
JordyUSA 360183e273 Merge main into feat/export-crf
Conflict in crates/engine/src/export_tools.rs: both sides added an
import (BitrateMode for CRF, GpuRendering from main); both kept.
main's new Chinese catalog requires every tl! string: added zh-CN for
"Quality (CRF)" and "CRF (constant quality)".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:45:31 +07:00
JordyUSA 055e95ab17 Export: FLAC (clean-room encoder; .flac files and FLAC audio in MP4/MOV)
New L0 crate filmcraft-flac, a FLAC encoder written from RFC 9639:
constant / verbatim / fixed / LPC subframes (Levinson-Durbin on Tukey-
windowed autocorrelation, up to order 12), partitioned Rice residuals,
left/side, side/right and mid/side stereo, CRC-8/CRC-16, STREAMINFO with
MD5 (RFC 1321, own implementation), levels 0-8, all lossless.

Export:
- Format::Flac, an audio-only .flac (16/24-bit), streamed one second at
  a time like WAV/AIFF; STREAMINFO is rewritten at the end with frame
  sizes, total samples and MD5. Preset "FLAC 48 kHz 24-bit".
- AudioCodec::Flac in MP4 and QuickTime (fLaC + dfLa), one frame per
  sample with the short last frame timed exactly; the dfLa STREAMINFO
  is replaced before the moov is written (Mp4Writer::set_sample_entry).
  MXF stays PCM.
- AudioSettings::flac_level (default 5); Export panel: FLAC (lossless)
  audio format and Compression Level; file.exportMedia `format: "flac"`,
  `audioCodec`, `flacLevel`. Spanish and Japanese strings.

ffmpeg oracle: every stream decodes bit-exactly with the STREAMINFO MD5
equal to ffmpeg's hash; .flac and FLAC-in-MP4/MOV exports decode to the
same samples as a WAV export of the range.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:26:28 +07:00
Brandon Thomas 4304cd9382 Merge origin/main into #421; GPU export opt-in, wgpu error handler, drop panicked renderers
- GpuRendering defaults to Off (opt-in per export) until measured on Windows and macOS;
  docs and ROADMAP say so.
- The shared export device installs an uncaptured-error handler and a device-lost callback
  that log once and retire GPU export for the session (frames go to the CPU) instead of
  wgpu's default panic.
- RendererPool drops a renderer that panicked and retires the pool, so the rest of the
  export renders on the CPU (regression test in gpu_hook_scenarios); the duplicate
  hostile-size test that raced on the global registry is folded into it.
- Rebased onto main's render_plan/transitions: render_export_prepared reads the linear
  accumulator after render_plan; transition (Composite) plans fall back to the CPU.
- es/ja rows for the new Export strings; web_time::Instant in the export pipeline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:21:38 -04:00
JordyUSA 2e21c44904 Export: never crash on WAV/AIFF over 4 GiB; stream PCM to disk
WAV and AIFF sizes were 32-bit with unchecked arithmetic: past 4 GiB
(24-bit 5.1 at 96 kHz after about 41 minutes) a debug build panicked
and a release build wrote a wrapped, corrupt header. The whole file was
also built in memory first.

- WAV past 4 GiB is written as RF64 (EBU Tech 3306) with a ds64 chunk;
  smaller files stay plain RIFF.
- AIFF has no 64-bit form: a longer one is refused before anything is
  written, naming WAV instead.
- The header is written from the known length, then the samples one
  second at a time, so memory stays flat; progress advances per second.
- Odd-sized data chunks get their pad byte; hostile lengths, channel
  counts and sample rates are errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 17:31:36 +07:00
JordyUSA 3a46156861 Export: CRF (constant quality) bitrate encoding for H.264
Adds BitrateMode::Crf with ExportSettings::crf (0-51, default 23) and
maps it to the built-in encoder's RateControl::Crf, which export never
used. The Export panel offers "CRF (constant quality)" with a Quality
(CRF) slider in place of the bitrate fields; file.exportMedia takes
`crf` and `bitrateMode: "crf"`. H.265 (hardware only) rejects it, and
VideoToolbox / NVENC decline it so the built-in encoder runs. Settings
saved before this read as CRF 23.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 17:09:05 +07:00
Brandon Thomas b32d1cd5ed Merge remote-tracking branch 'origin/main' into fix-361 2026-10-09 10:17:58 -04:00
Brandon Thomas 5f4e2d7c99 Merge remote-tracking branch 'origin/main' into fix-353
# Conflicts:
#	crates/engine/src/keyboard.rs
#	crates/engine/src/lib.rs
#	crates/ui-egui/src/panels/monitor.rs
2026-10-09 10:11:15 -04:00
Brandon Thomas 285e81b5da Merge origin/main into m8/export-stage-timings
NVENC export: keep main's Main 10 / Main dispatch and time both colour
conversions (rgbf_to_yuv420_10, rgba_to_yuv420_8) as Stage::Convert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:08:35 -04:00
Brandon Thomas 701d7c7111 Merge origin/main into multi-stream audio
Keeps #359's contiguous_starts audio timing, now per stream in Mp4Audio /
MkvAudio (starts and preroll in source sample frames). MP4 audio streams and
their decoders are built from the same (track, info) pairs so they stay
index-aligned. Adapts new main code to audio_streams / TrackItem::audio_stream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:08:09 -04:00
Brandon Thomas 95230b9072
Merge pull request #360 from SaymonMaster14/m3/nvenc-hevc-main10
Windows: NVENC H.265 Main 10 HDR (PQ / HLG) export
2026-10-09 10:05:10 -04:00
Brandon Thomas c9e2bfcac0 Merge origin/main into m3/nvenc-hevc-main10
Export panel: the HEVC profile labels go through tl! with Spanish entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:04:58 -04:00
Brandon Thomas afd5a6b347 M3: NVENC Main 10 review fixes: saturating plane sizes, as_chunks for clippy
encode / encode_10 compute the plane sizes they check with saturating_mul;
fill_p010, rgbf_to_yuv420_10 and the HDR export test use as_chunks instead of
chunks_exact with a constant size (clippy::chunks_exact_to_as_chunks).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:01:08 -04:00
Brandon Thomas efa89a7d2d Merge remote-tracking branch 'origin/main' into fix-337
# Conflicts:
#	crates/gpu/src/fx_tests.rs
2026-10-09 09:59:26 -04:00
Brandon Thomas 79a3b623fe Pool trim: free only the float shelf, and only after a standalone export
pool::trim() from Pipeline::drop flushed the whole process-wide pool after every
render-preview segment and proxy, and threw away playback's U8/U16 planes too.
Now Pipeline::drop calls pool::trim_f32() only when !settings.part_of_batch.
PoolStats gains f32_idle_bytes so the tests can check the float shelf alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:55:47 -04:00
Brandon Thomas 6ebc21f093 Merge remote-tracking branch 'origin/main' into fix-360
# Conflicts:
#	README.md
#	ROADMAP.md
#	crates/platform/README.md
2026-10-09 09:46:48 -04:00
Brandon Thomas 97a8eaffec Merge remote-tracking branch 'origin/main' into fix-299
# Conflicts:
#	docs/control-protocol.md
2026-10-09 09:45:27 -04:00
Manuel Camacho 7b73c8e887 GPU3d: GPU export rendering is Auto by default (#30)
Merlin's effects-heavy bench scene (GPU3c) settles it: with layers and
effects the GPU compositor exports 2.4x faster at 1080p (13.0 -> 5.0-5.6 s,
737 -> 238 CPU ms/frame) and 3.2x at 4K (38.7-39.3 -> 12.0 s, 2955 -> 775
CPU ms/frame); a single plain clip takes the same time either way
(decoding / encoding bound). Every Auto row rendered all its frames on the
GPU, without fallbacks. The CPU reference renderer stays the fallback for
anything the GPU stage does not run.

Trade-off: the GPU matches the CPU within the compositor's parity
tolerance, not bit for bit, so an export's bytes can depend on the
machine's GPU; Off keeps them byte-reproducible (the determinism tests
register no GPU renderer and are unaffected).

- settings: GpuRendering::Auto is the #[default]; ExportSettings::default.
- test: the default, settings saved without the field, and "off".
- docs/performance.md: GPU3 results (1080p and 4K).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 06:31:57 -07:00
Manuel Camacho 91056340ba GPU3b: pooled GPU export renderers, one-submission read-back (#30)
GPU export rendering was ~20 % slower in wall-clock time than CPU
rendering: one renderer behind a mutex made the export workers queue.

- Export workers share a pool of up to four renderers on one wgpu device
  (one per worker was no faster: the read-back then contends for memory
  bandwidth).
- render_export_prepared composites into the linear accumulator and
  copies it to a reused staging buffer in one submission (no sRGB resolve
  pass); read_accumulator shares the read-back, which now returns None
  instead of stale pooled values when a row is missing.
- f16_to_f32_fast: same result as f16_to_f32 for all 65536 inputs (test).
- Timing counters (export::export_lock_wait, gpu::export_renderer::timing)
  printed by the export bench.

RX 7900, same build, Off / Auto / Off: H.264 + AAC 4.67 / 4.71 / 4.76 s,
ProRes 422 4.20 / 4.21 / 4.21 s; CPU per frame 287-292 -> 277 (H.264),
316-317 -> 300 (ProRes). Was 4.86 -> 5.78 s. Parity, not faster: on this
single-clip scene decoding and encoding dominate (rendering is ~15 of
~290 CPU ms per frame), so GPU rendering stays Off by default.

Gates: fmt, clippy (gpu, export, ui-egui), layers, assets; gpu
export_pipeline, golden and export tests pass. Pre-existing on the
previous commit: fx_tests::gpu_effects_match_cpu_exactly fails on this
AMD GPU, and the gpu unit tests segfault in the driver when run in
parallel (pass serially apart from that test).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 06:18:17 -07:00
Manuel Camacho ba403212f6 GPU3: GPU export rendering off by default until it is faster (#30)
Set GpuRendering default to Off in ExportSettings so exports use the CPU
reference renderer by default until GPU export achieves lower wall-clock time.

🤖 Written by agy (Antigravity Agent, Gemini 3.8 Flash)
2026-10-09 06:18:17 -07:00
Manuel Camacho 2b0f263418 GPU3: render exports on the GPU compositor (#30)
Add off-screen GPU export renderer (filmcraft-gpu::ExportRenderer) reading back
the linear float accumulator as premultiplied RGBA f32, plug it into the
export pipeline via FrameRenderer hook and GpuRendering setting, register
in desktop app and CLI, and record export.gpu_frames statistics.

🤖 Completed by agy (Antigravity Agent, Gemini 3.8 Flash) based on draft by Merlin
2026-10-09 06:18:17 -07:00