Browse Source

Document complete keyframe admission and shared media opening

master
evgeny 4 days ago
parent
commit
7dd1176545
  1. 20
      doc/stream.txt
  2. 2
      src/stream/stream_media_buffer.h

20
doc/stream.txt

@ -760,8 +760,10 @@ first_video_frame_offset относительно начала video bytes: UINT
KEY=bit0 video flags; остальные биты запрещены. frame_id>0, <=16 описаний каждого трека.
Один полный видеокадр с конфигурацией <=2MiB. Общий формат допускает медиаблок <=64KiB; реальный максимум дополнительно
ограничен входом RS. Аудиокодек фиксирован на source_epoch. Кодек, разрешение, поворот и конфигурация видео меняются по config_revision.
Новая revision может пропускать номера; старая игнорируется. Изменение metadata без новой revision запрещено.
При переходе receiver удаляет неполный видеокадр и ждёт полный KEY, сохраняя историю PTS/кадров и аудио.
Новая revision может пропускать номера; регрессия revision во входящем потоке отвергается.
Изменение metadata без новой revision запрещено. При переходе каждый media cursor удаляет
неполный видеокадр и допускает новую revision только с полным KEY, сохраняя аудио.
Отстающий reader может дочитать прежнюю revision из кольца: сравнение ведётся с revision его выданного видео.
video_codec: 1=H.264, 2=H.265, 3=VP9, 4=AV1, 5=H.266/VVC. B-кадры при захвате запрещены.
KEY payload: config_length:4BE, decoder configuration (<=64KiB), access unit (непустой).
@ -774,9 +776,17 @@ audio_codec=0: нет аудио; audio_codec=1: Opus mono, audio_codec=2: Opus
Оба формата: 48000Hz, 960 кадров на канал (20ms), packet<=1275 bytes; interleaved stereo содержит 1920 отсчётов PCM.
Opus-пакеты между медиаблоками не разрезаются. Размеры треков не включают header/описания.
stream_media проверяет весь блок до изменения view. Receiver собирает один последовательный кадр.
При GAP, потере продолжения или конфликте metadata недособранный кадр удаляется, видео ждёт KEY.
Аудио обрабатывается независимо; неверный формат/длины не передаются платформенным декодерам.
stream_media проверяет весь блок до изменения view. Store индексирует подтверждённые пачки,
а отдельный cursor каждого reader собирает один последовательный кадр прямо из общего RS-кольца.
При GAP, потере продолжения или EXPIRED reader сбрасывает сборку и начинает с полного KEY.
Полный KEY передаётся декодеру сразу, без таймера ожидания; частичный KEY и зависимые кадры до него не выдаются.
Потери, восстановленные и проверенные FEC, не создают GAP и не требуют перезапуска декодера.
Аудио читается независимо; неверный формат/длины не передаются платформенным декодерам.
Конфликт metadata завершает чтение ошибкой. Неиспользуемый отдельный stream_media_receiver удалён:
проверки сборки и восстановления выполняются на рабочем store/cursor.
Desktop и Android открывают просмотр через stream_media_open: ядро проверяет выбранный source_epoch
и эпоху существующей session, создаёт подписку и cursor; при ошибке снимает только нового владельца.
Платформы сохраняют собственное планирование чтения и вывод; закрытие использует обычный stream_close.
Ретрансляторы не разбирают uAV2 и не пересоздают подписи источника.
Android:

2
src/stream/stream_media_buffer.h

@ -4,6 +4,8 @@
* Независимые audio/video позиции читают оригинал из кольца. Рабочая память cursor — один видеокадр,
* один Opus-пакет и два scratch медиаблока. Курсоры ничего не закрепляют против вытеснения.
* read возвращает заимствованный packet до следующего read/destroy; frontend копирует только ближайшие записи.
* Каждый cursor допускает новую video revision только с полным KEY; готовый KEY выдаётся без дополнительного ожидания.
* Смена video revision не сбрасывает аудио и не запрещает другим readers дочитать прежнюю revision.
* WAIT — материал ещё не готов/дальше audio lookahead. GAP/EXPIRED требуют новой точки KEY; END — весь материал выдан. */
#ifndef STREAM_MEDIA_BUFFER_H
#define STREAM_MEDIA_BUFFER_H

Loading…
Cancel
Save