The missing evidence-clip layer between your detector and storage. Point it at a video and a detection JSONL โ get a trimmed MP4 with bounding boxes already burned in. Python. No DeepStream required.
Rendered through cv-evidence-renderer itself. Synthetic scene, synthetic detections, real output.
Your detector fires. Now you need a 15-second MP4 with bounding boxes drawn on it, to attach to an alert or archive for compliance. Every CV team writes this code from scratch, ships the bug to prod, then writes it again on the next project.
"How to overlay bbox and save a clip on event?" โ recurring thread on the
NVIDIA DeepStream forum since 2022. The only official answer (Smart Record) has
no Python bindings in the official pyds bindings, and Smart Record
itself still has open multi-stream crash reports on DeepStream 7.1.
| cv-evidence-renderer | supervision | DeepStream Smart Record | KeyClipWriter | |
|---|---|---|---|---|
| Python-only install | โ | โ | โ | โ |
| Event-window trim (offline) | โ | โ | C only | โ |
| Cross-file event concat | โ | โ | โ | โ |
| Decode-once batch | โ | โ | โ | โ |
| Output duration cap (timelapse / framedrop) | โ | โ | โ | โ |
| Bbox burn-in | โ | โ | โ | โ |
| supervision interop | โ | โ | โ | โ |
| Ultralytics YOLO adapter | โ | โ | โ | โ |
| NVENC encode | ๐ง v0.2 | โ | โ | โ |
| Live RTSP ring buffer | ๐ง v0.2 | โ | C only | โ |
| Multi-stream pool | ๐ง v0.3 | โ | โ | โ |
from cv_evidence_renderer import render_from_jsonl
render_from_jsonl(
video="incidents/raw_001.mp4",
detections_jsonl="incidents/raw_001.detections.jsonl",
event_start=12.5, # seconds
event_end=22.0,
output="evidence/event_001.mp4",
encoder="libx264", # NVENC ships in v0.2
)
That's the whole API for the most common case. Pair with from_yolo_results or from_supervision if you're routing through Ultralytics or supervision.
5 s source, 30 fps, two detections burned in every frame. Reproduce with python scripts/benchmark.py.
| Resolution | Render time | Throughput | ร realtime | Output |
|---|---|---|---|---|
| 480p (854ร480) | 0.53 s | 282 fps | 9.4ร | 0.42 MB |
| 720p (1280ร720) | 0.89 s | 168 fps | 5.6ร | 0.70 MB |
| 1080p (1920ร1080) | 1.70 s | 88 fps | 2.95ร | 1.34 MB |
Pure CPU libx264 already runs faster than realtime up to 1080p. NVENC on a discrete GPU will join this table side-by-side once it ships.
Attach evidence clips to ops alerts. Operators open the MP4, see exactly what tripped the rule. No JSON sidecar they won't read.
Re-render every detection event from a week of footage as labeled MP4 clips. Hand to annotators or stack into a training set.
Render the exact frames your detector flagged for inclusion in a publication, demo reel, or stakeholder review.
sv.Detections straight in. We add what supervision doesn't have: event-window trim, ring buffer (v0.2), and eventually NVENC.pyds bindings don't expose Smart Record (a community fork exists with a custom-built wheel). Smart Record itself also has open multi-stream crash reports on DS 7.1. When NVIDIA upstreams a clean Python API we'll add a sink so you can use both together.