fix(telemetry): meter both bitrate fields over the media played, not the transfer (#514) - #666
Merged
Merged
Conversation
…the transfer (#514) Round one fixed the divisor of averageBitrateMbps; the reporter's retest showed the numerator was the other half of the same defect. Both fields were metered from demuxerBytesFetched, the reader's transfer counter, which parts from playback on every route that reads ahead: VOD prefetch and seek re-fetches counted as they arrived (a 20 Mbps stream read about 35), and a paused live session kept draining its origin into the DVR window (AE#443) while the divisor stood still, so its average climbed for as long as the pause ran. The pumps now record the played video and audio packets by presentation time into a PlayedMediaLedger (native producer next to the recording tap, software host after its timeline fold), and PlayedBitrateMeter charges what the playhead crossed on the same source axis: AVPlayer's clock plus the playlist shift on native, the synchronizer's source clock on software. A pause and a seek charge nothing, a re-fetched range is held once, and a span the ledger holds nothing for stays unmeasured (nil) rather than reading zero. The transfer stays in networkThroughputMbps and [LagDiag]; the remote-HLS bypass keeps its declared rates. Measured with aetherctl over HTTP, pause at 12 s, seek at 15 s: - native 18.2 Mbps H.264: main avg 723 -> 103 -> 52, fix 18.4 to 19.0 - software 8.9 Mbps VP9: main avg 385 -> 54 -> 26, fix 8.8 to 9.5 Live 8.17 Mbps TS, DVR 300 s, paused 50 s: - main avg climbs 23 -> 64 (native), 29 -> 71 (software) - fix holds 8.12 / 8.07 through the pause, 8.0 after Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Round two of #514, from the reporter's retest on Sodalite 1.0.0 (41).
Cause
Both
instantBitrateMbpsandaverageBitrateMbpswere metered fromdemuxerBytesFetched, the reader's transfer counter. Round one fixed the average's divisor; the numerator was the other half of the same defect. Transfer and playback part ways on every route that reads ahead:Fix
PlayedMediaLedger: the pumps record the played video and audio packets by presentation time on the source axis (native producer next to the recording tap, software host after its timeline fold, both loops). Exact duplicates are held once, a re-read from far behind drops the stale lead.PlayedBitrateMeter: each sampler tick charges the packets the playhead crossed since the last one, over the media seconds it crossed. A pause does not move the playhead, a seek (a step no playback rate can explain) charges nothing, and a span with no recorded bytes stays nil instead of reading zero.playlistShiftSecondson native (notsourceTime, which is the item axis on a sequential origin), the synchronizer's source clock on software.networkThroughputMbpsand[LagDiag]. The remote-HLS bypass keeps its declared rates.Verification
aetherctl playover a threaded HTTP origin,mainagainst this branch:swift test: 646 XCTest (1 skipped) and 3584 swift-testing tests green. tvOS build green.Issue514AverageBitrateTestsnow covers the reporter's four cases, seek plus re-fetch, and an off-axis playhead.🤖 Generated with Claude Code