Summary
Add a public, production-grade video analytics subsystem: NVIDIA DeepStream 9.0 pipelines (decode → detect → track → crop) fed by Triton over gRPC, with results stored durably and queryable (time/camera/class filters, text semantic search, reverse-image search) for an external UI. Runs on a single multi-GPU server via docker compose and ships a Kubernetes Helm chart with KEDA autoscaling and HA hygiene.
📄 Full implementation plan (4 documents): https://gist.github.com/davidamacey/aa2e01e46894f5437176b231caeb0645
01-overview-context-decisions.md — context, verified foundations on main, locked decisions, reconciled naming, risk register
02-core-pipeline-design.md — repo layout, DeepStream pipeline + PGIE/tracker configs, crop sampling/embedding, event schemas, track stitching, Postgres/OpenSearch/MinIO data model, query API, job orchestration, performance plan, testing
03-deployment-kubernetes-design.md — compose overlay, container images + Trivy gates, Helm chart, KEDA, GPU scheduling, HA checklist, scaling formulas, CI/CD, ops runbook
04-implementation-phases.md — validation spikes S1–S7 (riskiest-first, go/no-go), PR1–PR10 breakdown with definitions of done, end-to-end verification script
The implementation-guide comments below this issue contain ground rules, environment facts, spike details, and per-PR acceptance criteria for the implementing agent/developer.
Capabilities
- Live RTSP feeds — 1..N third-party IP cameras (we only receive; no edge control). Runtime camera add/remove without pipeline restarts (
nvmultiurisrcbin + a Postgres-backed assigner and a compacted Kafka control topic).
- Batch video segments — 5/10/15-minute chunks recorded from live feeds but delivered late; processed faster-than-realtime (K=8 concurrent file sources per GPU, ~20×+ realtime on an A6000), queue-driven, KEDA scale-to-zero.
- Ad-hoc uploads — arbitrary videos via
POST /v1/video/jobs (priority lane).
- Detection + tracking — existing
yolov11_small_trt_end2end engine (EfficientNMS in-engine, 80 COCO classes, vehicles prioritized) as nvinferserver PGIE via Triton gRPC; NvDCF tracker (perf preset live / accuracy preset batch).
- Search — 3–10 representative crops per track embedded with
mobileclip2_s2_image_encoder (512-d); OpenSearch kNN indexes for crops/tracks/scenes; text queries via the existing mobileclip2_s2_text_encoder path; cross-segment track stitching (spatiotemporal + appearance gates) yields global_track_id.
- Storage — PostgreSQL (source of truth: cameras, jobs, assets, tracks), OpenSearch (vectors/search), MinIO/S3 (segments, crops, keyframes, model repo), Kafka-protocol events (Redpanda locally; portable to Apache Kafka / AWS MSK incl. IAM auth).
Architecture
RTSP cams ──► video-worker-live (DeepStream: NVDEC → PGIE yolov11 @ Triton gRPC → NvDCF → probes) ─┐
5-15 min files ► MinIO ─ S3 events ─► job topics ─► video-worker-batch (same pipeline, K=8 files) ├─►
ad-hoc upload ► POST /v1/video/jobs ────────────────────────────────────────────────────────────────┘
│ crop JPEGs (nvjpeg → MinIO) + track/segment events (Kafka JSON)
▼
video-writer (Kafka → Postgres upserts → MobileCLIP embeddings via AsyncTritonPool
→ OpenSearch bulk → track stitching → rollups) video-janitor (leases, intake, GC)
▼
video-api (/v1/video/*: cameras, jobs, tracks, text/image search, presigned media) ─► external UI
Built on assets already on main: the hardened DeepStream 9.0 container (docker/hardened/deepstream/, CVE-gated, verified nvinferserver → Triton gRPC at ~951 FPS), the hardened Triton 26.06 image, existing TensorRT engines, AsyncTritonPool, and the OpenSearch kNN layer. Guiding rule: pixels stay on the GPU — only metadata, embeddings, and selected JPEGs leave the pipeline (NVIDIA VSS-blueprint pattern).
Scope
In: everything above + compose overlay (docker-compose.video.yml, ports 4620–4629), Helm chart (deploy/helm/openprocessor-video/) with bundled↔external switches (Redpanda↔MSK, CNPG↔RDS, MinIO↔S3, OpenSearch↔managed), CI workflows (image Trivy gates, helm lint/kind fake-mode smoke, compose validate), docs + runbook, demo profile (mediamtx fake cameras — zero-camera out-of-box demo).
Out (documented for later): VLM/summarization tiers, ReID tracker models (config-swap path documented), Avro/schema registry (JSON envelope now), DINO-style visual reranker, edge components (cameras are third-party).
Phase checklist
Acceptance criteria
make video-up + make video-demo on a GPU box: fake RTSP cameras register, tracks accumulate, camera removal detaches cleanly.
- Ad-hoc job on a known clip:
succeeded, track count within ±20% of golden, every track has ≥1 crop in MinIO and docs in OpenSearch.
- One clip split into two overlapping segments → the boundary vehicle carries a single
global_track_id.
POST /v1/video/search/text {"query":"red truck"} ranks the seeded truck track first; reverse-image search returns the same vehicle's other crops.
- Writer event replay changes no row/doc counts (idempotency).
make video-bench: >400 aggregate FPS on an A6000-class GPU; a 5-minute 1080p segment processes in <60 s.
- Trivy 0 CRIT / 0 HIGH (with documented VEX) on all published images;
helm lint + kubeconform + kind fake-mode install green.
- All Kafka client code runs unmodified against plain Apache Kafka (SASL/TLS) — verified by the release smoke.
Summary
Add a public, production-grade video analytics subsystem: NVIDIA DeepStream 9.0 pipelines (decode → detect → track → crop) fed by Triton over gRPC, with results stored durably and queryable (time/camera/class filters, text semantic search, reverse-image search) for an external UI. Runs on a single multi-GPU server via docker compose and ships a Kubernetes Helm chart with KEDA autoscaling and HA hygiene.
📄 Full implementation plan (4 documents): https://gist.github.com/davidamacey/aa2e01e46894f5437176b231caeb0645
01-overview-context-decisions.md— context, verified foundations onmain, locked decisions, reconciled naming, risk register02-core-pipeline-design.md— repo layout, DeepStream pipeline + PGIE/tracker configs, crop sampling/embedding, event schemas, track stitching, Postgres/OpenSearch/MinIO data model, query API, job orchestration, performance plan, testing03-deployment-kubernetes-design.md— compose overlay, container images + Trivy gates, Helm chart, KEDA, GPU scheduling, HA checklist, scaling formulas, CI/CD, ops runbook04-implementation-phases.md— validation spikes S1–S7 (riskiest-first, go/no-go), PR1–PR10 breakdown with definitions of done, end-to-end verification scriptThe implementation-guide comments below this issue contain ground rules, environment facts, spike details, and per-PR acceptance criteria for the implementing agent/developer.
Capabilities
nvmultiurisrcbin+ a Postgres-backed assigner and a compacted Kafka control topic).POST /v1/video/jobs(priority lane).yolov11_small_trt_end2endengine (EfficientNMS in-engine, 80 COCO classes, vehicles prioritized) asnvinferserverPGIE via Triton gRPC; NvDCF tracker (perf preset live / accuracy preset batch).mobileclip2_s2_image_encoder(512-d); OpenSearch kNN indexes for crops/tracks/scenes; text queries via the existingmobileclip2_s2_text_encoderpath; cross-segment track stitching (spatiotemporal + appearance gates) yieldsglobal_track_id.Architecture
Built on assets already on
main: the hardened DeepStream 9.0 container (docker/hardened/deepstream/, CVE-gated, verifiednvinferserver → TritongRPC at ~951 FPS), the hardened Triton 26.06 image, existing TensorRT engines,AsyncTritonPool, and the OpenSearch kNN layer. Guiding rule: pixels stay on the GPU — only metadata, embeddings, and selected JPEGs leave the pipeline (NVIDIA VSS-blueprint pattern).Scope
In: everything above + compose overlay (
docker-compose.video.yml, ports 4620–4629), Helm chart (deploy/helm/openprocessor-video/) with bundled↔external switches (Redpanda↔MSK, CNPG↔RDS, MinIO↔S3, OpenSearch↔managed), CI workflows (image Trivy gates, helm lint/kind fake-mode smoke, compose validate), docs + runbook, demo profile (mediamtx fake cameras — zero-camera out-of-box demo).Out (documented for later): VLM/summarization tiers, ReID tracker models (config-swap path documented), Avro/schema registry (JSON envelope now), DINO-style visual reranker, edge components (cameras are third-party).
Phase checklist
VideoSettings, compose infra (redpanda/postgres/minio/video-init), Makefile targets0001_video_schema, s3.py, kafka.py)Acceptance criteria
make video-up+make video-demoon a GPU box: fake RTSP cameras register, tracks accumulate, camera removal detaches cleanly.succeeded, track count within ±20% of golden, every track has ≥1 crop in MinIO and docs in OpenSearch.global_track_id.POST /v1/video/search/text {"query":"red truck"}ranks the seeded truck track first; reverse-image search returns the same vehicle's other crops.make video-bench: >400 aggregate FPS on an A6000-class GPU; a 5-minute 1080p segment processes in <60 s.helm lint+ kubeconform + kind fake-mode install green.