Commit Graph

11 Commits

Author SHA1 Message Date
gx e54d55371c templates.json: tpl_3 теперь 4 камеры + temp_chart-узкий
Было: tpl_3 = main + 2 preview + temp_chart (rs=4) + ha_chat.
При 4 active композитор выбирал tpl_3 (waste=1 vs tpl_4 waste=0 — wait,
tpl_3 имел 3 cam cells, при 4 active брал tpl_4=quad без виджетов).

Стало: tpl_3 = main + 3 preview + temp_chart (rs=2, низ-право) + ha_chat.
4 cam cells, при 4 active best-fit выбирает tpl_3 (waste=0, раньше в registry
чем tpl_4 → tie-breaker за tpl_3). Виджеты остаются видимыми.

Geometry validated: 36+4+4+4+4+12=64 микроячеек, no overlaps.

Hot-reloaded via reload_templates ZMQ в проде.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-07 19:17:56 +01:00
gx 3730c65a1e mqtt_overlays: убраны assist_question / assist_response
Conversation events HA Assist не приходят (архитектурное ограничение).
Чтобы placeholders ❯ Вы: ... и ✎ HA: ... не висели на экране без
данных — overlay'и убраны до решения вопроса с источником диалога.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 19:01:31 +01:00
gx a8ce3f1ccb mqtt_overlays.json: добавлены HA Assist question / response overlays
Подписка на assist/conversation/text + /response (plain-text retained,
schema см. home-assistant/.../assist_mqtt.md).

Позиция: левый-нижний угол стопкой —
  🤖 ответ внизу (margin_y=32)
  🗣 вопрос выше (margin_y=78)

Полупрозрачная подложка (bg_alpha=180), placeholder с эмодзи пока
turn'а не было.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 15:22:04 +01:00
gx 75271436f7 Phase 11b: MQTT-overlays конфигурируются через JSON (вместо --temp-topic)
User: "оверлеев которые выводят какую-то инфу из MQTT может быть
бесконечно много. Надо делать настраиваемым через json/yaml конфиг".

Заменили захардкоженный TempMqttOverlay на generic MqttOverlay:

  - cpp/mqtt_overlay.hpp/.cpp: класс MqttOverlayItem (один topic + один
    text overlay) + MqttOverlayManager (контейнер). Загрузка из JSON.
  - cpp/mqtt_overlay_c_api.cpp: extern "C" обёртка для grid_record.c.
  - docker/mqtt_overlays.json: default config с temp_outside примером.
  - grid_record.c: --mqtt-overlays=PATH (заменил --temp-topic).
  - src/CMakeLists.txt: temp_overlay* удалены, mqtt_overlay* добавлены.

JSON schema:
  {
    "overlays": [
      {
        "id": "temp_outside",
        "topic": "zigbee2mqtt/Температура на улице",
        "json_field": "temperature",      // пусто = raw payload string
        "format": "%+.1f°C",                // printf
        "anchor": "right-bottom",           // right-top, left-bottom, ...
        "margin_x": 32, "margin_y": 24,
        "pixel_size": 32,
        "color": [255, 255, 255], "alpha": 230,
        "font_path": "/fonts/DejaVuSans-Bold.ttf"
      }
    ]
  }

MqttBrokerCfg делятся между всеми overlays (one connect_async per item
но shared credentials). Добавление новых overlays = редактирование JSON +
restart cfc-grid (hot-reload через ZMQ — Phase 12).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 10:07:05 +01:00
gx 24d398526e Phase 11b: вернули asymmetric layouts с widget cells
User: "где сетки main+preview, сетки с виджетами?". Восстановили из
прежней истории:
  - tpl_3 (1+2+widget+widget): main 1440×810 + 2 преview 480×270 +
    widget temp_chart справа + widget ha_chat снизу
  - tpl_5 (1+4+widget): main + 4 preview right column + ha_chat снизу
  - tpl_6 (1+3+2+widget): main + 3 правых + 2 нижних + widget info
  - tpl_7 (1+3+3+widget): main + 3 правых + 3 нижних + widget ha_chat
  - tpl_8 (1+3+4): main + 3 правых + 4 в нижней строке (полное покрытие)
  - tpl_9 — 3×3 + widget полосы справа/снизу

Widget cells — placeholder (тёмно-серый Y=40 + LabelDecoration с именем
widget'а). Реальные виджеты (HA chat, температурный график) — Phase 12+.
Chёрные ячейки больше не будут — composer.maybe_relayout заполняет
свободные camera-cells остальными drawable из pool.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 09:44:00 +01:00
gx 9d2a0b2bd7 Phase 11b: fill свободных camera-cells остальными drawable камерами
User: "смущает чёрная ячейка в сетке". Причина: asymmetric templates
имели widget cells (placeholder тёмно-серый Y=40) + при недостатке active
camera cells оставались BlankCell (чёрный).

Два изменения:

1. templates.json — оставили только 16:9 layouts (tpl_1/tpl_4/tpl_9/tpl_16).
   Все camera-cells, никаких widget-областей. Cells full 16:9 (cs==rs
   микроячейки), полностью покрывают output 1920×1080 без чёрных полос.
   Asymmetric layouts (main + satellites) удалены — вернуть в Phase 12
   когда widget'ы будут реальными (HA-chat, temperature graph).

2. composer::maybe_relayout — заполнить свободные camera-cells остальными
   drawable камерами из pool (по priority), если template имеет больше
   cells чем motion-active. Условие: cap > active.size().

Производство при 4 источниках в pool:
  - 1 motion → tpl_1 (1 cell full screen)
  - 2 motion → tpl_4 (2 motion + 2 not-active drawable = 4 cells заняты)
  - 4 motion → tpl_4 (все 4 motion)
  - При добавлении новых камер (до 16) — tpl_9 при 5..9, tpl_16 при 10..16

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 09:15:20 +01:00
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
gx fa6ab3069a Phase 7 audio mixing — attempt + rollback + lessons
Несколько сессий попыток реализовать audio mixing в композитор'е.
Не достигнуто sub-секундной latency со стабильным video+audio.
Откатано на parallel mode (cfc-grid video-only, live от pipeline с audio).

Полный набор выводов и pitfall'ов — docs/LESSONS-audio-mixing-attempts.md.

Главные lesson'ы для будущей попытки:
- mpegts mux libavformat авто-инсёртит h264_mp4toannexb BSF которому
  не нравится Annex-B + inline SPS/PPS — NVENC OUTPUT_SPSPPS per-frame ломает
- SPSC ring drop newest при full, не oldest (consumer's domain)
- av_new_packet (не av_malloc) для av_interleaved_write_frame ownership
- Monotonic PTS на counter (frame_idx, total_samples) — не wallclock
- mediamtx env-var path names не должны иметь '-' (parser limitation)
- Default mediamtx ReadTimeout=10s короткий для burst write'ов

Изменения в repo сохранены для будущей доработки:
- src/writer.c — mpegts backend с audio stream support
- src/audio.c — RTSP AAC consumer + lock-free SPSC ring
- include/cuframes_composer/{writer,audio}.h — public API
- examples/grid_record.c — --format=mpegts + --audio-source flags
- include/cuframes_composer/composer.h — consumer_prefix field
- docker/Dockerfile — libavformat-dev добавлен в builder/runtime

cfc-grid composer стабильно работает на видео (substantially лучше
монолитного pipeline'а с audio bag'ом). TV рекомендуется использовать
rtsp://...:554/cfc-grid + опционально rtsp://...:554/live-audio
parallel.
2026-06-03 14:29:56 +01:00
gx 20b5234c41 docker: HEALTHCHECK через TCP probe ZMQ control port
netcat-openbsd добавлен в runtime layer (~50KB). HEALTHCHECK probe'ит
listening на 5599 (ZMQ control). Full functional ping через nc не сработает
(ZMTP требует binary greeting handshake), но liveness через TCP-проверку
достаточен для docker-compose restart-on-unhealthy логики.

Functional проверки делегированы external monitors:
  - MQTT health uptime_s растёт = composer не зависает
  - HA discovery sensor.composer_cfc-grid_active = camera-feed health
  - Phase 7 (Prometheus) добавит composition_time_us / fps metrics

Live-validated: cfc-grid container статус 'healthy' через 25с после
recreate, healthcheck Log shows exit 0.
2026-06-03 08:36:03 +01:00
gx cd4f3114d6 docker: CUDA 12.4 builder + runtime + PTX forward-compat для Pascal+Blackwell
CUDA 13 убрал sm_61 (Pascal), CUDA 12.4 убрал sm_120 (Blackwell).
Sweet spot: CUDA 12.4 с PTX-only для sm_89, JIT compile на Blackwell.

CMAKE_CUDA_ARCHITECTURES=61-real;75-real;86-real;89-real;89-virtual
покрывает Pascal/Turing/Ampere/Ada native + PTX для forward JIT.

Ubuntu 22.04 jammy glibc 2.35 forward-compatible с host 24.04 noble.

.dockerignore исключает build/ (от хостовой cmake) — иначе
docker build падает с 'CMakeCache directory mismatch'.
2026-06-03 07:51:57 +01:00
gx 804cadda08 Phase 6 prep: production Dockerfile + docker-compose пример
docker/Dockerfile — multi-stage build:
  builder: nvidia/cuda:12.6.0-devel-ubuntu24.04 + apt build-deps + cmake
  runtime: nvidia/cuda:12.6.0-runtime-ubuntu24.04 + apt runtime-deps
           + grid_record/simple_record + libcuframes.so.0 + libcuframes_composer.so.0

NVIDIA_DRIVER_CAPABILITIES=compute,utility,video в env image'а — обязательно
для NVENC dlopen libnvidia-encode.so.1.

docker/docker-compose.example.yml — образец для интеграции в
localhost-infra/hosts/R9-88.23/docker/cctv/. Два сервиса:
  cfc-grid          — композитор + control plane + MQTT health
  cfc-grid-ffmpeg   — pipe→RTSP push (использует существующий
                       ffmpeg-vf-cuda-grid image для совместимости glibc)

Сообщение в docs/docker/docker-compose.example.yml объясняет зависимости
(cuframes-ipc-anchor, cctv-mosquitto и т.д.) и нужный MQTT user.

Phase 6 deploy (intent перевести production):
  - Создать MQTT user composer + добавить в localhost-infra mosquitto passwd
  - Запустить cfc-grid параллельно с cuda-grid-pipeline (разные RTSP paths,
    не конфликтуют)
  - После проверки на проде — retire старый cuda-grid-pipeline
  - Обновить TV-плейлисты на новый rtsp://...:554/cfc-grid

Эти шаги требуют отдельных commit'ов в localhost-infra repo с явным
user approval, поэтому здесь только prep.
2026-06-03 06:26:14 +01:00