gx afc2dd7fff
build / cmake build (CUDA 12.4, Ubuntu 22.04) (pull_request) Failing after 1m50s
build / ffmpeg filter patch (out-of-tree) (pull_request) Has been skipped
python: DLPack + health stats + CUDA stream + docs (tasks #199-#202)
#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>
2026-06-13 21:33:21 +01:00

cuframes

build release license

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/consumer
  • cuframes-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_exportplanned для 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.

Документация

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.

S
Description
No description provided
Readme LGPL-2.1 601 KiB
2026-05-19 17:49:50 +01:00
Languages
C 54.3%
C++ 24.1%
Cuda 15.1%
CMake 3%
Python 2%
Other 1.5%