@openmoq/playback 0.0.0-stage → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE.txt +202 -0
  2. package/README.md +18 -2
  3. package/dist/adaptive-tolerance.d.ts +128 -0
  4. package/dist/adaptive-tolerance.d.ts.map +1 -0
  5. package/dist/adaptive-tolerance.js +339 -0
  6. package/dist/adaptive-tolerance.js.map +1 -0
  7. package/dist/bandwidth-estimator.d.ts +49 -0
  8. package/dist/bandwidth-estimator.d.ts.map +1 -0
  9. package/dist/bandwidth-estimator.js +77 -0
  10. package/dist/bandwidth-estimator.js.map +1 -0
  11. package/dist/browser/index.global.js +2813 -0
  12. package/dist/browser/index.global.js.map +1 -0
  13. package/dist/browser/index.js +2788 -0
  14. package/dist/browser/index.js.map +1 -0
  15. package/dist/buffer-based-controller.d.ts +87 -0
  16. package/dist/buffer-based-controller.d.ts.map +1 -0
  17. package/dist/buffer-based-controller.js +85 -0
  18. package/dist/buffer-based-controller.js.map +1 -0
  19. package/dist/decoder-state.d.ts +103 -0
  20. package/dist/decoder-state.d.ts.map +1 -0
  21. package/dist/decoder-state.js +145 -0
  22. package/dist/decoder-state.js.map +1 -0
  23. package/dist/gap-detector.d.ts +83 -0
  24. package/dist/gap-detector.d.ts.map +1 -0
  25. package/dist/gap-detector.js +129 -0
  26. package/dist/gap-detector.js.map +1 -0
  27. package/dist/index.d.ts +33 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +33 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/jitter-buffer.d.ts +73 -0
  32. package/dist/jitter-buffer.d.ts.map +1 -0
  33. package/dist/jitter-buffer.js +216 -0
  34. package/dist/jitter-buffer.js.map +1 -0
  35. package/dist/keyframe-validator.d.ts +26 -0
  36. package/dist/keyframe-validator.d.ts.map +1 -0
  37. package/dist/keyframe-validator.js +170 -0
  38. package/dist/keyframe-validator.js.map +1 -0
  39. package/dist/pipeline.d.ts +215 -0
  40. package/dist/pipeline.d.ts.map +1 -0
  41. package/dist/pipeline.js +852 -0
  42. package/dist/pipeline.js.map +1 -0
  43. package/dist/recovery.d.ts +166 -0
  44. package/dist/recovery.d.ts.map +1 -0
  45. package/dist/recovery.js +176 -0
  46. package/dist/recovery.js.map +1 -0
  47. package/dist/render-scheduler.d.ts +50 -0
  48. package/dist/render-scheduler.d.ts.map +1 -0
  49. package/dist/render-scheduler.js +84 -0
  50. package/dist/render-scheduler.js.map +1 -0
  51. package/dist/startup-buffer.d.ts +68 -0
  52. package/dist/startup-buffer.d.ts.map +1 -0
  53. package/dist/startup-buffer.js +107 -0
  54. package/dist/startup-buffer.js.map +1 -0
  55. package/dist/sync.d.ts +234 -0
  56. package/dist/sync.d.ts.map +1 -0
  57. package/dist/sync.js +343 -0
  58. package/dist/sync.js.map +1 -0
  59. package/dist/types.d.ts +229 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +12 -0
  62. package/dist/types.js.map +1 -0
  63. package/package.json +56 -3
@@ -0,0 +1,107 @@
1
+ /**
2
+ * StartupBuffer — holds frames before first drain to warm the jitter estimator.
3
+ *
4
+ * Prevents initial stutter by collecting N frames (determined by network class)
5
+ * before allowing the pipeline to start draining. During the hold, the adaptive
6
+ * tolerance controller calibrates from real arrival timing — so it's ready
7
+ * when playback begins.
8
+ *
9
+ * Network classification uses the QUIC handshake RTT (available before any media)
10
+ * to set initial parameters:
11
+ * - LAN (<1ms): 2 frames / 80ms max — near-zero startup delay
12
+ * - Near-LAN (1-5ms): 3 frames / 120ms
13
+ * - Metro WAN (5-50ms): 8 frames / 300ms
14
+ * - Long-haul WAN (>50ms): 12 frames / 500ms
15
+ *
16
+ * @see draft-ietf-moq-loc-01 §4.2 (decode order)
17
+ * @module
18
+ */
19
+ /**
20
+ * Classify network conditions from QUIC handshake RTT.
21
+ *
22
+ * @param handshakeRttMs Round-trip time from the QUIC/WebTransport handshake
23
+ */
24
+ export function classifyNetwork(handshakeRttMs) {
25
+ if (handshakeRttMs < 1) {
26
+ return { minFrames: 2, maxWaitMs: 80 };
27
+ }
28
+ else if (handshakeRttMs < 5) {
29
+ return { minFrames: 3, maxWaitMs: 120 };
30
+ }
31
+ else if (handshakeRttMs < 50) {
32
+ return { minFrames: 8, maxWaitMs: 300 };
33
+ }
34
+ else {
35
+ return { minFrames: 12, maxWaitMs: 500 };
36
+ }
37
+ }
38
+ // ─── StartupBuffer ──────────────────────────────────────────────────
39
+ /**
40
+ * Gates pipeline draining until enough frames have arrived for smooth startup.
41
+ *
42
+ * Usage:
43
+ * ```ts
44
+ * // In pipeline.pushObject():
45
+ * startupBuffer.recordFrame(clock.now() / 1000);
46
+ *
47
+ * // In pipeline.tick():
48
+ * if (!startupBuffer.shouldDrain) return; // hold frames
49
+ * // ... normal drain logic
50
+ * ```
51
+ */
52
+ export class StartupBuffer {
53
+ minFrames;
54
+ maxWaitMs;
55
+ _frameCount = 0;
56
+ _firstFrameMs = 0;
57
+ _lastFrameMs = 0;
58
+ _draining = false;
59
+ constructor(params) {
60
+ this.minFrames = params.minFrames;
61
+ this.maxWaitMs = params.maxWaitMs;
62
+ }
63
+ /**
64
+ * Record a frame arrival. Call from pushObject().
65
+ * @param nowMs Current time in milliseconds
66
+ */
67
+ recordFrame(nowMs) {
68
+ this._frameCount++;
69
+ if (this._frameCount === 1) {
70
+ this._firstFrameMs = nowMs;
71
+ }
72
+ this._lastFrameMs = nowMs;
73
+ // Check transition
74
+ if (!this._draining) {
75
+ const elapsed = this._lastFrameMs - this._firstFrameMs;
76
+ if (this._frameCount >= this.minFrames || elapsed >= this.maxWaitMs) {
77
+ this._draining = true;
78
+ }
79
+ }
80
+ }
81
+ /** Whether the pipeline should start draining (buffer phase complete). */
82
+ get shouldDrain() {
83
+ return this._draining;
84
+ }
85
+ /** Number of frames recorded. */
86
+ get frameCount() {
87
+ return this._frameCount;
88
+ }
89
+ /** Time elapsed since first frame in milliseconds. */
90
+ get elapsedMs() {
91
+ if (this._frameCount === 0)
92
+ return 0;
93
+ return this._lastFrameMs - this._firstFrameMs;
94
+ }
95
+ /** Accelerated EMA alpha for warmup (4x standard 1/16). */
96
+ get warmupEmaAlpha() {
97
+ return 0.25;
98
+ }
99
+ /** Reset to buffering state (e.g., after seek or pause→resume). */
100
+ reset() {
101
+ this._frameCount = 0;
102
+ this._firstFrameMs = 0;
103
+ this._lastFrameMs = 0;
104
+ this._draining = false;
105
+ }
106
+ }
107
+ //# sourceMappingURL=startup-buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-buffer.js","sourceRoot":"","sources":["../src/startup-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAWH;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,cAAsB;IACpD,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IACzC,CAAC;SAAM,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;IAC1C,CAAC;SAAM,IAAI,cAAc,GAAG,EAAE,EAAE,CAAC;QAC/B,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;IAC1C,CAAC;SAAM,CAAC;QACN,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,uEAAuE;AAEvE;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,aAAa;IACP,SAAS,CAAS;IAClB,SAAS,CAAS;IAE3B,WAAW,GAAG,CAAC,CAAC;IAChB,aAAa,GAAG,CAAC,CAAC;IAClB,YAAY,GAAG,CAAC,CAAC;IACjB,SAAS,GAAG,KAAK,CAAC;IAE1B,YAAY,MAAqB;QAC/B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,KAAa;QACvB,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAE1B,mBAAmB;QACnB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC;YACvD,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,iCAAiC;IACjC,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,sDAAsD;IACtD,IAAI,SAAS;QACX,IAAI,IAAI,CAAC,WAAW,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC;IAChD,CAAC;IAED,2DAA2D;IAC3D,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mEAAmE;IACnE,KAAK;QACH,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;CACF"}
package/dist/sync.d.ts ADDED
@@ -0,0 +1,234 @@
1
+ /**
2
+ * A/V sync controller with injectable clock.
3
+ *
4
+ * Audio-master model: the first audio sample establishes a sync reference
5
+ * mapping CaptureTimestamp (wall-clock microseconds) to local clock time.
6
+ * Video render times are computed relative to this reference.
7
+ *
8
+ * Drift detection: reportPresentationTiming measures VIDEO PRESENTATION SCHEDULE
9
+ * drift — actual presentation time minus the exact scheduled time carried with
10
+ * the frame. If it exceeds the adaptive threshold, presentationDriftExceeded
11
+ * signals and a sync_drift event is emitted — but no automatic re-anchor occurs.
12
+ * Actual audio/video skew is a separate metric (sync_skew).
13
+ * The reference is set once to avoid audio glitching from re-anchor jumps.
14
+ * In practice, gap recovery (skip_forward) and seek/pause naturally re-anchor.
15
+ *
16
+ * Live catch-up: measures end-to-end latency by comparing CaptureTimestamp
17
+ * (publisher wall-clock) to subscriber wall-clock. When latency exceeds
18
+ * targetLatency + threshold, activates catch-up (playback rate > 1.0).
19
+ * Hysteresis prevents oscillation near the threshold boundary.
20
+ *
21
+ * @see draft-ietf-moq-loc-01 §2.3.1.1 (CaptureTimestamp)
22
+ * @see draft-ietf-moq-msf-00 §5.1.16 (targetLatency)
23
+ * @module
24
+ */
25
+ import type { ClockSource, CatchUpState } from './types.js';
26
+ /**
27
+ * Render time calculation result.
28
+ */
29
+ export interface RenderTiming {
30
+ /** When to render this frame, in local clock microseconds. */
31
+ readonly renderTimeUs: number;
32
+ /** How far ahead (+) or behind (-) this frame is relative to now. */
33
+ readonly offsetUs: number;
34
+ /** Whether this frame should be dropped (too late to render). */
35
+ readonly shouldDrop: boolean;
36
+ }
37
+ /**
38
+ * Injectable wall-clock source for latency measurement.
39
+ * Returns Unix epoch microseconds (same domain as CaptureTimestamp).
40
+ * Default: `Date.now() * 1000`.
41
+ *
42
+ * @see draft-ietf-moq-loc-01 §2.3.1.1 (CaptureTimestamp = wall-clock µs)
43
+ */
44
+ export interface WallClockSource {
45
+ /** Current wall-clock time in microseconds since Unix epoch. */
46
+ now(): number;
47
+ }
48
+ export interface SyncControllerConfig {
49
+ readonly driftThresholdUs: number;
50
+ readonly dropThresholdUs?: number;
51
+ readonly clock: ClockSource;
52
+ /** Target end-to-end latency in ms. @see draft-ietf-moq-msf-00 §5.1.16 */
53
+ readonly targetLatencyMs?: number;
54
+ /** Max playback rate for catch-up (e.g., 1.1). Default: 1.0 (disabled). */
55
+ readonly maxCatchUpRate?: number;
56
+ /** Latency above target before catch-up activates (ms). Default: 500. */
57
+ readonly catchUpThresholdMs?: number;
58
+ /** Latency above target before catch-up deactivates (ms, hysteresis). Default: 50. */
59
+ readonly catchUpRecoveryMs?: number;
60
+ /** Injectable wall-clock for testability. Default: Date.now() * 1000. */
61
+ readonly wallClock?: WallClockSource;
62
+ }
63
+ /**
64
+ * A/V sync controller with live catch-up.
65
+ *
66
+ * @see draft-ietf-moq-loc-01 §2.3.1.1
67
+ * @see draft-ietf-moq-msf-00 §5.1.16
68
+ */
69
+ export declare class SyncController {
70
+ private _driftThresholdUs;
71
+ private readonly dropThresholdUs;
72
+ private readonly clock;
73
+ /** Local clock time when audio reference was set. */
74
+ private localBaselineUs;
75
+ /** CaptureTimestamp of the audio reference sample. */
76
+ private captureBaselineUs;
77
+ /** Accumulated drift measurement. */
78
+ private _currentDriftUs;
79
+ /**
80
+ * Video join offset — shifts video render times forward during live join.
81
+ *
82
+ * When joining a live stream, video starts from the GOP boundary
83
+ * (which has an older CaptureTimestamp than the current audio).
84
+ * This offset shifts video render times forward so the first frames
85
+ * render in the future instead of the past, preventing startup stutter.
86
+ *
87
+ * Snaps to zero when the video timeline catches up to the audio live edge.
88
+ * Audio render times are unaffected.
89
+ */
90
+ private _videoJoinOffsetUs;
91
+ private readonly wallClock;
92
+ private readonly targetLatencyMs;
93
+ private readonly maxCatchUpRate;
94
+ private readonly catchUpThresholdMs;
95
+ private readonly catchUpRecoveryMs;
96
+ private _catchUpActive;
97
+ private _currentRate;
98
+ private _lastLatencyUs;
99
+ constructor(config: SyncControllerConfig);
100
+ /** Whether a sync reference has been established. */
101
+ get hasReference(): boolean;
102
+ /** Current drift magnitude in microseconds. */
103
+ get currentDriftUs(): number;
104
+ /** Current drift threshold in microseconds. Mutable for adaptive tolerance. */
105
+ get driftThresholdUs(): number;
106
+ set driftThresholdUs(value: number);
107
+ /**
108
+ * Whether PRESENTATION SCHEDULE drift exceeds the threshold.
109
+ *
110
+ * Deliberately has NO live-join suppression. The exact queued schedule
111
+ * already contains the join offset, so missing that schedule during a join
112
+ * is a real miss. (The legacy PTS-era metric needed the suppression because
113
+ * the offset itself showed up as drift; see {@link needsResync}.)
114
+ */
115
+ get presentationDriftExceeded(): boolean;
116
+ /**
117
+ * @deprecated Threshold check for the legacy {@link reportActualRenderTime}
118
+ * metric, retaining its live-join suppression. Use
119
+ * {@link presentationDriftExceeded} with schedule-based measurement.
120
+ */
121
+ get needsResync(): boolean;
122
+ /** Whether catch-up is currently active. */
123
+ get catchUpActive(): boolean;
124
+ /** Current playback rate (1.0 when catch-up inactive). */
125
+ get currentRate(): number;
126
+ /**
127
+ * Last measured latency in microseconds.
128
+ * 0 before first measurement.
129
+ * @see draft-ietf-moq-loc-01 §2.3.1.1
130
+ */
131
+ get latencyUs(): number;
132
+ /**
133
+ * Establish sync reference from an audio sample.
134
+ * Maps captureTimestamp to the current local clock time.
135
+ * Resets drift measurement.
136
+ *
137
+ * @param captureTimestampUs CaptureTimestamp in microseconds
138
+ */
139
+ setAudioReference(captureTimestampUs: bigint): void;
140
+ /**
141
+ * Establish sync reference from a video frame (video-only mode).
142
+ * No-op if a reference already exists — audio has priority.
143
+ *
144
+ * @param captureTimestampUs CaptureTimestamp of the first video frame
145
+ */
146
+ setVideoReference(captureTimestampUs: bigint): void;
147
+ /** Current video join offset in microseconds. 0 = no offset active. */
148
+ get videoJoinOffsetUs(): number;
149
+ /**
150
+ * Apply video join re-anchor for live stream join.
151
+ *
152
+ * Called when the first video keyframe is decoded after a live join.
153
+ * Computes an offset that shifts video render times forward so the
154
+ * first frame renders at `now + cushion` instead of in the past.
155
+ *
156
+ * The offset is a constant added to all video render times. It preserves
157
+ * inter-frame timing (33ms spacing) while shifting the whole timeline.
158
+ * Snaps to zero when video catches up to the live edge.
159
+ *
160
+ * @param firstKeyframeCaptureUs CaptureTimestamp of the first keyframe
161
+ * @param cushionUs Extra future cushion (default: 16ms ≈ 1 rAF tick)
162
+ */
163
+ onVideoJoin(firstKeyframeCaptureUs: bigint, cushionUs?: number): void;
164
+ /**
165
+ * Compute render timing for a video frame.
166
+ *
167
+ * @param captureTimestampUs CaptureTimestamp in microseconds
168
+ */
169
+ computeVideoRenderTime(captureTimestampUs: bigint): RenderTiming | null;
170
+ /**
171
+ * Compute render timing for an audio sample.
172
+ *
173
+ * @param captureTimestampUs CaptureTimestamp in microseconds
174
+ */
175
+ computeAudioRenderTime(captureTimestampUs: bigint): RenderTiming | null;
176
+ /**
177
+ * Record PRESENTATION SCHEDULE drift: did the renderer present the frame
178
+ * when it was told to?
179
+ *
180
+ * `scheduledUs` must be the EXACT timestamp stored with the rendered frame.
181
+ * It already accounts for the playout cushion actually applied to that
182
+ * frame, the live-join offset, decode-output recomputation and late-frame
183
+ * handling — none of which may be recomputed or subtracted later, because an
184
+ * adaptive cushion can move between enqueue and presentation.
185
+ *
186
+ * The schedule is REQUIRED here. Optionality lives at
187
+ * `FrameRenderedFeedback`, where the pipeline suppresses the whole
188
+ * measurement/event transaction cleanly: missing evidence is not drift.
189
+ *
190
+ * Actual audio/video skew is measured separately as `sync_skew`.
191
+ */
192
+ reportPresentationTiming(scheduledUs: number, actualUs: number): void;
193
+ /**
194
+ * @deprecated Compares against the UNCUSHIONED PTS-anchored time, so a
195
+ * stream presenting exactly on its intended schedule reports the whole
196
+ * playout cushion as drift. Retained as a compatibility path only; use
197
+ * {@link reportPresentationTiming}.
198
+ */
199
+ reportActualRenderTime(captureTimestampUs: bigint, actualLocalUs: number): void;
200
+ /**
201
+ * Measure end-to-end latency from a wall-clock timestamp.
202
+ *
203
+ * Compares the publisher's wall-clock timestamp to the subscriber's
204
+ * wall clock, both in Unix epoch microseconds. A media-time timestamp
205
+ * (LOC-04 with Timescale) has no wall-clock meaning, so latency is
206
+ * unmeasurable and this returns null.
207
+ *
208
+ * @param captureTimestampUs Timestamp in microseconds
209
+ * @param isWallClock False when the timestamp is media time. Undefined means wall clock.
210
+ * @returns Latency in microseconds, or null if unmeasurable
211
+ * @see draft-ietf-moq-loc-01 §2.3.1.1
212
+ * @see draft-ietf-moq-loc-04 §2.3.1.2
213
+ */
214
+ measureLatency(captureTimestampUs: bigint, isWallClock?: boolean): number | null;
215
+ /**
216
+ * Evaluate catch-up state based on current latency.
217
+ *
218
+ * Hysteresis: activates when latency > target + threshold,
219
+ * deactivates when latency <= target + recovery.
220
+ *
221
+ * Rate is proportional to overshoot, quantized to 0.05x increments.
222
+ *
223
+ * @param captureTimestampUs CaptureTimestamp in microseconds (Unix epoch)
224
+ * @returns CatchUpState if evaluated, null if catch-up is disabled or no timestamp
225
+ * @see draft-ietf-moq-msf-00 §5.1.16 (targetLatency)
226
+ */
227
+ evaluateCatchUp(captureTimestampUs: bigint, isWallClock?: boolean): CatchUpState | null;
228
+ /**
229
+ * Reset the sync reference (e.g., after a skip-forward).
230
+ */
231
+ reset(): void;
232
+ private computeRenderTime;
233
+ }
234
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}