Skip to content

Fix #184: pin verified FFmpeg build and validate extracted frames - #192

Merged
edenaion merged 3 commits into
mainfrom
fix/issue184-ffmpeg-pin-and-validation
Jul 11, 2026
Merged

edenaion merged 3 commits into
mainfrom
fix/issue184-ffmpeg-pin-and-validation

Conversation

@edenaion

Copy link
Copy Markdown
Owner

Fixes #184.

Problem

Repair FFmpeg downloaded BtbN's rolling latest build. FFmpeg's release/8.1 branch picked up a CUDA rework on 2026-06-29 (after the n8.1.2 tag) whose builds can write corrupt EXR frames during hardware-decode extraction: invalid zlib chunks inside ZIP16 files. Reproduced locally on the reporter's exact clip with the exact extraction arguments the app generates. The same builds can also abort with allocation failures in the EXR encoder. Every user who ran Repair FFmpeg after June 30 received a defective build, and AI methods then failed with 'failed to read frame'.

Testing also showed the corruption race fires at a low rate on older builds, so validation has to protect every install, not just poisoned ones.

Fix

☼ Repair FFmpeg now downloads a pinned, dated, immutable autobuild (2026-06-27, tag-exact n8.1.2), verified against the reproduction clip. No rolling tags, no release-API dependency.
☼ Startup validation flags installed post-tag n8.1.2 rolling builds and shows a dedicated diagnostic that walks the user to Repair FFmpeg.
☼ The DWAB recompression pass reads every frame back and now reports unreadable frames instead of swallowing them. The .dwab_done marker is only written when every frame is clean.
☼ Corrupt extractions retry once in safe mode (software decode plus single-threaded EXR encode), re-validate with a pool-free sequential recompress, and raise an actionable error if frames are still unreadable.
☼ A worker process dying (BrokenProcessPool) or a crashed recompress subprocess now counts as per-frame failure and feeds the retry, never a silent 'clean'.
☼ Hardware-decode extraction failures on a resumed import now restart from frame 0 after the wipe, instead of seeking past the deleted prefix.
☼ Diagnostic dialogs: scroll viewports keep the app background (no white panel), long detail lines word-wrap.

Verification

☼ Pinned asset re-downloaded fresh and hash-matched against the build validated on the dev machine; EXR encoder confirmed present.
☼ Reproduction matrix on the reporter's clip: corruption reproduced on rolling builds with CUDA decode, encoder allocation failures reproduced with single-threaded encode on rolling builds, pinned build clean across runs.
☼ 30 ffmpeg-tools tests covering the pin, known-bad detection, retry flow, resume interaction, and subprocess failure semantics. Full suite: 732 passed.
☼ Startup modal exercised end to end against a simulated poisoned install (real diagnostics routine, real dialog, app theme).

edenaion added 2 commits July 10, 2026 18:33
Repair FFmpeg previously downloaded BtbN's rolling latest build. FFmpeg's
release/8.1 branch picked up a CUDA rework on 2026-06-29 whose builds can
write corrupt EXR frames (invalid zlib chunks) during hardware-decode
extraction, and can abort with allocation failures in the EXR encoder.
Users who ran Repair FFmpeg after June 30 got that build, and every AI
method then failed with 'failed to read frame' on affected clips.

☼ Pin Repair FFmpeg to the dated immutable autobuild 2026-06-27 (tag-exact
  n8.1.2), verified against the issue #184 reproduction clip. No rolling
  tags, no release-API dependency.
☼ Flag installed post-tag n8.1.2 rolling builds at startup and show a
  dedicated diagnostic that walks the user to Repair FFmpeg.
☼ Surface DWAB recompression read failures instead of swallowing them;
  the pass now doubles as a frame integrity check and only writes the
  .dwab_done marker when every frame reads back.
☼ Retry corrupt extractions once in safe mode (software decode plus
  single-threaded EXR encode), re-validate with a pool-free sequential
  recompress, and raise an actionable error if frames are still
  unreadable. The frame-corruption race exists at low rate in older
  builds too, so validation and retry protect every install.
☼ Keep recompression alive when a worker process dies (BrokenProcessPool
  is now a per-frame failure, not a silent abort), and log the tail of
  child stderr where the actual exception lives.
☼ Word-wrap the startup diagnostic detail label so long messages are
  never clipped.
☼ Tests: pinned-asset resolver, known-bad detection, safe-mode retry,
  sequential fallback wiring (28 ffmpeg-tools tests, full suite green).
In-app QA of the frame-corruption fix surfaced three adjacent defects.

☼ Adaptive EXR encoder threading. The encoder is frame-threaded and
  commits ~52 bytes per pixel per thread (measured: 435 MB per thread at
  4K, 15.6 GB total at auto threads on a 32-core machine). Machines
  without that much commit headroom failed 4K imports with 'Cannot
  allocate memory'. Extraction now probes free commit via
  GetPerformanceInfo and caps encoder threads to what the machine can
  afford (half of free commit, floor 2, ceiling cores). Machines with
  headroom keep full-speed auto threading; loaded or small machines
  import slower instead of failing.
☼ Out-of-memory failures now raise a human message naming the cause and
  the remedy instead of a raw codec error.
☼ Extraction failures are visible: the viewer re-renders instead of
  keeping the stale 'Extracting frames...' placeholder forever, known
  failure signatures open the diagnostic dialog with fix steps, and
  unknown ones show a warning box. Previously the only signal was an
  error sound and a log line.
☼ RUN EXTRACTION now retries clips in the ERROR state (wiping partial
  frames first via the existing retry path). The button was silently
  dead after any failure.
☼ Tests: adaptive cap decision table, cap plumbing into the FFmpeg
  command, OOM message, hermetic commit-probe isolation for existing
  tests (37 ffmpeg-tools tests, full suite 739 green).
@edenaion

Copy link
Copy Markdown
Owner Author

In-app QA drove three more fixes onto this branch (68863b3):

☼ Adaptive EXR encoder threading. Bench on the reporter-class pipeline: the encoder is frame-threaded at ~52 bytes/pixel/thread. At auto threads a 32-core machine commits 15.6 GB for one 4K import and fails with 'Cannot allocate memory' when commit headroom is smaller. Extraction now probes free commit and caps encoder threads to what the machine can afford; fast machines keep auto speed.

Encoder threads Time (470 frames 4K) Peak commit
auto (32) 36.9 s 15.63 GB
16 54.2 s 8.68 GB
8 88.9 s 5.26 GB
4 184.0 s 3.48 GB

☼ Out-of-memory extraction failures raise a human message instead of a raw codec error.
☼ Extraction failures are now visible in the UI (viewer re-renders, diagnostic dialog for known signatures, warning box otherwise) and RUN EXTRACTION retries ERROR clips. Previously the viewer showed 'Extracting frames...' forever and the button was dead.

QA evidence: poisoned-build startup modal, blocked import, Repair flow installing the pinned build, and status turning green were all exercised on the live app.

The issue #184 install held a master nightly delivered by the
2.1.0-era Repair. The stable-build fix in 2.1.2 only changed future
downloads and never audited what was already installed, so the
corrupting build survived two updates undetected. Any dev/nightly
build now fails validation with the repair prompt, exact reported
version string covered by tests.
@edenaion

Copy link
Copy Markdown
Owner Author

Reporter's version string came back: a master nightly (N-125505, built 2026-07-08), delivered by the 2.1.0-era Repair on his install day and never replaced or flagged by later updates. Postdates the CUDA rework, same corruption class as reproduced here.

That exposed a detection gap: the known-bad pattern only matched post-tag stable builds. 67cea6a flags every development nightly as needing repair, with his exact version string in the tests. Full suite 741 green.

@edenaion
edenaion merged commit 8222383 into main Jul 11, 2026
5 checks passed
@edenaion
edenaion deleted the fix/issue184-ffmpeg-pin-and-validation branch July 12, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EZ-CorridorKey 2.1.2 - Clip remains RAW after Generate, inference cannot start (RTX 5080)

1 participant