Skip to content

5.28.0 - Side reader link priority

Choose a tag to compare

@superuser404notfound superuser404notfound released this 28 Jul 21:08

The subtitle side reader and the video pump were competing for the same link, and on a link with little headroom the video path lost. Reported by cmcpherson274 (#240) with per-seek timings from a real device.

Fixed

  • Far seeks stop competing with the subtitle side reader for the source link. On Matroska a subtitle-only side reader is a second full copy of the stream: matroska_parse_cluster reads every block off the wire and only matroska_parse_block then honours the discard flag, so a session with subtitles on asks the link for roughly twice the media rate (2.6x measured in #220). Above about 2x headroom nobody notices. At 1.3x to 1.5x, an ordinary Wi-Fi bench in front of a high-bitrate remux, the two readers split the link and the video path misses its deadlines: the reporter measured the same segment serving in 2.2 s alone and 7.5 s alongside the prefetcher, which expired the seek landing budget, after which the recovery re-anchored, the clock jumped, the jump rebuilt the prefetch session, that took more link, and landings stacked to 25 s.

    The video path has priority now, as a rule rather than a share, because playback is load-bearing and subtitle lookahead is not. A seek in flight owns the link outright. A pump that is fetching outranks a side reader. A parked pump, which on a link with headroom is nearly all of the time, leaves the link to it. Two bounded escapes keep this from becoming a mute switch: a grace window after each anchor, so a freshly selected track fills even while the pump is busy, and a cap on continuous yielding, so a pump that never parks cannot silently disable lookahead for the rest of a session.

  • A playhead jump re-anchors the running prefetch session in place instead of rebuilding it. A rebuild pays a fresh demuxer open, the Matroska cue-index prewarm and a positioning seek, and since the bounded ranges of 5.24.0 each of those seeks takes a full range off the link, once per jump, on exactly the constrained link where a seek is already struggling. The running session already holds an open, positioned demuxer. Positioning is one shared function for both paths now, so an in-place move cannot drift from the session-start rules (#234).

Measured on a shaped bench (900 s Matroska at 8 Mbit/s, one SRT track, all connections sharing 1.4x the media rate, five far seeks 25 s apart, two runs per build): far-seek landings 23.5 s to 12.7 s at the median, source connections 35 to 21, and the side reader's share of the delivered bytes roughly halved. What remains is transfer geometry on a link that thin, not arbitration.

Added

  • Per-reader link attribution in the log. Every AVIOReader carries a label (pump, prefetch, nativesubs, extract), the connection-start line names it and reports its range length, and that line is no longer DEBUG-only. The 30 s memprobe reports pumpFetchedMB next to prefFetchedMB, plus the prefetcher's live state and cumulative link yield. Several readers against one origin were previously indistinguishable in a field log, and one reader walking forward in bounded ranges reads like several concurrent connections when nothing names it.
  • aetherctl play --seek-pattern a,b,c walks a list of absolute far-seek targets, one per --seek-every tick, and prints how long each seek(to:) took. The existing 6 s backward hop lands in the segment cache and never restarts the producer, so it exercises none of the machinery a far seek does.
  • Scripts/throttle-origin.py --shared shapes the sum of all connections instead of each one, which is what a real link does. With per-connection shaping two readers each get the full rate, so a contention defect cannot reproduce under it at all. --head MB sets how much of each body passes unshaped; set it to 0 when measuring a reader that fetches in bounded ranges.

No API changes. Hosts that drive HLSVideoEngine directly, without an AetherEngine, are unaffected: no gate is set, so the side readers behave exactly as before.