Out-of-tree patch + sources для FFmpeg-демаксера, который позволяет любому FFmpeg-based потребителю (Frigate, кастомные рекордеры, re-streamers) читать "cuframes://<key>" как обычный URL — без своего NVDEC. Состав: - filter/cuframesdec.c — реализация (libavformat-style) - filter/ffmpeg-7.1-cuframes-demuxer.patch — patch для FFmpeg n7.1 (Makefile / allformats.c / configure) - filter/README.md — инструкции по сборке + CLI smoke test + Frigate plan v1 ограничения (намеренно): - только NV12 - GPU → CPU копия через cudaMemcpy2DAsync (zero-copy AVHWFramesContext — v2) CLI smoke test 2026-05-17 (host build FFmpeg + libcuframes, publisher на камере 192.168.88.98 1920x1080 HEVC 25fps): ffmpeg -f cuframes -i cuframes://cam-ff -c:v copy -f null - → frame=100 fps=25 q=-1.0 speed=1x ✓ → "cuframes: connected to 'cam-ff' — 1920x1080 NV12" Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
FFmpeg cuframes demuxer
Custom input format cuframes://<key> для FFmpeg 7.x. Подключается к
запущенному cuframes-rtsp-source (или
любому другому cuframes publisher'у) и выдаёт NV12 raw video stream.
Цель: позволить FFmpeg-based потребителям (Frigate, custom recorders, re-streamers) подписываться на уже декодированные кадры — без своего NVDEC. Один decode у publisher'а на N consumer'ов.
Что в этой директории
cuframesdec.c— реализация demuxer'аffmpeg-7.1-cuframes-demuxer.patch— patch для FFmpeg 7.1 (правитlibavformat/Makefile,libavformat/allformats.c,configureи кладётcuframesdec.cвlibavformat/)
Limitations v1
- Пиксельный формат: только NV12 (как нативно отдаёт NVDEC через cuframes-rtsp-source)
- Кадры копируются GPU → CPU через
cudaMemcpy2DAsync— для PoC совместимости со всеми FFmpeg-pipeline'ами. Zero-copy черезAVHWFramesContext— запланировано в v2. - Один input = один stream; multi-stream publisher'ы — v2.
Как применить и собрать FFmpeg
# 1. Клон FFmpeg 7.1
git clone --depth 1 --branch n7.1 https://github.com/FFmpeg/FFmpeg.git ffmpeg
cd ffmpeg
# 2. Apply patch
patch -p1 < /path/to/cuframes/filter/ffmpeg-7.1-cuframes-demuxer.patch
# 3. Configure (минимальный пример; для Frigate-сборки используйте полный
# набор опций из их Dockerfile + добавьте --enable-libcuframes)
./configure \
--enable-libcuframes \
--extra-cflags='-I/path/to/cuframes/include -I/usr/local/cuda/include' \
--extra-ldflags='-L/path/to/cuframes/build/libcuframes -L/usr/local/cuda/lib64' \
...прочие опции вашей сборки...
# 4. Build
make -j$(nproc)
CLI smoke test
# Терминал 1 — publisher (host):
cuframes-rtsp-source --rtsp rtsp://... --key cam1 --verbose
# Терминал 2 — потребитель через нашу патченую FFmpeg:
LD_LIBRARY_PATH=/path/to/libcuframes ./ffmpeg \
-f cuframes -i cuframes://cam1 \
-c:v copy -f null -
Должно быть видно:
[cuframes @ ...] cuframes: connected to 'cam1' — 1920x1080 NV12
...
frame= 100 fps= 25 q=-1.0 size=N/A time=00:00:03.96 speed=1x
speed=1x — pipeline идёт в реальном времени с частотой камеры.
Опции demuxer'а
-cuda_device <int> CUDA device index (must match publisher's). Default 0.
-connect_timeout <int> Wait for publisher (ms); -1 = forever. Default 5000.
Frigate integration (план)
После того как Frigate-image пересобран с patched FFmpeg, в config.yml:
cameras:
cam_parking:
ffmpeg:
inputs:
- path: cuframes://cam-parking # detect через cuframes
roles: [detect]
- path: rtsp://admin:***@cam/main # recording — прямой RTSP
roles: [record] # mux без decode, как раньше
Detect-стрим декодируется один раз в publisher'е cuframes-rtsp-source, recording по-прежнему mux'ится Frigate'ом из encoded RTSP без decode.
Upstream FFmpeg PR (план v2+)
После стабилизации API (NV12 → universal hwframe NV12 в CUDA context) patch можно подать в upstream FFmpeg. Пока что — out-of-tree patch для custom builds.