91e69f0bcb9bce6cda9eeb6f7eb15c7d08c1925f
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2e9fa45580 |
feat(review): flag handles in the review player (metadata only)
Deploy / deploy (push) Successful in 3m31s
Renders run 8 frames past the cut at each end. Directors were flagging glitches in unfixed handles as shot problems, so the player now marks them — without trimming or burning anything into the EXRs/MOV/MP4. - Version.handleHead/handleTail/pictureStartFrame, Export.handleHead/ handleTail; migration backfills pipeline exports and their preview versions from the manifest's handleFrames (else 8) - AE panel: "Includes handles [8] frames each end" -> manifest.review; older manifests fall back to source.handleFrames - finalize copies handles onto the Version; worker 1.6.4 reports the head slate length (pictureStartSeconds), else the player infers it as MP4 frames - EXR frameCount - Player: hatched HANDLE / SLATE regions and cut marks on the timeline, "HEAD/TAIL HANDLE · NOT IN EDIT" overlay on handle frames, HANDLE badge on notes, "Edit range only" toggle (default on in the client portal) - Staff Handles editor on the review page for manual uploads/corrections Also fixes two player bugs found while testing: timeToFrame floored float error (every seek landed a frame early), and J/reverse never ran (the keyboard effect's cleanup stopped it on the next render). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
93137cdcd2 |
fix(connector): anchor built comps on the plate's own EXR timecode
Build Shot produced comps starting at 00:00:00:00 because the panel never actually read the EXR timecode. getFootageStartFrames ranked a fragile "New Comp from Selection" probe first: it toggles the Project panel via the Window menu to get focus, and where that does not land the menu item is greyed out, executeCommand silently does nothing, and the probe returns null. A shot with no timecodeStart then fell through the API rank to zero. The worker already reads EXR headers properly in ExrHeader.cs, and its validation ranks the plate's own timeCode above the API value, which stores the editorial in-point and sits a handle-length ahead of the plate by design. Shots were therefore being built from rank 3 and validated against rank 1. That is a timecode desync waiting to reach a delivery, not just a cosmetic start frame. readExrTimecode ports the worker's reader to ExtendScript and becomes rank 1: one short header read, walking `name\0 type\0 int32 size data` for timeCode and falling back to timeCodeString where a writer omitted the packed attribute. decodePackedTimecode mirrors Timecode.FromPacked, decoding the SMPTE 12M BCD a byte at a time so the arithmetic never touches the sign bit. The menu probe is kept as rank 2 and now runs only when the plate carries no timecode at all, so the Project-panel toggle is off the normal path. setCompStartFrame was the second failure. Assigning displayStartFrame on a version of AE that does not have the property is ignored silently rather than throwing, so the early return skipped the displayStartTime fallback entirely. It now reads the value back, falls through when it did not take, and returns whether anything stuck; buildShotFromCode logs when nothing does. A start frame that cannot be set is now visible in the diagnostics report instead of a comp quietly sitting at zero. A plate whose timecode is present but zero still falls through to the API rank, keeping the existing frames > 0 convention so the safety net survives. If a genuine 00:00:00:00 plate should win outright that is a deliberate follow-up. The parser is covered against synthetic headers, including the 0x18585712 example documented in ExrHeader.cs, drop-frame, truncated and non-EXR input. What is not yet exercised in a live After Effects session is mainSource.file resolving to the sequence's first frame and displayStartFrame taking on a given AE build, so build one shot and check its start against the plate before relying on this. Picture-lock automation was reverted for a timecode desync of the same shape. PANEL_VERSION goes to 2.6.0 per the documented rule, so Pipeline → Machines does not show two workstations on one version behaving differently. The startSource comment in the manifest schema enumerated only the two older values; the queue-time provenance check keys on /\bAPI\b/ and so already reads "EXR timecode …" as trustworthy rather than suspect. The same silent-failure setCompStartFrame still exists in the farm-side vfxr_build_preview.jsx, which is fed the right value from the manifest but can drop it the same way. Left for its own change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
37f73a2bd7 |
fix(validation): separate output file numbering from comp frame numbers
Deploy / deploy (push) Successful in 6m13s
A render carries frame numbers in two unrelated systems. The comp is anchored to its plate's timecode, so its timeline runs 1247792-1247896; the output module names files from 1001. Validation compared the file numbers against the comp range and failed every correctly-rendered shot by ~1.2 million frames — first_frame, last_frame and missing_frames all reporting a defect that was not there. The manifest now carries outputFrameStart (the output module's starting number, house convention 1001) alongside the comp range. Count and contiguity are measured on the output numbering; first/last compare against outputFrameStart and are SKIPPED on older manifests, where the count and gap checks still hold on their own. The same conflation broke the API timecode fallback: it anchored on the comp's frameStart while the render's first frame is 1001, producing a +1246791 frame "offset". Shot.timecodeStart is the edit in-point and the plate carries handleFrames of head handle, so the reference is the API value less handles, anchored on the render's own first frame. Verified on the shot that reported it: UNG_107_051_010 v004 now passes count, contiguity and a plate-anchored timecode match. Regression tests cover both coordinate systems, including that a genuine +8 handle offset still fails. Panel 2.1.2. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
feb1c7b3e9 |
feat(render-pipeline): validation, QC and delivery builder
Completes RenderPipeline2 phases 3-5. Additive throughout: with validation.enabled=false the pipeline behaves exactly as before. Validation (§8) runs on the worker straight after a render, while it still holds the job and the files are local. Everything is read from the EXR header — one 64 KB read per sampled frame, no pixel decode — so the engine needs no oiiotool. The render job deliberately stays open through the stage, so a worker that dies there is reaped and retried instead of stranding the export in VALIDATING. Timecode is the primary check and is anchored on the plate, never the API: measured on the live show, Shot.timecodeStart is the editorial in-point and sits one handle-length (8f) ahead of the plate, so checking against it would pass the defective exports and fail the correct ones. Reference precedence is manifest timing plate -> plate found on disk -> API value, and the API rank is WARN-only. The panel now resolves plate provenance by walking the comp's own footage layers, so the worker never guesses which element carries the comp's timing. Verified against real studio renders via the new --validate mode: it catches both defect classes seen in shipped work — the +8 handle offset and frame-derived timecode (00:00:41:17 = frame 1001 at 24fps). QC (§10) is one service behind two front doors, API-key for the panel and session for the web. PASS means ready to upload and nothing else; FAIL sets the comp task to CHANGES. The panel gains a QC section that imports the real EXR sequence at full res rather than the H.264. Delivery (§11) rides the existing queue as a DELIVERY_BUILD job: hard links with a copy fallback, verification by re-hashing delivered bytes against the validation-time digest, manifest.json and the CSV report. fsutil hardlink list is unavailable over SMB, so link identity is never queried — reading the bytes back covers links and copies alike. Also fixes ApiClient.ProgressAsync throwing on transport failure, which would have aborted work in flight during a brief server outage; progress reporting is best-effort by contract. Removes the stale RenderWorker/ rule from the root .gitignore. The worker's source is tracked like the rest of the repo and its own .gitignore already covers bin/, obj/ and publish/; the rule silently excluded new files while the existing 20 stayed tracked. Not yet applied: migration 20260813000000 was hand-written because the dev database was unavailable — run prisma migrate deploy and verify before relying on it. None of this has run against a live server. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
cc89415a29 |
feat(pipeline): render queue, worker service and automated preview generation
One "Queue Export" click now renders the EXR sequence, then rebuilds the shot headlessly with the studio slate/overlay template to produce the delivery MOV and review MP4. Implements RenderPipeline2 phases 1-2 plus the preview stage. Server: - New models Export, RenderJob, ExportEvent, Machine, WorkerHeartbeat, plus Project.deliveryConfig and per-submission slate fields (Export.vfxScope, Export.submissionNote, inherited from the shot's previous export). Both migrations are purely additive; no existing column is touched. - lib/render-pipeline: server-enforced state machine, transactional version increment with supersede, atomic FOR UPDATE SKIP LOCKED claim gated by machine availability windows, and a lease reaper run from instrumentation.ts. - /api/ext/* endpoints for the panel and workers; session-auth mirrors under /api/render and /api/machines for the web UI. - Pipeline pages: render queue, export detail, machine monitoring, plus an Exports tab on shot detail. RenderWorker (.NET 8 Windows service, new): - Registration, heartbeat as cancel channel, claim loop, aerender runner with progress parsing and stall watchdog, crash recovery and disk-spooled reporting that survives server downtime. - Preview stage: headless AE assembles the preview comp into a throwaway AEP with both output modules queued, then a single aerender pass renders them. Preview jobs are not claimed while an interactive AE session is open, so an artist's project is never taken over. AE panel: Queue Export with live status polling, urgent flag, retry, and the VFX Scope / Submission Note fields. Every existing panel action is unchanged. Preview chaining ships disabled behind SystemConfig preview.enabled. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |