5.15.5
Fixed
Unbounded aggregate memory growth in SubtitlePacketStore (#166)
On sources with many embedded subtitle tracks, process memory could climb without bound during normal VOD playback until the iOS host hit the jetsam limit and was killed.
Root cause. The store capped retained compressed subtitle packets at 32MB per stream (perStreamByteCap), but the pump tap and the forward prefetcher both harvest every embedded subtitle stream into the session store, so a track switch backfills instantly without a side demuxer (#112). Nothing bounded the sum across streams. A source with many tracks (99 in the field repro, mostly bitmap/PGS) had each stream independently climb toward its own 32MB ceiling, driving heap allocations toward N x 32MB (~3.2GB). The reporter's own memprobe telemetry showed mallocMB tracking subTracks, not playback time or bytes downloaded, and the process eventually jetsam-killed.
Fix. The store now enforces an aggregate byte budget (aggregateByteCap, 96MB) across all streams in addition to the per-stream cap:
- The active drain targets (primary + secondary subtitle selection) are protected, so a switch back to them still backfills from a full per-stream window.
- The coldest (least-recently-touched) non-protected streams evict oldest-first once the aggregate budget is exceeded.
- Total retained bytes are tracked incrementally (O(1) per append); a monotonic touch counter (no wall clock) orders eviction.
- The engine keeps the store's protected set in sync with the active subtitle selection on every change and re-asserts it on each drain tick.
The instant-switch behavior of #112 is preserved for the common case (a handful of tracks, or the tracks you actually switch between); only cold, long-untouched non-selected streams on pathological many-track sources are evicted, and they re-harvest from the pump / prefetcher if selected later.
Reported by Enoch Abiodun (iPhone 16 Pro Max, iPadOS 26.5.1 iPad 10th generation; 99-track source). Covered by Issue166AggregateByteCapTests (aggregate bound, protected-stream survival, coldest-first eviction, re-warm ordering, per-stream regression, and engine protection wiring). Full suite 848 tests green; strict-concurrency=complete and tvOS Simulator builds clean.
Full Changelog: 5.15.4...5.15.5