Files
SleppyOwl/docs/research/README.md
StenFredd b077388b74 Add documentation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:23:58 +03:00

8.6 KiB
Raw Blame History

Исследование движков воспроизведения (начало проекта, 2026-10-11…12)

Это исследование сделано до написания кода: по исходникам, issue-трекерам, Maven и дампу тестового ТВ. Часть выводов потом подтвердилась на реальном телевизоре, часть оказалась неверной. Что изменилось после тестов, сказано в конце этого файла, а итог описан в ../playback.md.

Файлы

Файл О чём
decisions.md Принятые решения: гибридный движок, выбор движка, fallback, тестовый ТВ, что проверить прототипом (часть 7 общего jellyfin-client-research.md)
media3.md media3/ExoPlayer: Dolby Vision, HDR, tunneling, частота дисплея, passthrough, FFmpeg, ASS (libass), контейнеры, DeviceProfile из jellyfin-androidtv
engines.md Как устроены несколько движков в других клиентах (Findroid, Wholphin, JellyPlay, Swiftfin, Plezy, Kodi…), дизайн абстракции, Gradle-модули, libVLC против libmpv, алгоритм выбора, runtime-fallback
device-xiaomi.md Тестовый ТВ Xiaomi S Pro Mini LED 75 и семейство MediaTek: известные баги декодеров, DV, passthrough, чек-лист проверок
library-profile.md Профиль медиатеки тестового сервера: какие контейнеры, кодеки, HDR, аудио и субтитры встречаются и сколько
tv-dump/ Сырые дампы ТВ: media_codecs-mt5896.xml, dumpsys display, audio_policy

Полный исходный документ со всеми частями (Jellyfin API, обзор клиентов, libVLC, Android TV, инструменты): jellyfin-client-research.md.

Главное из исследования

Цель — воспроизводить всё, что можно, без серверного транскода и с правильным HDR и Dolby Vision. Официальный клиент Jellyfin, Moonfin и Dune на этом ТВ спотыкались каждый на своих файлах: транскодировали, давали тусклый HDR или зависали.

  1. Одного движка недостаточно.
    • media3/ExoPlayer — единственный путь к аппаратному декодированию с HDR10, HDR10+, HLG и DV, а также к passthrough. Но он не открывает M2TS, ASF/WMV, ISO/BDMV, MKV со сжатием zlib, не умеет программно H.264 Hi10P, VC-1, MPEG-4 ASP и не рисует ASS сам.
    • libVLC и libmpv играют почти всё через ffmpeg, но HDR у них ненадёжен.
    • Отсюда гибрид: media3 основной, libVLC запасной.
  2. Запасным выбран libVLC 3.7.x, а не libmpv.
    • Это официальный артефакт VideoLAN со стабильным Java API, внутри libass, PGS и VobSub, есть passthrough.
    • Стоковый mpv-android переводит HDR в SDR через GLES, а AAR у него неофициальный.
    • Цена libVLC — +24–55 МБ на ABI.
  3. Автоматический выбор движка до запроса PlaybackInfo. Данные файла от Jellyfin (контейнер, кодек, битность, VideoRangeType, профиль DV, дорожки) сравниваются с возможностями устройства (MediaCodecList, HDR-типы дисплея, AudioTrack.isDirectPlaybackSupported). У каждого движка свой DeviceProfile.
  4. Runtime-fallback по образцу Plezy. Если движок упал, завис или не дал кадра, сессия переходит на другой движок с той же позиции; если не справился и он — серверный транскод. Среди Jellyfin-клиентов такого нет ни у кого.
  5. Архитектура:
    • свой узкий интерфейс PlaybackEngine плюс интерфейсы-возможности (задержка звука, стиль субтитров и т. п.);
    • каждый движок — отдельный Gradle-модуль, подключается через Hilt @IntoSet (позже DI перевели на Koin);
    • реализация движка «как media3 Player» (Findroid, Wholphin) приводит к десяткам TODO(), поэтому так не делаем.
  6. Риски, найденные заранее:
    • DV P7 в media3 без DV-декодера не откатывается на HEVC;
    • DV + HDR10+ зависает на MediaTek (#1895);
    • HEVC-декодер MTK падает посреди потока (#3421), и setEnableDecoderFallback это не ловит;
    • вечная буферизация при AC3 passthrough после быстрых перемоток (#3407);
    • TrueHD и DTS-HD из приложения на встроенных динамиках, скорее всего, не выйдут в passthrough;
    • смену частоты и HDR-режима media3 сам не делает.
  7. Тестовый ТВ (дамп через adb):
    • MediaTek MT9689, Android 14, только 32-bit userspace (armeabi-v7a), 2,4 ГБ RAM;
    • один режим дисплея 4K@60;
    • дисплей заявляет DV, HDR10, HDR10+ и HLG;
    • аппаратные AVC/HEVC/VP9/AV1 до 8K, MPEG-2/VC-1/MPEG-4 до 1080p.

Что тесты потом опровергли или уточнили

Ожидание из исследования Как оказалось на ТВ
DV P7 есть в железе (по XML-дампу) В рантайме MediaCodecList не показывает dvhe.dtb (P7). Наличие в XML не гарантирует наличие в API
H.264 Hi10P — только программно (libVLC) c2.mtk.avc.decoder заявляет High10 и играет Hi10P аппаратно
DV + HDR10+ виснет на MediaTek (#1895) На этом ТВ играет без зависаний, и с DV-декодером, и как базовый слой
DV-декодер даёт «тусклую» картинку ТВ действительно включает режим Dolby Vision (значок, DispService Hdr Dolby). «Тускло» — это режим изображения DV в настройках ТВ, а не поломка. DV-декодер включён по умолчанию
Смена частоты нужна вручную (preferredDisplayModeId) Android видит один режим 4K@60, но на аппаратном видеослое ТВ сам переключает панель: 23,976 → 119,88 Гц, 25 → 100 Гц. Через GPU-путь (TextureView) этого нет
HTTPS для libVLC достаточно проверить на самоподписанном сертификате libVLC (GnuTLS) через reverse proxy ненадёжен даже с нормальным сертификатом: зацикливается prefetch, перемотка к концу файла ждёт по ~10 с. Решено локальным HTTP-прокси внутри приложения
VLCVideoLayout и libVLC — вопрос API Главные проблемы VLC оказались в звуке (многоканальный PCM на этом ТВ беззвучен) и в сетевом кэше (prefetch выбрасывает прочитанное)
VC-1 через media3, если есть декодер Декодер зарегистрирован как MIME video/VC1 (регистр!), а media3 ищет video/wvc1
Аппаратное декодирование в libVLC — по умолчанию Опрос MediaCodec модулем VLC на MediaTek длится ~45 с. Аппаратно в VLC включаем только для видео больше 1080p