Browse Source

Document direct Android camera preview and surface ownership

master
evgeny 4 days ago
parent
commit
30dae7d7ed
  1. 7
      doc/service_lifecycle.md
  2. 23
      doc/stream.txt

7
doc/service_lifecycle.md

@ -100,6 +100,13 @@ Live media хранится в RS-кольце с общим индексом PT
части против вытеснения. После FIN publisher может снять своё владение, сохранив
завершённый источник для оставшихся локальных readers. Последний close освобождает
источник, индекс и кольцо. Новая публикация отсоединяет readers прежней эпохи.
Android preview собственного эфира не создаёт reader: Camera2 пишет прямо в TextureView
и encoder Surface. UI attach/detach меняет лишь camera session; audio/encoder/origin сохраняются.
UI, ожидающие команды camera handler и каждая camera session удерживают preview target отдельно.
TextureView возвращает false при destroy и снимает ссылку UI; Surface/SurfaceTexture освобождаются
после закрытия последней session. Capture stop запрещает attach и снимает своё владение target;
camera HandlerThread завершается после camera close и callbacks всех созданных sessions.
Отказ preview output возвращает encoder-only session и не завершает сам эфир.
При stop/destroy отменяются delivery и media-index callbacks до освобождения store;
destroy отсоединённого cursor не обращается к store. Frontend прекращает audio callback
и worker до освобождения своего DSP; borrowed handle/RS pointers между потоками не передаются.

23
doc/stream.txt

@ -834,13 +834,20 @@ Android:
Отсутствие output progress 10s при наличии работы даёт ERROR; сетевые паузы и ожидание PTS допустимы.
Состояния ожидания KEY и decoder разделены; логи показывают inputs/decoded/shown, рабочие slots, inflight и decoderLeadUs.
Короткие audio gaps заполняются Opus PLC, большой разрыв сбрасывает timeline.
Локальный preview использует обычную подписку на собственный источник с отключённым воспроизведением
своего микрофона, чтобы исключить акустическую обратную связь. Локальный preview ориентируется по сенсору своей камеры
и текущему положению экрана; верх картинки зрителей отмечается красной гранью на кнопках поворота.
Положение камеры хранится per-revision отдельно от wire, чтобы queued кадры не использовали параметры новой камеры.
Ручной поворот сохраняет размеры и ориентацию локального превью; метка «Верх» на видео не рисуется.
Удалённый viewer применяет video rotation источника без локальной метки. Камера при закрытии preview продолжает работать.
Viewer закрывается на Activity ON_STOP и создаётся заново на ON_START; publisher от UI не зависит.
Локальный preview получает прямой Camera2 output в TextureView одновременно с encoder Surface.
Собственный источник не открывает viewer/cursor, decoder, AudioTrack и playback controller.
Preview ориентируется по сенсору камеры и текущему положению экрана; ручной поворот трансляции его не вращает.
Верх картинки зрителей отмечается красной гранью на кнопках поворота; метка «Верх» на видео не рисуется.
В обычном режиме preview выбирает поддерживаемый SurfaceTexture размер того же aspect, не более 1280x720;
high-speed использует размер encoder и createHighSpeedRequestList для двух targets с фиксированным FPS range.
Attach/detach preview меняет только CameraCaptureSession, сохраняя camera, encoder, audio, revision и origin.
При отказе дополнительного output логируется ERROR, UI показывает ошибку preview, камера возвращается к encoder-only session.
TextureView возвращает false из onSurfaceTextureDestroyed; UI, очередь команд camera thread и camera sessions
держат отдельные ссылки. Surface/texture освобождаются после последнего onClosed/onConfigureFailed и ухода UI.
Логи direct preview показывают first frame, FPS, возраст frame по SurfaceTexture timestamp и поворот;
camera session logs показывают generation, outputs, размер preview и сохранённый encoder/origin.
Удалённый viewer применяет video rotation источника. ON_STOP закрывает viewer либо отсоединяет прямой preview;
ON_START создаёт output заново. Камера при закрытии preview продолжает работать; publisher от UI не зависит.
Видимый player удерживает экран включённым. Preview ограничен оставшимся местом, кнопки управления не перекрывает.
- Source list общий для Android/desktop: stream_sources_json в uasync использует stream_member_load
и stream_member_online. stream_watch_sources наблюдает один выбранный канал; group=0 снимает наблюдение.
@ -880,7 +887,7 @@ Kotlin progress — DEBUG раз в секунду; C packet-level диагно
Android H264AnnexBTest (Annex B/length-prefixed NAL, SPS/PPS/IDR и усечённые данные),
StreamCameraModesTest (точный режим новой камеры, снижение FPS и fallback 720p30),
StreamOrientationTest (четыре положения переднего/заднего сенсора, включая SENSOR_ORIENTATION=0),
StreamPreviewTest (независимое превью, верх передней/задней камеры, экран и camera switch при queued frames).
StreamPreviewTest (поворот прямого preview по сенсору/экрану и lifetime Surface при смене session/уничтожении UI).
Ручной поворот без изменения размера также проверяется test_android_stream с непрерывным аудио.
C-тесты проверяют новую revision, потерю первого KEY, stale revision, сохранение аудио и source_epoch.
Проверка 2026-10-12 на SM-A525F / LineageOS 23.2-20260622-NIGHTLY-a52q:

Loading…
Cancel
Save