NextVision
A domain-agnostic, production-oriented, high-performance Rust video perception runtime built on GStreamer.
Overview
NextVision ingests live or recorded video, normalizes frames into a library-owned abstraction, pushes them through a linear sequence of user-supplied perception stages, maintains temporal state (tracks, trajectories, motion features), models PTZ/view-state, and emits structured, provenanced outputs.
Workspace crates
| Crate | Purpose |
|---|---|
nv-core |
Shared types: IDs, timestamps, geometry, errors, metadata, health events, metrics |
nv-frame |
Frame abstraction — zero-copy, ref-counted FrameEnvelope |
nv-media |
GStreamer backend — the only crate that depends on gstreamer-rs. Optional cuda feature for GPU-resident frames |
nv-perception |
Stage trait, detection/track types, perception artifacts, derived signals |
nv-temporal |
Temporal state: trajectories, motion features, continuity, retention |
nv-view |
PTZ/view-state, camera motion modeling, epoch policy, context validity |
nv-runtime |
Pipeline orchestration, feed lifecycle, output, concurrency, provenance |
nv-metrics |
Optional OpenTelemetry metrics bridge — exports diagnostics and health events via OTLP |
nv-test-util |
Test harnesses, synthetic frames, mock stages, controllable clock |
Architecture
See ARCHITECTURE.md for the full specification.
Quick start
use ;
use ;
use ;
;
Batch inference across feeds
use ;
use ;
use ;
use ;
use StageError;
use Duration;
;
Design principles
- Domain-agnostic: No transit, retail, security, or other vertical concepts in core.
- GStreamer is an implementation detail: All GStreamer types confined to
nv-media. - Performance first: Zero-copy frame handoff, bounded queues, allocation-conscious hot paths.
- Operational clarity: Every queue is bounded, every restart path is explicit, every failure is typed.
- Composition over framework: Linear stage pipeline, not a DAG engine or meta-framework.
Requirements
- Rust 1.92+ (edition 2024)
- GStreamer 1.16+ runtime libraries (for video ingestion)
- Linux recommended for production; macOS supported for development; Windows supported with use of VS Code devcontainer
Installation
Add the crates you need to your Cargo.toml:
[]
= "0.1" # Full runtime (includes nv-core, nv-frame, etc.)
= "0.1" # Stage trait, detection/track types
= "0.1" # Optional: OpenTelemetry metrics bridge
For most applications, nv-runtime is the only direct dependency needed — it
re-exports the essential types from nv-core, nv-frame, nv-perception,
nv-temporal, and nv-view.
Building from source
# Install GStreamer development libraries (Debian/Ubuntu)
# Build the workspace
# Run the test suite
Telemetry
The runtime exposes lightweight telemetry through public APIs. Per-feed and
batch counters are atomic and allocation-free. Aggregate diagnostics snapshots
(Runtime::diagnostics()) allocate a Vec for the feed/batch lists and may
clone short strings (e.g. decode-status detail).
use ;
Batch coordinator telemetry:
use BatchHandle;
All counters are atomic — no per-frame allocations, no background polling threads, no additional mutex contention on hot paths.
OpenTelemetry export (nv-metrics)
The optional nv-metrics crate bridges runtime diagnostics and health events
into OpenTelemetry instruments, exported via OTLP/gRPC. It runs in a background
tokio task and does not touch the frame-processing hot path.
Two families of instruments are exported:
- Periodic gauges (30 instruments) — sampled from
Runtime::diagnostics()on a configurable poll interval. Covers per-feed frame counts, queue depths, stage latencies, view-state, batch metrics, and runtime uptime. - Event-driven counters (18 instruments) — incremented in real time as
HealthEventvariants arrive viahealth_subscribe(). Covers source disconnects, reconnects, stage errors, panics, feed restarts, backpressure drops, view epoch changes, and view degradations.
use MetricsExporter;
// Inside a tokio runtime:
let _exporter = builder
.runtime_handle
.otlp_endpoint
.service_name
.build?;
// Gauges poll automatically; health counters fire on events.
// Call exporter.shutdown().await for clean teardown;
// drop alone cancels the poll loop but does not flush.
See the nv-metrics crate docs for the full instrument table and builder options.
License
Licensed under either of
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.