Files
cuframes-composer/include/cuframes_composer/composer.h
T
gx 1e2b5d4e16 Phase 2: composer + libcugrid (N источников → 2x2 grid в NV12 буфер)
Multi-source композитор работает на 4K @ 25fps стабильно. Live-тест с
4 камерами (parking, back_yard, front_yard, gate_lpr): все 4 active,
350 кадров за 14с, 27.6 МБ H.264 файл, кадр декодируется ffmpeg'ом
с корректным 2x2 layout'ом.

Содержимое:

- include/cuframes_composer/cugrid.h — публичный API libcugrid:
  cfc_cugrid_fill_nv12 (region fill с alpha blend),
  cfc_cugrid_resize_nv12 (bilinear scale в rect).
- src/cugrid/cugrid.cu — извлечённые из vf_cuda_grid kernel'ы
  (Y+UV fill + bilinear resize), объединены с C launcher'ом в одном
  .cu файле, под LGPL-2.1+.
- include/cuframes_composer/composer.h — публичный API композитора:
  cfc_composer_cell_t для layout, get_health для observability.
- src/composer.c — manager N cfc_source_t + единый NV12 output buffer
  (cuMemAlloc, переиспользуется на каждом compose'е). compose_clear
  fillит фон BT.709-чёрным, compose_cell делает resize ACTIVE
  источника или оставляет blackout для DEAD/STALE/CONNECTING.
- examples/grid_record — Phase 2 smoke test: N --cell ключ,x,y,w,h
  → grid composer → NVENC → file.

Сборка: добавлен LANGUAGES CUDA и CMAKE_CUDA_ARCHITECTURES 89;120
(Ada + Blackwell). Compile options раздельные для C и CUDA
(-Wpedantic не подходит для .cu).

Phase 2 RTSP push отложен на отдельный commit — будет через pipe-out
к локальному ffmpeg'у, который публикует в mediamtx (вариант
утверждён в Q2 дизайн-документа).
2026-06-03 05:01:49 +01:00

98 lines
4.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* cuframes-composer — высокоуровневый композитор N источников в grid.
*
* Управляет:
* - N cfc_source (фоновые подписки на cuframes-publisher'ы)
* - Layout (cell positions + size)
* - Output NV12 buffer (cuMemAlloc, переиспользуется)
* - Композиция на каждом тике: clear background + resize/blit для каждого ACTIVE,
* fill чёрным для DEAD/STALE.
*
* Phase 2 архитектура:
* Композитор работает синхронно: caller вызывает cfc_composer_compose() →
* композитор для каждого источника берёт snapshot и пишет в output. После
* вызова output NV12 buffer готов к encode.
*
* Каноническая интеграция:
* for (;;) {
* cfc_composer_compose(comp); // grid готов в output buffer
* cfc_encoder_encode_frame(enc, ...); // → H.264
* }
*
* Лицензия: LGPL-2.1+
*/
#ifndef CUFRAMES_COMPOSER_COMPOSER_H
#define CUFRAMES_COMPOSER_COMPOSER_H
#include "source.h"
#include <cuda.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Описание одной ячейки grid'а — где на output буфере рисуется источник.
* Все координаты в full-res пикселях, должны быть чётными. */
typedef struct cfc_composer_cell {
const char *source_key; /* cuframes key, например "cam-parking" */
int x, y; /* top-left угол на output буфере */
int w, h; /* размер ячейки */
} cfc_composer_cell_t;
typedef struct cfc_composer_config {
/* Output буфер (одно фиксированное разрешение для всего grid'а). */
int width; /* output ширина (например 3840 для 2×2 1080p) */
int height; /* output высота (например 2160 для 2×2 1080p) */
/* Cells конфигурация. Массив указателей на cells (для удобства user'а). */
const cfc_composer_cell_t *cells; /* array, не копируется — caller держит */
int num_cells;
/* CUDA устройство. */
int cuda_device; /* индекс, обычно 0 */
/* Backgound цвет (BT.709 limited): Y=16/U=128/V=128 = чёрный. */
int bg_y, bg_u, bg_v;
/* Параметры stale/dead для источников. */
int reconnect_min_ms; /* default 1000 */
int reconnect_max_ms; /* default 30000 */
int stale_threshold_ms; /* default 500 */
int dead_threshold_ms; /* default 5000 */
} cfc_composer_config_t;
typedef struct cfc_composer cfc_composer_t;
/* Создать композитор. Выделяет output NV12 буфер, запускает N source thread'ов. */
int cfc_composer_create(const cfc_composer_config_t *cfg, cfc_composer_t **out);
/* Скомпоновать один кадр. Вернёт указатели на output NV12 (Y + UV) и pitch.
* Указатели действительны до следующего compose. */
int cfc_composer_compose(
cfc_composer_t *comp,
CUdeviceptr *out_y_ptr,
int *out_pitch_y,
int *out_width,
int *out_height
);
/* Получить layout статистику по источникам — для debug / health-репортов. */
typedef struct cfc_composer_health {
int total; /* всего источников */
int active; /* в состоянии ACTIVE */
int stale; /* в STALE */
int dead; /* DEAD/DISCONNECTED/CONNECTING */
} cfc_composer_health_t;
int cfc_composer_get_health(cfc_composer_t *comp, cfc_composer_health_t *out);
/* Уничтожить композитор. */
int cfc_composer_destroy(cfc_composer_t *comp);
#ifdef __cplusplus
}
#endif
#endif /* CUFRAMES_COMPOSER_COMPOSER_H */