Commit Graph
35 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 fafd82b6ec Crash and blank-screen fixes (desktop + web)
Desktop/shared:
- Frame workers catch panics per job: a failing decode/render no longer kills the worker
  or leaves its frame in flight forever (blank monitors). Counted as perf.stats failedJobs.
- UI pass catches panics and shows a "FilmCraft hit an error" window (Save Project /
  Continue) instead of closing the app.
- Panic hook writes <data dir>/Logs/crash-<day>.log with thread, location and backtrace;
  a window that can't start shows an error dialog instead of exiting silently.
- GPU compositor only on adapters that render/blend Rgba16Float with >= 4096 textures;
  GPU validation errors and oversize frames switch to the CPU compositor instead of
  wgpu's default panic.
- Dock layout and Media Browser splitter no longer panic on tiny panels/windows.

Web:
- Export mode / previews / voice-over / log reveal no longer call std::env::temp_dir
  (panics on wasm32): new filmcraft_engine::temp_dir(); default export dir /exports.
- Fatal-error overlay with Reload; WebGPU device failure retries on WebGL2 (?webgl);
  cache-busted wasm/glue URLs; webcodecs entries[0] guard.

Tests: robustness_ui (worker survives injected panics, UI panic recovery, tiny windows),
crash hook, dock split, GPU plan size, default export dir; web smoke test extended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 00:26:19 -04:00
Brandon Thomas 81873deedb Merge branch 'main' into worktree-agent-a861ca53f77717930
# Conflicts:
#	Cargo.toml
#	docs/architecture.md
#	xtask/src/main.rs
2026-10-03 08:55:10 -04:00
Brandon ThomasandClaude Opus 5.5 263a39132f M9.15: READMEs for mpeg2v / mpegts / ac3 (specs, accuracy, benchmark); architecture and testing docs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:14:23 -04:00
Brandon ThomasandClaude Opus 5.5 2078cc0e22 M9.15: MPEG-2 in QuickTime (XDCAM/IMX/HDV), MP4 (mp4v) and Matroska (V_MPEG2); MP2 in Matroska; fixture generators
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:59:54 -04:00
Brandon ThomasandClaude Opus 5.5 02a7039ac5 M11.4: filmcraft-cfb, a Compound File Binary ([MS-CFB]) reader and writer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:51:18 -04:00
Brandon ThomasandClaude Opus 5.5 2cbf91dded M9.15: MPEG-1/2 video decoder crate (frame/field pictures, 4:2:2, IEEE 1180 IDCT) with ffmpeg oracle tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 02:43:29 -04:00
Brandon ThomasandClaude Opus 5.5 efa8167962 M9.14: MXF (OP1a/OP-Atom) and Ogg demuxers, image sequences, BWF timecode
- crates/mxf (L0): KLV walk, partitions, primer, header metadata, index tables, material ->
  file package resolution, AVC/VC-3/ProRes/MPEG-2 identification, PCM/AES3 (ST 331) sound,
  timecode; OP1a and OP-Atom (clip wrapping).
- crates/ogg (L0): RFC 3533 pages/CRC/packets, RFC 7845 Opus timing (granules, pre-skip, end trim).
- codecs: MxfSource (GOP cache, POC ordering for AVC without temporal offsets, MPEG-2 reported
  unsupported), OggSource (Opus with pre-roll seeking, Vorbis), Annex B H.264 decoder.
- media: image sequences (numbered stills, missing frames held, frame cache); BWF bext/iXML
  TimeReference -> start timecode.
- engine/UI: file.import {imageSequence}, auto-detect setting, file.importImageSequence,
  Media Browser "Import as Image Sequence"; CLI probe details for MXF/Ogg/BWF/sequences.
- Oracle tests vs ffmpeg for MXF, Ogg, image sequences, BWF; truncation/mutation tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 17:33:29 -04:00
Brandon Thomas f5aa00ff7d Merge branch 'main' into worktree-agent-aacf40607c4b686e0
# Conflicts:
#	xtask/src/main.rs
2026-10-02 13:01:34 -04:00
Brandon ThomasandClaude Opus 5.5 7058004ecf xtask: wire cargo xtask version (root() helper, run via $CARGO) so xtask builds again
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 12:12:29 -04:00
Brandon ThomasandClaude Opus 5.5 b809240d2f xtask/version.rs: rustfmt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 12:11:45 -04:00
Brandon ThomasandClaude Opus 4.8 f02eefba26 Signed release pipeline (macOS/Windows/Linux/Web); README community note
Ports photocraft's release workflow + packaging (signing, notarization,
MSI/DMG/deb/rpm/AppImage/web), adds `cargo xtask version`. File-type
associations omitted (route B); app keeps its own .desktop. Fresh WiX
UpgradeCode. README 'about' note updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-02 12:06:09 -04:00
Brandon ThomasandClaude Opus 5.5 4a931a3400 app icon: owl with ear tufts (owner's ArtCraft drawing), Dock/taskbar/launcher wiring, palette docs
- assets/app-icon/: canonical SVG + light SVG, 1024 PNG, macOS runtime PNG, .icns, .ico,
  hicolor theme, LICENSE.txt and README (palette, geometry, provenance, regeneration).
- packaging/icons.sh regenerates everything with resvg, iconutil and the new `cargo xtask ico`.
- Native app sets the window icon (with_icon) and the Wayland app id; build.rs embeds the .ico
  and VERSIONINFO into filmcraft.exe on Windows (winresource, Windows-host build-dep only).
- packaging/linux/ai.storyteller.filmcraft.desktop with Icon=ai.storyteller.filmcraft.
- Web app: favicon.svg replaced by favicon.png from the same artwork; sidecars and
  ATTRIBUTION.md updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:52:46 -04:00
Brandon ThomasandClaude Opus 5.5 457aca112e M4.8: benchmark suite (cargo xtask bench)
Decode fps per codec (H.264, HEVC, VP9, AV1, ProRes at 1080p/2160p),
Program-monitor playback and scrubbing through the real frame scheduler,
timeline UI frame time with a 1000-clip / 20-track sequence under
egui_kittest (+ wgpu render), export throughput (H.264 + AAC, ProRes),
project save/open of 5000 clips, and peak RSS per section (each section
runs in its own process under /usr/bin/time). Writes JSON and Markdown
to target/bench. bench_playback now shares its code (examples/bench/).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 08:54:54 -04:00
Brandon ThomasandClaude Opus 5.5 fc18a6962e M10.5: Text-based editing / transcripts
- crates/speech (L2): Transcriber trait, FixedTranscriber, Whisper model catalogue (pinned,
  SHA-256 verified) with optional downloader (feature `download`: ureq + rustls + RustCrypto),
  pure-Rust Whisper inference on candle with word timestamps (feature `whisper`), log-mel, VAD
  word tightening, MFCC speaker clustering. Both features off by default and for wasm.
- project: per-media-item transcripts (Project::transcripts); schema v9 with a no-op v8->v9
  migration and a v8 fixture.
- edit::transcript: sequence transcript derived from clip transcripts, search, paragraphs,
  word ranges, pause/filler detection, ripple delete of many ranges, caption layout.
- engine: transcript.* commands (generate, set, delete, inspect, search, select, extract, lift,
  renameSpeaker, removeFillers, removePauses, createCaptions, models, downloadModel);
  Session::transcriber for hosts/tests; features `whisper` / `speech-download` (also on the
  desktop and CLI apps). Without whisper, transcript.generate fails with a clear error.
- ui: Text panel Transcript tab (Transcribe button, speaker paragraphs of clickable words,
  Shift+click selection -> In/Out, extract/lift/remove fillers/create captions, search) with
  text.transcript.* automation ids; headless UI test.
- docs/transcripts.md, crates/speech/README.md, architecture and project-files updates.
  whisper-tiny measures 12.2% WER over 797 words on local samples.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:25:49 -04:00
Brandon ThomasandClaude Opus 5.5 5f613aff25 M13.2: FilmCraft web app (apps/filmcraft-web) with Blob media, OPFS recovery, WebAudio, WebCodecs
- eframe web runner on WebGPU (WebGL2 fallback; GPU compositor on WebGPU, CPU on WebGL2).
- fs: virtual file table of File/Blob handles, 1 MiB chunked async range reads with an
  LRU cache and read-ahead (pending + retry instead of blocking), downloads for written
  files, /opfs/ paths written to OPFS.
- import: File System Access picker / <input type=file>, drag-and-drop anywhere,
  container index prefetch (moov wherever it is), retried imports; project open/save.
- recovery: OPFS auto-save snapshot while dirty, media copies, reopened on next visit.
- audio: AudioWorklet output fed ahead from the UI thread; played-frame audio clock.
- webcodecs: H.264/HEVC/VP9/AV1 MP4/MOV decoded by the browser VideoDecoder via a
  reader opener (fallback to our decoders on any error), probed with isConfigSupported.
- api: window.filmcraft (execute/request/commands/screenshot/importFiles/importUrl/
  openProject/files/readFile/info).
- cargo xtask web [--dev] [--serve PORT] (wasm-bindgen CLI); xtask wasm also checks
  filmcraft-ui-egui and filmcraft-web; layer L6 for the web app.
- Original web icon (favicon.svg) with attribution sidecar; docs/web.md; headless-Chrome
  smoke test (tests/smoke.mjs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:52:35 -04:00
Brandon ThomasandClaude Opus 5.5 1813bbaca2 M9.7: AV1 headers, symbol decoder, CDFs, intra decoding, transforms, intra prediction
New L0 crate filmcraft-av1 from the AV1 Bitstream & Decoding Process
Specification v1.0.0 with Errata 1 (tables extracted from the spec's Markdown
source by tools/extract_tables.py).

Stages: OBU parsing, sequence and uncompressed frame headers (all fields),
reference state (set_frame_refs, load_previous, reference update,
show_existing_frame), symbol decoder with CDF adaptation and
init/load/save/frame-end CDF handling, tiles, intra frame mode info
(partitions, segment ids, delta q/lf, CDEF index, modes, angle deltas, CfL,
palette, filter intra, tx size), coefficient decoding, dequantisation,
inverse transforms (DCT 4-64, ADST, identity, WHT), intra prediction (all
modes, edge filter/upsampling, recursive filter, CfL, palette), LR syntax.

All-intra libsvtav1 streams with in-loop filters disabled decode bit-exactly
against libdav1d (8/10-bit, 128x128..1280x720, odd sizes, presets 2-8).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 11:00:03 -04:00
Brandon ThomasandClaude Opus 5.5 226c139741 M9.6: DNxHD/DNxHR (SMPTE ST 2019-1 VC-3) decoder and DNxHR encoder
New L0 crate filmcraft-dnx, written from SMPTE ST 2019-1:2016 + Amd 1:2023
(tables extracted from the standard's text by tools/extract_tables.py).

Decoder: every compression ID (DNxHD 1235-1260 incl. field-coded and
macroblock-adaptive interlace, thin rasters, RGB 4:4:4; DNxHR 1270-1274
LB/SQ/HQ/HQX/444), 8/10/12-bit, 4:2:0/4:2:2/4:4:4, DCT and lossless alpha,
macroblock rows in parallel. Matches ffmpeg within IDCT precision (max 2 LSB,
<=50 per million beyond 1, 87-99% identical) on 22 ffmpeg fixtures; follows
ffmpeg where it departs from the standard's text (reconstruction offset,
CID 1271 weights, 4:4:4 signalling) - documented in the README.

Encoder: DNxHR LB/SQ/HQ/HQX(10/12-bit)/444, CBR at the eq. 7.1 frame sizes,
uniform-qsf binary search + per-macroblock refinement; ffmpeg decodes every
profile with -xerror (HQ luma PSNR 58.8-66.3 dB).

Wiring: MOV AVdn/AVdh import (codec label from the CID), export
Format::DnxHr (MOV AVdh, dnxProfile lb|sq|hq|hqx) in the export dialog and
file.exportMedia.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 10:53:02 -04:00
Brandon ThomasandClaude Opus 5.5 4b83e088eb Merge main into the playback branch (mixer recordStart moves to the end of preroll; GopCache keeps main's random-access key walk-back)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 08:30:04 -04:00
Brandon Thomas 97967d865a Merge main into M10 (text engine + graphics)
# Conflicts:
#	ROADMAP.md
2026-10-01 01:57:41 -04:00
Brandon ThomasandClaude Opus 5.5 b141c406e9 M10.1: text engine (crates/text): font database with bundled OFL fonts and system-font discovery, harfrust shaping, bidi, line breaking, paragraph layout, glyph cache and rasteriser; captions and Timecode/Clip Name burn-ins use it
- New L1 crate filmcraft-text: fonts (bundled Inter Regular/Medium/SemiBold/Bold/Italic,
  JetBrains Mono, Noto Serif; DirectorySource scans system font folders reading only name/OS2
  tables; family/style resolution with synthetic bold/italic; per-char fallback), layout
  (harfrust kerning/ligatures, unicode-bidi, unicode-linebreak, alignment incl. justify,
  leading, tracking, baseline shift, all/small caps, underline, carets/hit-test/selection,
  cached), raster (moved from captions; active-edge list, shapes, emboldening), render
  (outline + sub-pixel glyph-mask caches; transformed-outline path for rotation/skew),
  mask (distance-transform strokes, blur).
- Captions burn-in now shapes and kerns via the engine (font.rs/raster.rs removed).
- Timecode / Clip Name effects draw real text (full clip names, not seven-segment digits);
  text_burnin golden re-blessed.
- UI takes its font bytes from the text crate (no duplicate copies in the binary).
- New fonts: Inter Bold, Inter Italic (OFL-1.1, rsms/inter v4.1), Noto Serif Regular
  (OFL-1.1, notofonts) with sidecars, ATTRIBUTION.md rows and licence text.
- Perf: 3-line 96 px title at 1080p ~1.6 ms cold / 0.15 ms warm (release).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:22:30 -04:00
Brandon ThomasandClaude Opus 5.5 0aaa4f41de Merge main into M9.8 (VP9): Opus + VP9 together in codecs/mkv; vp9 at opt-level 3 in dev builds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:05:53 -04:00
Brandon ThomasandClaude Opus 5.5 5170376dcb M4.6: headless playback benchmark (cargo xtask bench-playback) and a correct dropped-frame count
- crates/ui-egui/examples/bench_playback.rs drives the Program monitor's own FrameServer,
  prefetch (now FrameServer::schedule_playback, shared with the monitor) and PlaybackMeter at a
  simulated 60 Hz display, optionally compositing on a headless wgpu device. Scenarios:
  h264-1080, stack3 (3 × 1080p, scaled/rotated/opacity), h264-2160, demo, after-preview
  (live play → Render Effects In to Out → 2 plays), seek-storm. Reports latency percentiles,
  on-time ratio, worker/decode wall and thread-CPU time, UI-thread present time, process CPU per
  frame, decoder seeks/samples (codecs::gop_stats) and wasted jobs; --json for machine output.
  Fixtures are generated with ffmpeg into target/fixtures/playback.
- FrameServer records per-job timings (thread CPU via rustix clocks) while profiling is on.
- Dropped/shown were counted per UI refresh: "shown" counted every refresh that had the frame
  (322 "shown" in an 8 s play of 192 frames) and "dropped" counted a frame that arrived a few ms
  after its first refresh. PlaybackMeter counts timeline frames: shown when the exact picture was
  on screen while due, dropped otherwise, including frames passed over without a refresh.

Baseline (GPU path, 8 s, load avg 104–168 on 14 cores; CPU columns are load-robust):
  h264-1080 Full 191/1 shown/dropped, 46 ms CPU/frame; Half 188/4
  stack3 Full 189/3, 102 ms CPU/frame; Half 157/35 (3 extra decoder seeks)
  h264-2160 Full 8/184, 313 ms CPU/frame, 10 seeks; demo Full 114/78, Half 191/1
  after-preview: live 0/192; 1st play after render 124/67, 2nd 119/73 (UI-thread present
  p50 21 ms / p95 45 ms); seek-storm: 0 of 40 seeks shown within 150 ms

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:44:23 -04:00
Brandon ThomasandClaude Opus 5.5 7655447233 T3: golden-image tests for the renderer + GPU parity; fix stale GPU uploads
crates/golden (test-only, L3): nine procedural 320x180 scenes (transform
and opacity, blend modes, Gaussian Blur, Lumetri basic, Crop, Cross
Dissolve / Dip to Black / Wipe mid-transition, timecode/clip-name text)
rendered on the CPU and compared with committed goldens (PSNR >= 45 dB,
max <= 12, p99 <= 2); FILMCRAFT_BLESS=1 regenerates them with
attribution sidecars. testkit::golden adds PNG I/O, diff metrics and
failure images. The same scenes are composited on the GPU and compared
with the CPU.

GPU parity exposed a real bug: GpuCompositor cached uploads by
pixel-buffer address without owning the buffer, so a new frame
allocated at a freed frame's address was drawn with a stale texture
(whole wrong frames, PSNR ~12 dB). The cache now keeps the buffer
alive; regression test upload_cache_keeps_buffers_alive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:26:14 -04:00
Brandon ThomasandClaude Opus 5.5 3704002f89 T2: cargo xtask fixtures pre-generates the oracle fixture matrix
Runs each crate's ignored generate_fixtures test (h264, hevc, isobmff,
matroska, prores) - the same generators the oracle tests use - and
prints made/cached/skipped per fixture plus a summary. Optional crate
filter: cargo xtask fixtures hevc prores.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:20:59 -04:00
Brandon ThomasandClaude Opus 5.5 8780d5ffa2 T1: shared ffmpeg/ffprobe discovery in filmcraft-testkit
New dev-dependency-only crate crates/testkit (L0, no FilmCraft deps):
FILMCRAFT_FFMPEG/FILMCRAFT_FFPROBE, then PATH (incl. .exe), then known
dirs; SKIPPED lines and FILMCRAFT_REQUIRE_ORACLES=1 to make skips fail;
require_ffmpeg!/require_ffprobe!/require_oracles!; fixtures_dir() under
<workspace>/target/fixtures with per-thread temp names and atomic
generation. Oracle helpers in aac, opus, h264, hevc, h264enc, isobmff,
matroska, prores and export migrated (codecs left on its local lookup).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:10:59 -04:00
Brandon Thomas 1c9073de2b Merge branch 'worktree-agent-a2fb03c37eff0a53c' 2026-09-30 23:37:44 -04:00
Brandon ThomasandClaude Opus 5.5 4c6e1db167 Add LICENSE-MIT and LICENSE-APACHE (the declared MIT OR Apache-2.0 licence had no licence files); README licence section; xtask layer error points at docs/architecture.md; matroska description includes muxer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:25:35 -04:00
Brandon ThomasandClaude Opus 5.5 4e2a8077d1 docs: public architecture, contributing, testing and agent guides
Public equivalents of the maintainer-local plan/: docs/architecture.md (layers as enforced by
xtask, Tick time base, data model, command system and undo, render/playback/export pipeline,
automation surfaces), docs/contributing.md (+ root CONTRIBUTING.md), docs/testing.md and
docs/agents.md (MCP/control channel usage, agent work loop, decision rules, Definition of Done).
CLAUDE.md points at the public docs wherever it references plan/; AGENTS.md gains a See also list;
README gains a Documentation section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:24:13 -04:00
Brandon Thomas 6f13cbe6ea Merge branch 'main' into worktree-agent-a2fb03c37eff0a53c 2026-09-30 23:14:19 -04:00
Brandon Thomas bfc4ad47b5 Merge branch 'main' into worktree-agent-adeb64ed6481c199b 2026-09-30 23:14:17 -04:00
Brandon ThomasandClaude Opus 5.5 916de99fda M9.8: filmcraft-vp9 clean-room VP9 decoder (profiles 0-3, tiles, superframes, scaling) with ffmpeg oracle tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:22:12 -04:00
Brandon ThomasandClaude Opus 5.5 ed47db6861 M9.13: Opus decoder (WIP: range decoder, packet parsing, CELT core, SILK tables)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:21:51 -04:00
Brandon ThomasandClaude Opus 5.5 ac63aad991 AGENTS.md asset rules (no Adobe iconography/images; open licences only; per-asset .attribution sidecars + ATTRIBUTION.md), cargo xtask assets gate in ci; hevc test fixture temp names unique per thread
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:18:48 -04:00
Brandon ThomasandClaude Opus 5.5 581e31b432 M0.12: xtask layers/wasm/ci gates (layer table, same-layer allow-list, UI crates barred below L5); cargo alias
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:02:36 -04:00
Brandon ThomasandClaude Opus 5.5 936b28e4c4 M0.1/M0.2: workspace skeleton, time and bitstream crates
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 05:33:20 -04:00