#199 DLPack export: - frame.dlpack_y() / .dlpack_uv() — explicit multi-plane access для NV12 - frame.__dlpack__() / __dlpack_device__() — protocol для torch/cupy - Capsule deleter правильно держит refcount на frame_keep_alive, releases shape/strides arrays. CUDA pointer принадлежит frame. #200 Health/stats counters: - frames_received, timeouts, errors — per-call counters - last_seq, gap_count — proxy для drop count (NEWEST_ONLY mode) - last_frame_pts_ns - stats() — snapshot dict для MQTT health publish - counted в pybind layer т.к. C API не expose'ит ring_occupancy #201 Per-subscriber CUDA stream + thread-safety: - consumer_stream kwarg в subscribe() — int (cudaStream_t pointer) - subscriber.consumer_stream property - Thread-safety contract в docstring CuframesSubscriber - next_frame() передаёт consumer_stream_ в cuframes_subscriber_next #202 Smoke test + docs: - 10/10 pytest passed (расширен +2 теста на consumer_stream) - docs/python.md (~250 строк): quick start, API reference, integration с PyTorch/CuPy, reconnect-loop pattern, per-stream usage, pitch alignment, thread-safety, error taxonomy, backpressure, Phase 0 limitations Verify build + tests: cmake -B build-python -DBUILD_PYTHON_BINDINGS=ON cmake --build build-python -j pytest python/tests/ -v # 10/10 Закрывает Phase 0 issue gx/cuframes#6. Разблокирует goldix-smart-home/yolo-world-detector Phase 1. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
cuframes
Zero-copy sharing декодированных видеокадров между процессами через CUDA IPC.
Статус: v0.1.0 released — production-deployed на multi-camera CCTV-стeке (Frigate + custom C++ processor, оба используют один publisher на одном NVDEC). См. BENCHMARKS.md для measurements, ROADMAP.md для v0.2 plans.
Минимальные требования
| Минимум | Рекомендуется | |
|---|---|---|
| OS | Linux kernel ≥ 5.4 | Ubuntu 24.04 |
| GPU | NVIDIA с compute capability ≥ 7.5 (Turing+) | Ampere/Ada/Blackwell |
| NVIDIA driver | 525 (для CUDA 12) | 555+ (для CUDA 13) |
| CUDA Toolkit (build) | 12.0 | 13.0+ |
| GCC / Clang | 11 / 14 | 12+ / 17+ |
| CMake | 3.20 | 3.28+ |
| Docker | 24.x + nvidia-container-toolkit 1.14+ | — |
Не работает на Windows, macOS, WSL2, AMD/Intel GPU, multi-GPU producer/consumer. Подробно — docs/requirements.md.
Идея в одну минуту
Типичный setup с несколькими сервисами видеоаналитики:
Camera ─► ffmpeg #1 (NVR, decode + record)
─► ffmpeg #2 (AI-detector, decode + inference)
─► ffmpeg #3 (custom analytics, decode + ...)
Каждый сервис делает свой decode на GPU. На 16 cameras × 25 fps × 3 consumers это сотни лишних NVDEC operations и GB/s VRAM-bandwidth впустую.
cuframes устраняет дублирование:
Camera ─► ffmpeg + cuframes filter ─► VRAM ─┬─► consumer 1 (NVR)
├─► consumer 2 (AI)
└─► consumer 3 (analytics)
Один decode, frame остаётся в VRAM, любое количество consumers читают zero-copy через CUDA IPC.
Состав
libcuframes— C library + C++ RAII wrapper (header-only) для producer/consumercuframes-rtsp-source— standalone bridge RTSP → cuframes IPC (используется как input для AI/mosaic consumer'ов; альтернатива FFmpeg-filter'а до v0.2)sub_count(examples/) — reference subscriber + smoke-test tool- Docker images — runtime для drop-in deployment (см. docker/Dockerfile.runtime)
- FFmpeg filter
cuda_ipc_export— planned для v0.2
Quickstart
# Publisher: декодирует RTSP в CUDA, публикует через cuframes IPC
docker run -d --name cuframes-cam --runtime=nvidia --ipc=shareable \
-v /run/cuframes:/run/cuframes \
gx/cuframes:0.1 \
/usr/local/bin/cuframes-rtsp-source \
--rtsp 'rtsp://user:pass@cam/stream' --key cam1 --ring 6
# Subscriber: получает декодированные frames zero-copy
# (для cross-container CUDA IPC нужны и --ipc, и --pid — см. docs/integration.md)
docker run --rm --runtime=nvidia \
--ipc=container:cuframes-cam --pid=container:cuframes-cam \
-v /run/cuframes:/run/cuframes:ro \
gx/cuframes:0.1 \
/usr/local/bin/sub_count --key cam1 --max-frames 100
# Или C++ кодом:
#include <cuframes/cuframes.hpp>
cuframes::SubscriberOptions opt;
opt.key = "cam1";
cuframes::Subscriber sub(opt);
cudaStream_t s; cudaStreamCreate(&s);
while (auto frame = sub.next(s, 1000)) { // 1s timeout
cudaStreamSynchronize(s);
process_on_cuda(frame->cuda_ptr(), frame->width(), frame->height());
}
Полный integration guide (docker-compose, cctv-processor, troubleshooting): docs/integration.md.
Документация
- docs/architecture.md — полный design document
- docs/protocol.md — bit-exact wire protocol spec
- docs/requirements.md — system requirements (hardware, software, build, Docker, k8s)
- docs/integration.md — integration guide для CCTV-стека (cuframes-rtsp-source + cctv-processor + Frigate)
- docs/benchmarks-phase0.md — Phase 0 latency/throughput measurements
Why
Подтверждённый спрос в Frigate community (#17033,
#20191, #21559)
— люди тычатся в NVDEC saturation при многокамерных setup'ах. Решения уровня
NVIDIA DeepStream закрытые / vendor-locked. Open source FFmpeg-plugin для этой
ниши не существует. См. подробный prior-art analysis в docs/architecture.md.
Roadmap
| Phase | Что | Статус |
|---|---|---|
| 0 | PoC spike, CUDA IPC latency measurements | ✅ done |
| 1 | libcuframes (producer/consumer ring buffer + handshake protocol) |
✅ done |
| 1.5 | C++ RAII wrapper, cuframes-rtsp-source, integration docs | ✅ done |
| 2 | FFmpeg filter vf_cuda_ipc_input + patched FFmpeg build |
planned |
| 3 | Python bindings (pybind11) | planned |
| 4 | Docker runtime-images в реестре, Frigate plugin POC | planned |
| 5 | Reference: 16-камерный mosaic consumer | planned |
| 6 | OSS launch (HN, reddit, FFmpeg upstream PR) | planned |
Contributing
Проект на ранней стадии. Перед PR сверьтесь с docs/architecture.md и CONTRIBUTING.md.