Skip to content

feat: compute-aware ABR feedback for Shaka and dash.js plugins#137

Merged
privaloops merged 1 commit into
mainfrom
feature/127-compute-aware-abr
May 29, 2026
Merged

feat: compute-aware ABR feedback for Shaka and dash.js plugins#137
privaloops merged 1 commit into
mainfrom
feature/127-compute-aware-abr

Conversation

@privaloops

Copy link
Copy Markdown
Owner

Adds a segment-level perf bus on which SegmentTranscoder publishes a
SegmentPerfStat (speedX = segDurMs / totalMs, width, height, frames)
for every successfully transcoded segment. A new ComputeAwareDecider
rolls those measurements through a hysteresis window and emits
subtractive cap decisions (lower / raise / hold). Player-specific
adapters wire the decider to each player's ABR knobs:

  • Shaka: handle.attachComputeAware(player, opts?) -> player.configure
    with abr.restrictions.maxHeight + maxBandwidth caps
  • dash.js: attachHevcSupport accepts adaptiveCompute -> updateSettings
    on a maxBitrate cap

ON BY DEFAULT. Bandwidth-based ABR has no way to observe transcode
cost, so a perfectly reachable variant can still saturate the device's
CPU. Default opt-in matches the actual cost shape of this library;
pass adaptiveCompute: false to opt out.

Defaults tuned for the compute-aware shape:

  • measureWindow: 2 (was 8)
  • lowerAfter: 1 (was 2) — buffer underrun is much worse than a brief
    unnecessary cap dip, so the decider reacts in ~2 segments instead of
    waiting for an 8-window average
  • raiseAfter: 6, targetSpeedX: 1.3 (unchanged — still need real
    hysteresis on the raise side)

attachComputeAware(player, opts?) merges register-time options with
runtime options — convenient when the telemetry sink (onObservation)
is only known once the UI exists. onObservation now receives the
decision reason (init | hold | lower | raise) for richer diagnostics.

The decider snapshots state before each decision so applyCap failures
(player destroyed, etc.) can be reverted in-band. Cold-start guard
prevents raising before any lower has happened.

Both plugins re-export subscribeSegmentStat + SegmentPerfStat from
@hevcjs/core for custom telemetry on the raw perf bus.

Demos wired with a compute-aware live overlay (active quality + segment
speedX + cap + reason) and a diagnostic perf-bus probe. README +
per-package READMEs + site docs updated.

Closes #127

Adds a segment-level perf bus on which SegmentTranscoder publishes a
SegmentPerfStat (speedX = segDurMs / totalMs, width, height, frames)
for every successfully transcoded segment. A new ComputeAwareDecider
rolls those measurements through a hysteresis window and emits
subtractive cap decisions (lower / raise / hold). Player-specific
adapters wire the decider to each player's ABR knobs:

- Shaka: handle.attachComputeAware(player, opts?) -> player.configure
  with abr.restrictions.maxHeight + maxBandwidth caps
- dash.js: attachHevcSupport accepts adaptiveCompute -> updateSettings
  on a maxBitrate cap

ON BY DEFAULT. Bandwidth-based ABR has no way to observe transcode
cost, so a perfectly reachable variant can still saturate the device's
CPU. Default opt-in matches the actual cost shape of this library;
pass adaptiveCompute: false to opt out.

Defaults tuned for the compute-aware shape:
- measureWindow: 2 (was 8)
- lowerAfter: 1 (was 2) — buffer underrun is much worse than a brief
  unnecessary cap dip, so the decider reacts in ~2 segments instead of
  waiting for an 8-window average
- raiseAfter: 6, targetSpeedX: 1.3 (unchanged — still need real
  hysteresis on the raise side)

attachComputeAware(player, opts?) merges register-time options with
runtime options — convenient when the telemetry sink (onObservation)
is only known once the UI exists. onObservation now receives the
decision reason (init | hold | lower | raise) for richer diagnostics.

The decider snapshots state before each decision so applyCap failures
(player destroyed, etc.) can be reverted in-band. Cold-start guard
prevents raising before any lower has happened.

Both plugins re-export subscribeSegmentStat + SegmentPerfStat from
@hevcjs/core for custom telemetry on the raw perf bus.

Demos wired with a compute-aware live overlay (active quality + segment
speedX + cap + reason) and a diagnostic perf-bus probe. README +
per-package READMEs + site docs updated.

Closes #127
@github-actions

Copy link
Copy Markdown
Contributor

Benchmark Results (GitHub Actions runner)

Resolution FPS ms/frame
1080p (50f) 36.5 fps 27.4 ms/frame
4K (25f) 10.4 fps 96.2 ms/frame

Note: GitHub Actions runners (2-core x86) are ~2-3x slower than Apple Silicon.
These numbers are for regression detection, not absolute performance.

Auto-generated by CI benchmark

@privaloops privaloops merged commit 8a2c2df into main May 29, 2026
19 checks passed
@privaloops privaloops deleted the feature/127-compute-aware-abr branch May 29, 2026 15:20
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.

Compute-aware ABR feedback for the Shaka (and dash.js) plugin

1 participant