Files
gx f8e27b9e85 Phase 10/11 WIP — pool + motion-mode + 8×8 templates (rolled back)
Объединённое состояние работ:
  - Phase 10: source pool, motion-driven layout, Frigate motion_pulse,
    zone-filter в pool, --source / --motion-mode CLI
  - Phase 11 Steps 1-3c: 8×8 микро-сетка, JSON templates с asymmetric
    layouts (tpl_1/3/4/5/6/7/8), reload через ZMQ, auto-labels per camera

В прод отдеплоено и откачено: используем gx/cuframes-composer:0.10 как
baseline. Phase 11 продолжится в branch phase11b-cpp как C++ refactor
с ООП-моделью Cell/Layout/Decoration.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 21:24:23 +01:00

109 lines
4.6 KiB
C
Raw Permalink 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 — модель layout'ов на 8×8 микро-сетке (Phase 11).
*
* Output (1920×1080) разбит на 8 cols × 8 rows микроячеек 240×135 px.
* Каждая микроячейка имеет aspect 16:9 — любой квадрат N×N микроячеек
* тоже 16:9 (без растяжения камер).
*
* Cell template — прямоугольник {col, row, cs, rs} в микроячейках,
* с ролью CAMERA либо WIDGET. Camera-cells получают source из pool
* композитора по polю `order`: order=0 → main (top-priority active),
* order=1 → next и т.д.
*
* Layout template — набор cells одного экрана. Composer хранит таблицу
* built-in templates + опционально загружает override из JSON (Step 7).
*
* Phase 11 Step 1: единственный built-in `tpl_1` = одна cell 8×8 (single).
*
* Лицензия: LGPL-2.1+
*/
#ifndef CUFRAMES_COMPOSER_LAYOUTS_H
#define CUFRAMES_COMPOSER_LAYOUTS_H
#ifdef __cplusplus
extern "C" {
#endif
#define CFC_GRID_COLS 8
#define CFC_GRID_ROWS 8
#define CFC_LAYOUT_MAX_CELLS 32
#define CFC_LAYOUT_MAX_NAME 32
#define CFC_WIDGET_NAME_MAX 32
typedef enum cfc_cell_role {
CFC_CELL_CAMERA = 0,
CFC_CELL_WIDGET = 1,
} cfc_cell_role_t;
/* Описание одной cell внутри layout-template'а.
* col, row — top-left угол в микроячейках (0..7)
* cs, rs — span в микроячейках (≥1, col+cs ≤ 8, row+rs ≤ 8)
* role — CAMERA или WIDGET
* order — для CAMERA: порядок placement'а активных камер
* (order=0 получает top-priority); игнорируется для WIDGET
* widget — для WIDGET: имя placeholder'а (текст подписи) */
typedef struct cfc_cell {
int col, row;
int cs, rs;
cfc_cell_role_t role;
int order;
char widget[CFC_WIDGET_NAME_MAX];
} cfc_cell_t;
/* Описание layout-template'а: набор cells + metadata. */
typedef struct cfc_layout {
char name[CFC_LAYOUT_MAX_NAME];
cfc_cell_t cells[CFC_LAYOUT_MAX_CELLS];
int nb_cells; /* всего cells */
int nb_camera_cells; /* кеш — для best-fit selection */
int priority; /* tie-break при best-fit (выше = победитель) */
} cfc_layout_t;
/* Найти layout по имени; NULL если нет. */
const cfc_layout_t *cfc_layout_find(const char *name);
/* Возвращает указатель на массив всех загруженных layout'ов и их количество. */
const cfc_layout_t *cfc_layout_all(int *out_count);
/* Перевести {col,row,cs,rs} в pixel-координаты под output W×H.
* x = col * (W/8), w = cs * (W/8) (выровнено на чётные).
* NV12 требует чётных координат — встроено внутрь. */
void cfc_layout_to_pixels(const cfc_cell_t *cell, int W, int H,
int *out_x, int *out_y, int *out_w, int *out_h);
/* Загрузить templates из JSON-файла. При успехе сменяет реестр; при ошибке
* реестр остаётся прежним (или built-in, если ничего не было).
* Возвращает количество загруженных templates, либо отрицательное число
* (-1 = parse error, -2 = invalid schema, -3 = file not found).
*
* Hot-reload: после успешного вызова cfc_layout_find/cfc_layout_all
* возвращают новые template'ы. Композитор подхватывает на следующем кадре.
*
* JSON schema:
* { "version": 1, "grid_cols": 8, "grid_rows": 8,
* "templates": [
* { "name": "tpl_1", "priority": 0,
* "cells": [
* { "col":0, "row":0, "cs":8, "rs":8,
* "role":"camera", "order":0,
* "widget":"ha_chat" // для role=widget
* }, ...
* ]
* }, ...
* ]
* } */
int cfc_layout_load_file(const char *path);
/* Перезагрузить из последнего успешно загруженного файла. Если файла не
* было — возвращает -1. */
int cfc_layout_reload(void);
/* Получить путь к текущему загруженному файлу (NULL если built-in). */
const char *cfc_layout_loaded_path(void);
#ifdef __cplusplus
}
#endif
#endif /* CUFRAMES_COMPOSER_LAYOUTS_H */