Skip to content

feat(stills): scrub stills on the software VOD path from the packet cache (AE#605) - #607

Merged
superuser404notfound merged 1 commit into
mainfrom
feat/605-sw-vod-scrub-stills
Sep 23, 2026
Merged

superuser404notfound merged 1 commit into
mainfrom
feat/605-sw-vod-scrub-stills

Conversation

@superuser404notfound

Copy link
Copy Markdown
Owner

Part of #605 (the first of its two gaps; the second is discussed on the issue).

What

A software VOD session already spools its packets to a disk cache with keyframe cursors, and its seeks land in that cache (#512/#519), but scrubThumbnail had no arm for it. On a source that refuses a second request, the FrameExtractor fallback cannot open either, so every VOD the device cannot hardware-decode scrubbed blind.

Verification

  • 9 new tests (Issue605SoftwareVODStillTests): the history walk across chunks, early stop, stale and evicted cursors, run shape, consumer cursor untouched, refusal past the frontier, span bound, packet bound.
  • swift test: 629 XCTest / 0 failures, 3356 swift-testing in 453 suites passed.
  • aetherctl play --sw --host-calls still (new VOD arm) on a 300 s 720p H.264 testsrc fixture over a threaded HTTP range origin:
    • before: supportsCacheBackedStills -> false, 0 of 3
    • after: -> true, 2 of 3. 4.37 s decodes the frame showing 4 (mid-GOP, not snapped to the keyframe) in 53 ms, 24.37 s decodes 24 in 41 ms. The aim 600 s past the frontier misses as designed.
    • playback during the stills: the clock advances 1.00 s per tick, rx stays flat (no network), and the drop counter matches the before arm.

🤖 Generated with Claude Code

https://claude.ai/code/session_014AVNwe8YDG9EQM7uHdjT3f

…ache (AE#605)

A VOD session the device cannot hardware-decode already spools its packets to a
disk cache with keyframe cursors, and its seeks land in that cache, but
scrubThumbnail had no arm for it and supportsCacheBackedStills was keyed on the
native segment cache alone. On a source that refuses a second request (an IPTV
account capped at one connection, a debrid link) the FrameExtractor fallback
cannot open either, so every such session scrubbed blind.

The still now comes out of that cache. SoftwarePacketDiskFIFO gains a history
walk from a cursor on handles of its own, so the consumer's reader never moves;
SoftwarePacketReadAhead plans the run (newest keyframe at or before the target,
video only, through the target plus a reorder tail) under the cached seek's own
eligibility rule; SoftwareStillExtractor replays the stored packets with their
full envelope. It runs on the #544 still queue with the same newest-wins ticket
and the same lazily built extractor. A target past what is retained answers nil
rather than the frame before it.

supportsCacheBackedStills is now true for a software VOD session reading a
remote source and for a software live session, which already served stills but
reported false. A local file keeps no cache and stays false.

aetherctl play --sw --host-calls still gains a VOD arm. On a 300 s H.264 fixture
over HTTP: before 0 of 3, after 2 of 3 (4.37 s shows 4, 24.37 s shows 24, in
53 and 41 ms, no network), and the aim 600 s past the frontier misses as it must.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014AVNwe8YDG9EQM7uHdjT3f
@superuser404notfound
superuser404notfound merged commit d741996 into main Sep 23, 2026
7 checks passed
@superuser404notfound
superuser404notfound deleted the feat/605-sw-vod-scrub-stills branch September 23, 2026 02:56
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