You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Split out of #295, where a ~100 ms blocked read on the demux thread turned into a visible picture stutter. The read defect is fixed. What is left is that nobody, including me, could say from a log how much cushion the software path had when it hit.
What actually bounds the read-ahead today
One thing, and it is not ours:
// SoftwarePlaybackHost.swift, runDemuxLoop
while !renderer.isReadyForMoreMediaData && !stopRequested() && !backgroundAudioOnly(){Thread.sleep(forTimeInterval:0.005)}
SampleBufferRenderer.isReadyForMoreMediaData forwards to AVSampleBufferVideoRenderer, whose fill policy is an AVFoundation heuristic. There is no target depth in seconds, no floor before playback starts, and no re-fill target after a stall. The 4-frame reorder buffer is for B-frame ordering and is not a cushion.
That may well be fine. The point is that it is unmeasured, so the question cannot be settled either way from a field trace.
Three signals that look like they answer it and do not
bufferedSessionTime / clock.bufferedPosition is the newest DEMUXED source PTS. It says how far the reader got, not how many decoded frames are waiting for the display.
[Renderer] isReadyForMoreMediaData=false at enqueue #N is latched to one line per session. It marks the first time the queue filled, which is normal and healthy, not that it stayed full.
So a session can show a full queue at enqueue #8, a healthy demuxed frontier, frameAhead=0.00s, and still drop frames from a 100 ms read, with nothing in the log distinguishing "the cushion was 40 ms" from "the cushion was 2 s and something else broke".
What would settle it
Seconds of decoded video actually queued for display: the enqueued-frame PTS frontier minus the synchronizer time, sampled in the periodic memprobe rather than only at milestones. That is the number that decides whether a given read block is survivable.
With those two, the design question underneath becomes answerable rather than a matter of taste: whether the software path should hold a floor of its own instead of inheriting whatever AVSampleBufferVideoRenderer happens to accept, and whether that floor should differ for a remote source and a local one.
No user-visible symptom is attached to this issue on its own. It is the instrument that was missing while #295 was open.
Split out of #295, where a ~100 ms blocked read on the demux thread turned into a visible picture stutter. The read defect is fixed. What is left is that nobody, including me, could say from a log how much cushion the software path had when it hit.
What actually bounds the read-ahead today
One thing, and it is not ours:
SampleBufferRenderer.isReadyForMoreMediaDataforwards toAVSampleBufferVideoRenderer, whose fill policy is an AVFoundation heuristic. There is no target depth in seconds, no floor before playback starts, and no re-fill target after a stall. The 4-frame reorder buffer is for B-frame ordering and is not a cushion.That may well be fine. The point is that it is unmeasured, so the question cannot be settled either way from a field trace.
Three signals that look like they answer it and do not
frameAheadisactiveProducerShiftSeconds - playlistShiftSeconds, the Clock/frame divergence accumulates under sustained seek rate (#35-class, #38 retest follow-up) #49 producer-shift fold on the native path, and it is 0 on software and audio by construction. In Software-path SD MPEG-2 (PAL 25i): intermittent brief picture glitches with no engine-log signature — first seen on 6.5.3, unchanged on 6.5.6 #295 it was read, reasonably, as "the software path runs with no read-ahead". It cannot support that claim in either direction, and the name invites exactly that reading.bufferedSessionTime/clock.bufferedPositionis the newest DEMUXED source PTS. It says how far the reader got, not how many decoded frames are waiting for the display.[Renderer] isReadyForMoreMediaData=false at enqueue #Nis latched to one line per session. It marks the first time the queue filled, which is normal and healthy, not that it stayed full.So a session can show a full queue at enqueue #8, a healthy demuxed frontier,
frameAhead=0.00s, and still drop frames from a 100 ms read, with nothing in the log distinguishing "the cushion was 40 ms" from "the cushion was 2 s and something else broke".What would settle it
With those two, the design question underneath becomes answerable rather than a matter of taste: whether the software path should hold a floor of its own instead of inheriting whatever
AVSampleBufferVideoRendererhappens to accept, and whether that floor should differ for a remote source and a local one.No user-visible symptom is attached to this issue on its own. It is the instrument that was missing while #295 was open.