Skip to main content

Crate grafton_ndi

Crate grafton_ndi 

Source
Expand description

High-performance Rust bindings for the NDI® 6 SDK (Network Device Interface).

This crate provides safe, idiomatic Rust bindings for the NDI SDK, enabling real-time, low-latency video/audio streaming over IP networks. NDI is widely used in broadcast, live production, and video conferencing applications.

§Quick Start

use grafton_ndi::{NDI, FinderOptions, Finder};
use std::time::Duration;

// Initialize the NDI runtime
let ndi = NDI::new()?;

// Find sources on the network
let options = FinderOptions::builder().show_local_sources(true).build();
let finder = Finder::new(&ndi, &options)?;

// Discover sources
let sources = finder.find_sources(Duration::from_secs(5))?;

for source in sources {
    println!("Found: {}", source);
}

§Core Concepts

§Runtime Management

The NDI struct manages the NDI runtime lifecycle. Create a handle before constructing SDK resources; those resources retain their own runtime references. SourceCache acquires the runtime on cache misses, while its cached owned source descriptors need no live runtime handle.

§Source Discovery

Use Finder to discover NDI sources on the network. Sources can be filtered by groups and additional IP addresses can be specified for discovery.

§Receiving

The Receiver type handles receiving video, audio, and metadata from NDI sources. It supports various color formats and bandwidth modes.

§Sending

Use Sender to transmit video, audio, and metadata as an NDI source. Senders can be configured with clock settings and group assignments.

§Thread Safety

All primary types (Finder, Receiver, Sender) implement Send + Sync with internal synchronization where required by the SDK. Borrowed receiver frame references support scoped thread transfer; FrameSync references remain tied to their owner and cannot be shared or transferred across threads. Immutable VideoPlane, VideoRows, and VideoPlanes views are Send + Sync from either capture family. Scoped workers may read those borrowed pixels while the frame guard stays on its permitted freeing thread.

§Async Sending

Sender::send_video_async takes ownership of a VideoFrame without copying its pixel or metadata allocations. The next submission returns the previous frame after SDK synchronization; finish recovers the final frame.

let first = VideoFrame::builder().resolution(1920, 1080).pixel_format(PixelFormat::BGRA).build()?;
let second = VideoFrame::builder().resolution(1920, 1080).pixel_format(PixelFormat::BGRA).build()?;
assert!(sender.send_video_async(first).is_none());
let mut reusable = sender.send_video_async(second).unwrap();
reusable.data_mut().fill(0);
let final_frame = sender.finish_video_async().unwrap();

Sender::send_video_async_copy explicitly copies a borrowed buffer into an owned frame, then uses the same pipeline and returns the previous frame. Source buffers can be reused immediately. Both paths use default SDK synchronization, with no SDK completion callback registration. Optional Rust completion handlers run on the calling thread after synchronization, outside internal locks.

Note: Only video supports async sending in the NDI SDK. Audio and metadata are always synchronous.

§Performance

  • Borrowed receive buffers: Read SDK-owned frames without wrapper pixel copies
  • Async completion: Owned frames are recovered after SDK synchronization
  • Bandwidth control: Multiple quality levels for different use cases
  • SDK processing: Encoding and acceleration depend on the installed NDI SDK

§Platform Support

Windows, Linux, and macOS are all exercised in CI (build, test, lint, and semver checks) against the NDI SDK.

  • Windows: Links the NDI SDK import library at build time; requires the NDI runtime DLLs at runtime. Supports x86 and x86_64 MSVC targets.
  • Linux: Supports both standard and Advanced SDK install directories; the runtime libraries must be discoverable by the dynamic linker. Uses GNU/glibc targets for x86, x86_64, ARMv6/ARMv7 hard-float, and ARM64.
  • macOS: Supports current NDI SDK package layouts used by the CI setup action and common local install paths.
  • Android: Cross-build CI links examples for ARM64, ARMv7, x86, and x86_64. Set NDI_SDK_DIR to the Android NDI SDK and configure the Android NDK linker/sysroot. Device runtime testing is separate from build coverage.

The current APIs are validated with NDI SDK 6.3.2. Apple mobile targets, including iOS, are not currently selected by the build script. See the SDK validation guide for exact target coverage and cross-compilation commands.

Re-exports§

pub use finder::Finder;
pub use finder::FinderOptions;
pub use finder::FinderOptionsBuilder;
pub use finder::Source;
pub use finder::SourceAddress;
pub use finder::SourceCache;
pub use frames::AudioFormat;
pub use frames::AudioFrame;
pub use frames::AudioFrameBuilder;
pub use frames::AudioFrameRef;
pub use frames::AudioLayout;
pub use frames::FormatCategory;
pub use frames::LineStrideOrSize;
pub use frames::MetadataFrame;
pub use frames::MetadataFrameRef;
pub use frames::PixelFormat;
pub use frames::PixelFormatInfo;
pub use frames::ScanType;
pub use frames::VideoFrame;
pub use frames::VideoFrameBuilder;
pub use frames::VideoFrameRef;
pub use frames::VideoPlane;
pub use frames::VideoPlanes;
pub use frames::VideoRows;
pub use framesync::FrameSync;
pub use framesync::FrameSyncAudioRef;
pub use framesync::FrameSyncAudioRequest;
pub use framesync::FrameSyncVideoRef;
pub use receiver::Capture;
pub use receiver::ConnectionStats;
pub use receiver::FrameSyncAttached;
pub use receiver::RawCapture;
pub use receiver::Receiver;
pub use receiver::ReceiverBandwidth;
pub use receiver::ReceiverColorFormat;
pub use receiver::ReceiverMode;
pub use receiver::ReceiverOptions;
pub use receiver::ReceiverOptionsBuilder;
pub use receiver::ReceiverStatus;
pub use receiver::Tally;
pub use runtime::NDI;
pub use sender::BorrowedVideoFrame;
pub use sender::BorrowedVideoFrameBuilder;
pub use sender::Sender;
pub use sender::SenderOptions;
pub use sender::SenderOptionsBuilder;
pub use frames::ImageFormat;

Modules§

finder
NDI source discovery and network browsing.
frames
Frame types for video, audio, and metadata.
framesync
Frame synchronization for clock-corrected video/audio capture.
receiver
NDI receiving functionality for video, audio, and metadata.
runtime
NDI runtime management and initialization.
sender
NDI sending functionality for video, audio, and metadata.
smol
smol runtime integration.
tokio
Tokio async runtime integration.

Structs§

AudioKind
Marker type for audio frame capture operations.
MetadataKind
Marker type for metadata frame capture operations.
VideoKind
Marker type for video frame capture operations.

Enums§

Error
The main error type for NDI operations.

Constants§

MAX_TIMEOUT
Maximum timeout duration supported by the NDI SDK (~49.7 days).

Traits§

CaptureKind
A sealed receiver capture kind with its borrowed and owned frame types.

Type Aliases§

Result
Alias for Result with our Error type