Files
cuframes-composer/include/cuframes_composer/overlay.h
T
gx 8cc5a5acfb Phase 3b: PNG icon overlays через libpng + alpha_blit_rgba_nv12
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 уже готовы.
2026-06-03 05:34:07 +01:00

110 lines
5.4 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 — 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 */