video-mode: flatten cursorExpression so ffmpeg 8's eval depth cap can't kill long renders - #43
Draft
mmkal wants to merge 3 commits into
Draft
video-mode: flatten cursorExpression so ffmpeg 8's eval depth cap can't kill long renders#43mmkal wants to merge 3 commits into
mmkal wants to merge 3 commits into
Conversation
ffmpeg 8 limits expression nesting to ~100; cursorExpression nests one if() per cursor waypoint segment, so long pointer-mode specs fail at render with 'Missing )' inside a multi-kilobyte command-line error. Diagnosis verified against ffmpeg 8.0.1; fix is a constant-depth sum-of-disjoint-windows rewrite. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WZz4ydAhbRixWwJLpUEnSj
…eg 8 ffmpeg 8 caps expression nesting at ~100 levels; the old form nested one if(between(...)) per cursor waypoint segment, so pointer-mode tests with ~35+ highlighted actions failed to render. The flat form sums disjoint half-open gte/lt window terms plus a complement term carrying the last waypoint's position, keeping depth constant at any length. New spec guards depth, ffmpeg parseability under production quoting, and boundary-exact values. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WZz4ydAhbRixWwJLpUEnSj
commit: |
…failing iterate spec Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WZz4ydAhbRixWwJLpUEnSj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ffmpeg 8 (homebrew's current: 8.0.1) added a recursion-depth cap (~100) to its expression parser. video-mode's pointer overlay builds the cursor's x/y as one nested
if(between(t,a,b), value, <rest>)level per cursor waypoint segment — depth O(actions). Any spec with roughly 35+ pointer-highlighted actions now dies at render time:Empirically: nesting depth 90 parses, 100 fails. ffmpeg ≤7 has no limit, which is why short specs and older installs never noticed. First seen rendering iterate's
specs/mobile/approvals.spec.ts(~350 filter nodes).Fix
The waypoint segments are sequential and disjoint, so the nested chain is just a first-match lookup. Flatten it to a constant-depth sum:
Half-open windows (instead of inclusive-both-ends
between) keep a shared segment boundary from firing two terms and doubling the coordinate; at a boundary the successor term yields the same position the nested version picked.baseis the last waypoint's coordinate, matching the old fallback outside all segments. Depth stays ~10 no matter how long the spec gets.Tests
spec/video-mode-cursor-expression.spec.ts(node-only, 400 segments — 4× the cap):Verification
Full suite on ffmpeg 8.0.1 (the strict parser): 157 passed, 3 skipped (llm-recover, needs credentials).
spec/todo-app.spec.tsrendered baseline:video-rendered.webm
The originally-failing iterate mobile approvals spec (48s, 100+ waypoint segments), rendered green against this branch's build:
video-rendered.webm
Review notes
Riskiest part: the boundary semantics of the flattened sum (double-fire / gap edge cases) — that's what the value test pins down, boundaries included. The complement term assumes segments are contiguous, which is structural (segments are consecutive waypoint pairs). Review order:
src/plugins/video-mode.ts(cursorExpression, one function), then the spec. On merge: rendered output is pixel-identical in intent; only the filter string shape changes.🤖 Generated with Claude Code
https://claude.ai/code/session_01WZz4ydAhbRixWwJLpUEnSj