Browse Source

Document call video layout and clock discontinuity fixes

master
evgeny 4 days ago
parent
commit
5e22da3098
  1. 55
      doc/call_video.txt
  2. 7
      doc/tasks.md

55
doc/call_video.txt

@ -63,11 +63,14 @@ Worker хранит pending-команду и применяет её перед
команда завершается отказом; нельзя бесконечно продлевать её таймаут.
Ограничитель очереди работает и во время ожидания. Если новый IDR не принят,
producer запрашивает следующий IDR по существующему контракту send_frame.
Desktop сохраняет старый encoder до готовности кандидата. Android переоткрывает
encoder последовательно (аппаратный ресурс может быть единственным), при отказе
восстанавливает прежнюю конфигурацию и подтверждает фактически восстановленный bitrate.
Допустима пауза картинки; аудио и capture timeline продолжаются. Реальные затраты переключения и
пиковый объём IDR нужно проверить для каждого доступного режима/backend.
Desktop готовит кандидата в отдельном потоке, продолжая кодирование старым encoder.
Готовый кандидат применяется только на IDR; при незавершённой подготовке текущий
GOP продолжается. Android сначала меняет bitrate через MediaCodec.setParameters
без остановки; подтверждает только проверенный KEY с PTS не раньше команды.
При отказе runtime API Android переоткрывает encoder последовательно (аппаратный
ресурс может быть единственным), при ошибке восстанавливает прежнюю конфигурацию
и подтверждает фактически восстановленный bitrate. В этой резервной ветке возможна
пауза картинки; аудио и capture timeline продолжаются.
Порядок реализации
[+] История первых ACK 500мс/50мс и снимок payload send_q/inflight отдельного сервиса.
@ -344,10 +347,11 @@ pixel format, отсутствие B-кадров и размер. Провер
эту проверку bitstream. Automatic-профили трансляций сохраняют прежний выбор GPU/SW.
Опции encoder сверены с https://ffmpeg.org/ffmpeg-codecs.html#libx265 и разделом libx264.
CallVideoEncoder принадлежит будущему video worker. Он хранит единственную pending
CallVideoEncoder принадлежит video worker. Он хранит единственную pending
команду generation/request/bitrate, отклоняет replay, чужой generation и выход за
согласованный maximumBitrate. На ближайшем IDR по capture PTS создаётся кандидат;
старый encoder сохраняется до получения полного KEY с точным исходным PTS.
согласованный maximumBitrate. После команды кандидат открывается в фоне;
на ближайшем IDR после готовности проверяется полный KEY с точным исходным PTS.
Старый encoder сохраняется до успешной проверки; stop ждёт завершения подготовки.
При отказе кандидата возвращается completion с bitrate=0 и используется прежний
контекст. Неизменный target также подтверждается на KEY без пересоздания.
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.
Работающий GUI автоматически не перезапускался; проверка полного звонка после исправления остаётся.
Desktop UI: принимаемый кадр раскрывает окно на весь экран с сохранением пропорций.
Своя камера отображается миниатюрой поверх изображения собеседника; при отсутствии
входящего видео — миниатюрой в обычном окне. Без кадров видеоплощадка не занимает места.
Esc/F11, кнопка и двойной щелчок переключают полноэкранный режим; геометрия окна сохраняется.
Настройки камеры/кодека/битрейта/звука и диагностика свёрнуты под «Настройки звонка».
Preview берётся из того же QVideoFrame, отдельная камера не открывается; обновление до 10 fps.
После 5 секунд без новых показанных RX кадров изображение скрывается: отдельного VIDEO_OFF
в протоколе пока нет. Возобновление видео снова открывает полный экран.
UI и периодические фризы (15.10.2026)
Android: принимаемое видео занимает весь экран, своя камера — миниатюрой поверх него.
Без RX локальная камера видна только миниатюрой на экране аудиозвонка; без кадров
место под видео не резервируется. Касание показывает кнопки, через 5с они скрываются.
Имя/статус/диагностика не рисуются поверх видео; параметры вынесены в «Настройки звонка».
TextureView и Surface сохраняются при показе кнопок; decoder освобождает старый Surface
до его 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-тест проходят. Полный звонок с камерами после этих правок
требует ручной приёмки; автоматические проверки не подтверждают его целиком.

7
doc/tasks.md

@ -46,7 +46,7 @@
Аппаратные блокеры устранены: общий C validator, AVC Baseline/CB, нормативный DPB,
независимые encoder/decoder probes, фактические profile/level, VBV убран из wire.
Decoder сообщает acceptance/rejection; Auto делает fallback, отдельный KEY request восстанавливает references.
Android последовательно заменяет encoder на IDR с восстановлением предыдущего режима при отказе.
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
@ -55,6 +55,11 @@
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 — большое изменяемое окно с панелью под видео. Без кадров пустая видеоплощадка скрыта.
Фризы: обе платформы сохраняют 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 и переключениями после исправления.
Аппаратные probes используют синтетические кадры.
Контракты, этапы и проверки: `doc/call_video.txt`.

Loading…
Cancel
Save