60 lines
4.4 KiB
Plaintext
60 lines
4.4 KiB
Plaintext
---
|
||
title: What is cuframes
|
||
sidebar_position: 1
|
||
slug: /intro
|
||
---
|
||
|
||
# cuframes
|
||
|
||
**Zero-copy decoded video frames over CUDA, shared across processes — without pid namespace sharing.**
|
||
|
||
Pure C library (LGPL-2.1+) для передачи decoded NV12 frames между Linux-процессами через CUDA VMM + POSIX file descriptors. Никаких re-encode, ни CPU-side memcpy, ни Unix-pipe сериализации — consumer получает указатель на ту же GPU-память что и producer.
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
RTSP[RTSP camera] --> Pub[Publisher<br/>NVDEC → VMM pool]
|
||
Pub -- POSIX FD via SCM_RIGHTS --> Sub1[Subscriber 1<br/>FFmpeg detect]
|
||
Pub -- POSIX FD via SCM_RIGHTS --> Sub2[Subscriber 2<br/>FFmpeg compose]
|
||
Pub -- POSIX FD via SCM_RIGHTS --> Sub3[Subscriber 3<br/>AI inference]
|
||
```
|
||
|
||
## Status
|
||
|
||
**v0.4 — early but production-tested.** Single deployment в реальной CCTV-системе (4 IP-cameras, NVENC re-encode chain, 25 fps). Не enterprise-ready: один maintainer, нет paid support, ABI ломался 4 раза за месяц разработки.
|
||
|
||
Подходит если ты строишь свой video pipeline и понимаешь риски OSS-библиотеки на ранней стадии. Не подходит как drop-in замена DeepStream / GStreamer для enterprise-сценариев.
|
||
|
||
## Why
|
||
|
||
Типичный кейс — один декодер RTSP-камеры, несколько consumer'ов (NVR-запись, AI-детектор, live-композитор для TV). Без cuframes:
|
||
|
||
- **Naive путь:** каждый consumer открывает свой RTSP-stream → N×NVDEC + N×NIC. Если камер 10, потребителей 3 — это 30 параллельных декодов.
|
||
- **DeepStream:** работает, но vendor lock-in, тяжёлый runtime, лицензионные ограничения.
|
||
- **CUDA IPC handles напрямую:** требуют shared PID namespace между процессами. Frigate, Docker-стек на k8s — это часто несовместимо.
|
||
|
||
cuframes решает третью проблему: один decoder publish'ит, любое число consumer'ов subscribe'ятся через unix socket, FD'ы передаются через `SCM_RIGHTS`, никакого pid sharing не нужно.
|
||
|
||
## Что cuframes не делает
|
||
|
||
- **Encoded video.** Frame ring — это decoded NV12. Для encoded H.264/H.265 packet stream есть отдельный packet ring (Annex-B byte stream через POSIX shm).
|
||
- **Cross-host.** Только same-machine — POSIX FD не передаётся через сеть.
|
||
- **Cross-vendor.** Только NVIDIA — `cuMemCreate` это CUDA API. AMD HIP / Intel oneAPI пока не поддерживаются.
|
||
- **Windows.** Только Linux (POSIX shm + Unix sockets + SCM_RIGHTS).
|
||
- **HA / failover.** Один producer per key — если падает, consumers видят `CUFRAMES_ERR_DISCONNECTED` и сами решают что делать.
|
||
|
||
## Architecture in 30 seconds
|
||
|
||
- **Producer** (`cuframes_publisher_create`) — allocates N×frame VMM pool (`cuMemCreate(POSIX_FILE_DESCRIPTOR)`), opens Unix socket `/run/cuframes/<key>.sock`, opens POSIX shm `/dev/shm/cuframes-<key>` для metadata header.
|
||
- **Subscriber** (`cuframes_subscriber_create`) — connects socket, handshake-receives N file descriptors через `SCM_RIGHTS`, imports их через `cuMemImportFromShareableHandle`, mmap'ит shm header.
|
||
- **Publish loop:** producer `acquire()` → memcpy в slot → `publish(stream, pts)` который делает `cuStreamSynchronize` + atomic update `slot.seq` + `global_seq`.
|
||
- **Consume loop:** subscriber polls atomic `global_seq`, читает frame через DtoD copy в свой stream.
|
||
- **Sync:** producer's `cuStreamSynchronize` перед publish гарантирует hardware coherence — consumer читает данные через atomic load без CUDA events (modern simplification от `v0.4`).
|
||
|
||
Полная спецификация — [Protocol reference](/docs/reference/protocol).
|
||
|
||
## Next
|
||
|
||
- [Install](/docs/getting-started/install) — apt / docker / from source.
|
||
- [First publisher](/docs/getting-started/first-publisher) — 30-line C example.
|
||
- [FFmpeg demuxer integration](/docs/integration/ffmpeg-demuxer) — `cuframes://key` URL scheme.
|