use nv_core::config::{CameraMode, SourceSpec};
use nv_core::error::StageError;
use nv_core::geom::BBox;
use nv_core::id::StageId;
use nv_perception::detection::{Detection, DetectionSet};
use nv_perception::{Stage, StageContext, StageOutput};
use nv_runtime::{DecodePreference, FeedConfig, OutputEnvelope, OutputSink, Runtime};
use std::sync::Arc;
struct MockDetectorStage {
next_det_id: u64,
}
impl MockDetectorStage {
fn new() -> Self {
Self { next_det_id: 0 }
}
}
impl Stage for MockDetectorStage {
fn id(&self) -> StageId {
StageId("mock_detector")
}
fn process(&mut self, ctx: &StageContext<'_>) -> Result<StageOutput, StageError> {
let det = Detection {
id: nv_core::DetectionId::new(self.next_det_id),
class_id: 0, confidence: 0.87,
bbox: BBox::new(0.3, 0.2, 0.4, 0.6),
embedding: None,
metadata: nv_core::TypedMetadata::new(),
};
self.next_det_id += 1;
let _ = ctx.frame.seq(); Ok(StageOutput::with_detections(DetectionSet {
detections: vec![det],
}))
}
}
struct MockClassifierStage;
impl Stage for MockClassifierStage {
fn id(&self) -> StageId {
StageId("mock_classifier")
}
fn process(&mut self, ctx: &StageContext<'_>) -> Result<StageOutput, StageError> {
let det_count = ctx.artifacts.detections.len();
if det_count > 0 {
}
Ok(StageOutput::empty())
}
}
struct DetectionLogger;
impl OutputSink for DetectionLogger {
fn emit(&self, output: Arc<OutputEnvelope>) {
let det_count = output.detections.len();
let stage_names: Vec<_> = output
.provenance
.stages
.iter()
.map(|s| s.stage_id.0)
.collect();
println!(
"seq={} detections={} stages={:?} total_latency={:?}",
output.frame_seq, det_count, stage_names, output.provenance.total_latency,
);
}
}
fn main() -> Result<(), nv_core::error::NvError> {
let runtime = Runtime::builder().build()?;
let config = FeedConfig::builder()
.source(SourceSpec::rtsp("rtsp://192.168.1.10/stream"))
.camera_mode(CameraMode::Fixed)
.stages(vec![
Box::new(MockDetectorStage::new()),
Box::new(MockClassifierStage),
])
.output_sink(Box::new(DetectionLogger))
.decode_preference(DecodePreference::CpuOnly)
.build()?;
let handle = runtime.add_feed(config)?;
println!(
"Feed {:?} running with mock detector + classifier",
handle.id()
);
std::thread::sleep(std::time::Duration::from_secs(5));
let m = handle.metrics();
println!(
"Processed {} frames, {} dropped",
m.frames_processed, m.frames_dropped,
);
runtime.shutdown()?;
Ok(())
}