Skip to content

Frame Bus & Plugins

Everything in Phrame moves media the same way: raw frames over a shared-memory bus, through native plugins that all speak one stable interface. Add a new transport or codec, and every service can use it — no rewrites.

Frame bus & native plugins — one C ABI service (Rust / C++)input-processorvision-mixersoutput-processor plugin .soplugin_open(json)read / write / close dlopen · C ABI transport / codecshared memory · network The plugins libvdi(VDI bus) libplugin-mxl(MXL) libphramendi(NDI) libst2110(SMPTE 2110) libplugin-hls(HLS) libSvtJpegxs(JPEG-XS) libplugin-null(test) hosts dlopen a .so and drive it through a stable C ABI; config is a single JSON string


The reason Phrame’s services are so interchangeable is a single architectural decision: one plugin interface for every transport and codec.

  • Future-proof I/O. New standards (a codec, a transport) arrive as a plugin, not a platform rewrite — every service gains it at once.
  • Best-of-breed transports. VDI and MXL for the live bus, NDI and SMPTE 2110 for standards interop, HLS and JPEG-XS for delivery — mixed and matched.
  • Shared-memory speed. Frames move between services through shared memory, not copies over sockets — the performance headroom that makes software-defined broadcast viable.
  • Stable contract. A versioned C ABI means the host code and the plugins can evolve independently.

In one line: one interface behind every format — the seam that lets the whole platform stay simple and keep up with the standards.


The plugins/ directory holds the native shared libraries (.so) every service loads to move media in and out. A host:

  1. dlopens a plugin (e.g. libplugin-mxl.so) and resolves its functions;
  2. calls plugin_open(name, json_config) to get a handle;
  3. reads/writes PluginFrames (plugin_read / plugin_write, with plugin_free_frame);
  4. plugin_closes it.

Configuration is always a single JSON string the plugin parses itself, so each plugin defines its own config shape. The plugins available:

.soPlugin
libvdi.soVDI — local frame bus
libplugin-mxl.soMXL — media exchange
libphramendi.soNewTek NDI
libst2110.soSMPTE ST 2110
libplugin-tr07.soVSF TR-07 (JPEG-XS / TS / SRT)
libSvtJpegxs.soSVT JPEG-XS codec
libplugin-hls.soHLS output
libplugin-dektec.soDekTec DVB-ASI / SDI
libplugin-null.sonull sink / source (testing)

Build order matters. plugins/ is a prerequisite of every consumer image. If anything in plugins/ or common/ changed, build the plugins first (plugins/phrame-make.sh <TAG> build-image).


The C ABI is defined in common/plugin-api/plugins.h (v0.0.2). Exported functions include plugin_open / plugin_close, plugin_read / plugin_read_timeout / plugin_write, plugin_is_frame_ready, plugin_free_frame, plugin_seek, plugin_query_uuid, plugin_query_config, and plugin_get_queue_depth.

Key data structures:

  • PluginFrame — one media unit: data_type (video/audio/ancillary), dimensions/channels/nb_samples, colour_format, components[4] (planes), a 32-char format string (e.g. v210, yuv422p10le, pcm_s24be), is_compressed/has_alpha, buffer/buffer_size, and metadata (stream_uuid, frame_index, origination_time, time_base, …).
  • PluginComponent — one plane: data, stride, dimensions, bytes_per_element, bit_depth.
  • PluginReturnCodeprcOK (0) plus negative error codes.

C++ plugins inherit PluginInterface::Base and implement init(config_json), Read_impl, Write_impl, Free_Frame, QueryUUID, is_valid, is_frame_ready, Seek; a C shim dispatches the C ABI to a 16-slot array of instances.

Also staged in plugins/: libPhrameImageUtils.so (SIMD image utilities) and the MXL/NDI runtime libs.


Part of the Phrame documentation system — one Markdown source, four audiences, a code-generated house-style diagram.