Interface IVideoFrameSink
- Namespace
- SharpConsoleUI.Video
- Assembly
- SharpConsoleUI.dll
Strategy for delivering decoded video frames to the terminal. Implementations provide different rendering backends — character-cell approximations (half-block, ASCII, braille) or the Kitty graphics protocol for pixel-accurate playback on supporting terminals.
public interface IVideoFrameSink : IDisposable
- Inherited Members
- Extension Methods
Remarks
Lifecycle:
IngestFrame(byte[], int, int, int, int, Color) is called on the playback background thread whenever FFmpeg produces a new frame. It may do heavy work (cell conversion, terminal transmission). Implementations must be thread-safe against concurrent Paint(CharacterBuffer, LayoutRect, LayoutRect, Color, Color) calls from the render thread.
Paint(CharacterBuffer, LayoutRect, LayoutRect, Color, Color) is called on the render thread from inside PaintDOM. It should be lightweight — blit cells, write placeholder cells.
OnStopped() is called when playback stops so the sink can release any terminal-side state (delete transmitted Kitty images).
Methods
ForceRefresh()
Requests that the sink rebuild any terminal-side state on the next ingested frame. No-op for cell-mode sinks; for the Kitty sink this triggers a full image+placement recreation, which is the same reset that happens on window resize and is the one reliable way to recover from the (rare) stuck-black state where the terminal stops redrawing after in-place frame updates. Exposed so a user-facing keybind can force recovery without having to resize the window.
void ForceRefresh()
GetPreferredPixelSize(int, int)
Returns the preferred pixel dimensions for FFmpeg to decode into, given the target cell area. Cell-mode sinks typically want (cellCols, cellRows * N) where N is the vertical pixel density of the mode; Kitty mode wants much higher resolution.
(int Width, int Height) GetPreferredPixelSize(int cellCols, int cellRows)
Parameters
Returns
IngestFrame(byte[], int, int, int, int, Color)
Ingests a freshly decoded RGB24 frame. The caller must guarantee the byte array
holds pixelWidth * pixelHeight * 3 bytes, row-major.
Implementations must not retain the byte array beyond this call — copy out or consume
synchronously, because the playback loop reuses the same buffer across frames.
void IngestFrame(byte[] rgb24, int pixelWidth, int pixelHeight, int targetCols, int targetRows, Color windowBackground)
Parameters
rgb24byte[]pixelWidthintpixelHeightinttargetColsintTerminal columns the playback loop intends the frame to occupy.
targetRowsintTerminal rows the playback loop intends the frame to occupy.
windowBackgroundColor
OnStopped()
Called when playback stops or the sink is being replaced. Releases any terminal-side resources (e.g. deletes transmitted Kitty images). Safe to call multiple times.
void OnStopped()
Paint(CharacterBuffer, LayoutRect, LayoutRect, Color, Color)
Paints the most recently ingested frame into the character buffer, centered within
contentRect, respecting clipRect. Also fills any
letterbox/pillarbox gaps with the window background so stale cells underneath don't
bleed through. Safe to call even if no frame has been ingested yet (fills with
background in that case).
void Paint(CharacterBuffer buffer, LayoutRect contentRect, LayoutRect clipRect, Color windowForeground, Color windowBackground)
Parameters
bufferCharacterBuffercontentRectLayoutRectclipRectLayoutRectwindowForegroundColorwindowBackgroundColor