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. It must be created before any other NDI operations and should be kept alive for the duration of your application’s NDI usage.

§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 as the underlying NDI SDK is thread-safe. However, for optimal performance, minimize cross-thread operations and maintain thread affinity where possible.

§Zero-Copy Async Sending

The library provides zero-copy async video sending using NDIlib_send_send_video_async_v2. The completion callback notifies when the buffer can be reused:

// Register callback to know when buffer is released
sender.on_async_video_done(|len| println!("Buffer released: {} bytes", len));

let buffer = vec![0u8; 1920 * 1080 * 4];
let frame = BorrowedVideoFrame::try_from_uncompressed(&buffer, 1920, 1080, PixelFormat::BGRA, 30, 1)?;
let token = sender.send_video_async(&frame);
// Buffer is now owned by NDI - cannot be modified until callback fires
// The AsyncVideoToken must be kept alive to track the operation

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

§Performance

  • Zero-copy: Frame data directly references NDI’s buffers when possible
  • Lock-free async: Atomic operations for minimal overhead in hot paths
  • Bandwidth control: Multiple quality levels for different use cases
  • Hardware acceleration: Automatically uses GPU acceleration when available

§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.
  • Linux: Supports both standard and Advanced SDK install directories; the runtime libraries must be discoverable by the dynamic linker.
  • macOS: Supports current NDI SDK package layouts used by the CI setup action and common local install paths.

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::AudioRef;
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::VideoRef;
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::Receiver;
pub use receiver::ReceiverBandwidth;
pub use receiver::ReceiverColorFormat;
pub use receiver::ReceiverOptions;
pub use receiver::ReceiverOptionsBuilder;
pub use receiver::ReceiverStatus;
pub use receiver::Tally;
pub use runtime::NDI;
pub use sender::AsyncVideoToken;
pub use sender::BorrowedVideoFrame;
pub use sender::Sender;
pub use sender::SenderOptions;
pub use sender::SenderOptionsBuilder;
pub use frames::ImageFormat;

Modules§

async_std
async-std runtime integration.
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.
tokio
Tokio async runtime integration.
waitable_completion
Zero-overhead completion signal for async operations.

Structs§

AudioKind
Marker type for audio frame capture operations.
FrameSyncAudioFree
Free strategy for audio frames captured through FrameSync.
FrameSyncVideoFree
Free strategy for video frames captured through FrameSync.
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
Single source of truth describing one NDI frame kind (video, audio, or metadata).
FrameFree
The free strategy for one captured-frame family: the SDK instance handle type plus the SDK call that releases a single frame.

Type Aliases§

Result
Alias for Result with our Error type