947 lines
121 KiB
Markdown
947 lines
121 KiB
Markdown
# Задачи по проекту
|
||
|
||
Сюда пишется список задач с короткой аннотацией. Если задача большая и имеет ТЗ - то ТЗ оформляется отдельным файлом, а сюда помещается аннотация и ссылка на ТЗ.
|
||
|
||
## Текущие задачи
|
||
|
||
[ ] **Разобрать нестабильную проверку аудиопауз 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.
|
||
|
||
[ ] **Устранить коллизию порта при перезапуске узла в test_dm_e2e** — 16.10.2026:
|
||
Общий check.sh при проверке Windows-курсора: 155/156, test_dm_e2e упал в phase=9 на создании B2.
|
||
Повторный bind 127.0.0.1:33843 вернул Address already in use; отдельный повтор теста проходит.
|
||
Проверить владение/резервирование порта между остановкой 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 и только он подтвердит исходную машину.
|
||
Логи: 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.
|
||
|
||
[+] **Проверять микрофон и спрашивать перед переходом трансляции на 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.
|
||
|
||
[ ] **Проверить трансляцию на 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.
|
||
|
||
[ ] **Доступность разговорного динамика в UI звонка** — при подключённой проводной гарнитуре Samsung убирает
|
||
EARPIECE из Telecom endpoints, но кнопка остаётся доступной по наличию физического встроенного устройства.
|
||
Нажатие создаёт отложенный запрос, который исполняется после отключения гарнитуры. Согласовать UI с доступными endpoints.
|
||
Также выбор проводной гарнитуры в 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.
|
||
|
||
[ ] **Тесты: нестабильное завершение 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.
|
||
Отдельный повтор и следующий полный прогон прошли. Добавить значения и проверить ожидание конкретного снимка;
|
||
причина не установлена, 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,
|
||
плавное снижение gain может не успеть за скачком входа. Проверить ограничение пиков
|
||
без щелчков и ухудшения адаптации. Лог: `/tmp/stream-camcorder-sm-live.log`.
|
||
|
||
[ ] **Desktop: выход после SIGTERM оставляет GUI после остановки ядра** — 13.10.2026:
|
||
при обновлении live-плеера старый vibechat завершил ядро/worker, но процесс остался
|
||
в QCoreApplication::exec с работающим audio output. В логах также DM SELECT после
|
||
уничтожения SQLite (`bad parameter or other API misuse`). Проверить отмену Quit
|
||
в 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 не восстановили
|
||
просмотр, desktop завершился по таймауту в 11:10:48 (colo2: 12:10:48). На SM публикация продолжилась,
|
||
colo2 снял свою подписку через 3 с. В том же интервале сервер видит RX timeout/переподключения TCP к SM;
|
||
первопричина остановки выдач пока не установлена: stream на colo2 наследовал error, детальных логов не было.
|
||
Повторить с заранее включённой диагностикой stream/etcp на SM и colo2, проверить upstream handles,
|
||
аренды, позиции и повторное согласование. Логи: `/tmp/stream-live-gui-final.log`,
|
||
`/tmp/stream-live-colo2-final.log`, `/tmp/stream-live-sm-final.log`.
|
||
Повтор 13.10 со stereo: до 15:20 desktop показывал ~30fps, затем video/audio очереди опустели;
|
||
decodeFps упал до 7–18 и viewer завершился по таймауту в 15:21:13 после пяти restart.
|
||
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`.
|
||
Поэтому запрос stop до завершения конструктора может не отменить запускаемый
|
||
поток. Согласовать отмену с состоянием потока и единым сигналом завершения;
|
||
проверить stop до SERVICE_STARTED, отказ конструктора и последующий start.
|
||
|
||
[ ] **Android: повторные отказы persisted node snapshots** — замечено 12.10.2026
|
||
на устройстве D2AR10P3600820 при проверке live media. В сохранённой БД ряд узлов
|
||
регулярно получает `invalid persisted snapshot` в `topo_node_sqlite_snapshot_load`,
|
||
затем NCD сообщает `node not found`; повторные попытки засоряют лог.
|
||
Лог: `/tmp/stream-av-device-initial.log`. Причина пока не установлена: текущий
|
||
текст объединяет отказ deserialize, несовпадение ID и отказ verify. Разделить
|
||
диагностику этих ветвей и проверить повторные попытки загрузки отвергнутого снимка.
|
||
Существующую БД устройства при проверке стриминга не очищали.
|
||
|
||
[+] **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.
|
||
|
||
[ ] **check.sh: изоляция сетевых integration-тестов** — после основного набора
|
||
автоматически запускает check-proxy/burst/load при доступном sudo. Скрипты
|
||
меняют rp_filter, таблицу 100 и iptables главного namespace; cleanup выставляет
|
||
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.
|
||
|
||
[ ] **Member files: исчерпание кеша результатов массовых изменений** — 10.10.2026:
|
||
Воспроизведено test_member_files_browser::recursiveDeletion(server-busy): из 76 объектов удаляются 64,
|
||
следующая команда получает MF_BUSY, остаются 12. storage.c: STORE_RECEIPTS=64, RECEIPT_TB=1200000 (120 секунд).
|
||
Лимит общий для успешных COMMIT/MKDIR/RENAME/REMOVE; затрагивает также рекурсивное копирование.
|
||
Нужен отдельный этап управления временем жизни receipts с сохранением идемпотентности повторных запросов;
|
||
простое вытеснение старых записей нарушает гарантию повторного ответа. После исправления изменить регрессию
|
||
на успешное удаление более 64 объектов и проверить повторные запросы/потерю ответа.
|
||
|
||
[ ] **Desktop: провалы вероятности VAD при компрессии** — диагностика 09.10.2026:
|
||
Воспроизведение пользователя: длительная гласная, затем временная нечувствительность; ближе к концу лога несколько повторов.
|
||
Новый лог 14:32:14–14:34:38: на 14:34:07–18 и 14:34:20–38 все 556 окон с RMS > -30dBFS имеют p < 0.5;
|
||
PCM непрерывен, errors=0, RX-gate не мешает, clips=5 не растёт. Сигнал не исчезает, порог остаётся 0.5.
|
||
--probe-stream: C-обёртка + реальный AGC + две Silero на одинаковом PCM, отличие — один reset состояния второй модели.
|
||
Синтезированный flite ah растянут до 24.576с: без AGC/клиппинга p первой секунды следующей речи 0.027 против 0.674 после reset.
|
||
При AGC 1dB (clips=0) — 0.012 против 0.662. Влияние истории модели подтверждено, провал на десятки секунд целиком не воспроизведён.
|
||
Лог стенда: /tmp/vad-vowel-context.log; запуск: test_silero_vad lib/silero_vad.onnx --probe-stream /tmp/vad-vowel-context48.pcm 993.
|
||
Вход стенда: mono s16le/48кГц, reset_window — индекс окна 512/16кГц; режим проверяет без AGC, 1dB и 15dB.
|
||
Автоматические сбросы в рабочем VAD не добавлялись; test_silero_vad PASS.
|
||
Уточнение: низкая вероятность держится десятки секунд, затем распознавание восстанавливается; краткий клиппинг это не объясняет.
|
||
Локальный лог 14:00:10–14:00:58: 15 сбросов AEC при пропусках референса, 16 clipped samples в VAD; vad DEBUG не был включён.
|
||
Добавлены секундные уровни raw/clean/reference и причина bypass/reset AEC; отдельное предупреждение о клиппинге VAD.
|
||
Секундный отчёт захвата работает также без PCM: возраст кадра, очередь, максимальная задержка и предупреждение о простое.
|
||
TRACE каждого окна содержит DC, число нулей и gain вместе с вероятностью/уровнем/паузой между окнами; видны сбросы и RX-gate.
|
||
В локальном build/vibechat.cfg включены vad=trace, aec/radio/call=debug, general=info; после диагностики вернуть обычные уровни.
|
||
Стенд --probe повторяет одинаковый PCM без reset: AGC 15/30dB после паузы обрезает пики (468/5625 samples на чистой записи).
|
||
Полного провала всей фразы почти до нуля стенд не воспроизвёл; нужен повтор живой речи с новыми логами для связи с AEC/AGC.
|
||
Алгоритмы обработки сигнала пока не менялись; исправление причины выбирается по результатам повтора.
|
||
|
||
[ ] **Linux headless CMake: актуализировать зависимости общего ядра** — 07.10.2026:
|
||
чистая сборка tools/chatgui-android/build_headless останавливается на lib/speex_aec.c:
|
||
speex/speex_echo.h не найден. utun_setup_sources включает этот исходник, но UTUN_INCLUDE_DIRS не содержит
|
||
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 во время работы.
|
||
|
||
[ ] **rlottie: разбор предупреждений GCC 15 в импортированных исходниках** — 05.10.2026:
|
||
при сборке `tools/chatgui/rlottie_src` GCC сообщает `-Wuninitialized` в
|
||
`VArenaAlloc::reset()`: fFirstBlock/fFirstSize/fFirstHeapAllocationSize читаются
|
||
после явного вызова деструктора. Проверить сохранение значений до разрушения
|
||
и повторный reset с реальными выделениями. Также проверить `-Wfree-nonheap-object`
|
||
в `vcow_ptr`: статическая модель default_s сохраняет базовую ссылку.
|
||
Лог: `/tmp/utun-rlottie-vendor-build.log`. Сборка библиотеки и подключение её
|
||
экспортированного CMake-пакета к ChatGUI на Linux прошли; Windows ещё не проверен.
|
||
|
||
[ ] **ChatGUI Windows: подтверждение обновления runtime компилятора** — 05.10.2026:
|
||
`cc-probe.log`: cc1 запускается из корня, но в `tools/chatgui/build` завершается
|
||
с `0xC0000139`; локальные DLL GCC/math/runtime отличаются от UCRT64.
|
||
Перед обеими точками сборки добавлено обновление существующих копий этих DLL;
|
||
раскладка FFmpeg использует для них UCRT64. Проверены обновление, повторный вызов,
|
||
сохранение кодеков и ошибки. Требуется 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 и проверить запуск приложения.
|
||
|
||
[ ] **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 кадров за интервал.
|
||
Счётчики сбрасываются до старта устройства; нужна повторная запись с новой сборкой.
|
||
|
||
[ ] **Оставшаяся задержка запуска аудио 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. Выигрыш по времени требует пробного звонка с новой версией.
|
||
|
||
[ ] **Гонка 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-конфигурации,
|
||
либо обрабатывать неудачу без спама).
|
||
|
||
[ ] **lwip/proxy: утечка pcb в FIN_WAIT_2** — `tcp_shutdown(pcb,0,1)` (half-close по FIN от
|
||
exit) не ставит `TF_RXCLOSED`, поэтому таймаут FIN_WAIT_2 в `tcp_slowtmr` не срабатывает:
|
||
если браузер никогда не пришлёт FIN, pcb навсегда остаётся в FIN_WAIT_2 (утечка, не crash).
|
||
Двойной 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`. Перед таймаутом —
|
||
`record socket read failed: err=104`, клиент ждал server-handshake.
|
||
Отдельный повтор того же бинарника прошёл. Причина нестабильности пока не установлена;
|
||
изменения Android JNI/UI транспортные исходники не затрагивали.
|
||
|
||
[ ] **test_etcp_reconnect** — флаки под параллельной нагрузкой `make check -j4`:
|
||
phase 4 (reconnect после server restart) таймаутит (`sent=480 recv=0`), при одиночном
|
||
запуске стабильно `TEST PASSED`. Наш код (chat_join/chat_sync) его не трогает.
|