Commit Graph
20 Commits
Author SHA1 Message Date
edde746 8f893e7a67 fix(player): demux Android direct play with media3 again
The in-app FFmpeg container demuxer classified every DTS variant as
plain DTS (profile-blind MIME mapping at the demux boundary), so
DTS-HD MA lost its lossless identity downstream, and it ignored
container display-aspect-ratio overrides. media3's extractors get both
right.

Delete the FFmpeg demuxer (JNI, extractor, and its setting); ExoPlayer
direct play demuxes with media3's DefaultExtractorsFactory again, and
mpv - the Android default - reads container display dimensions itself.

close #2124
close #2115
2026-08-26 18:59:28 +02:00
edde746 75c095a5b2 feat(player): demux direct-played containers with ffmpeg on Android
Direct play on Android kept accumulating container patches: AVI with
XviD packed-bitstream timestamps and missing VOL csd played broken,
ASF/WMV and MPEG-PS/VOB had no media3 extractor at all, and MKV needed
a custom extractor stack for zlib-compressed subtitles, LOAS/LATM
audio, cueless seeking, and font attachments.

Demux progressive containers with libavformat behind media3's
extractor API. An AVIO bridge serves libavformat from the
ExtractorInput: every position divergence defers into a RESULT_SEEK
round trip, header reads replay from a block cache while
avformat_open_input restarts, and avformat_seek_file executes seeks
with bounded loader round trips. Packets feed media3's TrackOutputs,
so decoders, passthrough carriers, Dolby Vision RPU/EL conversion
(dvh1 codecs string surfaced from DOVI side data), and the subtitle
pipeline are untouched: embedded fonts feed AssHandler over JNI, ASS
reaches libass as per-sample dialogue, SRT/VTT render as cues, VobSub
maps through media3's VobsubParser, and LOAS/LATM AAC unwraps via
LatmTrackOutput.

Under the default Auto preference FFmpeg demuxes AVI, ASF/WMV,
MPEG-PS, and Matroska/WebM and sits behind media3's list as an
any-container fallback; MP4/TS keep media3's extractors. A playback
setting exposes auto / FFmpeg first / media3 only, and the JNI
load-failure path falls back to stock media3. The custom Matroska
extractor stack and its reflection keeps are retired.

Verified on Pixel 7 (API 36), Box R 4K Plus TV (API 34), and SHIELD
TV (API 30): instrumentation playback suites, the minified R8
reachability gate, and an on-device container matrix with forward and
backward seek landings plus visual subtitle checks.

close #2052
2026-08-23 01:22:24 +02:00
edde746 eaccef33dc fix(subtitles): clear a displayed ASS cue immediately when subtitles are disabled
Turning subtitles off (or hiding them) while an ASS/SSA cue was on screen left
that cue painted until its natural end time on the ExoPlayer backend: AssHandler
nulls the libass track, after which every render returns null, no payload ever
reaches the GL thread again, and the overlay keeps its last swapped atlas. The
existing invalidateSubtitles() call from the #1387 fix could never repaint it.

The atlas pipeline now detects a trackless render request and hands the GL
thread one zero-quad payload, which clears and swaps a transparent frame. The
clear is keyed on the renderer state generation so one dropped as stale is
retried, and it self-heals from per-video-frame requests while playing; the
existing invalidate on the disable transition covers the paused case.

close #1884
2026-08-16 12:42:04 +02:00
edde746 5a0b595466 fix(android): play MKV files with late track metadata
MKV files whose Tracks element follows media clusters could direct-play with audio but no video. Upgrade Media3 to 1.11.0 and cover the extractor regression.

close #1947
2026-08-15 19:08:00 +02:00
edde746 83c50d93a2 fix(subtitles): flatten atlas-overflow ASS frames into an RGBA composite
Signs built from hundreds of overlapping paint-stroke drawings (masked
smartphone screens and similar typesetting) sum to far more bitmap area
than the paged ALPHA_8 atlas can hold: the issue sample needs 5 pages of
16M px at 1080p and 19 at 4K against the 4-page cap, so the packer
dropped the painter-order tail - the sign's text and late mask strokes.

Move the packer out of the JNI file into AssPack.c (pure C, compilable
against a desktop libass for verification) and add a composite fallback:
when a frame can never fit MAX_ATLAS_PAGES pages or the vertex budget,
blend the image list CPU-side into one premultiplied RGBA rect over the
union bounding box - O(frame area) instead of O(sum of image areas) -
and draw it as a single quad through a new MODE_COMPOSITE path in the
GL renderer. Oversized composites reuse the existing grow-and-re-render
contract; the atlas fast path is byte-identical for every frame that fits.

Verified with a desktop harness compiling the shipped AssPack.c against
fork libass 0.18.3 and the issue sample: all atlas-mode frames byte-match
the previous packer, the sign's frames composite with zero truncation and
byte-match a reference full-frame blend at 1080p and 4K, and the
multi-page composite grow path round-trips.

close #1868
2026-08-11 08:41:56 +02:00
edde746 7c6eaac2d0 fix(android): render double-NUL ASS subtitles
close #1681
2026-07-26 04:24:56 +02:00
edde746 3c2a353d32 build(android): upgrade Gradle and Kotlin toolchain 2026-07-24 03:56:40 +02:00
edde746 9f2e050797 fix(native): bound cross-platform lifecycle ownership 2026-07-24 03:56:40 +02:00
edde746 e6e7d8cdfd test: remove redundant coverage and shorten timers 2026-07-13 02:15:03 +02:00
edde746 4a81246986 build(libass): bump fork to 0.18.3 2026-07-12 00:44:08 +02:00
edde746 d5df426ab6 build(libass): bump to 0.18.2 2026-07-02 11:41:24 +02:00
edde746 6c96830033 fix(android): never-drop multi-page subtitle atlas 2026-06-29 02:31:14 +02:00
edde746 ec1473af5e fix(android): tile oversized subtitle images so the atlas never drops them 2026-06-28 21:49:19 +02:00
edde746 120749e442 fix(android): regenerate libass prebuilt archive 2026-06-27 06:43:37 +02:00
edde746 e90835c234 fix(ci): restore sanity checks 2026-06-25 07:21:16 +02:00
edde746 c9dc15b1d8 fix(android): improve libass frame timing 2026-06-24 01:26:46 +02:00
edde746 edd0618e64 fix: harden playback and discover state 2026-06-14 09:44:04 +02:00
edde746 e1c0df3bd7 fix(ci): resolve sanity check failures 2026-06-14 06:55:58 +02:00
edde746 c89c88647e fix(android): package libmpv's NDK r29 libc++_shared.so deterministically 2026-06-12 01:51:51 +02:00
edde746 1adb89c6b3 feat(android): frame-accurate libass pipeline + optimized native core 2026-06-12 01:45:19 +02:00