Document call video layout and clock discontinuity fixes

This commit is contained in:
evgeny committed 2026-10-15 01:25:22 +02:00
1 parent 13feaca674
commit 5e22da3098
2 files changed
+45 -17

No files matched your search

+39 -16
View File
@@ -63,11 +63,14 @@ Worker хранит pending-команду и применяет её перед
команда завершается отказом; нельзя бесконечно продлевать её таймаут. команда завершается отказом; нельзя бесконечно продлевать её таймаут.
Ограничитель очереди работает и во время ожидания. Если новый IDR не принят, Ограничитель очереди работает и во время ожидания. Если новый IDR не принят,
producer запрашивает следующий IDR по существующему контракту send_frame. producer запрашивает следующий IDR по существующему контракту send_frame.
Desktop сохраняет старый encoder до готовности кандидата. Android переоткрывает Desktop готовит кандидата в отдельном потоке, продолжая кодирование старым encoder.
encoder последовательно (аппаратный ресурс может быть единственным), при отказе Готовый кандидат применяется только на IDR; при незавершённой подготовке текущий
восстанавливает прежнюю конфигурацию и подтверждает фактически восстановленный bitrate. GOP продолжается. Android сначала меняет bitrate через MediaCodec.setParameters
Допустима пауза картинки; аудио и capture timeline продолжаются. Реальные затраты переключения и без остановки; подтверждает только проверенный KEY с PTS не раньше команды.
пиковый объём IDR нужно проверить для каждого доступного режима/backend. При отказе runtime API Android переоткрывает encoder последовательно (аппаратный
ресурс может быть единственным), при ошибке восстанавливает прежнюю конфигурацию
и подтверждает фактически восстановленный bitrate. В этой резервной ветке возможна
пауза картинки; аудио и capture timeline продолжаются.
Порядок реализации Порядок реализации
[+] История первых ACK 500мс/50мс и снимок payload send_q/inflight отдельного сервиса. [+] История первых ACK 500мс/50мс и снимок payload send_q/inflight отдельного сервиса.
@@ -344,10 +347,11 @@ pixel format, отсутствие B-кадров и размер. Провер
эту проверку bitstream. Automatic-профили трансляций сохраняют прежний выбор GPU/SW. эту проверку bitstream. Automatic-профили трансляций сохраняют прежний выбор GPU/SW.
Опции encoder сверены с https://ffmpeg.org/ffmpeg-codecs.html#libx265 и разделом libx264. Опции encoder сверены с https://ffmpeg.org/ffmpeg-codecs.html#libx265 и разделом libx264.
CallVideoEncoder принадлежит будущему video worker. Он хранит единственную pending CallVideoEncoder принадлежит video worker. Он хранит единственную pending
команду generation/request/bitrate, отклоняет replay, чужой generation и выход за команду generation/request/bitrate, отклоняет replay, чужой generation и выход за
согласованный maximumBitrate. На ближайшем IDR по capture PTS создаётся кандидат; согласованный maximumBitrate. После команды кандидат открывается в фоне;
старый encoder сохраняется до получения полного KEY с точным исходным PTS. на ближайшем IDR после готовности проверяется полный KEY с точным исходным PTS.
Старый encoder сохраняется до успешной проверки; stop ждёт завершения подготовки.
При отказе кандидата возвращается completion с bitrate=0 и используется прежний При отказе кандидата возвращается completion с bitrate=0 и используется прежний
контекст. Неизменный target также подтверждается на KEY без пересоздания. контекст. Неизменный target также подтверждается на KEY без пересоздания.
Completion отделён от отправки кадра: даже при закрытом admission его нужно Completion отделён от отправки кадра: даже при закрытом admission его нужно
@@ -525,11 +529,30 @@ ChatGUI пересобран; test_call_video_encoder — 10/10 PASS в кажд
Логи: /tmp/call-camera-locale-test-c.log, /tmp/call-camera-locale-test-ru.log. Логи: /tmp/call-camera-locale-test-c.log, /tmp/call-camera-locale-test-ru.log.
Работающий GUI автоматически не перезапускался; проверка полного звонка после исправления остаётся. Работающий GUI автоматически не перезапускался; проверка полного звонка после исправления остаётся.
Desktop UI: принимаемый кадр раскрывает окно на весь экран с сохранением пропорций. UI и периодические фризы (15.10.2026)
Своя камера отображается миниатюрой поверх изображения собеседника; при отсутствии Android: принимаемое видео занимает весь экран, своя камера — миниатюрой поверх него.
входящего видео — миниатюрой в обычном окне. Без кадров видеоплощадка не занимает места. Без RX локальная камера видна только миниатюрой на экране аудиозвонка; без кадров
Esc/F11, кнопка и двойной щелчок переключают полноэкранный режим; геометрия окна сохраняется. место под видео не резервируется. Касание показывает кнопки, через 5с они скрываются.
Настройки камеры/кодека/битрейта/звука и диагностика свёрнуты под «Настройки звонка». Имя/статус/диагностика не рисуются поверх видео; параметры вынесены в «Настройки звонка».
Preview берётся из того же QVideoFrame, отдельная камера не открывается; обновление до 10 fps. TextureView и Surface сохраняются при показе кнопок; decoder освобождает старый Surface
После 5 секунд без новых показанных RX кадров изображение скрывается: отдельного VIDEO_OFF до его release. Запоздалый detach предыдущего Surface не отключает новый.
в протоколе пока нет. Возобновление видео снова открывает полный экран. Preview берётся из того же Camera2 YUV кадра (до 5 fps), без второй камеры.
Desktop: первый RX кадр увеличивает обычное изменяемое окно, без автоматического fullscreen.
Видео сохраняет пропорции, своя миниатюра находится внутри видеоплощадки, панель — под ней.
Esc/F11, кнопка и двойной щелчок переключают fullscreen вручную; геометрия восстанавливается.
Preview берётся из того же QVideoFrame (до 10 fps). Без RX остаётся лишь своя миниатюра;
без обоих видео — обычное окно аудиозвонка. После 5с без показанных кадров RX скрывается:
отдельного VIDEO_OFF в протоколе пока нет.
Подтверждённая причина фризов раз в 1–2с: коррекция capture timestamp меняла audio source_epoch,
а обе платформы сбрасывали video decoder и ждали KEY. Теперь source_epoch обновляет
аудиопривязку без потери video references, готовых кадров и последнего показанного PTS.
Отдельный production RX тест: 90/90 кадров, 32 смены аудиоэпохи, 0 дополнительных KEY,
0 decoder rejection (/tmp/call-video-clock-final.log).
Android больше не отбрасывает кадр из-за интервала чуть меньше 33333мкс: Camera2 уже
ограничивает FPS; повторная фильтрация превращала дрожание timestamps в падение до 15fps.
Desktop rate test: 10/10 PASS, непрерывные H.264/H.265 4M -> 300k -> 4M, оба decoder.
H.264 commit 5–7мс; H.265 51–76мс включая кодирование первого кадра, подготовка — в фоне.
Измерение /tmp/call-video-background-test.log; для H.265 стоимость кодирования остаётся существенной.
Android assembleDebug и 81 unit-тест проходят. Полный звонок с камерами после этих правок
требует ручной приёмки; автоматические проверки не подтверждают его целиком.
+6 -1
View File
@@ -46,7 +46,7 @@
Аппаратные блокеры устранены: общий C validator, AVC Baseline/CB, нормативный DPB, Аппаратные блокеры устранены: общий C validator, AVC Baseline/CB, нормативный DPB,
независимые encoder/decoder probes, фактические profile/level, VBV убран из wire. независимые encoder/decoder probes, фактические profile/level, VBV убран из wire.
Decoder сообщает acceptance/rejection; Auto делает fallback, отдельный KEY request восстанавливает references. Decoder сообщает acceptance/rejection; Auto делает fallback, отдельный KEY request восстанавливает references.
Android последовательно заменяет encoder на IDR с восстановлением предыдущего режима при отказе. Android меняет bitrate без остановки MediaCodec на IDR; при отказе API последовательно заменяет encoder с восстановлением.
Unisoc кодирует HEVC и AVC; Samsung кодирует AVC и независимо принимает HEVC. Unisoc кодирует HEVC и AVC; Samsung кодирует AVC и независимо принимает HEVC.
Проверены аппаратные 4M -> 300k -> 4M, HEVC Unisoc -> Samsung, AVC Samsung -> Unisoc, Проверены аппаратные 4M -> 300k -> 4M, HEVC Unisoc -> Samsung, AVC Samsung -> Unisoc,
все три потока -> production decoder ChatGUI. AVC Unisoc -> Samsung пока вернул 3/4 все три потока -> production decoder ChatGUI. AVC Unisoc -> Samsung пока вернул 3/4
@@ -55,6 +55,11 @@
15.10.2026: USB-камера ChatGUI отдаёт кадры; обнаружен и исправлен отказ обоих TX codecs 15.10.2026: USB-камера ChatGUI отдаёт кадры; обнаружен и исправлен отказ обоих TX codecs
из-за LC_NUMERIC=ru_RU: дробный level 3.1 заменён целочисленным параметром 31. из-за LC_NUMERIC=ru_RU: дробный level 3.1 заменён целочисленным параметром 31.
ChatGUI пересобран; Qt codecs 10/10 PASS в C и ru_RU.UTF-8, включая 720p и смену bitrate. ChatGUI пересобран; Qt codecs 10/10 PASS в C и ru_RU.UTF-8, включая 720p и смену bitrate.
UI исправлен: Android fullscreen RX + своя миниатюра, управление и диагностика отделены;
desktop — большое изменяемое окно с панелью под видео. Без кадров пустая видеоплощадка скрыта.
Фризы: обе платформы сохраняют decoder при коррекции audio epoch; production RX 90/90 кадров,
32 коррекции часов, 0 KEY requests/rejections. Android Camera2 больше не теряет кадры на пороге 33333мкс.
Desktop готовит encoder при смене bitrate в фоне, применяет на IDR; Qt codecs 10/10 PASS.
Осталась ручная приёмка полного звонка с камерами, Surface, A/V и переключениями после исправления. Осталась ручная приёмка полного звонка с камерами, Surface, A/V и переключениями после исправления.
Аппаратные probes используют синтетические кадры. Аппаратные probes используют синтетические кадры.
Контракты, этапы и проверки: `doc/call_video.txt`. Контракты, этапы и проверки: `doc/call_video.txt`.