8cc5a5acfb
Live-validated на rtsp://192.168.88.23:554/cfc-grid с иконками temp_outside.png и offline.png из cuda_grid_icons volume. Содержимое: - cugrid.h/cugrid.cu — cfc_cugrid_blit_rgba_nv12 (Y+UV α-blend) + два новых kernel'я blit_rgba_y/uv (BT.709 limited-range RGB→YUV conversion, 4:2:0 chroma 2x2 averaging). - overlay.h — cfc_overlay_create_png + cfc_overlay_png_size + cfc_overlay_update_png. - overlay.c — libpng decode (paletted/gray/16-bit → 8-bit RGBA), cuMemAlloc atlas в VRAM, cuMemcpyHtoD один раз, draw_png через cfc_cugrid_blit_rgba_nv12. - CMakeLists.txt — find_package(PNG REQUIRED) + PNG::PNG в link. - examples/grid_record — флаг --icon path,x,y[,alpha] (несколько раз можно). Атлас грузится один раз при старте. PNG из cuda_grid_icons volume переиспользуются (offline, temp_outside, grafana_gpu, и пр.). PNG decode'ятся одинаково — paletted, RGBA, gray. Phase 3c (text rendering через FreeType + font atlas) — отдельный commit. Атлас text'а тоже окажется в VRAM как RGBA через тот же cfc_cugrid_blit_rgba_nv12 — kernels уже готовы.
110 lines
5.4 KiB
C
110 lines
5.4 KiB
C
/* cuframes-composer — overlay'и (border, png-иконка, текст) поверх
|
||
* композиции.
|
||
*
|
||
* Архитектура:
|
||
* cfc_overlay_t — opaque объект одного overlay'я (border, png, text).
|
||
* composer ведёт список overlays + порядок (z-order); на каждом compose'е
|
||
* проходит по списку и рисует их поверх NV12 grid'а.
|
||
*
|
||
* Типы overlay'ев:
|
||
* BORDER — цветная рамка вокруг rect'а (Phase 3a). Реализован через 4
|
||
* fill_nv12 операции (top/bottom/left/right). Полезно для:
|
||
* - визуальной отбивки ячеек grid'а
|
||
* - подсветки активных/неактивных источников (красная при DEAD)
|
||
* PNG — RGBA-изображение (Phase 3b). Decode-раз через stb_image,
|
||
* upload в VRAM, на каждом кадре alpha-blit через
|
||
* cfc_kern_alpha_blit_rgba_*. Для статичных иконок (NO SIGNAL,
|
||
* offline, recording dot).
|
||
* TEXT — динамический рендер строки (Phase 3c). Требует FreeType +
|
||
* font atlas. Сделать позже когда FreeType добавлен как зависимость.
|
||
*
|
||
* Жизненный цикл:
|
||
* cfc_overlay_create_*() — выделяет ресурсы (для PNG/TEXT — VRAM-атлас).
|
||
* cfc_overlay_update_*() — обновляет параметры (положение, видимость, текст).
|
||
* cfc_overlay_draw() — вызывается composer'ом на каждом кадре.
|
||
* cfc_overlay_destroy() — освобождает VRAM.
|
||
*
|
||
* Phase 3a лимит: только BORDER через fill_nv12.
|
||
*
|
||
* Лицензия: LGPL-2.1+
|
||
*/
|
||
|
||
#ifndef CUFRAMES_COMPOSER_OVERLAY_H
|
||
#define CUFRAMES_COMPOSER_OVERLAY_H
|
||
|
||
#include <cuda.h>
|
||
#include <stdint.h>
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
typedef enum cfc_overlay_type {
|
||
CFC_OVERLAY_BORDER = 0,
|
||
CFC_OVERLAY_PNG = 1, /* Phase 3b */
|
||
CFC_OVERLAY_TEXT = 2, /* Phase 3c */
|
||
} cfc_overlay_type_t;
|
||
|
||
typedef struct cfc_overlay cfc_overlay_t;
|
||
|
||
/* Параметры BORDER overlay'я. */
|
||
typedef struct cfc_overlay_border_config {
|
||
int x, y, w, h; /* прямоугольник в full-res пикселях */
|
||
int thickness; /* толщина рамки в пикселях */
|
||
int color_y, color_u, color_v; /* цвет в BT.709 (Y:16-235, UV:16-240) */
|
||
int alpha; /* 0..255; 0 = invisible */
|
||
int visible; /* 0/1 — выводить ли вообще */
|
||
} cfc_overlay_border_config_t;
|
||
|
||
/* Создать BORDER overlay. */
|
||
int cfc_overlay_create_border(const cfc_overlay_border_config_t *cfg,
|
||
cfc_overlay_t **out);
|
||
|
||
/* Параметры PNG overlay'я. */
|
||
typedef struct cfc_overlay_png_config {
|
||
const char *path; /* путь к PNG-файлу (декод один раз) */
|
||
int x, y; /* позиция top-left на output буфере (чётные) */
|
||
int extra_alpha; /* 0..255 общий множитель прозрачности */
|
||
int visible; /* 0/1 — выводить ли */
|
||
} cfc_overlay_png_config_t;
|
||
|
||
/* Создать PNG overlay. Декодирует файл через libpng, аллоцирует RGBA-атлас
|
||
* в VRAM (cuMemAlloc), копирует туда декодированные пиксели один раз.
|
||
*
|
||
* Размер изображения берётся из PNG header'а — caller узнаёт width/height
|
||
* через cfc_overlay_png_size после create. */
|
||
int cfc_overlay_create_png(const cfc_overlay_png_config_t *cfg,
|
||
cfc_overlay_t **out);
|
||
|
||
/* Получить реальный размер декодированного PNG. После create — стабильны
|
||
* до destroy. */
|
||
int cfc_overlay_png_size(cfc_overlay_t *ov, int *width, int *height);
|
||
|
||
/* Обновить параметры PNG overlay'я (без re-decode). */
|
||
int cfc_overlay_update_png(cfc_overlay_t *ov,
|
||
const cfc_overlay_png_config_t *cfg);
|
||
|
||
/* Обновить параметры BORDER overlay'я (можно переключить visible,
|
||
* сменить цвет, изменить позицию). Thread-safe? Нет — caller должен сам
|
||
* заботиться о том, чтобы update не пересекался с draw. В рамках одного
|
||
* compose-thread'а это естественно. */
|
||
int cfc_overlay_update_border(cfc_overlay_t *ov,
|
||
const cfc_overlay_border_config_t *cfg);
|
||
|
||
/* Нарисовать overlay поверх NV12 кадра. Вызывается из cfc_composer_compose.
|
||
* Возвращает 0 при успехе. */
|
||
int cfc_overlay_draw(cfc_overlay_t *ov,
|
||
CUstream stream,
|
||
CUdeviceptr dst_y, int pitch_y,
|
||
CUdeviceptr dst_uv, int pitch_uv,
|
||
int frame_w, int frame_h);
|
||
|
||
/* Уничтожить overlay (освободить VRAM если был). */
|
||
int cfc_overlay_destroy(cfc_overlay_t *ov);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* CUFRAMES_COMPOSER_OVERLAY_H */
|