← All pages
The video path

The picture

The straightforward way to get a decoded frame into a WPF window is the one thing that cannot carry HDR: it accepts eight bits per channel and nothing wider. So the frame does not go through it. libplacebo renders into a shared Direct3D 11 texture, and DirectComposition puts that texture on screen as a ten-bit plane, with the window's own overlay composed above it.

THE NETWORK THE GPU THE COMPOSITOR console → UDP packet reorder · reassemble error correction libplacebo · D3D11 shared NT texture d3d11va · vulkan · cuda WPF overlay (HUD, menu) visual: above video plane, 10 bit visual: below the window on screen The frame never passes through WPF's own image path, which refuses anything wider than eight bits per channel. It is composed beside the window's content instead, with the overlay above the plane, because that is the one arrangement that keeps both.

Why the order of the two layers matters

A composed video plane and a WPF overlay can be arranged three ways, and two of them lose something: put the plane on top and the stream HUD and the in-stream menu are behind it, invisible. The arrangement in use puts the overlay above the plane, which is the only one that keeps the picture at ten bits and keeps everything drawn over it. All three were built and looked at on a real window before one was chosen.

Paced by the display

  • The present interval is the refresh rate of the display the window is actually on, read from the system rather than assumed to be 60.
  • A display that changes rate during a session changes the pacing with it, so a switch to a different mode does not leave the stream a frame off for the rest of the evening.
  • A present that misses its deadline catches up rather than accumulating the delay, because a stream that slips once should not stay slipped.

What this asks of your GPU →

The renderer is yours

libplacebo's scalers, debanding, tone curves and colour mapping are exposed on two screens: presets for the settings nobody wants to learn, and every slider underneath for the people who do. The values are stored in the units the renderer takes, so what a slider says and what the renderer receives are the same number.