perf: benchmark native and Cast startup, seeks, and sustained playback

This commit is contained in:
2026-10-17 01:44:57 +02:00
parent fcad96de62
commit e1284936f9
6 changed files with 572 additions and 2 deletions
+19 -2
View File
@@ -3,7 +3,7 @@
- we don't need every minute detail (already described perfectly by the code btw) described in painstakingly verbose paragraphs in the readme.
- implementation details are not appropriate in a readme file (without a very good reason to be there).
- the readme should be compressed to actually useful information - nothing more - and verbose, irrelevant, or redundant information deleted.
- [ ] evaluate playback optimization opportunities for YouTube and Miruro — measure benefits before changing behavior
- [x] evaluate playback optimization opportunities for YouTube and Miruro — measure benefits before changing behavior
- [x] coalesce superseded, not-yet-started seeks in the player and Cast controls; preserve accumulated relative skips and play/pause ordering
- [x] expand Cast H.264/AAC remux coverage with keyframe-aligned segments; preserve seek accuracy, timestamps and receiver compatibility
- [x] reuse decoder/encoder state during sequential Cast playback; reset on random seeks and preserve independent keyframes and AAC continuity
@@ -12,7 +12,24 @@
- M4, three paired 12s/720p/30 MP4 runs: H.264/HEVC/VP9 native decode process CPU fell 77/88/92%; Cast relay process CPU fell 48/58/68%, with generation 2–7% slower. Prefer these measured codecs; AV1 keeps dav1d. Unpaced native decoding is slower; H.264 seek preview rose from 1.8ms to 4.1ms. These are process CPU measurements, not energy measurements.
- `make check-video-decoding` covers native Metal upload, mapped-frame lifetime, exact seek/step/EOF, dependent-packet seek fallback, Cast independent IDRs/AAC, and unsupported codecs; `video-decoding-software-check` and `cast-media-software-check` provide matched baselines. Unsafe seek starts use software decoding (until reopen for native playback).
- Existing Cast millisecond-timestamp limiting drops VP9 MKV frames in the software baseline; a direct relay comparison confirmed VideoToolbox preserves the same output PTS/counts. This evaluation does not change that limiter.
- [ ] benchmark cold start, cached/uncached seeks and sustained playback separately to prioritize the actual bottlenecks
- [x] benchmark cold start, cached/uncached seeks and sustained playback separately to prioritize the actual bottlenecks
- `make benchmark-playback`: M4/16 GiB, macOS 27.0.1; three fresh-process samples per source/latency profile. Shared 120s/720p/30 H.264 B-frame + 48kHz AAC fixture, two-second GOPs; YouTube-shaped split MP4 and Miruro-shaped restricted six-second HLS. Added response delay is per request, not simulated RTT/bandwidth. No playback behavior changed.
| Added delay ms | Path | Cold ms | Cached seek ms | Uncached seek ms | Sustained wall s | Sustained process CPU s |
| ---: | --- | ---: | ---: | ---: | ---: | ---: |
| 0 | Native split | 374.93 | 21.15 | 26.58 | 12.20 | 0.81 |
| 0 | Native HLS | 473.42 | 28.88 | 225.08 | 12.22 | 0.80 |
| 0 | Cast split | 627.88 | 3.36 | 482.14 | 4.27 | 1.60 |
| 0 | Cast HLS | 715.66 | 3.79 | 492.37 | 4.16 | 0.77 |
| 25 | Native split | 406.77 | 20.96 | 127.40 | 12.30 | 1.05 |
| 25 | Native HLS | 920.65 | 40.56 | 245.96 | 12.23 | 0.87 |
| 25 | Cast split | 1251.29 | 3.55 | 1451.26 | 7.61 | 1.65 |
| 25 | Cast HLS | 662.73 | 1.97 | 521.57 | 4.50 | 0.72 |
- Medians above: native sustained is 12 media seconds with real muted audio and offscreen 720p Metal draws; Cast is unpaced generation of 60 media seconds after the first segment. Native cold includes queued autoplay to 53ms of acknowledged audio-clock progress and pause; Cast cold includes preparation, manifest and first six-second segment. Native hits seek to retained 20.5s; misses seek to 100.5s beyond retained coverage. Cast hits repeat segment zero; misses regenerate it after both segment-cache and packet-history eviction.
- Prioritize investigating native HLS random-seek preroll and Cast first-segment/random-seek generation, not more sequential codec tuning: native HLS misses remained 220–415ms without injected delay versus 21–74ms for split MP4; Cast's first segment took 552–915ms while preparation took 5–39ms, and sustained generation remained faster than playback. These are bottleneck candidates, not measured benefits of an unimplemented optimization.
- Memory/request baseline: median pre-validation lifetime peak RSS across profiles was 230–251 MiB native / 238–253 MiB Cast, including renderer/loopback-client overhead. Zero-delay cold windows transferred roughly 51–55 MiB, with 6/12 native and 7/12 Cast upstream requests for split/HLS; counts and bytes include concurrent read-ahead, so even a cache hit can show network activity. Keep existing cache/segment limits and origin/header checks.
- All 24 source sessions passed (96 phase rows): accurate native seek acknowledgements, cache preconditions, real audio-clock advancement, repeated Cast byte equality, and independently decodable Cast endpoint segments with expected frame counts/timestamps/AAC. Large timing spread (25ms-delay Cast split cold 703–1973ms) prevents causal latency/CPU comparisons; no persistence/segment-size benefit is claimed. Fresh process/source is not cold OS caches; process CPU is not total hardware energy. Resolver/CLI launch, live CDN/TLS, bandwidth limits, other codecs/remux, visual appearance and physical receivers are not measured.
- do not enable Miruro HTTP persistence without preserving origin/header checks, or increase caches/shorten Cast segments without measuring the memory/request/codec tradeoffs
- [ ] add playlist support
- maybe by allowing multiple file selection? 🤔