PNG/JPG decode через libavcodec (системный decoder), conversion в RGBA8
через swscale, upload в pitched CUDA buffer, blit через Alpha_Blit_RGBA_Y/UV
(те же kernels что text).
Icon cache — shared by name (одна и та же иконка для нескольких overlays =
один GPU atlas). Lifecycle: load on first use, free в uninit.
Path resolution: <icon_dir>/<name> + try .png/.jpg extensions:
/var/lib/cuda-grid/icons (default)
/opt/cuda-grid/icons (fallback)
+ abs path supported
Options:
icon_dir= — overrides default search paths
Wire format: add_overlay <id> icon x=.. y=.. icon_name=domofon opacity=200
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Controller URL-encode'ит string values (text="hello world" → text=hello%20world)
чтобы пройти sscanf("%s") который stops on whitespace.
Filter inline decode'ит '%xx' obratno в bytes. Только для text + icon_name.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CPU rasterization через freetype (DejaVu/Liberation auto-detect или
font_file= option), upload pitched RGBA buffer to GPU, blit через
Alpha_Blit_RGBA_Y/UV kernels (Phase 4b-2 уже had).
Cache:
per-overlay-id atlas с keys (text, font_size, r/g/b) — re-rasterize
только при change. Cleanup при remove_overlay/clear_overlays/uninit.
Options:
font_file= — TTF path (default: search DejaVu/Liberation)
font_size= — default size if overlay не указал свой
Wire format: add_overlay <id> text x=.. y=.. text=hello font_size=24 r=255 g=255 b=255 opacity=200
Conditional на CONFIG_LIBFREETYPE — без него text overlays no-op
(остальные типы работают как обычно).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Без этого filter compileд но .ptx step failед: configure не knows что
filter требует nvcc/clang для .cu compile. Same pattern как scale_cuda.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add libnpp dependency в configure (cuda_grid_filter_deps)
- #include <nppi.h>, nppSetStream(s->cu_stream) перед resize batch
- Smart copy-or-scale в compose path:
- src.size == cell.size → cuMemcpy2DAsync (fast path, zero overhead)
- else → nppiResizeSqrPixel_8u_C1R для Y + _C2R для NV12 UV interleaved
- NPPI_INTER_LINEAR interpolation (bilinear — стандартный для video)
- Destination pointer offset через explicit pointer arithmetic
(NPP не имеет dst_offset параметра, нужно сместить pSrc указатель)
Это unblock'ает mixed-size cameras (parking 1920x1080 + gate_lpr 2688x1520
в одном grid с main_plus_preview layout — big cell scaled до 1280x1080,
small cells scaled до 640x360).
Phase 2 complete (2a + 2b). Phase 3 будет controller sidecar.
Phase 1 deliverable (см. gx/vf-cuda-grid#1):
- libavfilter/vf_cuda_grid.c (~270 LOC): multi-input filter, fixed 2×2 quad
- 4 NV12 CUDA frames same size → 2W × 2H output frame
- Composition: cuMemcpy2DAsync per Y + UV plane на каждый input
- framesync для lock-step pull всех 4 inputs
- Output hw_frames_ctx allocated from input device_ref
- Build wiring: CONFIG_CUDA_GRID_FILTER → libavfilter/{Makefile,allfilters.c}, configure deps на ffnvcodec
Limitations Phase 1:
- All inputs must be same size (no scaling)
- Quad layout hardcoded (no DSL, no runtime switching)
- NV12 only (no RGBA/YUV420P)
Phase 2: dynamic layouts + scaling. Phase 3: runtime control via process_command.
При первоначальном rsync ffbuild/ исключал случайно — думал что это
build artifacts. На деле — FFmpeg source templates (library.mak, common.mak
и т.п.), без которых make не работает.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Snapshot FFmpeg n7.1 (release tag) с применённым patch'ем для cuframes
input format. Используется как FFMPEG_REPO_OVERRIDE в NickM-27/FFmpeg-Builds
fork для статической сборки patched binary под Frigate (Debian 12 / glibc 2.36).
Apply changes:
+ libavformat/cuframesdec.c (новый — реализация демуксера)
M libavformat/Makefile (CONFIG_CUFRAMES_DEMUXER target)
M libavformat/allformats.c (extern declaration)
M configure (--enable-libcuframes option + dep check)
Patch source: https://git.goldix.org/gx/cuframes (filter/ffmpeg-7.1-cuframes-demuxer.patch)
History сброшена (snapshot вместо fork) потому что upstream shallow clone
не позволял push в gitea. Полная история FFmpeg — на github.com/FFmpeg/FFmpeg n7.1.