Browse Source

Document live playback queue bounds and latency regression

master
evgeny 5 days ago
parent
commit
736fb92ed7
  1. 8
      doc/stream.txt
  2. 8
      doc/tasks.md
  3. 7
      tools/chatgui/src/streamplayer_window.cpp

8
doc/stream.txt

@ -857,7 +857,9 @@ Desktop:
Post отменяется до destroy ядра; GUI/decoder не хранят заимствованные instance/handle pointers.
- stream_media_receiver собирает H.264 access units и выдаёт Opus 48kHz mono/20ms.
FFmpeg/Opus декодируются отдельным worker; Qt-очередь не накапливает кадры.
Очереди ограничены шестью декодированными видеокадрами и 25 аудиопакетами (500ms).
Очередь декодированного видео ограничена 128 кадрами и 256MiB, аудио — 25 пакетами (500ms).
Кадры сохраняются до достижения их PTS аудиочасами. При пределе видео отбрасывается новый
уже декодированный кадр; ближайшие к показу остаются в очереди, codec refs не меняются.
Видео декодируется без задержки frame-threading. При GAP сбрасываются decoder refs и timeline до KEY.
- После prebuffer 150ms показ следует физическим audio callback timestamps; без звука — монотонным часам.
Короткие пропуски аудио заполняются Opus PLC; большой разрыв/pressure сбрасывает timeline.
@ -865,7 +867,9 @@ Desktop:
Удаление канала сообщает STREAM_CLOSE_GROUP; остановка ядра снимает media и catalogue owners.
- Без FFmpeg окно сообщает, что декодирование недоступно. Нужна desktop-сборка с HAVE_FFMPEG.
Проверки: test_stream_view — настоящее ядро, старые эпохи/cancel, RX pressure, H.264 с поворотом и сменой revision без новой эпохи,
Opus/громкость на настоящем null audio backend, закрытие канала и полный баланс tracked allocations.
Opus/громкость на настоящем null audio backend, непрерывные 30fps при физической audio latency 200ms,
закрытие канала и полный баланс tracked allocations. Раз в секунду desktop viewer логирует decode/show FPS,
late/pressure drops, число и байты кадров, PTS границ очереди относительно часов и audio callback timing.
test_stream_service также проверяет общий каталог двух независимых источников одного канала.
21. Суперузлы: помощь в раздаче по запросу

8
doc/tasks.md

@ -4,6 +4,14 @@
## Текущие задачи
[+] **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.
[+] **Android: категории диагностики и обрезанный текст уровня** — 13.10.2026:
список берётся из native-ядра, включая stream/video/reality/dm/call/aec.
Поля уровня используют минимальную высоту вместо фиксированных 48 dp;

7
tools/chatgui/src/streamplayer_window.cpp

@ -181,7 +181,7 @@ void StreamPlayerWindow::decode() {
opus_codec_decoder_t* opus = nullptr;
bool waitKey = true, opened = false;
int64_t deadline = nowUs() + 10000000, reportAt = nowUs(), expectedAudio = -1;
uint64_t decoded = 0, discarded = 0, late = 0, pressureDropped = 0, previousDecoded = 0, previousShown = 0;
uint64_t decoded = 0, discarded = 0, late = 0, pressureDropped = 0, previousPressure = 0, previousDecoded = 0, previousShown = 0;
uint32_t videoRevision = 0;
auto reset = [&] {
avcodec_free_context(&decoder);
@ -317,9 +317,10 @@ void StreamPlayerWindow::decode() {
(long long)(p.videos.empty() ? 0 : p.videos.front().pts - clock),
(long long)(p.videos.empty() ? 0 : p.videos.back().pts - clock), p.audios.size(),
(long long)(p.audioPts < 0 ? 0 : now - p.audioAt), (unsigned long long)p.underruns);
if (pressureDropped) DEBUG_WARN(DEBUG_CATEGORY_STREAM, "desktop video queue pressure id=%llu dropped=%llu; preserve due frames",
if (pressureDropped != previousPressure)
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "desktop video queue pressure id=%llu dropped=%llu; preserve due frames",
(unsigned long long)p.id, (unsigned long long)pressureDropped);
previousDecoded = decoded; previousShown = p.shown;
previousDecoded = decoded; previousShown = p.shown; previousPressure = pressureDropped;
}
}
avcodec_free_context(&decoder); av_frame_free(&frame); av_packet_free(&packet);

Loading…
Cancel
Save