Commit Graph
67 Commits
Author SHA1 Message Date
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 ThomasandClaude Opus 5.5 9baa34fa45 Merge M10.1–2 + M3.2/M3.11 into M7.2 (audio mixer): preferences gain audio + playback + trim groups; ROADMAP refreshed
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 02:17:12 -04:00
Brandon ThomasandClaude Opus 5.5 14ae01885f M7.2: Audio Track Mixer and Audio Clip Mixer panels, timeline track keyframes, live recording
- Audio Track Mixer: strips for audio tracks, submixes and the Mix with
  effect/send slots (disclosure), input mapping, output assignment, pan
  knob, automation mode, M/S/R (solo safe on submixes), fader with dB
  scale and our own taper, stereo meters fed by the playing mix, value
  hot text, footer transport; horizontal/vertical scrolling. Fader and
  knob drags are mixer.touch while held and mixer.release on let go, so
  they are heard live and recorded in Latch/Touch/Write.
- Audio Clip Mixer: per-track strips for the clip under the playhead
  (clip Volume / Panner, write-keyframes toggle), clipMixer.set with one
  undo step per drag (Session::edit_merged).
- Timeline: per-track "Show Keyframes" button picks clip keyframes or a
  track lane (volume, panner, mute, sends, insert params); the lane is
  drawn across the track, Pen / Cmd-click adds, diamonds drag in time and
  value, right-click deletes.
- Playback starts an automation pass and stopping writes it; the audio
  callback reads the newest project snapshot (LiveMix), so mixer moves
  are heard while playing. Audio Meters read the graph's live meters
  instead of re-mixing at the playhead.
- Automation ids on every control; headless kittest tests drive the
  panels by id and by multi-frame drags (FILMCRAFT_UI_SNAPSHOT_DIR renders
  offscreen PNGs through wgpu).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 02:10:29 -04:00
Brandon ThomasandClaude Opus 5.5 04e714510b M4.6: GPU path converts layer texels on the frame workers, not on the UI thread
GpuCompositor::upload converted f32 RGBA layers (effects rendered on the CPU, captions,
whole-frame fallbacks) and 16-bit YUV frames (ProRes render previews) to half floats on the UI
thread every time a frame was shown: 8.3 M values per 1080p RGBA layer, 4 M per ProRes frame.
filmcraft_gpu::prepare(plan) now does those conversions on the frame worker that built the plan
(parallel chunks; 16-bit codes through a cached per-bit-depth table) and the plan cache stores
them with the plan (frames::GpuPlan), bounded by count and bytes (1 GiB). composite_prepared()
only copies bytes into textures. The texels are bit-identical (new test compares the read-back
output of both paths for f32, 10-bit 4:2:2 and fallback-image plans).

bench, same-session A/B (GPU path, after-preview Full, 2 rounds, load avg 50–95):
  UI-thread present time p50/p95: plays from previews 11–31 / 34–77 ms → 3.6–5.8 / 4–14 ms;
    live effects play 17–28 / 31–56 ms → 4.1 / 12 ms (first run)
  plays from previews: 184/8, 183/9, 189/3, 169/23 → 192/0, 192/0, 191/1, 192/0 shown/dropped
  live effects play (CPU-bound, ~6 cores at this load): too noisy to compare (0–117 shown either way)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 02:10:14 -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 daaee5072c M10.2: Type tool with on-monitor text editing, shape and pen tools, layer boxes and handles, graphic editor in Properties / Essential Graphics
- Program monitor overlay for graphic clips: Type tool click creates a text layer (in the
  selected graphic under the playhead or a new clip) and edits it in place with a caret,
  selection highlight, arrows/word/line navigation, Shift-select, Cmd+A/C/X/V, Return,
  Backspace/Delete, Esc; typing is one undo step. Selection tool selects, moves and scales
  layers (bounding box, handles, anchor); double-click edits text. Rectangle/Ellipse tools
  drag out shapes; Pen tool places a closed path. Automation ids program.layer.*.
- Properties (when a graphic is selected) and Essential Graphics: Layers list, Align and
  Transform (align / distribute), Text (source text, font family + style incl. system fonts,
  size, paragraph alignment, tracking, leading, baseline shift, box width, faux bold/italic,
  caps, underline, kerning/ligatures), Shape, Appearance (fill, 2 strokes, background,
  shadow). Automation ids graphics.*.
- Headless UI test (egui_kittest) drives the whole flow through the control channel; with
  FILMCRAFT_UI_SHOTS it renders PNGs via wgpu (works with a locked screen).
- docs/graphics.md; architecture, ROADMAP, ATTRIBUTION (code-drawn glyphs) updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:57:18 -04:00
Brandon ThomasandClaude Opus 5.5 4918555906 M10.2: graphic clips — text and shape layers in the project model, vector renderer (CPU + GPU plan), graphics.* commands
- project: ItemKind::Graphic (transparent canvas source, hidden from the Project panel,
  unlimited duration); graphic layers are hidden effect instances graphic_text /
  graphic_shape on the clip (serde for free, keyframes on every animatable property,
  Source Text holds), with appearance (fill, two strokes outer/centre/inner, background
  box with radius, drop shadow) and transform (position, anchor, scale, rotation,
  opacity); eval_layer gives a plain LayerSpec. No schema migration: all additive.
- render: graphic_clip rasterises each layer straight to the output transform (crisp at
  any Motion scale/rotation), caches layer rasters, composes a tight image for the GPU
  plan; standard effects on a graphic run at source resolution first.
- engine: graphics.newText (Cmd+T) / newShape (new clip above the footage at the playhead
  or a layer in an existing clip), setText (typing coalesces into one undo step), set,
  selectLayer, deleteLayer, arrangeLayer, align (frame / selection), distribute,
  graphics.list, fonts.list. EditorState.graphic_layers holds the layer selection.
- goldens: graphic_title, graphic_shapes (CPU and GPU parity).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:38:04 -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 5110b694d8 M4.5: fix UI hang after preview render (macOS App Nap starved the hidden app; ui.screenshot waits forever)
Root cause: not a lock. When the window is hidden or behind others (always when the app is
driven over the control channel), macOS App Nap drops every thread of the process to background
priority 4 and defers its timers. On a loaded machine (load avg ~150) a priority-4 process gets no
CPU: after Render In to Out + play the UI thread stayed runnable inside the run loop's timer
callout, every thread at PRI 4 (`ps -M`), 0 % CPU, control channel silent. Relaunched with App Nap
off the same script ran through: render 2–13 s instead of 15 s, every reply immediate (2/2 runs).

- apps/filmcraft/src/app_nap.rs: hold a user-initiated, latency-critical NSProcessInfo activity
  for the life of the process (= NSAppSleepDisabled for a bundle; idle system sleep allowed).
- ui.screenshot: a hidden window or sleeping display never presents, so the screenshot event
  never came and the UI repainted at full speed forever (100 % CPU). It now fails after 10 s with
  "no frame was presented (window hidden or display asleep)" and polls at 60 Hz meanwhile.

Regression test: app_nap::tests (the activity is taken on macOS). The starvation itself needs a
hidden window on a loaded machine and is checked with the control-channel script in the commit
notes (captions.newTrack/add, markIn/Out, Full, renderInToOut wait, stop, playhead.set,
renderBar, ui.screenshot): all replies within 10 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:17:13 -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 68e5e91bfe Merge main into the playback branch
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:52:31 -04:00
Brandon Thomas 4eb1ffaa59 Merge branch 'main' into worktree-agent-a4e518618b8b67600 2026-10-01 00:46:36 -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 9db963e0e6 M9.8: VP9 wired into codecs — WebM/MKV V_VP9 and MP4 vp09 (+vpcC) import, 8/10/12-bit 4:2:0/4:2:2/4:4:4 (4:4:0 expanded, RGB to RGBA) output, key-frame-checked GOP random access, Decoder::reset / is_keyframe, oracle seek tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:42:11 -04:00
Brandon ThomasandClaude Opus 5.5 7dcdef6974 T5: headless scripted UI tests (egui_kittest + control channel)
crates/ui-egui/tests/scripted.rs runs the real FilmcraftApp under
egui_kittest's eframe harness (no window/GPU) and drives it through
ControlRequests, stepping frames until each reply arrives; synthetic
ui.click input is fed through the app's raw_input_hook. Tests: demo
project + widget registry, razor/undo/redo with timeline locate,
source insert, apply Gaussian Blur and see it in Effect Controls,
playback toggle/stop, click a tool button by automation id, error
replies. docs/testing.md documents coverage and limits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:39:14 -04:00
Brandon ThomasandClaude Opus 5.5 8eb8f5ff68 T4: BS.1770 loudness oracle test against ffmpeg ebur128
Seven generated signals (sine, pink noise at 48/96 kHz, speech-like at
48/44.1 kHz, gated stereo with silence and sub-gate passages, fs/4
inter-sample peak) written as float WAV and measured by LoudnessMeter
and ffmpeg ebur128 (metadata, 3 decimals per 100 ms). Tolerances: M/S
+-0.1 LU every 100 ms, I +-0.1 LU, LRA +-0.5 LU, true peak +-0.2 dB.
Measured: M/S <= 0.0005, I <= 0.007, LRA <= 0.04 LU, TP <= 0.045 dB.
On the fs/4 tone ffmpeg's true peak is +0.6 dB above the analytic
value, so that case is checked against the analytic peak (ours -0.053).
testkit gains a float WAV writer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:32:25 -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 34f53fe9cf Merge main into M11.1–2 (autosave/recovery): previews follow save/open/recover; bare pre-envelope projects with version 1 or 2 load as schema v1 (regression test)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:23:01 -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 ThomasandClaude Opus 5.5 516978b4d4 M11.2: auto-save ring + crash-recovery journal
- Engine autosave module: Preferences (autoSave.enabled/intervalMinutes=5/maxVersions=20/
  saveCurrentProject/recoveryJournal/recoveryIntervalSeconds), persisted in the per-user data
  dir; prefs.get/set/reset commands.
- Background worker (filmcraft-autosave thread): the UI thread only hands over the Arc<Project>
  snapshot; JSON encoding and atomic writes happen on the worker. Premiere-style auto-saves to
  <project dir>/Auto-Save/<name>-YYYY-MM-DD_HH-MM-SS.fcproj (local time), only when changed,
  rotated to Maximum Project Versions, optionally also saving the project.
- Recovery journal: debounced snapshot of unsaved changes in <data>/Recovery/<session>/ guarded
  by an OS file lock; on launch, sessions whose lock is free and that left a snapshot are offered.
  Clean quit removes the journal (or keeps it, marked cleanExit, if changes were unsaved).
- Commands: file.recover, file.discardRecovery, file.recoveryList, file.autoSaveNow,
  file.autoSaveStatus, file.listAutoSaves.
- UI: Preferences ▸ Auto Save page (Edit ▸ Preferences, Cmd+,; FilmCraft ▸ Settings… on macOS),
  "Recover Unsaved Changes" dialog at startup, Revert confirmation; all with automation ids.
- Desktop: --recover / --no-recover / --data-dir; local-time offset via chrono (clock).
- Verified in the app: edits, kill -9, relaunch, dialog, Recover restores the edits (unsaved, original path).
- docs/project-files.md: auto-save, recovery and measured costs (2,000 clips: 2.5 ms encode,
  1.4 MB, ~30 ms atomic write+fsync, all off the UI thread). ROADMAP M11 updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:10:23 -04:00
Brandon Thomas 9e54812b2a Merge branch 'worktree-agent-ae361fad8d71a0eef'
# Conflicts:
#	crates/engine/src/commands.rs
#	crates/export/src/lib.rs
#	crates/ui-egui/src/frames.rs
#	crates/ui-egui/src/state.rs
2026-10-01 00:08:58 -04:00
Brandon Thomas b0ddca7169 Merge branch 'worktree-agent-a726528c34396e2d2'
# Conflicts:
#	ROADMAP.md
2026-10-01 00:07:18 -04:00
Brandon ThomasandClaude Opus 5.5 9eb12c0043 M10.4: caption commands in the engine (captions.* — tracks, add at playhead, split/merge/trim/move/delete, text/speaker/timing, style, next/previous, show/hide, list), file.import detects .srt/.vtt/.scc into a new caption track, File ▸ Export ▸ Captions… (SRT/VTT/SCC), Clear/Ripple Delete on selected captions; caption overlays in render + GPU frame plans; burn-in on export (ffmpeg-oracle test)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:06:29 -04:00
Brandon ThomasandClaude Opus 5.5 ba4a04e031 M11.1: .fcproj schema versioning + migrations, atomic saves
- New crate filmcraft-format (L3): files are an envelope {format, schema_version, generator,
  project}; a chain of single-step JSON migrations (v1 bare Project → v2 envelope) upgrades old
  files on load; newer-than-supported files are refused with a clear "update FilmCraft" error;
  damaged/foreign files report as such.
- atomic_write: temp file in the same dir + fsync + rename + dir fsync; used for every project
  write (FsServices), so a crash mid-save never corrupts the project.
- Engine: file.save/saveAs/open go through the format crate; new file.saveCopy (Save a Copy…,
  Cmd+Alt+S) and file.revert; the first save over an upgraded file keeps
  "<name> (schema vN backup).fcproj". Project.version dropped (the envelope carries it).
- Hand-made v1 fixtures (minimal + edit without later serde-default fields) in
  crates/format/tests/fixtures; 2,000-clip encode/decode timing test.
- docs/project-files.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:54:04 -04:00
Brandon ThomasandClaude Opus 5.5 740fcd95cb M4.5: render-bar segments + render previews in the engine — segments cut at every video edit point, 128-bit content hash relative to the segment start (clips, sources, effects + keyframes, transitions, sequence settings; stable across save/load and ripple moves), measured yellow/red cost estimate; content-addressed ProRes preview cache per project (temp folder until first save), Render Effects In to Out (Enter), Render In to Out, Render Selection, Render Audio (float WAV previews mixed into playback), Delete Render Files (In to Out), sequence.renderBar query; renders run as cancellable jobs on the export pipeline
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:43:26 -04:00
Brandon ThomasandClaude Opus 5.5 421af286dd M10.4: caption tracks in the sequence model (project v2) + filmcraft-captions (SRT/WebVTT/SCC read+write, CEA-608 pop-on/roll-up/paint-on decoder, pop-on encoder with frame-exact load scheduling, burn-in layout + own rasteriser over skrifa outlines with Inter) + caption edit ops (add/split/merge/trim/move/delete, sync-locked insert/extract)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:42:06 -04:00
Brandon ThomasandClaude Opus 5.5 608a83f33e M9.13: Opus in WebM/MKV and MP4 import
crates/codecs decodes Opus with filmcraft-opus (48 kHz output):
- Matroska/WebM A_OPUS: CodecPrivate = OpusHead. CodecDelay removes the
  pre-skip exactly (header pre-skip when CodecDelay is absent); packet starts
  are accumulated from TOC durations because block timestamps are only
  tick-accurate. Random access decodes max(SeekPreRoll, 320 ms) first.
- MP4/MOV Opus + dOps: edit list removes pre-skip (dOps pre-skip without
  one); same pre-roll on random access.
- Family-1 surround reordered from Vorbis to WAV/SMPTE channel order;
  corrupt packets are concealed instead of failing.
Tests (ffmpeg/libopus fixtures, skipped when absent): WebM stereo, MKV mono
VoIP (SILK/hybrid), MKV 5.1 multistream, MP4 stereo; sample-aligned against
libopus (52-89 dB sequential, 45-89 dB after random access).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:37:19 -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 0594cdf8b6 M11: interchange in the engine — file.import detects and merges EDL / FCP7 XML / FCPXML / OTIO (links media on disk, rebases EDL source timecode); File ▸ Export ▸ EDL, Final Cut Pro XML, FCPXML, OpenTimelineIO
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:45:22 -04:00
Brandon Thomas 13beb09833 Merge branch 'worktree-agent-ae43da33282300438' 2026-09-30 22:41:15 -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 dc9e3933a8 M7.3: clip audio effects run on filmcraft-audio-dsp (Amplify, Dynamics, Hard Limiter, Delay, Parametric EQ, High/Low/Bandpass, DeNoise, DeHummer, Studio Reverb, Invert, Pitch Shifter) with keyframed params, latency compensation and a continuation cache with pre-roll for random access
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:40:58 -04:00
Brandon ThomasandClaude Opus 5.5 c14a7d44a4 M11.3: EDL — filmcraft-interchange crate with CMX 3600 import/export
New L2 crate filmcraft-interchange (roxmltree for XML reading). API: import/import_with,
export, export_edl_per_track, detect, merge_into, rebase_source_timecode, Report.
EDL: drop-frame FCM, dissolves/wipes/keys, BL fades, V/A/AA/B/AA/V/A3/A4 channels,
M2 speed/reverse/freeze, reel modes (8/32), clip name/source file/effect/LOC comments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:38:19 -04:00
Brandon ThomasandClaude Opus 5.5 de7e84307d M7.1: BS.1770 loudness in Audio Meters (momentary/short-term/integrated LUFS, true peak) fed with contiguous programme audio; matches ffmpeg ebur128
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:33:53 -04:00
Brandon Thomas 498ac6da23 Merge branch 'worktree-agent-a4193d1e7345108d5' 2026-09-30 11:12:22 -04:00
Brandon ThomasandClaude Opus 5.5 d3ed28ed61 Cargo.lock: hevc in codecs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:12:22 -04:00
Brandon Thomas 2e6adb1a20 Merge branch 'worktree-agent-a14267622437e4bbe' 2026-09-30 11:08:28 -04:00
Brandon Thomas 51acfddf66 Merge M9.1/M9.2: filmcraft-hevc decoder (Main/Main 10, bit-exact on 41 fixtures) 2026-09-30 11:08:07 -04:00
Brandon ThomasandClaude Opus 5.5 627c230871 M7.1: BS.1770 loudness meter
New crate filmcraft-audio-dsp (L1, dependency-free): K-weighting for any
sample rate via bilinear transform, momentary/short-term/integrated
(gated) loudness, LRA (Tech 3342), sample and true peak (polyphase 4x),
normalisation helper, RBJ biquads, radix-2 FFT, parameter smoothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:58:11 -04:00
Brandon ThomasandClaude Opus 5.5 77a096884b M9.9: Matroska/WebM demuxer (WIP: EBML reader, metadata, cluster scan, packets, seek)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:57:02 -04:00
Brandon ThomasandClaude Opus 5.5 d0304c41b8 M9.1: filmcraft-hevc — clean-room H.265 decoder (Main / Main 10)
Parameter sets (VPS/SPS/PPS incl. VUI, scaling lists, short/long-term RPS,
tiles, WPP entry points), slice segment headers, POC / RPS / DPB management
with bumping, CABAC for all Main/Main10 syntax elements, coding / transform
quadtrees, AMP, PCM, transform skip, lossless bypass, intra prediction (35
modes, substitution, filtering, strong smoothing), merge / AMVP / TMVP,
8-tap / 4-tap interpolation, weighted prediction, DCT 4..32 / DST, scaling,
deblocking and SAO run row-pipelined, frame-threaded decoding.

Syntax tables extracted from the ITU-T H.265 text by tools/extract_tables.py.
41 libx265 / VideoToolbox fixtures bit-exact vs ffmpeg (single and
multi-threaded).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:11:22 -04:00
Brandon ThomasandClaude Opus 5.5 3f3265bb35 M6: H.264 MP4 export (own encoder, High profile, VBR, B-frames with edit list) + AAC
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 09:38:45 -04:00
Brandon Thomas bd816ead68 Merge M6.1: filmcraft-h264enc encoder 2026-09-30 09:35:35 -04:00
Brandon ThomasandClaude Opus 5.5 7103b58df9 M6.1: filmcraft-h264enc — clean-room H.264 encoder (High/Main/Baseline, CABAC/CAVLC, intra/inter mode decision, deblocking, RC)
- SPS/PPS/AUD/SEI with VUI (SAR, colour description, timing, reorder), avcC, Annex-B or length-prefixed packets
- Intra 16x16/4x4/8x8 + chroma, hexagon ME with half/quarter-sample refinement, 16x16/16x8/8x16/8x8, P_Skip
- B-frames (1-3, spatial direct/B_Skip, L0/L1/Bi), variance AQ, scene-cut IDR
- 4x4/8x8 transforms, deadzone quant, decimation; normative deblocking in the loop
- CABAC (init tables checked against the spec text) and CAVLC
- Rate control: QP, CRF-like, 1-pass ABR + VBV, closed-loop 2-pass VBR
- Slice-parallel encoding with rayon, concurrent B-frames, parallel lookahead/hpel
- ffmpeg-oracle tests: zero decode errors, exact frame counts, decoder output bit-identical to reconstruction

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 09:32:20 -04:00
Brandon ThomasandClaude Opus 5.5 efc617cb97 M6.2: own AAC-LC decoder replaces the symphonia bootstrap for AAC; AAC encoder for MP4 export
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 07:38:47 -04:00
Brandon Thomas b80de3ea96 Merge M6.2: filmcraft-aac encoder + decoder 2026-09-30 07:37:46 -04:00
Brandon ThomasandClaude Opus 5.5 627931fc72 UI fidelity pass from the Premiere 26 black-box reference: measured palette and label colours, square panels with 4 pt gutters, tab strips with underline + menu glyph, header layout, native macOS menu bar (muda), status/hint bar, Properties panel, timeline restyle (clip bodies, name band, fx badge, head thumbnails, rectified waveforms, hatched transitions, track header layout with patch/target buttons, markers row, 30 pt toolbar, zoom bar knobs), monitor controls, meters, tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 07:37:38 -04:00