From df36e504fcb949f631d26e32adc0754f4ec5dfb5 Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 21 Oct 2026 15:47:30 +0200 Subject: [PATCH] docs: remove completed and obsolete project tasks --- doc/tasks.md | 1079 ++++---------------------------------------------- 1 file changed, 73 insertions(+), 1006 deletions(-) diff --git a/doc/tasks.md b/doc/tasks.md index 009e5a73..88b910d5 100644 --- a/doc/tasks.md +++ b/doc/tasks.md @@ -4,20 +4,6 @@ ## Текущие задачи -[+] **Chatgui: своя плитка без звука, раскрытие чужой и управление своей** — 20.10.2026: - Собственная плитка показывает прямой QVideoFrame издателя, без reader, decoder и входа микшера. - Клик по чужому видео разворачивает его во весь экран, повторный клик/Esc/кнопка возвращают сетку. - Геометрия и видимость меняются без пересоздания удалённых players; drag при zoom не раскрывает плитку. - Клик по своей плитке открывает окно публикации; его закрытие/Esc возвращает фокус прежней сетке. - Смена эпохи/удаление развёрнутого источника возвращает сетку; свой источник удаляется без drain/retry. - Головная C-сборка и chatgui PASS. test_stream_view 20/20, test_gui_language 9/9, - test_stream_publish 23 PASS/15 SKIP (Xvfb/platform). Под Xvfb проверка сетки 5/5, - отдельная проверка живой публикации и Esc 3/3: эпоха ab55772ddfdab987 сохранена, video PTS 143134→209876. - Проверены доставка клика через нативное окно Qt, Esc с фокусом на ползунке и прежний reader после возврата. - Рабочий chatgui не перезапускался; новая сборка применяется при следующем запуске. - Логи: /tmp/desktop-stream-tile-final-build.log, /tmp/desktop-stream-tile-final-tests.log, - /tmp/desktop-stream-grid-final-xvfb.log, /tmp/desktop-stream-controls-final-xvfb.log. - [ ] **Desktop publisher: проверить восстановление после недопустимого FPS в Xvfb-тесте** — 20.10.2026: Широкий screenAndWindowCapture прошёл закрытие управления с active=1 и продолжением публикации, затем не получил видео revision>=3 после запроса fps=61 и возврата engine.config().video.fps к 15. @@ -25,92 +11,10 @@ Причина и связь с UI-изменениями не установлены; отдельная проверка закрытия управления PASS. Лог /tmp/desktop-stream-controls-xvfb.log, тест tools/chatgui/tests/test_stream_publish.cpp. -[+] **Android: управление своей трансляцией из сетки с возвратом** — 20.10.2026: - Своя плитка открывает экран управления поверх сетки; стрелка и системный Back возвращают просмотр. - Удалённые readers остаются в композиции; собственный прямой preview передаётся между поверхностями. - На экране публикации убраны отдельные «Смотреть…» и «Смотреть все активные»; вход просмотра остаётся в шапке чата. - При проверке обнаружен и исправлен поздний dispose старой плитки, отключавший новый preview: - dispose снимает observer, AndroidView.onRelease отсоединяет только свой target; ON_STOP по-прежнему отключает output сразу. - Головная C-сборка, APK и Android unit 129/129 PASS. Финальный APK установлен на SM-A525F. - В Stream-Camera-Test (один собственный участник) проверены оба возврата, фон/возврат и stop из управления. - После stop сетка остаётся открытой с ожиданием источников, собственная плитка удалена. - По логам восемь target получили кадры и освобождены; publisher/origin/generation=1 не менялись, - encoder завершил 1902 кадра/dropped=0, собственных viewer/decoder opens нет. - Ошибок stream/video нет; два прежних предупреждения clipping исходящего компрессора, вне изменений UI. - Одновременное сохранение удалённых readers под управлением проверено по структуре композиции, не живым local+remote сценарием. - Тестовая публикация завершена. Логи: /tmp/stream-grid-controls-final-sm.log, - /tmp/stream-grid-controls-evidence.json, /tmp/stream-grid-controls-final-android-build.log, - /tmp/stream-grid-controls-final-core-build.log; исходное воспроизведение: /tmp/stream-grid-controls-sm.log. - -[+] **Своя трансляция: глобальная кнопка управления и фильтр выбора** — 20.10.2026: - Android/chatgui показывают красную камеру в шапках всех групп, пока локальный publisher действует; - Android также показывает её в шапке главного экрана. Сетевой каталог не управляет видимостью кнопки. - Нажатие открывает действующую публикацию: Android выбирает её канал, desktop открывает окно publisher. - Завершение скрывает кнопку; STARTING/STOPPING оставляют управление доступным до освобождения ресурсов. - Выбор одиночной трансляции и счётчик просмотра исключают self; общая сетка сохраняет собственный preview. - Головная C-сборка, chatgui и финальный APK PASS; Android unit 129/129. - Desktop test_gui_language PASS; test_stream_publish 23 PASS/14 SKIP (сценарии Xvfb/platform вне этого прогона). - Итоговый APK установлен на SM-A525F. В Stream-Camera-Test (только свой узел) проверены: - иконка главного экрана, иконка другой группы ннн, переходы обоих экранов в нужный канал публикации; - selector remote=0/ownExcluded=1, собственное имя отсутствует, Watch all доступен. - При остановке видимость LIVE → STOPPING → false; UI подтверждает скрытие на главном экране и в другой группе. - Ошибок stream/video и навигации нет. Пользовательская публикация перед обновлением остановлена с явного согласия; - отдельная тестовая публикация также завершена. Рабочий desktop-процесс не перезапускался. - Логи: /tmp/stream-header-final-sm.log, /tmp/stream-header-sm-live.log, - /tmp/stream-header-final-android-build.log, /tmp/stream-header-final-desktop-build.log, - /tmp/stream-header-desktop-tests.log, /tmp/stream-header-desktop-publish-tests.log. - -[+] **Android multiview: собственная трансляция напрямую и без местного звука** — 20.10.2026: - Собственная плитка получает Camera2 preview до кодирования, без reader/decoder/Opus playback/mixer input. - Общий StreamPreviewPlayback используется экраном публикации и сеткой; полноэкранный режим сохраняет target. - Собственная плитка не запускает remote retry и не ждёт декодируемый хвост при удалении. - Головная сборка, APK и Android unit 129/129 PASS; APK установлен на SM-A525F. - Проверено в существующем Stream-Camera-Test (единственный участник — свой узел), 20:19:51–20:24:57: - публикация со звуком, переход preview → сетка → fullscreen → сетка, фон/возврат, stop при развёрнутой плитке. - Во всём сеансе generation=1/origin неизменны, encoder 9048 кадров/dropped=0; - fullscreen target=249460734, кадры 369→5389 без новой camera session. Все три preview target освобождены. - Локальных viewer/decoder/mixer opens=0; завершение автоматически удалило выбранную плитку и вернуло панели окна. - Затем две удалённые трансляции: 1126/780 показанных кадров, один mixer input/AudioTrack; - tap/Back, viewer failed/released/retry=0. Одновременный local+remote в общем канале отдельно не проверялся. - В исходящем звуке прежний компрессор сообщил 11 clipping предупреждений; ошибок video/stream не было. - Логи /tmp/sm-self-live.log, /tmp/sm-self-evidence.json; проверка /tmp/sm-self-evidence.py; - сборки /tmp/sm-self-core-build.log, /tmp/sm-self-android-build.log; снимок /tmp/sm-self-fullscreen.png. - -[+] **Android multiview: нажатие разворачивает плитку** — 20.10.2026: - Нажатие на видео разворачивает его на весь экран; повторное нажатие или Back возвращает сетку. - Общий immersive-режим восстанавливает панели окна; видео вписывается без обрезки с поворотом 0/90°. - Плоский keyed Layout сохраняет все TextureView: выбранная плитка перекрывает остальные, общий звук продолжается. - Удаление выбранного source/epoch возвращает сетку; скрытые плитки исключены из accessibility. - Головная сборка, APK и Android unit 129/129 PASS; APK установлен на SM-A525F. - На телефоне проверены обе плитки, повторный tap и Back: прежние viewer/texture ID, resize 1070x602 ↔ 1920x1080. - По логам: две начальные Surface/decoder, release/failed/retry/audio detach=0, оба счётчика кадров растут. - Последний APK: accessibility выбранной плитки занимает [0,0][1080,2400], Back возвращает сетку. - Логи /tmp/sm-expand-live.log, /tmp/sm-expand-final.log; снимки /tmp/sm-expand-fullscreen.png, - /tmp/sm-expand-grid-return.png; сборка /tmp/sm-expand-accessibility-build.log. - -[+] **Android SM: устранено мигание multiview из-за повторного demand** — 20.10.2026: - В старом APK за 25 секунд семь ошибок Decoder already owns a working frame и перезапусков viewer. - pull выдавал record, оставляя повторный requested: следующий AVAILABLE создавал лишний ответ. - Выдача теперь погашает demand атомарно под viewer mutex; пустой pull сохраняет ожидающий запрос. - Добавлены ограниченные по частоте логи replies/repeats/pending и подробности занятого decoder input. - Native regression PASS: AVAILABLE после ответа, WAIT, отмена, audio-only, FIN и отсутствие утечек. - Головная C-сборка и APK PASS; Android unit 129/129, desktop stream_view 19/19. - APK установлен на единственный подключённый SM-A525F (RZ8R72MG64B), updateTime=19:47:07. - Живой просмотр 19:47:24–19:50:56: прежние два viewer ID, 6308/4423 показанных кадров, 29.73/20.80 fps; - viewer failed/retry/GAP/released=0, два первичных открытия decoder, аудиовыход продолжает воспроизведение. - Погашено не менее 11776 повторных demand; диагностические снимки подтверждают pending=0. - При старте был timeout отдельной сетевой probe; воспроизведение обоих источников продолжалось. - Логи: /tmp/sm-fix-live.log, /tmp/sm-fix-evidence.json, /tmp/sm-fix-native-test.log, - /tmp/sm-fix-android-build.log, /tmp/sm-fix-desktop-test.log; снимок /tmp/sm-fix-preview.png. - -[+] **Multiview desktop: Escape из плитки останавливает только её player** — исправлено 20.10.2026: - При fullscreen сетке и фокусе на QSlider событие получает StreamPlayerWindow::keyPressEvent. - embedded не учитывается: close() скрывает плитку и снимает reader, а сетка остаётся fullscreen. - Воспроизведено: grid_fullscreen=1, tile_hidden=1, tile_attached=0, tiles=1. - QShortcut сетки с WidgetWithChildrenShortcut обрабатывает Escape до дочернего player. - gridLocalPreviewAndTileNavigation проверяет фокус на QSlider, возврат из раскрытой плитки и сохранение reader. - Проверки offscreen и Xvfb PASS; /tmp/desktop-stream-grid-final-xvfb.log. - Временный стенд: /tmp/multiview-review/test_stream_view.cpp; лог /tmp/multiview-review/lifecycle.log. +[ ] **Проверить одновременную собственную и удалённую трансляции в multiview** — 20.10.2026: + Собственный preview и удалённые readers по отдельности проверены; их совместный живой сценарий в одном канале не проверялся. + На desktop/Android проверить переход в управление своей публикацией и возврат, fullscreen/Back/Esc, + сохранение удалённых readers и общего звука, отсутствие местного звука и остановку собственной публикации. [ ] **Multiview desktop: terminal CLOSED оставляет аудиовход и timer** — проверка 20.10.2026: fail(reason, false) ставит complete=true/failed=false, но tick снимает audio только по ended/failed. @@ -120,152 +24,6 @@ Временный regression-проверочный стенд и лог: /tmp/multiview-review/test_stream_view.cpp, /tmp/multiview-review/lifecycle.log. Исходники реализации при проверке не менялись. -[ ] **Проверить нестабильные паузы звука в test_stream_view** — 20.10.2026: - В полном диагностическом прогоне realH264RenderingAndClose: silenceGaps=4 вместо 2, - audio gap cause=pcm_short, got=288/480; /tmp/multiview-review/desktop-review.log. - Изолированный повтор исходного теста PASS: /tmp/multiview-review/audio-original.log. - Причина и связь с multiview пока не установлены; не считать изолированный PASS устранением. - -[+] **Просмотр всех активных трансляций: desktop, затем Android** — 20.10.2026: - Пункт в меню канала открывает автоматически обновляемую сетку; пустое окно ждёт новые источники. - Desktop: 2x2/3x3/4x4 с расширением по числу плиток; Android: раскладка по доступной площади экрана. - Общий stream_viewers хранит независимые handles/cursors; перекладка не пересоздаёт действующие players. - Отдельные Opus/SoundTouch/PTS/аудиочасы каждого источника, сумма PCM в одном output с limiter. - GAP, завершение и ошибка одного источника не останавливают остальные; размеры RS-колец не менялись. - C/desktop и Android APK собраны; Qt stream_view 19/19, шесть stream/audio recovery целей и native Android PASS. - Android unit 129/129; check.sh 164/165: прежний encrypted_attachment phase=5/heartbeats=12001. - Проверка на физическом SM-A525F и установка исправленного APK — в записи об устранении мигания выше. - Контракты и ограничения: doc/stream.txt. Логи: /tmp/multiview-desktop-audit-test.log, - /tmp/multiview-desktop-final-tests.log, /tmp/multiview-android-native-final.log, - /tmp/multiview-android-final.log, /tmp/multiview-full-check.log. - -[+] **Multicast с исходящими дескрипторами и входящими подписками** — 20.10.2026: - Отдельный routing_layer/multicast.c; контракт и примеры использования — multicast.h. - Номера 1..65535 выдаются последовательно без поколений; подписки на (группа, source, descriptor). - Общая FIFO 256 КиБ на ETCP-соединение, разделение по маршрутам, отмена при close/stop; - отчёты с участком src/dst, получателями, префиксом payload и счётчиком: общий бюджет 16 КиБ, таймер 300 мс. - test_multicast PASS: разветвление, тихий drop, lifetime, лимиты, таймер, смена маршрута, - длинные отчёты, backpressure/restart, исчерпание и обход номеров. Valgrind: 0 ошибок, lost=0. - check.sh: 163/165; прежние encrypted_attachment phase=5 и local_transport_packets line=209 - (отдельный повтор PASS). Логи: /tmp/multicast-full-check.log, /tmp/multicast-valgrind.log, - /tmp/multicast-valgrind-test.log, /tmp/multicast-local-transport-retry.log. - -[+] **Выбор битрейта трансляции до 12 Мбит/с** — 20.10.2026: - Desktop и Android: верхний ручной пункт 12М, прежние сохранённые значения выше приводятся к лимиту. - Android пересекает выбор с диапазоном encoder и сохраняет лимит при смене режима/камеры; - если ручного диапазона нет, используется автоматический выбор. Автоматический расчёт битрейта не менялся. - C/desktop/Android APK собраны, Android unit и Qt captureSettingsSurviveReopening PASS. - Логи: /tmp/stream-bitrate12-android-final.log, /tmp/stream-bitrate12-desktop-build.log, - /tmp/stream-bitrate12-settings-xvfb.log (изолированный экран; offscreen-проба была пропущена). - Готовые сборки в этой правке не устанавливались. - -[+] **Desktop/Android: codec probes при запуске вместо задержки каждого звонка** — 20.10.2026: - Звонок e55c56204f7bf159, локальный Linux: ACTIVE 01:01:17.892, decoder probes до 01:01:26.255, - encoder probes до 01:01:28.284. Samsung уже опубликовал RX CAPS за 4мс; первый input через 10459мс, - фактический показ через 10648мс. Источник задержки — последовательная матрица TX worker Linux. - Проверки обоих направлений перенесены в фоновую подготовку при старте приложения, результаты - сохраняются до завершения процесса. Desktop теперь кэширует и encoder, Android прогревает прежний кэш. - Все режимы/профили/ориентации и восемь кадров сохраняются; pacing нужен только до первого выхода, - после измерения pipeline хвост проверяется без искусственных пауз. GPU/CPU fallback не менялся. - Decoder Linux: 8.3 -> 2.7с; настоящий запуск обновлённого GUI: вся подготовка 4.7с, без камеры/сети. - Samsung: фоновая подготовка 18.8с, второй телефон 47.8с; оба завершили её до следующего звонка. - До завершения прогрева ранний звонок ждёт оставшуюся подготовку, частичные CAPS не публикуются. - Qt video/GPU/clock/camera 4/4 и дополнительная отмена/кэш/GUI проверка PASS; Android APK/118 unit PASS. - check.sh 162/164: прежний encrypted_attachment и local_transport_packets (отдельный повтор PASS). - Оба телефона обновлены, локальный GUI штатно перезапущен. Нового живого звонка ещё не было. - Логи: /tmp/video-warmup-qt-tests.log, /tmp/video-warmup-clock-verified-test.log, - /tmp/video-warmup-full-check.log; подробности: doc/call_video.txt. - -[+] **Разобрать нестабильный flood-тест test_local_transport_packets** — 20.10.2026: - Общий check.sh при подготовке codec cache: line=198 failed: invitations - before == 8. - Отдельный повтор PASS: миллион hostile packets, bounded flood/events/memory, discovery recovery. - Код local transport не менялся. Логи: /tmp/video-warmup-full-check.log, - /tmp/video-warmup-local-packets-retry.log; причина и связь с нагрузкой пока не установлены. - Проверка multicast: line=209, invitations == before + 9; отдельный повтор PASS. - Логи: /tmp/multicast-full-check.log, /tmp/multicast-local-transport-retry.log. - Исправлено 21.10: сетевые LAN-тесты используют общий discovery-порт и мешали друг другу. - Runner запускает оба после общего пула по одному; проверка барьера добавлена в test_run_tests.py. - Полный check.sh 165/165 + proxy/burst/load PASS: /tmp/test-fixes-full-check.log. - -[+] **Android: fullscreen вдоль длинной стороны и повторное использование codec probes** — 20.10.2026: - Общее вписывание со стримами поворачивает только изображение большого видео, интерфейс остаётся - неподвижным; миниатюры не поворачиваются. Проверены пропорции и отсутствие обрезки: четыре unit tests. - Завершённые codec probes сохраняются в процессе, RX публикуется до проверки своих encoder. - INFO метки отделяют подготовку, первый input, decode и Surface ACK. Native test подтверждает, - что обновление CAPS того же звонка сохраняет RX очередь/счётчик/уведомления/peer. - На втором телефоне холодная подготовка 23811мс, три обращения к кэшу суммарно 306мкс. - C/Android APK и 118 unit PASS; check.sh 162/164: прежние local_transport TTL и encrypted_attachment phase=5. - APK установлен на оба телефона. Первый звонок после перезапуска процесса ещё требует полной пробы. - Задержка первого Linux -> Samsung звонка локализована отдельно выше. - -[+] **Samsung RX: фризы из-за поздней регистрации Surface ACK** — 20.10.2026: - В живом логе 1.99 fps, ожидание ACK 538мс в медиане/1019мс максимум. Callback регистрировался - в onSurfaceTextureUpdated после захвата списка текущего draw и ждал постороннего обновления окна. - Регистрация перенесена в onPreDraw, timestamp проверяется после commit того же кадра. - Отдельный TextureView/EGL тест на Samsung воспроизвёл 15 кадров за 8с до исправления; - после — 483/8с при 60fps и 241/8с при 30fps. Основной чат не заменялся, сеть/камера не использовались. - Добавлены диагностика texture/commit/ACK и аппаратный regression probe. APK и 114 unit PASS; - check.sh 162/164: прежние local_transport TTL (повтор PASS), encrypted_attachment phase=5. - Исправленный APK собран, живой сетевой звонок на нём ещё не проверен. Подробности: doc/call_video.txt. - -[+] **Режимы камеры до 60 fps и восстановление задержки без потери encoded кадров** — 20.10.2026: - Исправлен фильтр Windows камер 50/100/330 fps; размер/FPS передаются через изолированный camera IPC. - Desktop и Android выбирают пары размер/FPS, проверяют encoder/decoder 30/50/60 в обеих ориентациях. - Частота передачи не снижается; raw отбирается до encode. Все encoded кадры декодируются последовательно. - Ускоренный показ сохраняет кадры при наличии запаса частоты экрана; устойчивый долг снимается только - пропуском decoded presentation, с диагностикой причины. Часы двигает только ACK, очередь ready <=3. - Android APK/114 unit, native video/playout, desktop build/Qt 5/5 — PASS. Samsung: 72 аппаратные фазы - вплоть до Full HD60, все 72 KEY приняли desktop и второй Android. Unisoc: 24 фазы 640x480 при 30/50/60. - check.sh 163/164: прежний encrypted_attachment phase=5/heartbeats=12001, local_transport PASS. - Новые сборки в живом Windows/Android звонке не проверены и не установлены. Подробности: doc/call_video.txt. - -[+] **HEVC Samsung: согласование High tier и проверка реального приёма** — 19.10.2026: - В звонок добавлен HEVC Main/High tier с level >=4, отдельными decode-пробами Android/desktop. - Samsung encoder повторно проверяется с level 4; рабочая настройка совпадает с probe. - Производственные VPS/SPS не переписываются, старые ограничения BR/CPB/DPB/reorder сохраняются. - На Samsung прошли 24 production encode/decode фазы, включая обе ориентации Full HD и смену bitrate. - Все 24 реальных KEY декодированы desktop и вторым Android. Подробности: doc/call_video.txt. - Сборки, native video, Android unit и Qt video/camera/clock прошли. Живой звонок после обновления обеих сторон ещё не проверен. - -[+] **Разобрать нестабильный test_local_transport под общей нагрузкой** — 19.10.2026: - В check.sh для HEVC: 162/164, кроме прежнего encrypted_attachment упал peers():95 failed: found; - перед отказом endpoint peer=2 удалён по TTL (age_ms=30331). Отдельный повтор прошёл. - Логи: /tmp/hevc-high-core-check.log, /tmp/hevc-high-local-transport-retry.log; код local_transport не менялся. - Повторилось при исправлении Android Surface ACK: age_ms=30335, тот же peers():95; - отдельный повтор PASS. Логи /tmp/video-surface-freeze-full-check.log, /tmp/video-surface-freeze-local-retry.log. - 21.10 воспроизведено при совместном запуске с test_local_transport_packets: посторонний UDP flood, - endpoint peer=2 удаляется по TTL, отправка request=103 не проходит. Оба LAN-теста теперь выполняются отдельно от пула. - Логи /tmp/local-packets-debug/test_local_transport.log, /tmp/test-fixes-full-check.log (165/165 PASS). - -[+] **Разобрать ожидание запросов ключей после перезапуска автора в test_encrypted_attachment** — 19.10.2026: - При проверке настроек входящих звонков общий check.sh: 160/162; test_encrypted_attachment остановился в phase=5, - heartbeats=12001. Отдельный повтор также остановился в phase=5: после старта автора не получены два pending incoming-запроса. - Причина и связь с изменениями не установлены. Логи: /tmp/phone-busy-full-check.log, - /tmp/phone-busy-encrypted-recheck.log; артефакты: /tmp/utun_encrypted_attachment_RVU2yS. - Повторилось при проверке независимого видеопланировщика: check.sh вне sandbox 163/164, - тот же phase=5/heartbeats=12001; /tmp/video-independent-check-full.log, - артефакты /tmp/utun_encrypted_attachment_IW0W28. Код вложений в этой работе не менялся. - Повторилось при проверке Full HD звонков: check.sh 163/164, тот же phase=5/heartbeats=12001; - /tmp/fullhd-core-check.log, артефакты /tmp/utun_encrypted_attachment_MIwfM3. - Исправлено 21.10: ATTACHMENT_KEYS и RADIO_CALL имели ID=0x40; radio_call перезаписывал обработчик вложений. - Для ATTACHMENT_KEYS выделен 0x42. Следующий этап выявил поздний CM UP с освобождённым media_download: - TIMEOUT терял живой handle. Handle закрывается при отказе, сохраняется при QUERY и разделяется блоками держателя. - Добавлен детерминированный тест отмены позднего UP; вложение проходит все 10 фаз, полный check.sh 165/165 PASS. - Логи /tmp/attachment-core-stack.log, /tmp/media-handles-focused/, /tmp/test-fixes-full-check.log. - -[+] **Full HD в видеозвонках и реальные разрешения desktop-камеры** — 19.10.2026: - Desktop использует общий со стримами отбор аппаратных режимов до 1920x1080 при 30/29.97fps. - Список и hotplug приходят из отдельного процесса; выбранный режим открывается точно, без подстановки ближайшего. - Android добавляет 1920x1080 в пересечение YUV-режимов камеры и проверенных кодеров; учтены обе ориентации. - Encode/decode CAPS объявляются после настоящих проб, GPU/CPU выбираются с учётом размера. - Общий RGB-буфер камеры расширен до Full HD; очередь показа остаётся на три кадра. - Пробы decoder отменяются при stop, незавершённые CAPS не кэшируются. - Ядро, полный desktop и Android APK собраны; Android unit 111/111, Qt video/camera/clock/audio 5/5, - общий механизм режимов камер 3/3, native bitstream/Full HD — PASS. - Полный check.sh: известный сбой test_encrypted_attachment, остальные 163 PASS. - Проверка живого Full HD звонка на Windows и телефонах ещё не выполнена. - Подробности и логи: doc/call_video.txt. - [ ] **Разобрать нестабильную загрузку storage-узлов в test_media_delivery_chat** — 19.10.2026: В том же общем прогоне storage st1/st2 не собрали файл, n2 исчерпал попытки блока 0 (15/19 внутренних проверок). Отдельный повтор прошёл 19/19. Причина не установлена; сравнить маршруты и готовность storage под общей нагрузкой. @@ -284,12 +42,13 @@ Получатель принял приглашение и дважды отправил ACK; до проверки в логе отправителя нет приёма этого ACK. Отдельный повтор прошёл. Логи: /tmp/utun-stream-preview-local-transport-failure.log, /tmp/utun-stream-preview-local-transport-retry.log. -[ ] **Разобрать нестабильную проверку аудиопауз desktop-трансляции** — 17.10.2026: - При проверке зума test_stream_view::realH264RenderingAndClose получил silenceGaps=3 вместо gapsBefore=2. - В логе есть desktop audio gap cause=pcm_short, got=96/480; видео продолжает выводиться (50 кадров к stop). - Первый полный Qt-прогон прошёл; сбой повторился с общим check.sh и после его завершения. - Причина не установлена; нужны диагностика PCM/часов и воспроизведение под нагрузкой. - Логи: /tmp/stream-zoom-full-view-audio-gap.log, /tmp/stream-zoom-full-view.log. +[ ] **Разобрать нестабильную проверку аудиопауз desktop-трансляции** — 17–20.10.2026: + test_stream_view::realH264RenderingAndClose нестабильно получает silenceGaps=3–4 вместо 2. + Зафиксированы pcm_short с got=96/480 и 288/480; видео продолжало выводиться. + Сбой повторялся с общей нагрузкой и после её завершения; изолированные повторы проходили. + Проверить актуальные PCM workers/часы под нагрузкой; единичный PASS не подтверждает устранение. + Логи: /tmp/stream-zoom-full-view-audio-gap.log, /tmp/stream-zoom-full-view.log, + /tmp/multiview-review/desktop-review.log, /tmp/multiview-review/audio-original.log. [ ] **Устранить коллизию порта при перезапуске узла в test_dm_e2e** — 16.10.2026: Общий check.sh при проверке Windows-курсора: 155/156, test_dm_e2e упал в phase=9 на создании B2. @@ -297,213 +56,30 @@ Проверить владение/резервирование порта между остановкой B и созданием B2 при параллельном прогоне. Логи: /tmp/win-stream-cursor-dm-e2e-failure.log, /tmp/win-stream-cursor-dm-e2e-retry.log. -[+] **Постепенно увеличивать аудиобуфер при подтверждённых сбоях backend** — 16.10.2026: - AudioDevice получает WASAPI DATA_DISCONTINUITY, ALSA EPIPE и PulseAudio hole/overflow/underflow. - Два опроса со сбоями за 5с увеличивают период на 5мс; между изменениями минимум 5с, - первый 1с после запуска пропускается. Запрошенная полная ёмкость ограничена 100мс. - Начальные настройки Linux сохранены (capture 10мс); новая сессия/устройство возвращает исходный запрос. - Backend может округлить фактический размер: он и каждый шаг записываются в лог; повторные сбои агрегируются за 5с. - Перезапуск захвата выполняется без блокировки GUI, с сохранением RX звонка/рации и безопасным stop во время close. - Проверены реальные callback-уведомления, нижняя граница/лимит, reopen/backoff и uninit=700мс. - GUI собран; 7/7 аудиотестов PASS: /tmp/audio-buffer-final-tests.log. - Проверка слышимого результата с Windows-драйвером остаётся на следующем звонке пользователя. - -[+] **Проверять поступление PCM микрофона в desktop-звонках и рации** — 16.10.2026: - Секунда без первого/очередного корректного PCM отключает захват с понятным сообщением GUI. - Цифровая тишина допустима; отсутствие callbacks, nullptr и frames=0 проверяются отдельно. - RX сохраняется, PTT снимается и блокируется до выбора другого входа или новой сессии. - Неисправный backend закрывается асинхронно; stop во время закрытия не блокирует GUI, - новый захват ждёт завершения прежнего. Контекст и callback живут до завершения worker. - Тест с uninit=700мс проверяет heartbeat GUI, stop<300мс, удержание lease звонка и отсутствие повторных открытий. - GUI собран; audio_recovery, microphone_watchdog, radio_panel, call_video_encoder, call_video_clock: 5/5 PASS. - Захват экрана 3440×1440 под Xvfb: H.264/H.265 продолжают выдавать кадры, stop=7/59мс. - check.sh: 156/156, proxy 9/9, burst/load PASS. Логи: /tmp/mic-stream-final-tests.log, - /tmp/mic-stream-core-check-unrestricted.log, /tmp/stream-h265-progress.log. - -[ ] **Устранить неподвижный кадр Windows-трансляции на Android и зависание stop** — 16.10.2026: - Новый 4.log и Samsung epoch=d8252b9a534ff713 установили цикл ожидания: - KEY=20669261, первый звук=21097059 (позже на 427798мкс), lookahead=80мс, written=played=0. - Cursor теперь прогревает аудио от фиксированной первой аудиометки, сохраняя ограниченный lookahead. - Регрессия с этими PTS и реальными RS/Opus/SoundTouch выдаёт PCM и продвигает часы; reset проверен отдельно. - В Windows videoLoop пишет stopped, но GUI застревает на join после возврата из функции. - Join video/audio вынесен в отдельный worker; GUI работает до полного выхода потоков, включая native TLS. - FIN отправляется после workers параллельно асинхронному закрытию микрофона; owner/lease сохраняются до завершения. - Проверяется cleanup native TLS с BlockingQueuedConnection к GUI, обычный stop и destructor. - Финальный Xvfb 3440×1440: 32/32 PASS, включая H.264/H.265, CPU consent, watchdog и общий захват рации. - Общие playback-тесты: 2/2 PASS. check.sh: 156/156, proxy 9/9, burst/load PASS (134с). - APK и Android unit-тесты собраны, Samsung RZ8R72MG64B обновлён. Старый источник виден в каталоге, - но отдаёт только остаток seq=918 без KEY, после чего новый viewer получает open timeout. - Нужна свежая трансляция/stop из Windows после пересборки; оба исправления на исходной паре устройств ещё не подтверждены. - Отдельно libx265 3440×1440 в Windows выдаёт примерно 2–3fps: это ограничение CPU остаётся. - Новый 4.log подтвердил более позднее застревание: GUI timer работает, `videoLoop()` вернулся, - но native video thread не вышел за 20с; поэтому join worker не послал FIN. - `QVideoFrame::toImage()` перенесён в долгоживущий image worker между захватом и encoder worker. - Под Xvfb конверсия 3440×1440 занимает 51–106мс и выполняется с gui_thread=0; GUI получает лишь последний кадр. - Encoder worker вышел на всех stop; полный Xvfb-тест трансляции: 32/32 PASS, /tmp/stream-persistent-image-xvfb.log. - Осталась проверка новой сборкой Windows: в Qt Multimedia другой backend и только он подтвердит исходную машину. +[ ] **Проверить Windows-трансляцию на исходной машине после исправлений playback/stop** — 16.10.2026: + Цикл ожидания позднего аудио исправлен; join и закрытие микрофона выполняются асинхронно, + QVideoFrame::toImage() вынесен в долгоживущий image worker. Linux/Xvfb-регрессии проходят. + Осталась свежая трансляция Windows → Samsung и stop после пересборки Windows: исходный Qt backend ещё не проверен. + На RYS HFR USB2.0 Camera проверить сообщение об отсутствии PCM, отзывчивость при завершении WASAPI, + отказ/согласие на CPU после отказа NVENC. Причина frames=0 микрофона пока не установлена; + подробный AudioDiag реализован только для Linux. libx265 3440×1440 на исходном CPU выдаёт около 2–3fps. Логи: 4.log, /tmp/stream-viewer-new-run.log, /tmp/late-audio-test.log, - /tmp/stream-viewer-after-update.log, /tmp/stream-persistent-image-xvfb.log, - /tmp/stream-audio-stop-full-check.log. + /tmp/stream-persistent-image-xvfb.log, /tmp/stream-audio-stop-full-check.log. -[+] **Проверять микрофон и спрашивать перед переходом трансляции на CPU** — 16.10.2026: - По 4.log/6.log: GPU-кодировщики недоступны, WASAPI-микрофон камеры выдаёт frames=0, - повторное закрытие устройства блокировало GUI примерно на 4 с. Список кодеков больше не запускает пробное кодирование. - До первого корректного PCM не открываются видеокодировщики; тишина в полученном PCM допустима. - При отказе GPU показывается вопрос с отказом по умолчанию; согласие действует на кодек только текущей трансляции. - При отсутствии PCM в течение секунды трансляция прекращается с сообщением, без цикла повторного открытия микрофона. - Закрытие последнего audio backend идёт в worker (Windows COM и сохранение контекста до завершения учтены). - Проверены устаревший ответ, закрытие окна с вопросом, новый запуск без сохранённого согласия, - пропажа PCM после начала, отсутствие первого PCM и отзывчивость GUI при медленном закрытии. - GUI собран; Xvfb: 29/29; call_video_encoder, call_video_clock, audio_recovery: PASS. - check.sh: 156/156, proxy 9/9, burst/load PASS. Логи: /tmp/stream-start-{x11-final,related-check,full-check}.log. +[ ] **Проверить появление значка свежей трансляции на SM после сна через colo2** — 16.10.2026: + Пробуждение и перезапуск SM во время сна уже проверены на обновлённом colo2: + новый линк снимает прежний таймер, Merkle завершается без ожидания полного сна 120с. + Осталась визуальная проверка значка новой desktop-трансляции после возврата SM в foreground; + в прежнем прогоне активных источников не было (count=0). + Логи: /tmp/stream-wake-live-{sm,colo2}-*.log. -[ ] **Проверить трансляцию на Windows с RYS HFR USB2.0 Camera** — 16.10.2026: - Проверить на исходном устройстве сообщение об отсутствии PCM и отзывчивость окна при завершении WASAPI, - отказ/согласие на CPU после отказа NVENC. Автотесты воспроизводят условия отказа на Linux, не Windows-драйвер. - Причина frames=0 самого микрофона ещё не установлена; подробный AudioDiag сейчас реализован только для Linux. - -[+] **Снять устаревший сон пира при пробуждении через новый линк** — 16.10.2026: - После перезапуска SM colo2 сохранял peer_phase_timer прежнего соединения; normal keepalive нового линка - не снимал его из-за ka_peer_sleeping=0. Merkle отменял сессии, объявление трансляции задерживалось примерно на 110 с. - Normal keepalive теперь отменяет фазу/таймер всего ETCP_CONN независимо от флага линка, включая будущее засыпание. - Повторный RX не отодвигает TX; ACK сна не пробуждает пира; REINIT сам по себе не меняет режим сна. - Проверены UDP/TCP, новый линк, min_sleep=90 с, быстрый hide/show, повтор normal после потери/запоздалого SLEEP. - Сценарий desktop → промежуточный узел → mobile доставил источник в каталог за 1045–1047 мс после foreground, - отменив таймер сна 120 с; удержание ACTIVE трансляцией и освобождение последнего владельца также проверены. - Семь профильных C-тестов и 106 Android unit-тестов прошли; ядро и APK собраны. - Общий check.sh: 156/156, proxy 9/9, burst/load PASS (120 с). - Логи: /tmp/stream-wake-{server,standby,catalogue,service-final,android-tests,full-check}.log. - -[ ] **Проверить исправление сна на SM через обновлённый colo2** — 16.10.2026: - Пользователь обновил colo2: подтверждены fc526d16/919c3d76 и новый процесс от 13:58. - Живой SM: скрытие GUI → STANDBY; открытие в 14:02:47.098 → ядро ACTIVE в .108, colo2 awake в .750. - Пробуждение произошло через 22,5 с сна, раньше min_sleep=90 с (полный сон 120 с). - Перезапуск приложения во время сна повторил исходный сценарий: colo2 сохранил ETCP_CONN 0x2344866e0288, - новые TCP-линки 6/7 поднялись в 14:05:03.103/.158, peer awake пришёл в .158, Merkle завершился в 14:05:04.718. - При открытом GUI старые фазы больше не усыпляют соединение. Логи: /tmp/stream-wake-live-{sm,colo2}-*.log. - Осталась визуальная проверка значка свежей трансляции: - во время проверки активных источников нет (count=0); пользователю отправлен запрос запустить desktop-трансляцию. - -[ ] **Равномерный показ видео с минимальной задержкой** — 15.10.2026: - Общий call_video_playout подключён к Android/desktop: абсолютные сроки 1.04x, A/V -50..+40мс, - отдельная метка доступности кадра в RX port, отсутствие накопления опозданий CPU. - Android продолжает подачу decoder во время ожидания показа; desktop публикует через coalesced UI notification. - Управляемые сценарии, реальный Qt decoder с задержками сети/CPU/UI и повторным start, codec/transport - и 103 Android unit-теста прошли; ядро/ChatGUI/APK собраны, обновление установлено на Samsung и Q8. - Живой звонок 11342339676311998023: SM ~29.2fps без drops, desktop ~26.4fps с ~10% late drops. - Остаточные паузы и обратное направление ещё требуют проверки. В финальную сводку добавлены - gap_pts_us/gap_rx_us/gap_dispatch_us для точного разделения причин; подробности в doc/call_video.txt. - Финальная сборка, звонок 9002196988226353494: последнее окно SM 29.94fps без drops, - desktop 29.61fps и 8 late drops/20с. Длинные интервалы видны уже при поступлении кадров. - Обнаружено ожидание внешнего события после лимита TX flush 16x1200 байт; крупный SM-кадр - имел queue_age=39.9мс. Добавлено отменяемое продолжение через uasync_call_soon после исчерпания - лимита 16 фрагментов, с сохранением сетевого backpressure и A/V-барьера; закрытие/discard отменяют callback. - test_call_video_flush проверяет целостность 45001 байта без audio/tick, порционность, сетевые ограничения, - audio/CAPS, конкурирующий flush и отмену перед освобождением. Он, video/rate/playout, test_call (2/2) - и Qt clock/encoder (13/13) прошли; Android unit-результаты 103/103 актуальны (Gradle up-to-date). - Ядро/ChatGUI/APK собраны, оба телефона обновлены, ChatGUI перезапущен. В секундной сводке TX появились - flush_yields/runs/wait_max_us/net_wait/audio_wait, в выборочном send — budget_yields. - Живой звонок 12694689407894286842 подтвердил продолжение: SM-кадры 42429/43309 байт, - budget_yields=2, queue_age=600/500мкс. Последние 20с: SM 29.87fps без drops, desktop 29.91fps/3 late drops. - A/V внутри границ; отдельные промежутки SM до 63.8мс остаются. Краткие invalid audio clock сбрасывают - якорь видео; причина invalid в текущем логе не видна. Следующий шаг — агрегированная диагностика причин - invalid clock и времени получения снимка, затем проверка связи с gap_*; слепое изменение часов не делать. - -[+] **Измерить задержку видео desktop -> Samsung по этапам** — 15.10.2026: - Добавлена выборочная трассировка по одному окну исходного PTS в секунду: encode/send/receive, - pull/queue/decode/release, Android frame commit и desktop select/publish. Протокол и A/V-планировщик не менялись. - Проверка показала две ловушки диагностики: MediaCodec callback на Samsung возвращает source PTS в поле времени, - а TextureView.onSurfaceTextureUpdated может читать timestamp предыдущего кадра до работы RenderThread. - Для Android используется registerFrameCommitCallback; это завершение UI-рендера, ещё не физическое появление пикселей. - Звонок 14610053360084326214; полные замеры в doc/call_video.txt, раздел диагностики 15.10.2026. - На стабильном участке сеть ~4–5мс, decoder SM ~6мс. RX ждёт audio clock; в обратном направлении - камера/кодер телефона уже задерживают кадр ~125мс, поэтому desktop почти не ждёт аудио перед показом. - Уменьшение только времени encoder не убирает ожидание audio clock; произвольного сдвига видео не добавлено. - Ядро, desktop и APK собраны, 103 Android unit-теста, test_call_video_clock и 13 Qt encoder-проверок прошли. - Диагностический APK установлен на Samsung, ChatGUI перезапущен; непрерывные логи и снимки сохранены в /tmp/video-timing-*. - -[ ] **Снижение минимального запаса JB звонка до 20мс** — 15.10.2026: - Нижняя граница общего call_jitter изменена с 60 до 20мс; адаптация по 10-секундному окну сохранена. - Добавлен общий модуль src/call/call_delay.h/.cpp: direct PCM с удалением одиночных сэмплов (<=2%) - и SoundTouch (<=1.6), вход/выход при избытке 120/40мс, ограниченная история исходного PCM. - Обе границы перехода точные: контекст на входе отбрасывается только до уже выданной позиции; - на выходе выдаётся весь готовый Copy, затем сохранённый raw-хвост. flush/сброс аудиочасов не используются. - Прямой режим только ускорением доводит разность входа/выхода до целого числа кадров 960 сэмплов; - учитывает тишину устройства, не расходует сетевой резерв на коррекцию. Ожидания пересборки кадров нет. - JB начинает/возобновляет PCM при наличии reserve + запрошенный блок; Opus/сетевое окно остались в JB. - Регрессия ровной доставки с запасом 20мс исправлена без ослабления проверки отсутствия underrun. - test_call_delay проверяет каждый сэмпл по Copy/Mix, 20 фаз доставки, 20 начальных пауз, - 200 границ повторного переключения, хвост без flush, изменяемые pull 1..8192 сэмплов. - test_call_jitter проверяет перебой 80мс, рост/спад резерва и отсутствие новых underrun после восстановления. - Семь профильных C++-тестов и полный check.sh (ядро/proxy/burst/load) проходят; desktop/APK собраны, - Android unit-тесты проходят. В периодический лог JB добавлены режим, точный tempo, фаза и число удалений. - APK установлен на оба телефона. В живом desktop -> Samsung звонке стабильный direct: tempo=1, phase=0, - JB reserve=20мс, AudioTrack queue=20мс, hardware underrun=0; акустический end-to-end ещё не измерен. - Дополнительная задержка обнаружена в Android output: AudioFlinger 113–114мс при app queue=20мс, - обычный PRIMARY без FAST. В сохранённой трассе timestamp даёт 137–140мс при app queue=40мс. - Android теперь запрашивает PERFORMANCE_MODE_LOW_LATENCY, логирует принятый режим и задержку outputUs; - аппаратный timestamp используется для A/V независимо от debug. При потере timestamp часы устаревают, - возврат к head после аппаратного якоря запрещён; смена маршрута инвалидирует старую метку. - После нулевой AudioTrack.write повторный JNI progress не вызывается; PCM не отбрасывается. - Desktop: готовая PCM-очередь адаптируется 40 -> 20мс, учитывает полный callback, растёт при недостачах; - неудачные пробы уменьшают частоту последующих попыток. Частичный блок учитывается отдельно. - Оба UI показывают очередь приложения и полный аудиовыход (он уже включает очередь, складывать нельзя). - 100 Android unit-тестов и 10 профильных C++/Qt-тестов прошли; ядро, desktop и APK собраны. - Обновление установлено на SM_A525F и Q8_DA6B8P01, приложения запущены, непрерывный logcat пишется в /tmp/call-output-*-live.log. - Живой звонок c66f218c68855546 после обновления: Samsung отклонил FAST (requested=0x4, output=0x2), - AudioPolicy назначила VOIP_RX=0x8000 на PRIMARY. При app queue=20мс outputUs в среднем 112.6мс, - при 40мс — 138.2мс; hardware underrun=0. Переключение speaker -> earpiece обновило timestamp generation; - progressCall сократился с 6–7мс до ~0.06–0.2мс на блок. Сетевой JB по-прежнему растёт при недостачах. - Desktop после пробы держит один готовый блок: pcm_after_mix в среднем ~18.6мс вместо ~38.6мс; - после начального пустого callback новых starvation нет. Стартовый callback повысил резерв 2 -> 3, - возврат 3 -> 2 -> 1 занял 40с; обучение стартового периода стоит отделить от рабочего starvation. - Отдельный APK audio-probe проверен на обоих телефонах: VOICE_COMMUNICATION/SPEECH, активный захват, - тишина на выходе, данные микрофона отбрасываются. На этапе этой пробы основное приложение использовало AudioTrack. - Samsung: AudioTrack с буфером 20мс даёт outputUs ~103мс в среднем; повторное открытие не включает FAST. - AAudio/MMAP на speaker: shared mono/stereo ~30мс, exclusive mono/stereo ~24мс, буфер 20мс, underrun=0. - Earpiece отсутствует в MMAP-профиле устройства; AAudio падает в legacy shared с буфером 40мс и outputUs ~129мс. - Проверен круг speaker -> earpiece -> speaker: обе смены дают AAUDIO_ERROR_DISCONNECTED; - повторное открытие speaker возвращает MMAP/exclusive и 24.281мс в среднем (22.471..25.700), underrun=0. - Q8: все варианты AAudio остаются legacy, outputUs ~166–172мс при буфере 40мс. - AudioTrack Q8 с 20мс нестабилен (353/352/362 underrun за три этапа по 8с); - контроль с 40мс даёт 160–162мс в среднем и ноль underrun на всех трёх этапах. - Это оценка аудиовыхода по timestamp, включая очередь приложения, не акустическая задержка всего звонка. - Изолированная проба не проверяет DSP-нагрузку реального звонка и качество AEC; перед интеграцией нужны эти проверки. - Следующий этап: один владелец выхода, повторный выбор быстрого backend после подтверждённой смены маршрута, - закрытие/открытие вне realtime callback, новая эпоха аппаратных часов при сохранении шкалы медиа/JB. - Callback должен только выдавать подготовленный PCM. Legacy AAudio не дал выигрыша: сохранять AudioTrack fallback. - Смена маршрута не должна навсегда запрещать новую пробу MMAP; неудачи ограничивать в пределах текущего маршрута. - Не обещать бесшовность аппаратного DISCONNECTED: судьбу PCM, уже переданного старому устройству, нужно определить отдельно. - Сборки ядра, :app:assembleDebug и :audio-probe:assembleDebug прошли; оба диагностических прогона освободили ресурсы. - Логи: /tmp/aaudio-probe-{sm,q8}.log; AudioFlinger: /tmp/aaudio-probe-{sm,q8}-flinger.txt; - AudioPolicy Samsung: /tmp/aaudio-probe-sm-policy.txt. - Повтор: установить audio-probe/build/outputs/apk/debug/audio-probe-debug.apk через adb install -g -r; - открыть com.utun.audioprobe/.ProbeActivity при завершённых звонках и оставить Activity видимой. - Полная матрица запускается без аргументов; для круга Samsung: --es api aaudio --ei channels 1 - --es sharing exclusive --ez roundtrip true --ei seconds 20; контроль Q8: --es api track --ei buffer_ms 40. - Логи adb logcat -s AudioProbe; для нового прогона сначала am force-stop com.utun.audioprobe после завершения предыдущего. - Реализован CallAudioOutput: AAudio для подтверждённого SPEAKER, AudioTrack для остальных выходов/отказа fast. - AAudio пишет подготовленный PCM по аппаратному периоду с ограниченным общим таймаутом 100мс; - дополнительной PCM-очереди/callback нет. NON_BLOCKING заполняет ёмкость MMAP сверх рабочего bufferSize: - прямая проба дала ~63мс, штатное ожидание по периоду — ~24.4мс без underrun и с восстановлением после route change. - Источник поведения: AOSP AudioStreamInternalPlay::processDataNow и AudioStreamInternal::processData. - Подтверждённый AudioManager device ID запускает повторный выбор выхода; одинаковые уведомления игнорируются. - DISCONNECTED/DEAD_OBJECT обрабатывает playback worker, повтор ограничен текущим маршрутом, далее AudioTrack. - Новое устройство получает локальный head=0 и общий base=accepted PCM. Незаписанный хвост блока сохраняется. - Очередь уже закрытого устройства не переигрывается: pendingFrames логируется, при переключении возможен короткий разрыв. - call_audio_suspend_device инвалидирует аппаратный якорь без сброса JB/DSP/PTS. Старые timestamps отвергаются по generation. - AEC использует полную задержку выхода и возраст аппаратной метки захвата, без смешивания старого/нового frame counter. - Реальный видеозвонок на Samsung: SPEAKER ~23.1мс, wired MMAP ~23.4мс, EARPIECE AudioTrack ~137мс при буфере 40мс; - возврат EARPIECE -> SPEAKER снова выбирает MMAP. На всех выходах hardware underrun=0, ошибок аудиочасов нет. - Однако wired MMAP физически продолжал играть из динамика: Telecom, AudioPolicy и HAL показывали headset/0x4, - пользователь дважды подтвердил неверный звук. Контроль с AudioTrack исправил физический выход (подтверждено пользователем). - Поэтому быстрый backend разрешён только на SPEAKER; для гарнитур сохранён AudioTrack, несмотря на формальную доступность MMAP. - Исправлен auto-headset: ручной выбор speaker действует до следующего подключения/отключения гарнитуры, - дубликаты событий не отменяют ручной выбор. Рация явно отключает авторежим при ручном выборе, её поведение сохранено. - Добавлены INFO только при изменении списка устройств, Telecom endpoints и видимого состояния аудиокнопок. - 103 Android unit-теста, test_call_timeline, test_call_video_clock, test_call_delay, test_call_jitter прошли; - ядро и APK собраны. Финальный APK установлен на оба телефона. Логи переходов: /tmp/route-sm-live.log; - противоречащий физическому звуку HAL-маршрут: /tmp/headset-failure-{audio,policy,flinger}.txt. +[ ] **Проверить остаточные паузы видеозвонка на актуальном playout** — 15.10.2026: + После исправления TX flush живой звонок 12694689407894286842 дал SM 29.87fps без drops, + desktop 29.91fps/3 late drops за последние 20с; отдельные промежутки SM доходили до 63.8мс. + В старой трассе краткие invalid audio clock сбрасывали якорь, точная причина invalid не была видна. + После переработки playout/ACK и чтения аудиочасов 19–20.10 повторить оба направления на устройствах, + сопоставить gap_pts_us/gap_rx_us/gap_dispatch_us и причины недоступности часов, если паузы сохраняются. + Текущий контракт и результаты поздних проверок: doc/call_video.txt. [ ] **Доступность разговорного динамика в UI звонка** — при подключённой проводной гарнитуре Samsung убирает EARPIECE из Telecom endpoints, но кнопка остаётся доступной по наличию физического встроенного устройства. @@ -511,120 +87,18 @@ Также выбор проводной гарнитуры в CallScreen сейчас запрашивает BLUETOOTH_CONNECT при отсутствии этого разрешения; проверку разрешения нужно привязать к выбранному типу гарнитуры. -[x] **Завершение звонка и видеопорта после обрыва транспорта** — 15.10.2026: - Трасса test_call доказала потерю HANGUP при смене эпохи сигналинга: router reset удалял старую очередь. - HANGUP/CANCEL/DECLINE теперь подтверждаются END_ACK и повторяются каждые 300мс, максимум 20с. - Медиа/локальная TX-очередь освобождаются сразу, CM и завершённая запись — после ACK или deadline. - Проверены причины ENDED, потеря двух ACK, повторный HANGUP после удаления записи во время нового звонка, - одновременное завершение, DECLINE и освобождение без подтверждения. Поздние видеокоманды отменяются; - старый close не закрывает новый видеопорт, detach отменяет ожидающий post. - Core/desktop/APK собраны, 154 теста ядра, test_call_video_clock и 97 Android unit-тестов прошли. - Обновление установлено на Samsung RZ8R72MG64B; ChatGUI требует перезапуска для нового протокола. - Проверка реального звонка после обновления обеих сторон остаётся ручной. - -[ ] **Видеозвонки Android и ChatGUI** — 14.10.2026: - H.265 с fallback H.264, смена камеры/разрешения/кодека/битрейта во время звонка. - Общая шкала захвата, приёмное видео следует аудиоряду; адаптация по ACK 500мс/50мс и задолженности. - Реализованы router ACK/debt и подключение регулятора к видеотранспорту; check.sh 154/154 + proxy/burst/load проходят. - Реализован вариант 2: фактическая карта Copy/Mix SoundTouch, CallTimeline, capture PTS/эпоха/Opus delay - в протоколе, часы воспроизведения desktop/Android. Сборки успешны, 79 Kotlin-тестов и профильные C++-тесты проходят. - Добавлены видеопротокол, CAPS/ACK, ограниченная сборка/отправка, отдельные очереди audio/video/control, - удержание TX-видео по аудио, generation-safe bitrate ACK. Сетевой тест проверяет backpressure, - смену H.265/H.264 и hangup; payload синтетический, реальные codecs/камера/UI ещё не подключены. - Выявлена нестыковка capabilities: нужны profile/level/tier и предел bitrate/VBV. - x265 может отменить reconfigure при смене level и вернуть 0; ACK требует проверки применения. - По правилу AGENTS.md подключение codecs остановлено; решение и оставшиеся этапы описаны в плане. - Добавлен атомарный диапазон битрейта в настройках аудио ChatGUI/Android: по умолчанию 300–4000 кбит/с. - Применяется во время звонка, учитывает codec cap и незавершённую команду. Модель плохой/хорошей связи - достигает обеих границ без неограниченного роста очереди; сетевой тест смены диапазона проходит. - ChatGUI собран, Android assembleDebug + 81 unit-тест прошли; итоговый check.sh 154/154 + proxy/burst/load PASS. - Камера/codec/render ещё не подключены. - Перед интеграцией H.265 найден дефект x265 4.1: reconfigure/getter сообщают 300 кбит/с, - реальный выход остаётся 4 Мбит/с. Ручная цель probe_call_x265 воспроизводит отказ. - Минимальный патч владения параметрами проверен на отдельной библиотеке в /tmp: - реальный выход 4.02 -> 0.298 -> 4.21 Мбит/с, декодируются 360/360 кадров. - Патч сохранён в tools/chatgui/ffmpeg/patches, к сборке/приложению пока не подключён. - Пользователь выбрал переключение на ближайшем плановом IDR: проверено пересоздание x265 без патча, - 4.01 -> 0.310 -> 4.02 Мбит/с, 360/360 кадров декодируются с сохранёнными PTS кодера. - Обычный reconfigure на IDR не помогает. В плане уточнены ожидание <= одного GOP, pending ACK, - backpressure и сохранение аудиошкалы; подключение к платформенным workers ещё предстоит. - Реализован ChatGUI CallVideoEncoder поверх выделенного общего LiveVideoEncoder: - проверка фактического профиля декодером, pending-команда, новый контекст на IDR, - сохранение PTS/старого контекста при отказе, предел bitrate и защита generation/request. - Реальная проверка H.264/H.265: 360 кадров на codec, 4M -> 300k -> 4M, один decoder, 5/5 cases PASS. - Трансляции: 11 PASS, 1 skip (Xvfb); ChatGUI собран; check.sh 154/154 + proxy 9/9 + burst/load PASS. - Реализован CAPS envelope: фиксированные profile/tier, согласование level и пределов bitrate/VBV, - H.265 -> H.264, проверка TX/RX и неизменности формата внутри generation. CallVideoEncoder получает общий формат. - При сужении peer CAPS ожидающий кадр отбрасывается и admission закрывается; сетевой тест 2/2 PASS. - Реальная codec-проверка повторена с выбранным общим кодом level 3.0: 5/5 cases PASS, 360 кадров на codec. - Итоговые ChatGUI/Android assembleDebug собраны; check.sh 154/154, proxy 9/9, burst/load PASS (128с). - Подключены общий ограниченный call_video_port, desktop camera/encoder/decoder/audio-clock render и окно управления; - Android JNI/Camera2/YUV/MediaCodec/RX Surface, CallService и экран управления. Обе сборки проходят. - Новые сетевой port-тест 2/2 и production desktop decoder 5/5 проходят; полный видеозвонок ещё не принят. - Аппаратные блокеры устранены: общий C validator, AVC Baseline/CB, нормативный DPB, - независимые encoder/decoder probes, фактические profile/level, VBV убран из wire. - Decoder сообщает acceptance/rejection; Auto делает fallback, отдельный KEY request восстанавливает references. - Android меняет bitrate без остановки MediaCodec на IDR; при отказе API последовательно заменяет encoder с восстановлением. - Unisoc кодирует HEVC и AVC; Samsung кодирует AVC и независимо принимает HEVC. - Проверены аппаратные 4M -> 300k -> 4M, HEVC Unisoc -> Samsung, AVC Samsung -> Unisoc, - все три потока -> production decoder ChatGUI. AVC Unisoc -> Samsung пока вернул 3/4 - кадров конечной пробы и требует диагностики. APK установлен на оба телефона. - Итог: check.sh 154/154 + proxy 9/9 + burst/load, Qt codecs 6/6, Kotlin 81/81 PASS. - 15.10.2026: USB-камера ChatGUI отдаёт кадры; обнаружен и исправлен отказ обоих TX codecs - из-за LC_NUMERIC=ru_RU: дробный level 3.1 заменён целочисленным параметром 31. - ChatGUI пересобран; Qt codecs 10/10 PASS в C и ru_RU.UTF-8, включая 720p и смену bitrate. - UI исправлен: Android fullscreen RX + своя миниатюра, управление и диагностика отделены; - desktop — отдельное изменяемое окно видео со своей миниатюрой в углу; звонок и настройки — в своём окне. - Только при отсутствии RX своя миниатюра остаётся в окне звонка. Закрытие видеоокна не завершает звонок. - Android сохраняет ориентацию интерфейса, поворачивает только большое видео и вмещает весь кадр без обрезки. - Android: Назад из видео открывает управление звонком; две миниатюры разворачиваются нажатием, - второе видео остаётся в углу. RX TextureView/Surface сохраняются при смене режима. - Кнопки учитывают системные панели (включая боковую навигацию) и вырез экрана. - Своё видео теперь идёт напрямую Camera2 -> TextureView через общий StreamPreview: SM 29–30 fps, - без прежней Bitmap-конвертации 192 px / 5 fps; Surface удерживается camera session до закрытия. - Низкий FPS desktop -> SM: capture=30, encoded=20, accepted=5, audio_busy=15, RX late=0. - Исправлены порог 33333мкс (бюджет кадров с допуском) и ожидание аудио (FIFO до 32 кадров/500мс/2MiB). - Повторный звонок: desktop TX / SM RX около 30 fps, audio_busy=0, late=0. - Остаточные пропуски при уходе фазы камеры исправлены; регрессия охватывает 10 минут и вход 30/40/60 fps. - Исчезновение RX на desktop: SM откладывал bitrate из-за автоматических IDR до тайм-аута 12с. - Граница смены bitrate теперь отсчитывается от нашего запроса IDR, автоматический IDR её не переносит. - Тесты: KEY/P за audio barrier, порядок и переполнение; Qt cadence/codec/clock; 81 Android unit — PASS. - Видео удерживает экран включённым без proximity-overlay; EARPIECE -> SPEAKER только после FAR, - UNKNOWN/NEAR ждут, ручной выбор/выключение видео/конец звонка отменяют ожидание. HEADSET сохраняется. - Фризы: обе платформы сохраняют decoder при коррекции audio epoch; production RX 90/90 кадров, - 32 коррекции часов, 0 KEY requests/rejections. Android Camera2 больше не теряет кадры на пороге 33333мкс. - Desktop готовит encoder при смене bitrate в фоне, применяет на IDR; Qt codecs 10/10 PASS. - Runtime bitrate проверен на Samsung AVC и Unisoc HEVC/AVC: все 360 кадров каждого потока, - ограничение low-rate и возврат к 4M. Android сохраняет P-кадры, ожидающие нового KEY. - Итог: Android 81/81, check.sh 154/154 + proxy 9/9 + burst/load PASS; APK обновлён на обоих телефонах. - Осталась ручная приёмка полного звонка с камерами, Surface, A/V и переключениями после исправления. - Аппаратные probes используют синтетические кадры. - Контракты, этапы и проверки: `doc/call_video.txt`. - -[+] **Android live: увеличение и перемещение видео как в просмотрщике файлов** — 14.10.2026: - Общий VideoZoomState задаёт масштаб 1x..4x вокруг центра жеста, ограничение сдвига и центрирование при возврате к 1x. - File/live используют одну геометрию; смена размеров окна или aspect ограничивает текущий offset заново. - Жесты преобразуют только GraphicsLayer видео и продлевают таймер controls, без пересоздания TextureView/decoder/reader. - Добавлены пять проверок геометрии: точка под пальцами, границы сдвига, возврат к 1x, верхний предел и смена размеров. - Все 75 Kotlin-тестов и assembleDebug прошли; APK установлен на SM. - На SM проверены pinch до 4x, перемещение до границ и возврат к 1x/Offset.Zero; во время жестов viewer продолжал показ. - Логи: /tmp/stream-zoom-android-build.log, /tmp/stream-zoom-sm.log, /tmp/stream-zoom-check-final.log. +[ ] **Ручная приёмка видеозвонков Android и ChatGUI после последних исправлений** — 14–20.10.2026: + Сигналинг, CAPS, реальные codecs/камера/render и A/V подключены; живые звонки уже проводились. + Осталась полная проверка после изменений Full HD/50–60fps, HEVC High tier, Surface ACK и фоновых codec probes: + Windows ↔ Samsung/Q8, камеры и оба направления, первый и повторный звонок, смена камеры/разрешения/кодека/битрейта, + A/V, завершение и освобождение Surface/видеопорта. Аппаратные probes не заменяют эту проверку. + Архитектура, контракты и выполненные проверки: doc/call_video.txt, doc/chat_call_arch.md. [ ] **Тесты: нестабильное завершение test_stcp_traffic** — 14.10.2026: В полном прогоне после NCD CLOSE server получил 1029466/1048576 bytes (done=0), client — 1048576 (done=1). Упала проверка test_stcp_traffic.c:216; отдельный повтор прошёл. Причина не установлена, сетевой код в задаче zoom не менялся. Проверить завершение двусторонней передачи относительно закрытия handle; первичный лог сохранён: /tmp/stream-zoom-stcp-first.log. -[+] **Android live: полноэкранный просмотр с автоповоротом и скрываемым управлением** — 14.10.2026: - StreamViewerScreen выбирает sensor landscape/portrait по aspect первого KEY, уже учитывающему rotation источника. - Видео вписано целиком в экран, без зависимости от надписей; имя, статус и крестик закрытия находятся поверх изображения. - Управление скрывается через 3s live и возвращается касанием; при подключении/ошибке остаётся видно. - Выход восстанавливает ориентацию и системные панели. Capture preview сохраняет отдельное управление публикацией. - На SM подтверждены landscape, TextureView 1920x1080 в экране 2400x1080, скрытие/возврат управления, - неизменные bounds видео, закрытие крестиком и возврат в portrait. Поворот не пересоздал viewer; более 2000 кадров, underruns=0. - APK установлен на SM; 70 Kotlin-тестов, 151 тест ядра, proxy 9/9, burst и load прошли. - Логи: /tmp/stream-viewer-android-build.log, /tmp/stream-viewer-check.log, /tmp/stream-viewer-sm.log. - [ ] **Тесты: диагностировать нестабильную проверку TX snapshot в test_android_stream** — 14.10.2026: В полном прогоне один раз упала строка 177: snapshot успешен и 0 < video_bytes < 500000 после test_clock_run_for(ua, 1000). Сам publisher обновляет snapshot таймером 1000; текущий CHECK не выводит result/sample_us/video_bytes. @@ -632,219 +106,6 @@ причина не установлена, Kotlin-аудиовывод этот C-тест не вызывает. Логи прогонов: /tmp/stream-audio-check-host.log, /tmp/stream-audio-native-retry.log, /tmp/stream-audio-check-final.log. -[+] **Android live: убрать остановку просмотра SM при запуске AudioTrack** — 14.10.2026: - StreamAudioOutput владеет устройством и одним остатком PCM; WRITE_NON_BLOCKING вызывается один раз за проход worker. - Видео и control продолжают обслуживаться при частичной/нулевой записи; 100ms ожидание внутри write удалено. - Аппаратные часы берутся из playbackHeadPosition без экстраполяции; пауза сохраняет PCM, GAP сбрасывает весь timeline. - Запас PCM соответствует фактическому bufferSizeInFrames, короткий EOF получает ограниченную тишину без сдвига media PTS. - Проверены 13 регрессий аудиовывода; все 70 Kotlin-тестов и assembleDebug прошли. - APK установлен только на SM. Первый просмотр: 1203 показанных кадра за 43s, discarded=0 и underruns=0; - повторное открытие также работает, аппаратный старт занял 206ms и 185ms вместо прежнего ошибочного лимита 100ms. - Повтор полного прогона ядра: 151/151; отдельный нестабильный CHECK статистики вынесен выше. - Контракт: doc/stream.txt. Логи: /tmp/stream-audio-sm-final.log, /tmp/stream-audio-android-build.log. - -[+] **Live: согласовать выдачу cursor с проверкой revision/KEY в media store** — 14.10.2026: - Каждый cursor хранит revision последнего выданного полного видео и пропускает новую только с полным KEY. - Неполный кадр прежней revision удаляется; аудио и чтение старой истории другими readers сохраняются. - После GAP, нарушения последовательности фрагментов и вытеснения reader начинает с полного KEY; - зависимые кадры и частичный KEY не выдаются. Готовый KEY не ждёт таймера. - Регрессии включены в обычный test_stream_media; отдельный запуск: `tests/test_stream_media --revision-transition`. - Неиспользуемый stream_media_receiver удалён; сборка, FEC, конфликты формата и восстановление проверяются на store/cursor. - Desktop/Android используют общий stream_media_open с проверкой выбранной эпохи и откатом нового owner при ошибке. - Дополнительный reader-объект не нужен: владение и курсор уже находятся в STREAM_HANDLE. - -[+] **Live: оценить оставшиеся оптимизации архитектурного плана** — 14.10.2026: - stream_member_supernode читает adm_tags конкретного node_id при deleted=0, без списка канала, сортировки и снимков узлов. - Синтетический замер SQLite в памяти: проверка роли 1024 участников — около 540 мс прежним способом против 2,9 мс рабочим API. - test_stream_service проверяет подписанные выдачу/отзыв роли, изоляцию каналов, absent/deleted и независимость от чужого snapshot. - Полная проверка корректного профиля stream_member_load занимает около 0,30 мс на этом стенде; проверки подписей сохранены. - Кэш авторизации не добавлен: он требует учёта участников, подписантов и ключей канала, одной версии профиля недостаточно. - Relay/network оставлены вместе: общий транспорт, учёт активных выдач и срок жизни подписки уже имеют единое владение. - Механический перенос потребовал бы дополнительных внутренних интерфейсов без упрощения жизненного цикла. - -[+] **Live: прямое превью Android без собственного decoder** — 14.10.2026: - Камера одновременно выводит в encoder Surface и TextureView; собственное превью больше не открывает - stream viewer/cursor, MediaCodec decoder, AudioTrack и адаптивные часы воспроизведения. - Attach/detach меняет только camera session, сохраняя encoder, audio, revision и origin; - ON_STOP снимает preview output сразу, без ожидания Compose recomposition. Отказ preview сохраняет encoder-only эфир. - Surface/texture удерживаются UI, ожидающими командами и camera sessions до окончания использования; - CameraDevice.onClosed освобождает также sessions, для которых Android не доставил отдельный onClosed. - TextureView сам учитывает sensor orientation; дополнительный UI rotation компенсирует лишь поворот дисплея. - Повторный поворот сенсора убран, DisplayListener учитывает также 180° без изменения размеров окна. - Диагностика показывает native transform, sensor/display/UI rotation, first frame, FPS, возраст кадров и освобождение outputs. - REALTIME timestamp сравнивается с elapsedRealtimeNanos; UNKNOWN не выдаёт выдуманный абсолютный возраст. - На SM проверены AV1, задняя/передняя камеры, ручной поворот, фон/возврат, закрытие/открытие preview, - полная остановка и повторный запуск. Нет собственного decoder; типичный возраст кадров около 130ms - вместо накопленных 6s; перед stop median=133.7ms, p95=175.7ms по 297 диагностическим samples. - Stop освободил codec и все sessions, camera HandlerThread завершён; после проверки восстановлены AV1/main/0°. - 151 тест ядра и Kotlin unit tests прошли, в том числе 6 проверок preview; APK установлен на SM. - Архитектура: `doc/stream.txt`, `doc/service_lifecycle.md`. - Логи: `/tmp/direct-preview-{full-check,android-orientation-build,sm-live}.log`. - -[+] **Live: независимая подача decoder и устранение вечного ожидания AV1 на SM** — 14.10.2026: - Причина: Android подавал максимум три кадра и читал видео только на 80ms вперёд от остановившегося clock; - c2.android.av1-dav1d.decoder требовал заполнения своего конвейера. KEY уже был принят, но UI продолжал ждать KEY. - Общий cursor теперь запрашивает следующий видеокадр независимо от PTS показа; audio сохраняет временной lookahead. - Bridges готовят один ответ на запрос, получение ответа/AVAILABLE не создают скрытого prefetch. - Android StreamDecodePump держит один input и один output, обслуживает выход перед входом и использует готовность codec. - KEY/decoder ожидания разделены; старт clock/audio после первого decoded frame, low latency при поддержке. - Защитный guard учитывает наблюдённый decoder lead; EOF освобождает inflight metadata и не блокирует audio tail. - Desktop использует тот же контракт: один рабочий AVPacket, два готовых изображения, EAGAIN сохраняет вход, - FIN дренирует decoder до EOF. Кодек/rotation меняют video revision, аудиошкала сохраняется. - 151 тест ядра без ошибок/пропусков, proxy/integration/burst/load прошли; check.sh — 126s. - Четыре CTest stream/audio timing прошли; восемь Kotlin pump-сценариев прошли, APK обоих ABI и vibechat собраны. - Проверены 4/8 входных кадров при замороженном clock, сетевые паузы, поздний ответ чтения, пустой EOS и guard. - Настоящие FFmpeg кадры с задержкой выхода в четыре кадра: запуск после 80ms и полный drain короткого потока из трёх кадров. - Реальный AV1 на SM-A525F: первый decoded frame через 67–117ms после KEY в проверенных запусках, - длительный показ и поворот работают; завершённый запуск показал 21609/21609 decoded/shown, без discarded. - Исправленный APK установлен на SM. Сетевой протокол и формат RS остаются прежними; colo2/Q8 не обновлялись. - Архитектура: `doc/stream.txt`, `doc/service_lifecycle.md`. - Логи: `/tmp/av1-pump-{full-check,ring-test,bridge-test,service-test,gui-tests,android-final-build,sm-live}.log`. - -[+] **Live: публикация с desktop ChatGUI** — 14.10.2026: - Камера, микрофон, экран и окно через Qt >=6.6 Multimedia/FFmpeg; Wayland/XWayland использует системный портал. - Отдельный controller сохраняет эфир при закрытии окна, сырое превью обновляется до 30Hz независимо от encode. - Выбор рабочего H.264/H.265/VP9/AV1/H.266, разрешения/FPS, bitrate и поворота 0/90/270 с отметкой верха. - Encoder проверяет два принудительных KEY, затем открывает чистую сессию; hardware имеет приоритет. - Смена видеонастроек сохраняет capture, звук и source_epoch; libx264 меняет bitrate без смены encoder. - Ошибка видеорежима откатывает последнюю подтверждённую конфигурацию; fatal Opus завершает эфир и освобождает микрофон. - Stereo Opus/128kbps с общим gain и текущими настройками компрессора рации; mono input обозначается явно. - Общий C stream_publisher для Android/desktop: ограниченные очереди/admission/KEY recovery, uAV2/RS, FIN/drain 2s, - согласованные 100ms TX snapshots (video queue, all-connection inflight, send buffer, ACK_1s). Протокол не меняется. - Microphone lease публикации эксклюзивен, прежняя совместная работа голосовых функций сохраняется. - 151 тест ядра и proxy/integration/burst/load прошли; полный check.sh — 129s. Все 32 CTest ChatGUI прошли. - Publisher отдельно: 11 проверок прошли, экранный сценарий запущен отдельно под Xvfb/private D-Bus — без пропусков. - Проверены реальные H.264/H.265/VP9/AV1 encoder/decoder, сохранение decoder при изменении libx264 bitrate, - настоящий X11 screen/window capture, непрерывный неподвижный экран, сырое превью, два стереотона, - H.264 → VP9 и rollback без смены audio/source_epoch, Opus failure, FIN и concurrent detach/leak count. - vibechat и APK arm64-v8a/x86_64 собраны, Kotlin unit tests прошли; Windows runtime/installer fixtures прошли. - Физическая камера, захват через Wayland portal и Windows runtime вручную не проверялись; VVC encoder отсутствует. - Устройства/colo2 не обновлялись. Архитектура: `doc/stream.txt`, `doc/service_lifecycle.md`. - Логи: `/tmp/desktop-stream-{full-check,final-gui-tests,final-publish-test,screen-test,android-build,runtime-test,installer-test}.log`. - -[+] **Live: выбор видеокодека/битрейта и статистика отправки 10Hz** — 14.10.2026: - Android показывает доступные Surface encoder в порядке H.264/H.265/VP9/AV1/H.266, - проверяя профиль, разрешение/FPS и диапазон bitrate; аппаратные encoder имеют приоритет. - Битрейт выбирается отдельно (Авто либо пресет), LIVE обновляется без перезапуска encoder, - при отказе используется смена видеоконфигурации с rollback. Звук и source_epoch сохраняются. - uAV2: прежний 32-byte header, пять video_codec IDs, KEY = config_length:4BE/config/access unit. - Конфигурация повторяется при каждом KEY и защищена общей подписью/RS; оба плеера выбирают decoder по codec ID. - NAL parameter sets объединяются без дублирования, partial codec config собирается с пределом 64KiB. - Publisher каждые 100ms показывает остаток video queue, общий inflight, полный send buffer и ACK_1s. - Буфер учитывает отдельные очереди video/audio, ожидающие RS-выдачи и ETCP/normalizer без двойного учёта input_send_q; - историю кольца не включает. ACK всех соединений учитывается один раз при подтверждении найденного пакета; - окно — десять завершённых buckets по 100ms, переживает REINIT/close пира и не требует BBR link. - Статистика имеет отдельный StateFlow; строки не меняют высоту превью при обычном изменении чисел. - Реальные H.264/H.265/VP9/AV1, отдельная decoder configuration, FIN и смена revision проверены. - H.266 проверен на уровне формата/KEY; реального VVC encoder в тестовом окружении нет. - Устранена блокировка нового desktop viewer старыми control records в лимите подготовки медиа. - 151 тест ядра прошёл без ошибок/пропусков; check.sh с proxy/burst/load — 119s. - Qt stream/audio timing и Kotlin-проверки прошли; vibechat и APK arm64-v8a/x86_64 собраны. - Устройства/colo2 не обновлялись. Протокол и формулы: `doc/stream.txt`, lifecycle: `doc/service_lifecycle.md`. - Логи: `/tmp/stream-codecs-{full-check,final-gui-tests,android-build,media-test,tx-test,native-test}.log`. - -[+] **Live: воспроизведение из RS-кольца и минутная адаптация задержки** — 14.10.2026: - Android и desktop используют общее кольцо кодированных данных, метаданные PTS/KEY и отдельные - cursor каждого reader. Пауза player не останавливает live ingest/selector; длинные кадры собираются - ограниченными проходами с отложенным продолжением без ожидания новых пакетов. - Убрана фиксированная стартовая буферизация 150ms; вне кольца остаются ближайшие кадры и рабочая порция PCM. - Общий контроллер хранит 60 секундных минимумов запаса. История корректируется по фактическому - простою/услышанному материалу, включая аппаратную очередь и расход ранее поставленного ускоренного PCM. - После полной здоровой минуты плавный темп до x1.1 уменьшает задержку до безопасного остатка; - SoundTouch сохраняет высоту звука и стереобаланс. Обычная нехватка сохраняет decoder references; - GAP, вытеснение и разрыв медиапоследовательности начинают новый KEY и новую историю. - FIN дочитывается каждым reader; close завершённого publisher сохраняет кольцо для локальных owners. - Проверены шестисекундная пауза сетевого reader без restart, точные remote/local FIN drain, - независимые cursors, поздняя повреждённая RS-часть, большой кадр, разрывы, конфигурация и границы PTS. - Реальные H.264/Opus: 30fps при audio latency 200ms, preroll, revision/rotation, stereo x1.1 без изменения тона, - физические аудиочасы, громкость и баланс памяти. Диагностика показывает запас/минимум, коррекцию, темп и wait/resume. - 150 тестов ядра прошли без ошибок/пропусков; полный check.sh с proxy/burst/load — 129s. - Три Qt stream/audio timing теста прошли; vibechat и APK arm64-v8a/x86_64 собраны. - Устройства/colo2 в этой задаче не обновлялись. Архитектура: `doc/stream.txt`, lifecycle: `doc/service_lifecycle.md`. - Логи: `/tmp/stream-playback-{clock-test,full-check}.log`, `/tmp/stream-final-{gui-tests,desktop-build,android-build}.log`. - -[+] **Live: переменный размер RS и одна подпись внутри пачки** — 13.10.2026: - RS принимает фактическую длину, уменьшает все части одной пачки до одинакового минимального размера - и дополняет максимум k-1 нулями; один контекст/матрица используются повторно, без аллокаций RS на encode/decode. - Источник подписывает метаданные и содержимое один раз, затем RS защищает сообщение вместе с 64-байтной подписью. - Проверка источника выполняется после восстановления; неверная подпись/подписанные поля дают один GAP без закрытия owner. - Следующая корректная пачка принимается. Ретранслятор пересылает части до decode, сохраняя малую задержку. - Дескриптор хранит максимальный размер, кольцо/очереди/метрики — фактические длины; слоты по-прежнему резервируются по максимуму. - При 6+2 содержимое 1000 байт даёт части 243 байта вместо 1300; полная вместимость содержимого — 7345 байт. - Wire version=5; бинарники участников трансляции нужно обновить вместе. Формат описан в `doc/stream.txt`. - Проверены все 28 пар потерь, малые/полные пачки, подмена содержимого/подписи/поля времени/индекса, - padding, неверный ключ, фактический учёт байтов, пересылка до проверки и продолжение после отвергнутой пачки. - 149 тестов ядра прошли без ошибок/пропусков; полный `check.sh`, включая proxy/burst/load, завершился за 131 с. - Desktop stream/audio timing прошли; vibechat и APK arm64-v8a/x86_64 собраны, новый encoder проверен в обеих native-библиотеках APK. - Логи: `/tmp/stream-batch-{core,media,service,android-native,full-check}.log`, - `/tmp/stream-batch-{desktop-build,gui-tests,apk-build}.log`. - -[+] **Live: callback обнаружения поставщиков** — 13.10.2026: - Принятые изменения Merkle и BGP помечают roster оптимизаторов соответствующего канала устаревшим. - Сверка/пробы выполняются после callback одним объединённым отложенным проходом в uasync. - Новый доступный поставщик опрашивается сразу; существующие пробы, цикл и backoff ошибок сохраняются. - Временно пустой буфер повторно опрашивается через 100 мс в пределах фиксированных 5 с, - чтобы ранняя подписанная опция не оставляла недостающие субпотоки до обхода через 30 с. - Регрессия с настоящим Merkle/BGP и задержанным READY: до исправления проверка задержки падала, - после принятого объявления INFO получен через 6 мс. Повторные callbacks не размножают пробы; - общий старт 8/2 и освобождение всех tracked allocations проверены. - 149 тестов ядра, 43 Android-теста и desktop stream/audio timing прошли; GUI и APK собраны. - Логи: `/tmp/stream-provider-callback-{before,retry,full-check}.log`, - `/tmp/stream-provider-callback-{gui-tests,android-build}.log`. - -[+] **Live: выбранная выдача отменяла помощь до READY/ACCEPT** — 13.10.2026: - Первое открытие desktop 17:07:41.035 → первый кадр 17:07:44.500 заняло 3.464 с; - запрос помощи отправлен через 99 мс, первый FEC через 2.490 с, KEY ещё через 0.796 с, - prefill/показ заняли 0.178 с. Повторное открытие заняло 0.983 с. - Merkle объявил буфер colo2 до READY: selector выбирал его INFO, но отменял STARTING-запрос, - потому что выдача ещё не ACTIVE. Четыре CANCEL закрыли собственную выбранную выдачу. - Запрос теперь удерживается также выбранными CONNECTING/INFO/REQUESTED upstream; INFO-пробы, - ENDED/CLOSED и чужие downstream не удерживают его. Аренда/idle и проверки поколений сохранены. - Регрессия с задержанным READY и настоящим Merkle/ETCP воспроизводит ошибку до исправления - и проходит после него без преждевременного CANCEL и tracked allocation leaks. - На colo2 всё ещё работает 14e2cdc2: опрос субпотоков раз в 100 мс и секундная задержка STATUS. - В сохранённом запуске helper генерировал STATUS в 18:07:42.465 и 18:07:43.476; - для полного ускорения нужен новый бинарник сервера. Логи: `/tmp/stream-first3s-{desktop,colo2,sm}.log`, - `/tmp/stream-first3s-regression-{before,after}.log`, `/tmp/stream-first3s-colo2-version.log`. - -[+] **Live: ускорить начальное подключение** — 13.10.2026: - Дедлайн помощи 100 мс и первый пригодный INFO выбирают поставщика; DATA использует один общий старт. - Управление просыпается по событиям, подтверждение поколения и новые состояния помощи не ждут 1 с. - READY требует восстановленной FEC-пачки. Регрессии: прямой/relay победитель, поздние ответы, - отмена до дедлайна, пустой источник, дубликаты, общий индекс 8/2 и освобождение ресурсов. - Начальная очередь аудио прогревает Opus и обрезается по первому KEY; prefill 150 мс начинается после него. - 149 тестов ядра, 43 Android-теста и desktop stream/audio timing прошли; GUI и APK собраны. - В сетевом тесте первый восстановленный блок через помощника получен за 192 мс, n=8/r=2. - Проверены поздний прямой INFO, отмена запроса до READY, отсутствие помощи для пустого доступного источника - и отсутствие дополнительных STATUS на повторы REQUEST. Все tracked allocations освобождены. - Desktop-регрессия прогревает 800 мс реального stereo Opus до KEY: звук молчит до начала видео, - затем сохраняются 30fps, stereo balance и смена revision при физической audio latency 200 мс. - Логи: `/tmp/stream-startup-full-check.log`, `/tmp/stream-startup-service-final.log`, - `/tmp/stream-startup-desktop-tests.log`, `/tmp/stream-startup-android-final.log`. - Контракт: `doc/stream.txt`, раздел 21. Замеры приведены для тестового стенда. - -[+] **Live: сквозное стерео и три компактные кнопки поворота** — 13.10.2026: - CAMCORDER/Opus/компрессор/Android AudioTrack/desktop output используют два канала, - Opus AUDIO 128kbps. audio_codec=2 обозначает stereo; 960 кадров на канал дают 1920 PCM-отсчётов. - Capture/playback timestamps считают кадры на канал; mono-пакеты upmix выполняет libopus. - Три кнопки 0/90/270 подсвечивают выбранную и показывают верх цветной гранью на самой кнопке; - положение грани учитывает камеру и экран, наложение на превью удалено. - 148 тестов ядра, 43 Android-теста и desktop stream/audio timing прошли. - Проверены stereo balance после AGC/Opus и независимые каналы на audio device (отношение энергий 15.99 при исходном 16). - APK/чатгуи обновлены; SM подтвердил channels=2 и ненулевой lrDifference. - Повороты 90/270 и возврат 0 проверены во время публикации без смены audio codec handle/epoch; - desktop показал ~30fps. Логи: `/tmp/stream-stereo-sm-final.log`, `/tmp/stream-stereo-final-desktop-tests.log`. - -[+] **Android live: CAMCORDER и компрессор с настройками рации** — 13.10.2026: - AudioRecord.CAMCORDER, 48kHz mono; общий audio_compressor перед Opus AUDIO/64kbps, - lookahead=0, без изменения PTS. DataStore передаёт включение, max_gain и общий rise_rate - из настроек рации в audio worker; обновления применяются без перезапуска захвата/эпохи. - 43 Android-теста и 631 проверка компрессора прошли, включая реальный Opus roundtrip, - live bypass, смену gain, отсутствие накопления output и утечек. APK установлен на SM. - На SM подтверждены CAMCORDER(5), переключение on/off/on в одном codec handle и восстановление - исходных enabled=true/max_gain=45/rise=6. Desktop продолжил показ ~30fps. - Лог: `/tmp/stream-camcorder-sm-final.log`. - [ ] **Общий AGC: клиппинг после резкого роста сигнала при max_gain=45dB** — на SM при проверке CAMCORDER с настройками рации rise=6/release=30 наблюдались 4581 обрезанный отсчёт за интервал около 1s. Это общий алгоритм radio/stream, @@ -858,24 +119,6 @@ в MainWindow::closeEvent (всегда ignore), порядок уведомлений и отключение GUI от БД. Снимок: `/tmp/stream-desktop-shutdown-backtrace.log`, лог vibechat 13:04:09. -[+] **Desktop live: очередь видео вытесняла будущие кадры до показа** — 13.10.2026: - SM → colo2 доставлял ~30fps, desktop декодировал ~30fps, но videoQ=6 постоянно - выбрасывал ближайший кадр до достижения его PTS аудиочасами. Регрессия H.264/Opus - 30fps с физической audio latency 200ms на старом коде не показала ни одного кадра. - Видео ограничено 128 кадрами/256MiB; при пределе сохраняются ближайшие к показу. - Добавлены decode/show FPS, late/pressure и PTS очереди относительно часов; - поштучное нормальное вытеснение транспортного буфера перенесено в trace. - Исправленный test_stream_view: 8/8; test_audio_timing прошёл. Живой просмотр - SM → colo2 после обновления: средний showFps=29.81 за 40s, videoQ=8–9, pressure=0. - Метрики: `/tmp/stream-desktop-fixed-live-metrics.log`; краткие просадки showFps до 22.4 остаются наблюдаемыми. - -[+] **Android: категории диагностики и обрезанный текст уровня** — 13.10.2026: - список берётся из native-ядра, включая stream/video/reality/dm/call/aec. - Поля уровня используют минимальную высоту вместо фиксированных 48 dp; - изменения диагностики применяются сразу без перезапуска при выходе из настроек. - Общий уровень сохраняется в [global] debug_level; оба парсера принимают все категории, - а превышение лимита логируется. Регрессия: test_config_debug, файл и INI-текст. - [ ] **Стриминг SM → colo2 → desktop: восстановление частично остановившихся субпотоков** — 13.10.2026: помощь подключилась за ~8 с, все 8 субпотоков через colo2 приняты с общего индекса 5844. Позже шесть субпотоков перестали продвигаться около seq=111625; четыре restart не восстановили @@ -890,16 +133,6 @@ SM при этом сохранял ~30fps без dropped. Новые логи: `/tmp/stream-stereo-desktop-delivery-stall.log`, `/tmp/stream-stereo-colo2-delivery-stall.log`, `/tmp/stream-stereo-sm-delivery-stall.log`. -[+] **Стриминг: помощь суперузлов по запросу** — 13.10.2026: автоматический запрос - при невозможности получения k субпотоков, внутреннее владение точной эпохой, - общий буфер со зрителями, аренды и остановка без downstream. Relay-only - экземпляры не удерживают друг друга. Подписанное управление с подтверждением - поколения, таймаут READY, защита от поздних запросов и пустой END. - Routed ID перенесён на 0x3C из-за конфликта с MEMBER_FILES; wire v4. - Исправлено владение CM handles репликации медиа при смене роли суперузла. - Контракт: `doc/stream.txt`, раздел 21. 148 тестов прошли, 1 пропущен; - `test_stream_service` и отдельный `--relay-only` завершились без утечек. - [ ] **Android: отмена асинхронного запуска до готовности ядра** — при проверке мониторинга 12.10.2026 обнаружено: `NativeLib.stop()` пропускает native stop, если `isReady()==false`, а `instance_lite_stop()` возвращается при `g_inst==NULL`. @@ -916,17 +149,6 @@ диагностику этих ветвей и проверить повторные попытки загрузки отвергнутого снимка. Существующую БД устройства при проверке стриминга не очищали. -[+] **STUN IPv4: резервное определение типа NAT по IP/netif** — уточнённый план - 12.10.2026 в `doc/nat_detection.txt`. Одна группа и отдельный тестовый UDP-порт - на уникальный IP/netif, общий кэш с generation/TTL. При NO_OBSERVER/NO_HELPER - применять пригодную оценку STUN с явным source; измеренный ETCP приоритетен. - mapped адрес тестового сокета не переносить на рабочий. Проверить дубликаты, - переход STUN -> ETCP, различия по портам и жизненный цикл; namespace-стенд. - Реализовано 12.10.2026: группировка, кэш/TTL, история портов через reload, - source в подписанном NODEINFO/SQLite/мониторе и приоритет частичного ETCP. - 145/145 тестов; три ASAN-теста без утечек; реальные cone/restricted/dependent - NAT и переключение STUN -> ETCP прошли в изолированном стенде. - [ ] **STUN IPv6** — отдельный этап: IPv6 endpoint/config/DNS и XOR-MAPPED, scope/netif, тесты IPv6/NAT66. IPv4-оценки не переносить на IPv6 или TCP. @@ -936,61 +158,12 @@ rp_filter=1 вместо сохранённого значения. Перенести тесты в отдельный namespace и проверять неизменность родительской сети, как в tests/stream_netns. -[ ] **Стриминг: реализация по stream.txt** — 10.10.2026: - ТЗ и этапы: doc/stream.txt, разделы 15–16. Основа данных реализована в src/stream: - подписанные FEC-блоки 1300 байт, общий буфер 32 МБ, относительные timestamp-метрики, - источник с таймером 100 мс и категория stream. test_stream_core прошёл; - ./check.sh: 143 passed, 0 failed, 0 skipped; proxy/full, burst и load — PASS. - 11.10.2026 подключены жизненный цикл CHAT, локальные handles/API и события потребителя, - атомарные опции мембера через Merkle, подписанные профили и BGP-фильтр кандидатов. - test_stream_service прошёл на четырёх ядрах: две группы, смена эпохи/членства, restart, - rollback профиля, закрытие из callback и нулевой остаток аллокаций после destroy. - Лог: /tmp/stream-service-test-final.log. Исправлена выявленная утечка BGP node_paths при удалении узла. - Общий ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full, burst и load — PASS. - Лог: /tmp/stream-service-check.log (107 с). - 11.10.2026 подключена сетевая выдача raw ETCP через собственный NCD owner: INFO/поколения, - handles/watermark, общий старт от первого DATA, курсоры/пути/GAP/LOOP, подпись END и аренда/RENEW. - Routed REVERSE_REQ/CLOSED подписываются end-to-end. Явные receive API позволяют открыть/закрыть выдачу и начать новую попытку. - Сетевая цепочка источник -> relay -> получатель, две группы/FEC на одном ETCP, GAP/restart, - повторы/reverse, END, lease timeout и REINIT прошли под ASAN/LeakSanitizer без ошибок/утечек. - Логи: /tmp/stream-network-asan-core.log и /tmp/stream-network-asan-service.log. - После восстановления обычной сборки ./check.sh: 144 passed, 0 failed, 0 skipped; - proxy/full (9/9), burst и load — PASS. Лог: /tmp/stream-network-check.log (88 с). - Wire и численные пределы зафиксированы в doc/stream.txt, раздел 17. - 11.10.2026 подключены timestamp-метрики/rates/stops, nonce/метрики INFO и RTT uint32 мс, - A/D/X/Q выдач/пиров/модуля, интервалы 200мс и история 10с, подтверждение перегрузки 500мс. - OVERLOAD с frozen rates, FEC/альтернативами при выборе, SELECT/CLOSED, неизменным сроком 2с и fallback; - глобальный бюджет нескольких пиров требует backlog и локальной загрузки, CPU отдельно не режет. - 4-секундный предел возраста control/ожидающих заданий, GAP/X при истечении и наблюдаемый статус accepting. - Частичная/сильная/глобальная разгрузка, короткий глитч и поздний SELECT прошли под ASAN/LeakSanitizer без ошибок/утечек. - Логи: /tmp/stream-pressure-asan-core.log и /tmp/stream-pressure-asan-service.log. - Обычная сборка восстановлена; ./check.sh: 144 passed, 0 failed, 0 skipped; - proxy/full (9/9), burst и load — PASS. Лог: /tmp/stream-pressure-check.log (90 с). - Wire версии 2 и пределы обновлены в doc/stream.txt, раздел 17. - 11.10.2026 подключён автоматический планировщик: stream_subscribe_open начинает получение, - ручной режим выделен в stream_subscribe_manual_open. INFO-only пробы, цикл 32/1с/30с, - проверенные пути/RTT/метрики/слоты, backoff, распределение FEC, перенос с перекрытием и failover. - Первый DATA задаёт общий N; пустой источник и курсор last+1 ждут данные, END без DATA также подписан и доставляется. - Сохранён желаемый режим frontend; stream owners удерживают ACTIVE до close, затем восстанавливается STANDBY. - Статус/настройки — stream_selection_get_info/configure; wire версии 3 и пределы — doc/stream.txt, раздел 17. - На четырёх ядрах проверены 400 непрерывных пачек, общий планировщик владельцев, цикл 30с, - FEC spread, overlap до проверенного DATA, остановка relay/CLOSED и восстановление без разрыва ETCP. - Core/service, NCD и standby transport прошли ASAN/LeakSanitizer; остаток аллокаций — ноль. - Логи: /tmp/stream-optimizer-asan-{core,service,ncd,standby}.log. - Односторонняя смена stream generation восстанавливается по nonce INFO без разрыва ETCP и вращения эпох другой стороны; - регрессия и весь service-тест прошли ASAN/LeakSanitizer: /tmp/stream-generation-asan-service.log. - ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full (9/9), burst и load — PASS. - Лог: /tmp/stream-optimizer-check.log (97с). - Следующий этап — длительные/масштабные сетевые проверки: NAT/reverse, мультилинк, - одновременная перестройка, несколько автоматических источников/групп и mobile standby на устройстве. - -[+] **test_reality_tls: коллизии порта слушателя** — 10.10.2026: - В общем прогоне 140 passed, 1 failed: stcp_server_create не смог занять порт 34922, bind errno=98 (EADDRINUSE). - Причина: выбор порта как 34000 + time(NULL) % 1000 без гарантии его доступности. - Слушатель создаётся с port=0; stcp_server_get_port возвращает назначенный ОС порт для подключения клиента. - Логи показывают фактические порты REALITY и HTTPS. Сборка прошла; 8 параллельных TLS/HTTP-тестов прошли - при занятом всём прежнем диапазоне 34000–34999. ./check.sh: 141 passed, 0 failed, 0 skipped; - proxy/full, burst и load — PASS. +[ ] **Стриминг: оставшиеся длительные и масштабные сетевые проверки** — 10–12.10.2026: + Реализация ядра, публикации, приёма и автоматического выбора поставщиков завершена; контракт — doc/stream.txt. + Есть 16-процессный namespace-стенд с NAT/reverse и выбором UDP/TCP: tests/stream_netns/README.md. + Осталось подтвердить покрытие длительной нагрузки, смены адресов/мультилинка, одновременной перестройки + нескольких ретрансляторов, нескольких автоматических источников/групп и mobile standby на устройстве + (doc/stream.txt, раздел 16). Сохранённые проверки отдельных этапов не закрывают всю матрицу. [ ] **Member files: исчерпание кеша результатов массовых изменений** — 10.10.2026: Воспроизведено test_member_files_browser::recursiveDeletion(server-busy): из 76 объектов удаляются 64, @@ -1026,20 +199,11 @@ lib/speexdsp/include. Проверить полный состав Speex/voice зависимостей отдельного каркаса; основная Autotools C-сборка и Android NDK-сборка проходят. -[ ] **REALITY: исправить формат ClientHello и продолжение TLS-потока** — 07.10.2026: - supported_groups и signature_algorithms не содержат внутренние двухбайтовые длины списков. - После ClientHello/ServerHello идёт STCP без TLS record framing; это распознаётся пассивным наблюдателем. - [ ] **Завершить проверку реакций и голосов на SM** — 07.10.2026: - причина отказа установлена: у записей корней `signed_by=0/NULL` были нулевые/отсутствующие подписи дерева. - Проверка корня ключом канала остаётся обязательной; добавлены причины отказа и проверка доверенного Ed25519. - Исправлено применение подтверждённой подписи при равной/старой версии профиля и её сохранение при нулевом блоке - в более свежем профиле. Создание канала проверяет обе подписи корня до записи собственного мембера. - На local восстановлены шесть подписей канальными приватными ключами без изменения остальных полей записей. - Разовый скрипт и резервная копия: `/home/user/utun2-backups/root-certificates-20261007`. - Проверены все 18 участников local и 17 участников копии SM; тесты требуют отказа при нулевой/поддельной подписи. - Linux/Android/desktop собраны; `./check.sh`: 133 passed, 0 failed, 1 skipped; proxy/full, burst, load и 7 Qt-тестов — PASS. - Осталось установить APK на SM (`RZ8R72MG64B`) и проверить реакцию/голос на устройстве: SM отключился от ADB во время работы. + Исправления подписей корней и их сохранения реализованы, проверены тестами; local и копия SM проверены. + Последующие APK уже устанавливались на SM, поэтому прежнее ожидание подключения ADB неактуально. + Осталась явная проверка реакции/голоса на устройстве с текущей БД и сборкой. + Разовый скрипт и резервная копия подписей: /home/user/utun2-backups/root-certificates-20261007. [ ] **rlottie: разбор предупреждений GCC 15 в импортированных исходниках** — 05.10.2026: при сборке `tools/chatgui/rlottie_src` GCC сообщает `-Wuninitialized` в @@ -1058,155 +222,57 @@ сохранение кодеков и ошибки. Требуется Windows-прогон `check_cc.bat`: cc1 после обновления, повтор команды Ninja и сборка Opus должны завершиться с кодом 0. -[ ] **ChatGUI Windows: обновление остальных DLL приложения после обновления MSYS2** — 05.10.2026: - в `cc-probe.log` также отличаются Qt и другие DLL. `tools/chatgui/build.sh` - пропускает раскладку при наличии основного комплекта, без сравнения версий; - рекурсивная раскладка копирует только отсутствующие зависимости. - Runtime GCC обновляется отдельно; для остальных DLL нужно продумать обновление - с сохранением приоритета собственной сборки FFmpeg и проверить запуск приложения. +[ ] **ChatGUI Windows: обновление остальных DLL приложения после обновления MSYS2** — 05–06.10.2026: + Пропуск раскладки при наличии основного комплекта уже убран: зависимости проверяются на каждой сборке, + Qt DLL/плагины и собственный комплект FFmpeg копируются заново; runtime GCC обновляется отдельно. + Осталось определить обновление прочих уже существующих транзитивных DLL: рекурсивный проход + по-прежнему копирует только отсутствующие файлы. Сохранить приоритет собственной сборки FFmpeg + и проверить запуск приложения после обновления MSYS2. [ ] **Android: время жизни config provider** — 03.10.2026: `utun_bridge_init()` передаёт адрес локального `utun_config_provider_t` в `utun_config_set_provider()`, который хранит указатель. После возврата из init он недействителен; перед использованием `cfg_get_*` обеспечить постоянное хранение provider. -[ ] **uasync: ложные ERROR об утечке перед cleanup** — 01.10.2026: - test_dm_e2e и существующий test_conn_mgr проходят, но uasync_destroy() - пишет Timer leak до освобождения отменённых heap/immediate таймеров. - После cleanup счётчики сходятся, финальная проверка проходит. Перенести - предварительные счётчики в DEBUG; ERROR оставить для реального расхождения - после cleanup, отдельно показывать активные и отменённые таймеры. - [ ] **Общий лимит check.sh после clean** — 01.10.2026: расчёт по времени предыдущего прогона дал 205с вместе с полной сборкой и оборвал проверку после успешных тестов до `test_uasync_socket_race`. Повторный запуск на готовой сборке с большим лимитом прошёл за 206с, включая proxy/burst/load. Разделить бюджет сборки и запуска тестов либо учитывать clean при расчёте. -[ ] **Паузы аудио Qt при звонке с SM** — 01.10.2026, звонок - `939a3ea36f3eeac3`, прямой LAN TCP `192.168.40.250:44604 ↔ 192.168.40.247:44173`. - Tcpdump: общие паузы входящего трафика до 645мс; ping до роутера в среднем - 100мс, до SM 128мс. ПК на 2.4ГГц, SM на 5ГГц. Одновременно `CallAudio: cb` - падает до 20–40/с вместо 100/с, буфер Qt растёт до 2с, на SM повторяется refill. - В 8с strace аудиопоток продолжает обслуживать PulseAudio без долгих syscall; - причина редких аудиоколлбэков пока не установлена. Добавить измерения интервалов - и длительности callback, кадров capture/playback и сводку CALL_STATS; сравнить - сетевые задержки после подключения ПК к 5ГГц или кабелю. - Повторный звонок `b2a423ed2d36ed83` (01:25:31–01:27:39): DIRECT сохраняется, - RTT 2–3мс; в начале на SM gap tone длится 1.8–2.0с примерно каждые 6с. - На Qt частота callback падает вплоть до 4/с, входящий PCM продолжает приходить: - буфер 65→465→1465→2079мс за 3с, затем растёт до нескольких секунд, dropped=0. - Локализовано прекращение обслуживания duplex-аудио Qt; ожидание backend и - задержка обработки PCM пока не разделены. Часы SM отстают от Qt примерно на 1.24с. - Добавлена диагностика backend/устройств, времени между callback и длительности - capture/playback, фактической частоты callback и PCM кадров за интервал. - Счётчики сбрасываются до старта устройства; нужна повторная запись с новой сборкой. +[ ] **Повторно проверить паузы desktop-аудио при звонке с SM** — 01.10.2026: + В звонках 939a3ea36f3eeac3/b2a423ed2d36ed83 частота callback падала до 4–40/с, + входящий PCM продолжал приходить, очередь росла до нескольких секунд без dropped. + Диагностика backend, интервалов callback и capture/playback уже добавлена; позднее менялись аудиовывод и его буферы. + Нужен повтор на текущей сборке с CALL_STATS и временными метриками, чтобы проверить сохранение исходного сбоя. + Сетевую задержку оценивать отдельно: в одном из прежних звонков DIRECT RTT был 2–3мс. -[ ] **Оставшаяся задержка запуска аудио SM** — после обновления 01.10.2026, - звонок `2b9ad4e21a54d8ba`: стартового gap tone нет на обеих сторонах; Qt - стабильно работает около 100 callback/с, max_idle=15.3мс, буфер 55мс, RTT=2мс. - На SM первый capture появляется через 1140мс от startAudio (1164мс от ACCEPT). - router.start=781мс, получение снимка устройств=0мс, AudioRecord create=24мс, - startRecording=7мс; от начала startRecording до первого кадра=328мс. - Capture worker стартует раньше playback, но общий выигрыш пока не виден. - AudioTrack create=21мс, play=327мс; система сообщает AudioPortCache contention=497мс - и восстановление AudioTrack при setPreferredDevice. Разделить замеры регистрации - callback, BT-профиля и применения маршрута; отдельно проверить первый AudioRecord.read. - На SM входящий буфер за время подготовки вырос до 1149мс и к концу звонка снизился - до 570мс; ускорение старта playback также сократит начальное накопление. - Реализован независимый запуск AudioTrack и AudioRecord в play/capture потоках; - частичный старт отменяется до освобождения устройств/native. AEC измеряется после готовности обоих. - Добавлены callbackMs/btProfileMs/applyMs/refreshMs, длительность первого read и время первой записи playback. - Резерв теперь зависит от изменения задержки доставки по timestamps CALL_MEDIA, отдельно от глубины очереди; - стартовое накопление и догон не повышают запас. Сохранность FIFO и uint32 wrap проверяются регрессиями. - Сборки ядра, Qt и Android после clean успешны; три аудиотеста прошли. Полный check: - 113 PASS, 0 FAIL, 1 SKIP (auto_socket_dynamic требует root); proxy/burst/load прошли. - Регрессия refill учитывает остаток SoundTouch: два новых кадра могут уже заполнить запас 60мс. - SM и Q8 обновлены 01.10.2026 в 03:03. Выигрыш по времени требует пробного звонка с новой версией. +[ ] **Измерить оставшуюся задержку запуска аудио SM после исправлений** — 01.10.2026: + В исходном звонке 2b9ad4e21a54d8ba первый capture приходил через 1140мс от startAudio; + router.start=781мс, startRecording → первый кадр=328мс, AudioTrack.play=327мс. + Независимый запуск capture/playback, отмена частичного старта и подробные замеры уже реализованы; + позднее добавлен выбор AAudio/AudioTrack. Осталось измерить текущую сборку на SM: + callbackMs/btProfileMs/applyMs/refreshMs, первый AudioRecord.read и первая запись playback, + начальное накопление очереди. Старые длительности не считать характеристиками текущей реализации. [ ] **Гонка invite-файла в test_chat_join_e2e** — `wait_file()` проверяет только существование файла, а `wf()` создаёт его до записи. Читатель иногда получает пустую ссылку и ошибку префикса `utun://`. Публиковать готовый файл атомарно. -[ ] **Некорректное время в выводе check-proxy** — успешные `basic_1mb` и - `stress_sessions` иногда печатают огромные положительные/отрицательные миллисекунды, - хотя итоговая скорость и длительность передачи выглядят нормально. Проверить расчёт вывода. - [ ] **Linux ONNX Runtime: повторная регистрация схем при запуске теста** — 03.10.2026: test_silero_vad при загрузке модели печатает серии `Schema error: ... already registered`. Инференс, речь, тишина и reset проходят; отдельно проверить состав и загрузку Linux-библиотек ONNX. Диагностика: `/tmp/vad-compressor-silero-tests.log`; Android-сборка таких сообщений не содержит. -[ ] **test_tcp_proxy_full: некорректное время в диагностике** — 03.10.2026: - полный check.sh проходит, но строки basic/stress/concurrent/half_close выводят - огромные или отрицательные миллисекунды (например, -1611883348002232012ms). - Отдельно проверить формат/аргументы вывода длительности; `/tmp/vad-compressor-check.log`. - [ ] **debug_parse_config: формат и индексы категорий** — parser ожидает `:`, документация описывает `=`; преобразование битовой маски осталось после перехода enum на индексы. [Разбор](etcp_full_suite_findings.md). -[ ] **DM: прямой p2p чат с любым пользователем группы** — отдельная DM-подсистема. - ТЗ и архитектура: `/doc/dm_arch.md`. Статус: реализовано (dm_core/dm_mailbox/dm_crypto), - тесты `test_dm` (крипто) и `test_dm_e2e` (интеграция). Остались задачи ниже. - -[ ] **Звонок (P2P аудио)** — голос 1:1, из CHAT-группы или p2p-чата (DM). Отдельный - каталог `src/call/`. Сигналинг + conn_mgr + аудиопоток (Opus) с backpressure - (локальный буфер отправки при переполнении роутера) + адаптивный джиттер-буфер - (SoundTouch, ускорение до 1.6x) + тоны (глитч/завершение) + watchdog 20с. - Android: переключение источника (трубка/громкая/гарнитура). - Архитектура: `/doc/chat_call_arch.md`. - - [ ] **DM-звонки** (fallback `group_id==0`) — не сделано: `call_is_online`/`call_start` - требуют реальную группу (`topo_groups_find`), для DM (group_id==0) маршрута нет. - -## Рефакторинг: per-instance chat/dm (однопоточный test_dm_e2e) - -[ ] **BGP-гонка: дропнутый REQUEST_TABLE** (отдельная задача, как договорились). - - **Место:** `topo_group_new_conn()` в `src/routing_layer/topo_group.c:571`. Дедуп-ветка - «conn already in senders_list» (строки 579–587) делает `return` БЕЗ повторной отправки - `topo_group_send_table_request()`. - - **Зачем дедуп:** тот же `ETCP_CONN` стреляет `ETCP_CONN_STATUS_UP` дважды (UDP-линк, - затем TCP-линк). Повторная обработка задваивает `active_conn_count`, из-за чего - переподключение не стартует. Поэтому `return` в дедупе — правильный. - - **В чём гонка:** REQUEST_TABLE — это то, что заставляет пира отдать свою таблицу - (NODEINFO/узлы группы). Сценарий «разнесённого старта»: - 1. A↔C соединение поднято. A шлёт C `REQUEST_TABLE` для группы G (`topo_group_new_conn` - → `topo_group_send_table_request`, `topo_group.c:602`). - 2. У C группа G ещё **не создана** (создаётся позже, по мере загрузки каналов/синка). - C получает `REQUEST_TABLE`, но `topo_group_handle_request_table` не находит G → - дропает запрос. - 3. C наконец создаёт G (`topo_groups_create_group` → обход connections → - `topo_group_new_conn(G, conn_A)` на стороне C) → C шлёт A свой `REQUEST_TABLE`. - A отвечает своей таблицей → **C узнаёт A**. - 4. Но A больше не шлёт C `REQUEST_TABLE` → **A так и не узнаёт C** в группе G. - Итог: при разнесённом старте A не видит C в CHAT-группе (односторонняя видимость). - - **Фикс (предполагаемый):** в дедуп-ветке не просто `return`, а предварительно - идемпотентно `topo_group_send_table_request(group, conn)`: - ```c - if (((struct TOPO_GROUP_CONN_ITEM*)se->data)->conn == conn) { - topo_group_send_table_request(group, conn); /* повторно, идемпотентно */ - DEBUG_INFO(..., "conn already in senders_list, re-request table (%s)", conn->log_name); - return; - } - ``` - `topo_group_send_table_request` не ведёт состояния — просто шлёт REQUEST_TABLE, - пир отвечает снимком таблицы (идемпотентно). Лишний дубль таблицы безвреден. - - **Замечание:** в однопоточном `test_dm_e2e` (и `test_chat_join_e2e`) из-за - детерминированного порядка группа успевает создаться до прихода REQUEST_TABLE — - поэтому тест проходит. Реальная гонка остаётся для асинхронных сетей. Отдельный - воспроизводимый тест для этой гонки пока не написан. - -[ ] **«packet undecryptable» на линках C** (вторичное). A, узнав B через BGP, через - `topo_group_connect` пытается поднять прямой A↔B линк (`seskey 4777737b`), но B не - настроен принимать A → crypto-шум каждые ~1с. Разобраться с авто-подключением - (не пытаться соединяться с узлами, для которых нет `[client]`/ncd-конфигурации, - либо обрабатывать неудачу без спама). +[ ] **Повторно проверить crypto-шум при автоподключении в сценарии A–C–B**: + В старом test_dm_e2e попытка прямого A↔B через topo_group_connect давала packet undecryptable примерно раз в секунду. + Наблюдение относилось к прежним настройкам приёма и архитектуре подключений; устранение не подтверждено. + Воспроизвести на текущих NCD/ETCP и установить точную причину по логам до изменения политики подключения. + Отсутствие [client] само по себе не считать основанием запрета: CHAT использует собственных NCD-владельцев. [ ] **lwip/proxy: утечка pcb в FIN_WAIT_2** — `tcp_shutdown(pcb,0,1)` (half-close по FIN от exit) не ставит `TF_RXCLOSED`, поэтому таймаут FIN_WAIT_2 в `tcp_slowtmr` не срабатывает: @@ -1214,6 +280,7 @@ Двойной free по TIME_WAIT уже закрыт (detach по локальному закрытию + guard abort). ## Открытые флаки + [ ] **test_etcp_transport: таймаут восстановления REALITY-сессии** — 18.10.2026: в общем `./check.sh` сценарий `reality=1 simultaneous=0 restart=0` завершился `Session recovery timed out: phase=1 stream=15 control=6`. Перед таймаутом —