pub struct Receiver { /* private fields */ }Implementations§
Source§impl Receiver
impl Receiver
pub fn new(ndi: &NDI, create: &ReceiverOptions) -> Result<Self>
pub fn ptz_is_supported(&self) -> bool
pub fn ptz_recall_preset(&self, preset: u32, speed: f32) -> Result<()>
pub fn ptz_zoom(&self, zoom_value: f32) -> Result<()>
pub fn ptz_zoom_speed(&self, zoom_speed: f32) -> Result<()>
pub fn ptz_pan_tilt(&self, pan_value: f32, tilt_value: f32) -> Result<()>
pub fn ptz_pan_tilt_speed(&self, pan_speed: f32, tilt_speed: f32) -> Result<()>
pub fn ptz_store_preset(&self, preset_no: i32) -> Result<()>
pub fn ptz_auto_focus(&self) -> Result<()>
pub fn ptz_focus(&self, focus_value: f32) -> Result<()>
pub fn ptz_focus_speed(&self, focus_speed: f32) -> Result<()>
pub fn ptz_white_balance_auto(&self) -> Result<()>
pub fn ptz_white_balance_indoor(&self) -> Result<()>
pub fn ptz_white_balance_outdoor(&self) -> Result<()>
pub fn ptz_white_balance_oneshot(&self) -> Result<()>
pub fn ptz_white_balance_manual(&self, red: f32, blue: f32) -> Result<()>
pub fn ptz_exposure_auto(&self) -> Result<()>
pub fn ptz_exposure_manual(&self, exposure_level: f32) -> Result<()>
pub fn ptz_exposure_manual_v2( &self, iris: f32, gain: f32, shutter_speed: f32, ) -> Result<()>
Sourcepub fn video(&self) -> Capture<'_, VideoKind>
pub fn video(&self) -> Capture<'_, VideoKind>
Capture video frames from this receiver.
Returns a Capture view whose verbs cover the three capture styles:
capture— reliable owned capture that retries across the NDI SDK’s initial-sync warm-up.try_capture— a single owned poll,Ok(None)when no frame is ready.try_capture_ref— a single zero-copy poll borrowing the SDK buffer in place.
Video frames may carry per-row padding (e.g. RGBX/BGRX); see
VideoFrame for how to read them correctly.
§Examples
// Reliable owned capture
let frame = receiver.video().capture(Duration::from_secs(5))?;
println!("{}x{}", frame.width(), frame.height());
// Zero-copy borrow
if let Some(frame) = receiver.video().try_capture_ref(Duration::from_secs(1))? {
let pixels = frame.data();
println!("{} bytes in place", pixels.len());
}Sourcepub fn audio(&self) -> Capture<'_, AudioKind>
pub fn audio(&self) -> Capture<'_, AudioKind>
Capture audio frames from this receiver.
Returns a Capture view; see video for the three
capture verbs it exposes (capture,
try_capture,
try_capture_ref).
§Examples
if let Some(audio) = receiver.audio().try_capture_ref(Duration::from_secs(1))? {
println!("{} channels, {} samples", audio.num_channels(), audio.num_samples());
}Sourcepub fn metadata(&self) -> Capture<'_, MetadataKind>
pub fn metadata(&self) -> Capture<'_, MetadataKind>
Capture metadata frames from this receiver.
Returns a Capture view; see video for the three
capture verbs it exposes (capture,
try_capture,
try_capture_ref).
§Examples
if let Some(meta) = receiver.metadata().try_capture(Duration::from_millis(100))? {
println!("metadata: {}", meta.data());
}Sourcepub fn is_connected(&self) -> bool
pub fn is_connected(&self) -> bool
Check if the receiver is still connected to its source.
Returns true if there is at least one active connection to the source,
false otherwise. This can be used to detect when a source goes offline
or becomes unavailable.
§Examples
if receiver.is_connected() {
println!("Still connected to source");
} else {
println!("Lost connection to source");
}Sourcepub fn reconnect(&self) -> Result<()>
pub fn reconnect(&self) -> Result<()>
Re-establish this receiver’s connection to its original source, in place.
Re-points the existing NDI receiver instance at the Source it
was created for without destroying and recreating the
receiver. This is intended for mid-session recovery: when a
source’s feed has gone silent (for example an encoder-bound
NDI|HX camera that dropped its proxy stream under load), a
reconnect forces a fresh connection attempt while avoiding the
source-rediscovery round trip — and the discovery race — that
tearing down and rebuilding the receiver would incur.
Liveness can be observed via Self::is_connected and
Self::connection_stats (video_frames_received resuming its
climb indicates frames are flowing again).
§Thread safety
NDIlib_recv_connect is the one receive call the SDK does not make
safe to run concurrently with NDIlib_recv_capture_v3 on the same
instance. This method therefore takes the receiver’s capture guard
exclusively: it blocks until every in-flight capture on this receiver
returns, and holds off any capture that starts while it runs. Captures
on the same receiver still run concurrently with each other; only a
reconnect is exclusive. Because it can block for as long as a capture’s
timeout, prefer short capture timeouts on receivers you intend to
recover, and call it off the async runtime — AsyncReceiver::reconnect
does this for you.
§Errors
Returns an error only if the stored Source cannot be
re-marshalled to its FFI representation; NDIlib_recv_connect
itself reports no status, so a returned Ok means the reconnect was
issued, not that the feed has recovered — confirm recovery via
Self::connection_stats.
Sourcepub fn source(&self) -> &Source
pub fn source(&self) -> &Source
Get the source this receiver is connected to.
Returns a reference to the Source that was specified when creating
this receiver. This is useful for identifying which source a receiver
is associated with when managing multiple receivers.
§Examples
let source = receiver.source();
println!("Connected to: {name}", name = source.name);Sourcepub fn connection_stats(&self) -> ConnectionStats
pub fn connection_stats(&self) -> ConnectionStats
Get connection and performance statistics for this receiver.
Provides detailed statistics including:
- Number of active connections
- Total frames received (video, audio, metadata)
- Dropped frames (video, audio, metadata)
- Queued frames waiting to be processed
This is useful for monitoring receiver health and diagnosing performance issues in production applications.
§Examples
let stats = receiver.connection_stats();
println!("Connections: {connections}", connections = stats.connections);
println!("Video frames: {received} (dropped: {dropped})",
received = stats.video_frames_received,
dropped = stats.video_frames_dropped);
println!("Frame drop rate: {rate:.2}%",
rate = stats.video_drop_percentage());Sourcepub fn poll_status_change(
&self,
timeout: Duration,
) -> Result<Option<ReceiverStatus>>
pub fn poll_status_change( &self, timeout: Duration, ) -> Result<Option<ReceiverStatus>>
Poll for status changes (tally, connections, etc.)
§Arguments
timeout- Maximum time to wait for status change. Must not exceedcrate::MAX_TIMEOUT(~49.7 days).
§Returns
Some(ReceiverStatus)- Status has changedNone- Timeout occurred with no status change
§Errors
Returns Error::InvalidConfiguration if timeout exceeds crate::MAX_TIMEOUT.
Trait Implementations§
impl Send for Receiver
§Safety
The NDI 6 SDK documentation explicitly states that recv operations are thread-safe.
NDIlib_recv_capture_v3 and related functions use internal synchronization.
The Receiver struct only holds an opaque pointer returned by the SDK, and the SDK
guarantees that this pointer can be safely moved between threads.
impl Sync for Receiver
§Safety
The NDI 6 SDK documentation guarantees that NDIlib_recv_capture_v3 is internally
synchronized and can be called concurrently from multiple threads. This is explicitly
mentioned in the SDK manual’s thread safety section. The capture verbs (via
Receiver::video, Receiver::audio, and Receiver::metadata) can be
safely called from multiple threads simultaneously.