Commit Graph
3365 Commits
Author SHA1 Message Date
vangel76andClaude Sonnet 5.5 24612b0eaf Merge upstream/main into gap-behaviors-presets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 02:02:16 +02:00
Davit MatchakhelidzeandClaude Opus 5.5 7999754a13 i18n(ka): Georgian rows for the panel strings main added; drop one it no longer uses
Copy, Paste, Copy Source Path, Guide Layer and Layer Styles join GEORGIAN in the Chinese order;
Edit Value…, Remove Expression and Effects move there from GEORGIAN_PANELS now that the Chinese
catalogs carry them; Freeze on Last Frame is only a menu command now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 03:20:50 +04:00
Davit MatchakhelidzeandClaude Opus 5.5 5a069af3fd Merge i18n-improvements (main merged)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 02:58:18 +04:00
Davit MatchakhelidzeandClaude Opus 5.5 7d03c0a1f6 Merge main; context menus use upstream's context_item (#1308)
Upstream now translates the Timeline, Composition and Effect Controls context menus itself, so
command_label is left for the dock's tab titles and the workspace bar, on menu_catalog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 02:58:04 +04:00
Kristian MyramandClaude Sonnet 5.5 0c70ee026b WAV markers: the host test covers the bound layers parameter and undo/redo
The end-to-end test called Update Markers From Source only through the
selection. It now also passes the layer as the bound `layers` parameter (what a
script or the menu binding supplies), checks the markers by name, and checks
that the update is one undo step: undo removes the restored marker again and
redo brings it back.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 00:56:32 +02:00
Kristian MyramandClaude Sonnet 5.5 620d340d15 WAV markers: read RF64 files and bound the adtl list
Two findings from the review of #1423.

RF64 (WAVs over 4 GB): a chunk too big for 32 bits has a size field of
0xFFFFFFFF and its real size in the file's `ds64` chunk. The reader took the
field literally, so it stopped at the `data` chunk and never reached the
`cue ` and `_PMX` chunks that follow it. It now resolves such sizes through
`ds64` (the `data` size, and a table of other chunks, capped at 1,024 entries),
with checked arithmetic, and leaves the field as it was when there is no
usable `ds64`.

The `adtl` list: every `labl` record scanned the growing list of names, which
is quadratic in the number of records, and nothing bounded how many were
kept. The cue points are now read first, names and lengths are kept only for
those ids in hash maps, and at most 40,000 `adtl` sub-chunks are looked at.
The duplicate check between the cue and XMP markers uses a set instead of a
scan. What a file yields is unchanged for any file within the bounds: a `labl`
still wins over a `note`, and the first `ltxt` still gives the length.

Tests: an RF64 file whose markers follow a sentinel-sized `data` chunk, sizes
taken from the `ds64` table (and not taken when the table has no entry),
hostile `ds64` sizes and tables and every truncation of an RF64 file, and a
100,000-record `adtl` list that is read in linear time, with the cap applied.
The RF64 tests fail with the previous reader.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 00:56:32 +02:00
iannitramandClaude Opus 5.5 c1d411b249 Tests: serialise disk-cache-opening tests with the roto tests
The Roto/Object Matte segment store is one per process (roto::set_seg_store),
and every Session::configure_disk_cache that opens a cache takes it over. The
roto and disk-cache tests already serialise on hold_roto_cache_test_lock(), but
many other engine tests build a Session with a settings store, which opens the
disk cache at the platform folder and takes the store; once that session drops,
the weak store is dead and object_matte_mattes_persist_in_the_disk_cache sees
no disk writes. It failed 3 of 3 in the full parallel suite here.

configure_disk_cache now takes that lock under cfg(test) before opening a
cache, so every such test runs apart from the roto tests. Re-entry on the same
thread is a no-op. Product code is unchanged: only the app's one session ever
opens a disk cache, so users cannot hit the race.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:51:47 -06:00
Kristian MyramandClaude Sonnet 5.5 79dec68d63 Marker names: a short duration stays visible beside the name box
When a named marker's duration ended inside the name box, the box's fill covered
the duration's end cap and most of its bar, so the duration could not be seen.
The box now steps past the end cap in that case (and stays at the flag when the
bar is longer than the box, or ends before it).

The new test puts a 0.1 s duration on a named marker, takes the timeline's scale
from a second marker, and checks that the cap and the bar are drawn and that the
box starts after the cap; it fails with the previous drawing. The two render
tests now take a lock, because two tests creating a GPU device at once crash
some Vulkan loaders.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 00:35:59 +02:00
sanyamsingh001andCodex 9bcf2e2dfd Use symmetric HexTile cell coordinates on CPU and GPU
Keep the existing regression and tolerance while preserving upstream
WireRemoval and test-service recovery changes.

Co-authored-by: Codex <codex@openai.com>
2026-10-18 21:48:26 +00:00
Higgs32584andClaude Opus 5.5 88f940d54e Export: CPU cap bounds images waiting to encode and survives a GPU stop (#1615)
Review of #1763:
- With EFFECTCRAFT_CPU_INFLIGHT set, each window is the CPU cap instead of
  one frame per thread, so rendered images held before encoding count
  against the cap too (a cap of 2 on 16 threads held up to 16 images).
- Once the GPU stops for good, the GPU cap lapses and the CPU cap alone
  applies, instead of the smaller cap (often the GPU default of 1) holding
  for the rest of the batch.

The caps are now an `Inflight { gpu, cpu }` that `map_frames_while`
re-evaluates per window and chunk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 17:05:03 -04:00
Kushagra Kumar f7922a9fba test(engine): add undo and redo assertions for queued still frame export 2026-10-19 02:11:05 +05:30
Kushagra Kumar aacf09a5ca fix(render): use pixel units for text animator tracking amount
In After Effects, text animator Tracking Amount adds the value in absolute
pixels between neighbouring characters, independent of font size. EffectCraft
previously scaled tracking by 1/1000 em (matching static Character-panel
tracking), causing tracking reveals to have significantly reduced spread.

Apply Tracking Amount directly in pixels during glyph positioning layout,
update existing tracking tests to reflect pixel units, and add a regression
test verifying font-size independence.

Fixes #1798
2026-10-19 02:07:17 +05:30
Kushagra Kumar 791e6bb5eb fix(engine): preserve alpha channel when saving still PNG frames
Exporting still frames via comp.saveFrameAs previously flattened the
rendered frame against the composition background color, stripping
the alpha channel. Single still frames queued in the Render Queue also
defaulted to an RGB-only PNG sequence output module.

Preserve straight alpha by default in comp.saveFrameAs (while honoring
transparent: false if requested), and set TemplateSlot::Still to default
to 'PNG Sequence with Alpha'.

Fixes #1815
2026-10-19 01:59:48 +05:30
Michael Higgins 14dd6d333d Merge branch 'storytold:main' into fix/1615-cpu-inflight-cap 2026-10-18 15:02:44 -04:00
Dylan M. Taylor 75fce6b2d8 docs: put SonarCloud and CodeRabbit badges on their own line 2026-10-18 14:47:37 -04:00
Dylan M. Taylor ef74d82902 ci: configure Dependabot for Cargo and GitHub Actions
Co-authored-by: Dylan M. Taylor <dylan@dylanmtaylor.com>
2026-10-18 12:31:27 -06:00
Anubhav-RaiandClaude Opus 5 3b9d243ac5 Shift Channels: After Effects' Take … From menu order, so 10 is Full Off (#1797)
The menu had an extra "Half On" at position 10, where After Effects has
"Full Off", so a project or script written for After Effects set a channel
to 50 % grey instead of turning it off, with no error: the RGB-split recipe
(three copies, each keeping one channel and setting the other two to Full
Off, blended with Add) rendered pastel instead of pure red, green and blue.

After Effects' ten options now come first, in its order, and "Half On" sits
last as an EffectCraft extra, so values 1 to 10 mean what they mean in After
Effects and nothing is lost. Instances saved with the old order keep the
option they chose: upgrade_instance already remaps popup values by label.

The GPU path keeps its own copy of the table, so it is reordered to match;
a GPU-vs-CPU parity case now covers the constant sources at the end of the
menu, where the two tables could drift apart unnoticed. Both paths clamped
the index to a hardcoded 10 and now use SHIFT_ORDER.len() - 1, so the clamp
cannot go stale if the list changes again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-18 23:34:25 +05:30
tylerjenningsw 70ad68eb85 Preview: the Extended Viewer startup test doesn't race the first frame (#947)
startup_finishes_when_extended_viewer_frames_are_larger failed on busy
machines. The harness clock moves 1/30 s per step however long a frame
takes, so a slow first frame could use up the startup's limits in
harness time. The test now waits for the first frame in real time
before stepping on, as it is about the wait for the frames ahead, and
checks the fake device was started and not stopped.
2026-10-18 12:58:09 -04:00
tylerjenningsw ef60d3db9d Preview: a slow first frame keeps the opening sound (#947)
Under load the first frame could take longer than STARTUP_WAIT to be
cached. The start then gave up, started the sound on that uncached
frame, and the stall path stopped it in the same step, so the opening
played silently.

STARTUP_WAIT (2 s) now counts from when the first frame is cached, and
only bounds the wait for the frames ahead. A new STARTUP_LIMIT (10 s
from Play) still ends the wait for a first frame that never gets cached.
The sound is never started on a frame that isn't cached: the preview
goes on as a stalled one does, and the sound starts once frames are in.

Tests (ui_audio_scrub): a first frame held uncached for 3 s still gets
its sound from frame 0, and the device keeps playing (fails on the
previous commit). The two give-up tests now check that no sound is
started and dropped.
2026-10-18 12:58:09 -04:00
Dylan M. Taylor 20c03451c0 docs: describe color grading panel, scope SDK plug-in warning, qualify rendering tests, and link parity checklist 2026-10-18 12:51:59 -04:00
tylerjenningsw dd50e42486 Merge remote-tracking branch 'origin/main' into enhance/pickwhip-index-refs
# Conflicts:
#	crates/ui-egui/tests/ui_inline_edit.rs
2026-10-18 12:38:44 -04:00
Charles BaumerandClaude Opus 5.5 bd961131a4 Media tests: ffmpeg fixtures survive concurrent first runs on Windows
Tests that share a fixture each generate it on a first run and rename
their temp file into place. On Windows the losing rename fails with
PermissionDenied while the winner has the file open. Treat a failed
rename as "another test made it first" when the fixture exists, as
`png_sequence` already does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:23:28 +00:00
Charles BaumerandClaude Opus 5.5 4fa31b5e5b Engine tests: clippy passes on Windows (Stills is Unix-only)
`Stills` is only used by the `#[cfg(unix)]` part of
`footage_on_other_computers_is_never_looked_at`. On Windows it was dead
code, so `cargo xtask ci` stopped at clippy (`-D warnings`).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:12:55 +00:00
Davit MatchakhelidzeandClaude Opus 5.5 6c6b54a182 Georgian interface text draws from an installed font
Georgian joins the installed-font fallback like Thai, Hebrew and the Indic scripts:
Sylfaen on Windows, SF Georgian on macOS, Noto Sans Georgian or DejaVu Sans on Linux.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-18 19:54:25 +04:00
Claude bccbc666a2 #1417: WAV markers show on the audio layer
A WAV's markers were never read, so its audio layer showed none. The importer
now reads the file's cue points (`cue ` chunk named by `LIST/adtl` `labl` and
`note`, sized by `ltxt`) and Adobe's XMP markers (`_PMX` chunk, `xmpDM:markers`
entries as elements or attributes, in frames of the track's `xmpDM:frameRate`).
A marker present in both encodings is listed once. The reader is bounds-checked
and caps the marker count and XMP size.

- `Footage.markers` (optional in the file format) holds them at footage time; a
  layer made from the footage starts with them.
- Layer ▸ Markers ▸ Update Markers From Source also works on footage layers.
- Markers from a file have no label colour.

Tests: reader unit tests (cue, note, ltxt, both XMP forms, both encodings,
truncated and hostile files), a probe test, and an end-to-end test through the
fully wired session. Not checked against a WAV written by Adobe's tools.

Claude-Session: https://claude.ai/code/session_013fTnVxnXTv2MBW6uj2PPyU
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 17:38:44 +02:00
Kristian MyramandClaude Sonnet 5.5 4124ec6de7 Marker names are drawn in a small outlined box, in theme colours
A named marker drew its name as bare text beside the flag. After Effects puts
it in a small outlined box. The box uses the theme's field fill, field outline
and text tokens, so it follows Dark, Darker and Light instead of a fixed grey.

It applies to every marker with a name, composition markers included; the dimmed
names of nested-comp markers on a precomp layer's bar are unchanged.

Split out of the WAV markers change (#1423), where the review asked for it to be
its own decision. Test: ui_marker_names renders the timeline in Dark and in
Light, samples the box's fill and outline pixels, and checks they equal that
theme's tokens and differ between the themes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 17:38:28 +02:00
Brandon Thomas 22072d9f25 Merge pull request #1317
# Conflicts:
#	crates/ui-egui/src/panels/effects_presets.rs
#	crates/ui-egui/src/panels/timeline.rs
2026-10-18 11:12:44 -04:00
Brandon Thomas 033890fdcf Merge pull request #1802 2026-10-18 11:12:27 -04:00
Dylan M. Taylor 99bdcde092 docs: add SonarCloud and CodeRabbit badges to README 2026-10-18 11:01:31 -04:00
FredApps b0acbbe121 CLI: regression tests for render --progress (#1778) and template media values (#1787)
- render --progress with a piped stderr writes well-formed
  `progress <done> <total> <elapsed> <left|->` lines, one per change, and
  the same render without the flag writes none.
- A template's Media Replacement control takes {"path"|"file"|"media": …},
  is found by name ignoring case, and a path that cannot be imported fails
  with an error naming the control and the path.
2026-10-18 16:46:06 +02:00
Dylan M. Taylor cb70a0cdbe docs: replace Lumetri effect reference with generic color grading 2026-10-18 10:42:59 -04:00
Matej Kozlovský 14f4c56732 Cryptomatte: define CryptoAux, which the previous commit used but never added (#473)
crypto_aux_image_with now takes CryptoAux::{ColorsAndMatte, MatteOnly}
instead of a bool, and CryptoAux::for_display holds the rule for which
displays read the ID colours (Colors without Matte Only). IdColorMemo uses
get_mut instead of indexing, and the CPU effect zips the pixels with the
aux index map instead of indexing it. No behaviour change.
2026-10-18 16:42:36 +02:00
Dylan M. Taylor c7d8824e09 docs: drop references to competing commercial software 2026-10-18 10:42:22 -04:00
FeiLiuEM 2fbcc6b59a ui: the interface prefers the platform's UI faces, rendered text keeps the print ones
Windows ships a UI variant of its Japanese and Chinese families (`Meiryo`/`Meiryo UI`, `Yu
Gothic`/`Yu Gothic UI`, `MS Gothic`/`MS UI Gothic`, `Microsoft YaHei`/`Microsoft YaHei UI`,
`Microsoft JhengHei`/`Microsoft JhengHei UI`) whose kana and kanji are drawn for the screen, and its
own link table for `Segoe UI` picks the UI one for everything it draws. The interface should ask for
it - but the same lists feed `fonts::fallback_for`, which shapes composed frames, so reordering them
would change how existing projects render. The two orders are therefore separate: this leaves
`crates/text/src/fonts.rs` exactly as it is and gives the interface its own candidate list in
`install_script_fallbacks`, which falls back to the shared choice when the platform has no UI variant,
none is installed, or it does not cover the probe.

`PMingLiU` is in the interface list for its proportional spacing, not as a sibling of `MingLiU`: it is
MingLiU's proportional relative.

The rendered order is pinned by a test now: the Japanese list keeps `Yu Gothic` ahead of `Yu Gothic
UI`, and no UI name appears in the lists a document renders with. `the_interface_asks_for_the_
platforms_ui_faces` pins the interface list and checks that every other script the install probes has
none, so a script that draws correctly in any face keeps the shared order.

Review fixes: the locale is mapped once (the call passes the language, the helper maps it), the new
test sits after the #394 test it had split from its doc comment, and the fonts.rs test asserts instead
of panicking inside a closure. Rebased on current main; #1395 has not landed yet, so there is nothing
to rebase after it.
2026-10-18 22:28:56 +08:00
Brandon ThomasandClaude Opus 5.5 f3f24ef189 Land batch: fix clippy lints and the #1424 test after #1413 changed layer_menu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:42:33 -04:00
Brandon Thomas 7804cfd223 Format merged community PRs 2026-10-18 09:37:06 -04:00
Brandon Thomas 10cf6690c4 Merge pull request #1730
# Conflicts:
#	crates/engine/src/commands/prop_groups.rs
2026-10-18 09:36:40 -04:00
Brandon Thomas 7c99ba6eeb Merge pull request #1696
# Conflicts:
#	contributors/people.toml
2026-10-18 09:36:05 -04:00
Brandon Thomas a594abf4f7 Merge pull request #1652
# Conflicts:
#	docs/gaps.md
2026-10-18 09:35:51 -04:00
Brandon Thomas 17c4b02149 Merge pull request #1790 2026-10-18 09:35:35 -04:00
Brandon Thomas 043eb5a157 Merge pull request #1787 2026-10-18 09:35:35 -04:00
Brandon Thomas dfff3f9010 Merge pull request #1785 2026-10-18 09:35:35 -04:00
Brandon Thomas 692feb7925 Merge pull request #1778 2026-10-18 09:35:35 -04:00
Brandon Thomas 1dac4c0e6b Merge pull request #1759 2026-10-18 09:35:35 -04:00
Brandon Thomas 0867d837d4 Merge pull request #1753 2026-10-18 09:35:35 -04:00
Brandon Thomas 869ce1db39 Merge pull request #1752 2026-10-18 09:35:35 -04:00
Brandon Thomas 681d99c0e7 Merge pull request #1731 2026-10-18 09:35:35 -04:00
Brandon Thomas d9e3c56404 Merge pull request #1721 2026-10-18 09:35:35 -04:00
Brandon Thomas 436f826c3d Merge pull request #1712 2026-10-18 09:35:35 -04:00
Brandon Thomas 415e353dc0 Merge pull request #1711 2026-10-18 09:35:35 -04:00