Когда controller broadcast'ит overlay command ко всем cuda_grid instances
(quad/single/mpp), overlay с cell=2 (gate_lpr cell в quad/mpp) попадает
в single layout который имеет nb_cells=1 → overlay_pixel_rect возвращал
AVERROR(EINVAL) → render_overlays propagated к cuda_grid_compose →
"Error while filtering: Invalid argument" каждый frame → pipeline crash loop.
Fix: return 1 (positive skip) вместо AVERROR. render_overlay_rect уже
имеет `if (ret != 0) return ret < 0 ? ret : 0;` — positive skip правильно
обрабатывается без error.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Invalidate cached icon atlas by name. Next render автоматически re-reads PNG
file с disk. Used controller'ом для periodic re-render dynamic overlays
(charts/chats) — write new PNG → send reload_icon → filter подхватывает.
Без этого pattern dynamic overlay невозможен — icon overlay cached forever
after first load by icon_name.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.
2026-05-19 20:47:00 +01:00
5 changed files with 1805 additions and 0 deletions
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.