fix: audio silence (idempotent sync-delay configure), webcam gray block, truncated videos
- AudioSyncDelay.Configure reallocated/zeroed its buffer every ~10ms tick
(AudioMixer re-reads the UI setting each mix), so any non-zero sync offset
erased the just-written audio -> total silence. Now early-returns when the
delay samples are unchanged. Regression test proven both ways.
- SceneCompositor.BlitContentRaw defaulted cbW/cbH=0 when CropBounds is null
(regression from ed9d7c1) -> webcam blit to an empty rect = gray block.
Default to src.Width/Height. Regression test proven both ways.
- Truncated recordings: rawvideo mux stamps frames at declared 60fps by
arrival; a scene whose first layer is dynamic (hidden elements still count)
kills the bake cache -> full render ~35ms -> ~27fps submitted -> halved
file length. Static scenes bake once (246ms cold, then <1ms) -> 60fps,
full-length (probe + 13:53 take, 301/300 per 5s, 12.46s file from 12.3s
wall). FramePump.ProbeRender names the hot render path on slow frames.
This commit is contained in:
@@ -258,13 +258,7 @@ public sealed class SceneCompositor
|
||||
var ew = (float)element.Width;
|
||||
var eh = (float)element.Height;
|
||||
var isRound = element.ClipShape == ClipShape.Round;
|
||||
|
||||
// Webcam diagnostic: Log when webcam frames are processed
|
||||
if (element is WebcamSceneConfig)
|
||||
{
|
||||
AppLog.Write($"Compositor webcam: {frame.Width}x{frame.Height}, IsOpaque={frame.IsOpaque}, element={element.GetType().Name}");
|
||||
}
|
||||
|
||||
|
||||
// All rect-placed elements route through the paste cache (take-9 lesson): the
|
||||
// IsOpaque bypass kept re-sampling the webcam (~156k px) EVERY tick even when
|
||||
// the device frame had not changed; an opaque source rasterizes to an opaque
|
||||
@@ -434,10 +428,16 @@ public sealed class SceneCompositor
|
||||
|
||||
float scale, ox, oy, invScale;
|
||||
float drawnW, drawnH;
|
||||
// No CropBounds means "the whole source canvas is the crop region" — cbW/cbH
|
||||
// MUST default to the full source dims, not 0. A zero cbW/cbH makes every
|
||||
// sxCrop/syCrop below evaluate to 0 regardless of position, collapsing the
|
||||
// entire sampled rect to source pixel (0,0) (the webcam gray-block regression,
|
||||
// 2026-09-12: introduced by the CropBounds Fill-style scaling work the same
|
||||
// day — CropBounds-bearing sources, i.e. the web widget, were never affected).
|
||||
var cbX = 0;
|
||||
var cbY = 0;
|
||||
var cbW = 0;
|
||||
var cbH = 0;
|
||||
var cbW = src.Width;
|
||||
var cbH = src.Height;
|
||||
|
||||
if (src.CropBounds is { } cb)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user