Commit Graph

25 Commits

Author SHA1 Message Date
Brandon Thomas 333cc3fdf4 M8.10: HDR metadata field in the AAF test media info from main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 11:52:34 -04:00
Brandon Thomas 0948dcf682 Merge branch 'main' into M3.13/M8.10 2026-10-03 11:50:01 -04:00
Brandon Thomas 2a199425d0 M8.10: HDR-aware Lumetri, mastering metadata tone-map peak, HSL Refine, Lumetri Presets grid, Comparison View match
- Lumetri grades PQ / HLG working spaces in their own signal normalised to
  HDR White (Basic Correction) / HDR Range (Curves) in cd/m²
  (filmcraft_color::GradeSpace): exposure in stops of light, highlights above
  HDR White kept, HDR Specular scales them; Rec. 709 unchanged.
- HDR static metadata (mdcv/clli, Matroska MasteringMetadata/MaxCLL/MaxFALL)
  on VideoStreamInfo::hdr; PQ media use MaxCLL / mastering peak as the
  BT.2390 source peak; media.colorInfo reports it.
- HSL Secondary Refine: Denoise (median of the key) and Blur (Gaussian).
- Lumetri Presets (18 original looks in 4 folders) with thumbnails rendered by
  our Lumetri on a procedural preview picture; Effects panel rows and a
  thumbnail grid when wide; lumetri.presets / applyPreset / presetThumbnails.
- Color Match: Comparison View toggle; Apply Match uses its reference frame.
- Goldens lumetri_hdr_pq and lumetri_presets_grid; D-Log M stays unsupported
  (no published formula).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 10:31:00 -04:00
Brandon Thomas 6cddaf08aa M11.4: document AAF / OMF interchange and the cfb crate
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:55:23 -04:00
Brandon Thomas 0658967a5b M11.4: AAF (Edit Protocol) and OMF 2.0 import/export in filmcraft-interchange
Shared mob-style composition model; AAF objects in structured storage over
filmcraft-cfb; OMF objects in a Bento container; embedded / consolidated audio
supplied by the caller (essence::audio_needs, MediaOptions).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:23:20 -04:00
Brandon Thomas ee9fd53079 M10.7: graphics templates (.fcgt), rolls/crawls, responsive design, per-character styles, MCC/STL/TTML/DFXP captions
- Text engine: per-character style runs (layout_rich), per-run underline/colour index.
- Project: graphic_design (style runs, pins, roll/crawl maths, responsive time, source graphics),
  gtemplate (.fcgt format, validation, base64 resources, 8 original built-in templates; .mogrt refused).
- Render: item-level graphic evaluation (responsive time, pins, rolls), per-run fills.
- Engine: graphics.template.* (list/apply/export/install/remove/set/controls/thumbnail),
  graphics.setRoll/setResponsiveTime/pin/setCharStyle, Upgrade Caption to Graphic,
  Upgrade to Source Graphic (shared edits), Replace Fonts in Projects, fonts used.
- Captions: MacCaption MCC (CDP, CEA-608 + CEA-708), EBU STL (Tech 3264), TTML/IMSC1, DFXP.
- Schema v12 (no-op migration + fixture), docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:52:15 -04:00
Brandon Thomas a34bc7f038 M3.11: remaining Premiere menu items — Scene Edit Detection, Normalize Mix Track, Simplify Sequence, Find / search bins, Automate to Sequence, Project Settings, ALE export…
- Scene Edit Detection: pure-Rust cut detection (render::scene: luma grid + RGB
  histogram difference, adaptive threshold with sensitivity, min shot length),
  background job with progress/cancel; applies cuts (linked audio too), clip
  markers and subclips in one undo step.
- Sequence: Normalize Mix Track…, Simplify Sequence…, Transcribe Sequence…,
  Captions ▸ Show Active Caption Tracks Only, Apply Default Transitions to
  Selection works on selected clips; Sequence menu in Premiere's order.
- Markers: Add Flash Cue Marker… (MarkerKind::FlashCue).
- File: New ▸ Search Bin (live saved queries), Close, Close All (Other)
  Projects, Save as Template… (+ new project from template), Import from Media
  Browser, Get Media File Properties for ▸ File…/Selection…, Project Settings ▸
  General…/Scratch Disks… (scratch disks drive previews, proxies, auto-save),
  Export ▸ Selection as FilmCraft Project…, Export ▸ Avid Log Exchange…
- Edit: Find… / Find Next (project columns/operators/all-any, timeline clips
  and markers), Edit Original (OS opener host hook).
- Clip: Edit Offline…, Source Settings…, Update Metadata… (XMP sidecars),
  Generate Audio Waveform, Restore Captions from Source Clip (disabled: no
  embedded caption reader), Automate to Sequence…
- View ▸ Dynamic Audio Waveforms; Help ▸ Reveal Log Files…, System
  Compatibility Report… (with the wgpu adapter).
- Dialogs for all of the above (panels::menu_dialogs, ui.set menuDialog).
- Project schema v11 (no-op v10_to_v11, fixture, docs row).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 11:08:58 -04:00
Brandon Thomas e222d025cf Merge transcripts (M10.5) and clip/project commands (M3.10); clip schema renumbered to v10
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:34:12 -04:00
Brandon Thomas c3d2f740d0 M3.10: Edit/Clip/File menu commands — labels, Paste/Remove Attributes, subclips, frame holds, time interpolation, audio options, Replace With Clip
Edit: Label ▸ 16 colours + Select Label Group, Paste Attributes… (⌥⌘V, with
Scale Attribute Times), Remove Attributes…, Select All Matching, Remove
Unused, Consolidate Duplicates. File: New ▸ Sequence From Clip, Bin From
Selection (⇧B), Offline File…; Close Project (⇧⌘W, asks to save), Save All.
Clip: Make Subclip… (⌘U, Restrict Trims), Edit Subclip…, Modify ▸ Audio
Channels… (⇧G) / Timecode…, Video Options ▸ Frame Hold Options…, Add Frame
Hold (now splits at the playhead), Insert Frame Hold Segment, Field
Options…, Time Interpolation (Frame Sampling / Frame Blending / Optical
Flow, blending rendered on CPU; optical flow falls back to blending),
Fit to frame / Fill frame; Audio Options ▸ Breakout to Mono, Extract Audio
(WAV next to the project, imported); Replace With Clip ▸ From Source
Monitor / Match Frame / From Bin. Hold Filters: effects animate through a
hold unless set. Menus support nested submenus (egui and native) and follow
Premiere's order. Dialogs in panels::clip_dialogs with automation ids and
ui.set {clipDialog}.

Project schema v9 (no-op migration v8→v9, v8-subclip fixture): clip
time_interpolation / hold_filters / field_options / source_channels,
Interpretation.audio_channels, Subclip.restrict_trims.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:28:37 -04:00
Brandon Thomas 858403ebf3 M3.9: Sequence and Markers menu long tail
Sequence: Reverse Match Frame (Shift+R), Go to Gap > Next/Previous in
Sequence (Shift+; / Cmd+Shift+;) and in Track, Selection Follows Playhead,
Show Through Edits (bow-tie marks on the timeline, wrench toggle), Join
Through Edits (clip context menu), Make Subsequence (Shift+U), Delete
Tracks... (dialog: all empty tracks or one track per kind).

Markers: Mark Split and Go to Split (Video/Audio In/Out) on the sequence
and the Source monitor; source split points make J/L-cuts on Insert and
Overwrite. Add Range Marker (Ctrl+Shift+M), Add Range Marker to In and Out
(Ctrl+M), Add Chapter Marker..., Clear Markers label, Show All Marker
Colors with a Markers panel colour filter, Ripple Sequence Markers
(insert, paste insert, extract, ripple delete, close gap, ripple trim) and
Copy Paste Includes Sequence Markers.

Edit crate: through-edit detection/join, track and sequence gaps, range
clipping. Shifted punctuation keys (Shift+; arrives as ':') now match
their bindings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:25:38 -04:00
Brandon Thomas a9278c81cc Merge M12 (multicam) into M5.5–7 (masks/presets): schema v7 = masks, v8 = multicam (WIP: CI not yet run)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 11:55:13 -04:00
Brandon Thomas 650a266352 M12.2: multicam and sync — Synchronize (In/Out/timecode ± hours/clip marker/audio), Merge Clips, Create Multi-Camera Source Sequence (camera names, audio camera 1/all/switch, Processed Clips bin), multi-camera clips (angle render, Switch Audio mix, GPU plan passthrough), switch angle / Ctrl+N cut / keys 1–9, live recording as one undo step, Enable/Flatten/Edit Cameras, audio follows video; nested sequence audio now plays; project schema v7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 11:08:45 -04:00
Brandon Thomas fbaf487237 M5.5: effect masks (ellipse / 4-point polygon / pen Bezier) with keyframable path, feather, opacity, expansion, inverted, modes; opacity masks; WGSL coverage parity; on-monitor editing
- project:😷 MaskPath (cubic Bezier, clip pixels) as ParamValue::Path (vertex-wise keyframe interpolation), Mask, MaskMode, TrackMethod; schema v7 (no-op migration)
- render:😷 analytic antialiased coverage via signed distance + feather falloff in linear light; masked effect = lerp(original, effected, coverage); opacity masks before Motion; adjustment layers
- gpu::GpuMask: same coverage + mix in WGSL compute (max |cpu-gpu| ~3e-6)
- engine masks.* commands (add/remove/set/moveVertex/translate/addVertex/removeVertex/toggleVertexSmooth/select/list); keyframe commands take "mask"
- UI: Effect Controls mask rows; Program monitor overlay (vertices, handles, feather/expansion handles, body drag, pen tool) with automation ids
- goldens: mask_blur, mask_color, mask_inverted, mask_opacity

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 10:48:47 -04:00
Brandon Thomas 9f4208bb08 Merge main into M11.7–9 (relink, proxies, project manager): GopCache keeps main's continuation algorithm with a same-thread reentrancy guard (nested rayon requests decode privately instead of deadlocking); ProRes export combines profile choice with HDR signalling; project schema v6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 09:19:19 -04:00
Brandon Thomas b98c886133 M11.7: offline media and relinking
- Missing media no longer fails: opening a project scans for missing files
  (`media.findMissing`, `file.open` → missingMedia). Missing clips render our own
  offline slate (render::offline: red striped field, warning triangle, "MEDIA NOT
  FOUND", file name, hint) with silent audio, and the Link Media dialog opens.
- Media identity: imports record the size and a fast content fingerprint (hash of
  size + first/last MiB) in MediaClip::identity (optional field, older builds
  ignore it, no schema bump).
- media.relink checks file name / extension / fingerprint ("Clip ID") / duration /
  media start / frame size+rate+channels, refuses a mismatched fingerprint unless
  forced, supports Align Timecode (Project::shift_media_time), and relinks the
  others automatically by the derived folder remap (Windows/macOS separators).
- media.autoRelink {from,to} | {folder}, media.search, media.replaceFootage,
  media.makeOffline {deleteFiles?}, media.offlineAll, media.status, media.linkMedia.
- Media pool caches sources per reference (path, offline flag), so relink, Make
  Offline and undo take effect at once; proxy-aware resolution and a full-res
  provider that export uses.
- codecs::gop no longer holds its lock while decoding: rayon decoders inside a
  parallel export could steal another frame of the same source and deadlock.
- UI: Link Media dialog (rows, match options, folder search with preview, Locate…,
  Link, Offline, Offline All, Cancel), Make Offline dialog, Project panel offline
  markers and context menu, media thumbnails keyed by media reference.
- Tests: moved media opens offline (slate rendered) and relinks others by folder,
  prefix remap and folder search, fingerprint mismatch refused, Make Offline,
  headless UI test of the dialog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 09:00:35 -04:00
Brandon Thomas 6a0a3add7f M7.4: Essential Sound model and commands — audio types, per-type settings as clip effects, presets, loudness auto-match, ducking keyframes
- project::essential: Dialogue/Music/SFX/Ambience settings (Loudness, Repair, Clarity, Creative,
  Ducking, Pan, Clip Volume, Mute), our own EQ/reverb/type presets, and apply(): settings become
  ordinary clip effects (EffectInstance::essential) in canonical order; only changed parameters
  are written, so keyframes survive; auto-match gain → clip gain, Clip Volume → Volume offset,
  Pan → Panner
- effect defs: DeEsser, DeReverb (params), Enhance Speech, Stereo Width; render mappings for them,
  and DeNoise amount / DeHummer gain now reach the DSP; Mute; render::audio::clip_signal
- engine essentialSound.* (inspect, setType, clearType, set, applyPreset, savePreset,
  deletePreset, autoMatch, generateDucking), undoable; per-type loudness targets and user presets
  in preferences
- tests: auto-match within 0.001 LU of target (−23 / −16, with and without a chain), ducking
  keyframes within 20 ms on a synthetic dialogue+music project and −15.00 dB in the mix, repair
  metrics (hum −39 dB, rumble −22 dB, noise floor −13 dB, sibilance −19 dB, reverb tail −10 dB),
  render chunking bit-identical and WAV export = render; full Dialogue chain 22× realtime (release)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 08:28:38 -04:00
Brandon Thomas 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 Thomas 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 Thomas 6b00314e96 M7.2: audio mixer graph, track automation and mixer commands
- project: MixerStrip on every audio track, submix tracks and the Mix
  (automation mode Off/Read/Latch/Touch/Write, lanes for volume/pan/mute/
  send levels, effect-parameter automation in the insert's own keyframes,
  sends pre/post fader, output routing, record arm, solo safe, input map);
  pre/post-fader flag on inserts; serde defaults (no schema migration).
- render: mixer graph (tracks -> submixes -> Mix) in Premiere's order:
  pre-fader inserts, pre-fader sends, mute, fader, meter, post-fader
  inserts, post-fader sends, pan/balance. Per-sample automation, effect
  params on an absolute 64-sample grid (output independent of request
  cutting), route-level latency compensation, cached continuation state
  with pre-roll, solo/solo-safe logic, -3 dB constant-power pan law for
  mono tracks, balance for stereo. LiveMix carries held controls (Touch
  ramps back over the automatch time), meters and the newest project.
- engine: mixer.* commands (setStrip, setValue, touch/release,
  recordStart/recordStop, submixes, inserts, sends, track keyframes,
  writeAutomation, inspect) and the automation recorder (gesture streams
  thinned into keyframes, one undo step per pass, Switch to Touch after
  Write); Preferences > Audio (automatch time, keyframe thinning).
- tests: gain/pan law, block-boundary automation, solo/mute/solo-safe,
  sends, latency alignment, render-vs-playback identity, recorder modes,
  perf (24 tracks x EQ+Dynamics+Reverb + submix: 6.3x realtime, one core).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:29:49 -04:00
Brandon Thomas 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 Thomas 2fabddec3d M11.6: interchange API tests (detect, merge_into, rebase_source_timecode)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:39:14 -04:00
Brandon Thomas 4e2fefdcda M11.6: OTIO — OpenTimelineIO JSON import/export
Timeline/Stack/Track/Clip.1+2/Gap/Transition/Marker/External/Missing/GeneratorReference,
LinearTimeWarp/FreezeFrame, SerializableCollection; exact RationalTime↔Tick by rate snapping;
nested sequences as Stacks; metadata.filmcraft round-trips effects, labels, links, groups,
gain, track state, sequence settings and media info. Golden plain-OTIO document with gaps
and transitions; lossless property round trips including sample-accurate audio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:38:33 -04:00
Brandon Thomas d6908b6c0d M11.5: FCPXML — 1.9–1.11 import/export
Exact rational time strings, formats/assets/media/effect resources, library/event/project,
spine with asset-clip/clip/ref-clip/gap/transition, connected clips and secondary storylines
by lane, srcEnable audio/video merge, timeMap constant speed/reverse/freeze, adjust-transform/
blend/volume with keyframes, markers and chapter markers. Golden document and round trips.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:30:18 -04:00
Brandon Thomas b31c655338 M11.4: FCP7 XML — xmeml v4/v5 import/export
Project/bin/clip/sequence, clipitems with pproTicks-exact source, files by id, nested
sequences, generatoritems, transitionitems with alignment, Basic Motion/Opacity/Time Remap/
Audio Levels/Audio Pan filters with keyframes, generic effects by id/name, labels, markers,
links, enabled/locked. Golden Premiere-style document and property round trips.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:27:48 -04:00
Brandon Thomas 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