Skip to content

fix(software): don't treat an empty read-ahead buffer as the end of the file - #811

Open
williamliu0516 wants to merge 2 commits into
superuser404notfound:mainfrom
williamliu0516:fix/readahead-empty-store-eos
Open

williamliu0516 wants to merge 2 commits into
superuser404notfound:mainfrom
williamliu0516:fix/readahead-empty-store-eos

Conversation

@williamliu0516

Copy link
Copy Markdown
Contributor

What

On the software path, a read that finds the read-ahead buffer empty now waits and tries again instead of reporting the end of the file. Only the file's real end stops playback.

Why

When you seek to a spot that isn't cached, the buffer is cleared and refilled from the new position. A read that happens right in that gap found it empty and was taken as "end of file", so playback stopped right after the seek. It shows up most with DVDs, because their seeks finish almost instantly.

Test plan

MacBook Pro (M1 Pro), macOS 26.6, Xcode 27, a test DVD with six seeks per run:

  • Before: 7 of 8 runs stopped after the first seek.
  • After: 0 of 8; all 48 seeks kept playing.
  • A new test fails without the fix and passes with it. Other tests are unchanged.

…y when the source ended

A seek that misses the packet cache empties the store while holding
`operations`. A consumer read that began inside the seek's window left
its wait at once (its reader was not current yet), then waited for
`operations`. When it got the lock the seek had landed and the reader
was current again, so the admission check passed, the store was empty,
and `read` returned nil. The demux loop takes nil for end of stream:
playback parked at the landing as "end of media".

DVD-Video hits it most, as its IFO time-map seek settles at once. On a
MacBook Pro (M1 Pro), aetherctl playing a test disc with six seeks into
other cells, each missing the cache, ended at the landing of its first
such seek in 7 of 8 runs (7 of 13 cache-miss seeks). `read` now reports
the end only when the producer has seen the source's own end; an empty
store before that throws `.interrupted`, which the demux loop already
treats as "read again" (it then waits for the refill). With the fix,
0 of 8 runs ended: all 48 cache-miss seeks landed and played on.
Conflict only in CHANGELOG.md: the fix's entry moves under the current
[Unreleased] Fixed list. SoftwarePacketReadAhead.swift is unchanged
upstream since the branch point, so the fix applies as it was.
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