Scope justification: Assets/starting-background.jpg is outside this unit — the creator's replacement art, still awaiting their visual check (recorded in the landmines).
41 lines
2.7 KiB
Markdown
41 lines
2.7 KiB
Markdown
# HANDOFF — 2026-11-12 (bitrate + audio-clock fixes; sync number pending)
|
||
|
||
## State
|
||
|
||
- `main`; `b265d42` is the latest pushed commit. Everything after is local.
|
||
- **Bitrate saga closed.** An @8 stream averaged 5.1 Mbps because the args were capped VBR, not CBR
|
||
(measured: 9 kbps vs 1951 kbps at a 2000k target on a static frame). `700c7a8` adds `-rc cbr` for
|
||
NVENC/AMF, nothing for QSV (infers CBR from bitrate == maxrate) or OpenH264 (no measurable gain).
|
||
- Ladder `1708667` (12/10/6); floor `93719a2` (tier YouTube minimum); rate box `f2cab5c`; rate history +
|
||
consent proposal `b0f8263`; pre-release 60 fps switch `1e3a4f7`.
|
||
- **Audio drift closed** (`47f409f`, `102cb96`, `751d9b1`): the mix is driven by the monotonic clock,
|
||
counts only audio whose write reached the pipe, and starts its clock at session open. Measured
|
||
across three recordings: +2.1% long → 226 ms short → 137 ms short → **lengths now match (34 ms in
|
||
13 s)**.
|
||
- **What is left is one number.** `5ae5280` gives the mic delay a 0..500 slider (off/175/350) and logs
|
||
the applied value. Measured on the last clip: `-185 ms`, i.e. sound still 185 ms EARLY, so the value
|
||
to try is **350–360 ms**. `Audio.MicSyncOffsetMs` is stored per profile.
|
||
- **675 tests green, 0 warnings.** `scripts/avsync.py` measures any recording in seconds.
|
||
|
||
## Next action
|
||
|
||
- Creator: set the mic delay to 350, record ~15 s, run `./scripts/avsync.py "<clip>" --crop
|
||
764x764+1032+159`. Target: `offset` inside ±30 ms and `lengths match`.
|
||
- Then resume the queue: **40·A/C/D → Move → 9·5 → 14·16/17/18 → 66 → 67 → 68 → 69 → 70 → 36**.
|
||
- Do not push app commits absent a checkpoint request.
|
||
|
||
## Landmines
|
||
|
||
- `Assets/starting-background.jpg` is modified in the working tree, **awaiting the creator's visual
|
||
check** — do not commit it with another unit.
|
||
- **Never read a field the constructor assigns later** (`RefreshRateProposal()` at ctor 354 reads
|
||
`_framePump`, built at 468 — 8 failing tests, `e654a16`).
|
||
- **Never pipe a long job through `tail`** — it buffers, so a live gate looks dead, and verify's phase-3
|
||
build writes to `/dev/null`. Use `vstest --logger:"console;verbosity=normal"`; it names the failure.
|
||
- A killed test run leaves `testhost.exe` holding `LlamaCasty.dll`; every later build then fails on the
|
||
copy. `taskkill.exe /F /IM testhost.exe` before rebuilding.
|
||
- `ChromaKeyRealClipTests`, `AudioPipelineTests.Mix_*`, `AppLogRotationTests` and
|
||
`NotificationAreaIntegrationTests` flake under load; each passes alone.
|
||
- Every rate change is a full encoder relaunch; rates go through `MainViewModel.EffectiveQuality`.
|
||
- `MainWindow` tests need a temporary `LayoutPathOverride` cleared in `finally`; read render numbers in Release.
|