Skip to content

fix(cache): publish retained software VOD resident ranges - #759

Open
orut34iop wants to merge 3 commits into
superuser404notfound:mainfrom
orut34iop:codex/fix-software-vod-resident-ranges
Open

orut34iop wants to merge 3 commits into
superuser404notfound:mainfrom
orut34iop:codex/fix-software-vod-resident-ranges

Conversation

@orut34iop

@orut34iop orut34iop commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Software VOD can retain substantial compressed-packet history and satisfy backward/forward seeks from its disk FIFO, but AetherEngine.residentRanges is only populated by the native segment-cache observer. A host that draws its cache band from this public property therefore sees no software cache coverage.

Using [currentTime, bufferedPosition] as a host fallback is insufficient: bufferedPosition is a continuous forward frontier, not evidence of a resident start. Moving the playhead moves the inferred start, and a backward scrub can leave that inferred range even though the packets are still retained. In a target-filtering timeline, that produces a disappearing/reappearing cache band.

This PR publishes software VOD residency through the existing residentRanges contract, on the same display timeline as currentTime and seek(to:).

Implementation

Derive ranges from packet evidence

  • Expose presentation-time spans from SoftwarePacketCoverage with exact integer-to-seconds checks. Invalid/inexact timestamps do not manufacture coverage.
  • Reuse SoftwareVideoPacketCoverage's verified successor-PTS intervals for H.264/HEVC. Preserve reordering, discontinuities, invalidation and the unknown end of the final picture.
  • Intersect video with the selected audio stream when audio is present, including when muted. Video-only playback does not require an audio range; missing selected-audio coverage does not become video-only coverage.
  • Keep gaps as separate spans instead of extending a single high-water mark across them.

Respect actual disk retention

  • Track bounded per-chunk timestamp summaries, rather than retaining a per-packet in-memory index or reading packet files for UI updates.
  • When whole chunks are evicted, accumulate discarded video/audio end timestamps and conservatively clip the published ranges. This matters for reordered PTS: the timestamp of the first surviving packet alone cannot prove an earlier picture is still retained.
  • Require an eligible retained video keyframe and clip against the audio discard floor. Metadata pressure can shorten the reported history; it cannot enlarge coverage or change the FIFO's retention policy.
  • Publish no ranges for a closed/reset/repositioning/failed store or a FIFO without retained history.

Publish without tying residency to the playhead

  • Copy bounded coverage metadata under the existing state lock, then perform conversion, intersection and keyframe selection in a background task. No disk reads or range calculation are added to the main actor.
  • Sample from the existing periodic host timer, including while paused, and map source timestamps to the session's display origin before publication.
  • Coalesce periodic sampling and reject delayed results after seek/stop invalidation. Check host identity, load generation and time-origin ownership before applying the result.
  • A cache hit preserves the resident spans throughout the seek. A miss clears them at the discard decision; teardown clears them as well.

The public property's type is unchanged. Native segment-cache and live-window behavior stay separate. This patch does not change decode routing, source reads, download policy, disk budgets, seek admission, or dependency versions.

Synthetic example

For a video-only store holding [0, 4] seconds, moving the clock or committing cached seeks to 3, 1, 2.5 and 0.5 seconds continues to publish [0, 4]. A cold seek outside the store clears it. With video coverage [0, 4] and selected audio islands [0.5, 1] and [2, 3], the published spans are exactly those two intersections.

These are synthetic packet-test values, not excerpts from a playback session.

Regression coverage

SoftwareResidentRangesTests.swift covers:

  • forward and backward cached seeks through begin/prepare/settle, followed by a miss and close;
  • selected-audio intersections, holes and missing audio;
  • reordered successor PTS, discontinuities, invalidated ordering and no invented final-frame end;
  • real FIFO eviction while verifying all consumed packet envelopes remain byte-identical;
  • discarded reordered timestamps, bounded metadata, overflow and reset;
  • nonzero display origins, negative clipping and unknown origins;
  • delayed publication, coalesced ticks, main-actor progress while a sample is suspended, and stale-result rejection after invalidation/replacement;
  • paused growth, eviction and reset without a playback-clock tick.

Tests use generated packet envelopes, temporary FIFOs and controlled asynchronous publication. They require no media files, network server, account or playback logs. Waiting follows the shared waitFor helper, and the blocking FIFO consumer runs on a dedicated thread with cancellation closing the source.

Validation

CI follow-up (2026-10-13): The first full macOS CI run executed 4,355 tests and reported one issue: the source-wide rule requiring BlockingWork.detached found the newly added bare detached task in the residency publisher. Commit 761b031b switches that call to the upstream blocking executor. The equivalent source scan now passes; the updated commit has been pushed for a fresh full CI run, including the one-thread cooperative-pool lane. The focused local results below describe the preceding revision; they are not a claim that this fresh CI run has completed.

On the PR branch based on upstream main at 833a9f1:

  • SwiftPM build, including test targets and the compiled examples: passed.
  • 91 focused tests across 12 suites passed, including the 10 new residency/publication tests, existing native resident-range tests, software coverage/read-ahead/QoS regressions, and API/constant documentation checks.
  • python3 Scripts/check-doc-links.py: all relative links and anchors in the six published documents resolve.
  • git diff --check: passed. Package.swift and Package.resolved are unchanged.

The focused selection can be reproduced with:

swift test --filter 'SoftwareResidentRange|ResidentRangesTests|ResidentSpanTests|Issue613PacketCoverageTests|Issue592CoverageFrontierTests|SoftwarePacketReadAheadParkTests|Issue276RetainedCoverageTests|Issue303SoftwareReadAheadTests|Issue605SoftwareVODStillTests|PublicAPIDocumentationTests|DocumentedConstantsTests|Issue519ReadAheadQoSTests|Issue318CoverageCrossingTests'

Local execution used the native SwiftPM build system and explicitly signed the host test bundle with a valid Apple Development identity. No full-suite result is claimed.

The corresponding downstream fix was separately built, signed, installed and accepted by the tester on Apple TV 4K (3rd generation), tvOS 27.2 beta. The reported backward/forward scrubbing and cache-band flicker issue passed that physical check. This is downstream integration evidence; it is not a claim that an app built from this exact upstream-base PR was installed or that the entire upstream suite/device matrix passed.

No media titles, filenames, URLs, screenshots, playback positions, account details, device identifiers or raw session logs are included in this PR.

Documentation and review scope

  • Update docs/api.md to describe software residency and distinguish it from the forward frontier.
  • Add an Unreleased changelog entry.
  • Base the contribution on upstream main, carrying only this cache metadata/publication change and its tests/docs. Application-specific timeline code and unrelated downstream changes are excluded.

Residency remains a conservative observation, not a guarantee of instant seek/decode. Bounded metadata and missing/invalid timestamps may under-report retained bytes; the implementation deliberately does not fill unknown coverage from byte counts, bitrate or a historical maximum.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant