namespace ytLive.Services; /// /// A normalized CPU frame (32bpp BGRA, tightly packed). The capture path hands /// these to the UI thread, which copies them into the shared WriteableBitmap. /// Deliberately the only pixel type the rest of the app knows about — every /// future capture source (screen, background-removed webcam) feeds the same seam. /// public sealed class VideoFrame { public int Width { get; } public int Height { get; } public byte[] BgraPixels { get; } public int Stride => Width * 4; /// Producer frame epoch — a monotonically increasing number stamped by /// sources that RECYCLE their pixel buffers (the screen-capture ring, take-11 spike /// fix). Consumers that key caches on buffer identity (the compositor's paste cache) /// MUST include it, or a recycled array false-hits with stale content. Producers /// that hand out fresh arrays per frame leave it 0 — identity alone is then enough. public long Epoch { get; init; } /// Producer contract: every alpha byte in is 255 /// (DWM capture surfaces and MediaCapture video carry no alpha — the OS fills 255). /// Lets the compositor take a straight-copy fast path for a full-canvas opaque /// layer instead of 2M per-pixel blends. NEVER set it for paths whose pixels can /// be transparent (static art, web overlays, chat, the social-bar strip). public bool IsOpaque { get; init; } public VideoFrame(int width, int height, byte[] bgraPixels) { Width = width; Height = height; BgraPixels = bgraPixels; } }