/** * Compute-aware ABR decider — player-agnostic. * * Maintains a rolling window of per-segment `speedX = segDurMs / totalMs` * measurements and decides whether the variant cap should move up, down, * or stay put. Hysteresis (different counters + a wider raise threshold * than the lower threshold) prevents the cap from oscillating. * * Plug into a host player (Shaka, dash.js) by: * 1. Subscribing to `perf-bus.subscribeSegmentStat`. * 2. On each stat, calling `decider.observe(stat.speedX, currentVariantIdx)`. * 3. When the returned `reason` is "lower" or "raise", applying * `decision.capIndex` to the player via its public restriction API. * * The decider knows nothing about heights, bandwidths, or the host player. * It works purely on a ladder represented as `0..ladderSize-1` (ascending * by quality). The adapter is responsible for the mapping in both directions. */ export interface ComputeAwareConfig { /** Require this much headroom over real-time before raising the cap. Default 1.3 (= 30% headroom). */ targetSpeedX?: number; /** Number of consecutive `avg > targetSpeedX` windows before raising. Default 6. */ raiseAfter?: number; /** Number of consecutive `avg < 1.0` windows before lowering. Default 1. */ lowerAfter?: number; /** Rolling-window size for smoothing. Default 2. */ measureWindow?: number; } export interface ComputeAwareDecision { /** * New cap index in the ladder (0 = lowest quality variant, ladderSize-1 = highest). * `null` means no cap has ever been applied yet (cold start). */ capIndex: number | null; /** Smoothed speedX over the rolling window. */ avgSpeedX: number; /** * - `init` — not enough data yet, or ladder unknown * - `lower` — cap was just lowered * - `raise` — cap was just raised * - `hold` — no change this observation */ reason: "init" | "lower" | "raise" | "hold"; } export declare class ComputeAwareDecider { private readonly cfg; private window; private consecutiveLow; private consecutiveHigh; private capIndex_; private ladderSize_; private prevCapIndex_; private prevWindow_; private prevConsecutiveLow_; private prevConsecutiveHigh_; private hasRevertablePoint_; constructor(config?: ComputeAwareConfig); /** Set or update the number of available variants. Must be called at least once before observe(). */ setLadderSize(n: number): void; get currentCap(): number | null; get ladderSize(): number; /** * Feed one speedX measurement plus the player's currently-active variant * index (used as the starting point on first activation, per the * "subtractive only on first activation" rule). * * Returns the decision: a `capIndex` plus the reason. The adapter applies * the cap to the player only when `reason` is "lower" or "raise". */ observe(speedX: number, currentVariantIdx: number): ComputeAwareDecision; /** * Roll back the most recent "lower" or "raise" decision. Adapters call * this when applying the cap to the host player throws — so the decider * state stays in sync with what's actually configured on the player. * Safe to call when no decision has happened yet (no-op). */ revertLastDecision(): void; /** Test/debug — reset everything except the configured thresholds. */ reset(): void; private snapshotForRevert; private resetAfterChange; } //# sourceMappingURL=compute-aware-decision.d.ts.map