supervision 0.1.7 → 0.2.0-next.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.
- package/dist/detections/chunked-detection-frame-source.d.ts.map +1 -1
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8856 -4559
- package/dist/index.js.map +1 -1
- package/dist/mask-preparation.worker.js +310 -164
- package/dist/mask-preparation.worker.js.map +1 -1
- package/dist/media/display-pixel-ratio.d.ts +15 -0
- package/dist/media/display-pixel-ratio.d.ts.map +1 -0
- package/dist/media/engine-import-failure.d.ts +16 -0
- package/dist/media/engine-import-failure.d.ts.map +1 -0
- package/dist/media/media-condition-probe.d.ts +51 -0
- package/dist/media/media-condition-probe.d.ts.map +1 -0
- package/dist/media/media-conditions.d.ts +28 -0
- package/dist/media/media-conditions.d.ts.map +1 -0
- package/dist/media/media-errors.d.ts +6 -0
- package/dist/media/media-errors.d.ts.map +1 -1
- package/dist/media/media-normalization.d.ts.map +1 -1
- package/dist/media/media-probe.d.ts.map +1 -1
- package/dist/media/media-source.d.ts +17 -0
- package/dist/media/media-source.d.ts.map +1 -1
- package/dist/media/mediabunny-media-source.d.ts.map +1 -1
- package/dist/media/video-engine-media-source.d.ts +44 -0
- package/dist/media/video-engine-media-source.d.ts.map +1 -0
- package/dist/render-preparation/mask-frame-artifact.d.ts +46 -12
- package/dist/render-preparation/mask-frame-artifact.d.ts.map +1 -1
- package/dist/render-preparation/mask-frame-compositor.d.ts +5 -5
- package/dist/render-preparation/mask-frame-compositor.d.ts.map +1 -1
- package/dist/render-preparation/mask-frame-preparer.d.ts.map +1 -1
- package/dist/render-preparation/mask-preparation-worker-count.d.ts +4 -4
- package/dist/render-preparation/mask-preparation-worker-protocol.d.ts +12 -3
- package/dist/render-preparation/mask-preparation-worker-protocol.d.ts.map +1 -1
- package/dist/render-preparation/prepared-render-window.d.ts +23 -0
- package/dist/render-preparation/prepared-render-window.d.ts.map +1 -1
- package/dist/render-preparation/prepared-window-timeline.d.ts +2 -6
- package/dist/render-preparation/prepared-window-timeline.d.ts.map +1 -1
- package/dist/renderers/mask-palette.d.ts +14 -0
- package/dist/renderers/mask-palette.d.ts.map +1 -0
- package/dist/renderers/mask-vertex.d.ts +14 -0
- package/dist/renderers/mask-vertex.d.ts.map +1 -0
- package/dist/renderers/media-renderer-core.d.ts.map +1 -1
- package/dist/renderers/media-renderer-scene.d.ts +37 -0
- package/dist/renderers/media-renderer-scene.d.ts.map +1 -1
- package/dist/renderers/media-renderer-state.d.ts +11 -1
- package/dist/renderers/media-renderer-state.d.ts.map +1 -1
- package/dist/renderers/media-renderer-transport.d.ts +59 -0
- package/dist/renderers/media-renderer-transport.d.ts.map +1 -0
- package/dist/renderers/pixi-box-layer.d.ts +5 -0
- package/dist/renderers/pixi-box-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-focus-layer.d.ts +18 -2
- package/dist/renderers/pixi-focus-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-frame-present.d.ts +77 -0
- package/dist/renderers/pixi-frame-present.d.ts.map +1 -0
- package/dist/renderers/pixi-id-mask-shader.d.ts +12 -2
- package/dist/renderers/pixi-id-mask-shader.d.ts.map +1 -1
- package/dist/renderers/pixi-interaction-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-interaction-presentation-layer.d.ts +13 -2
- package/dist/renderers/pixi-interaction-presentation-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-mask-halo.d.ts +24 -0
- package/dist/renderers/pixi-mask-halo.d.ts.map +1 -1
- package/dist/renderers/pixi-mask-layer.d.ts +71 -8
- package/dist/renderers/pixi-mask-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-media-scene.d.ts +67 -0
- package/dist/renderers/pixi-media-scene.d.ts.map +1 -1
- package/dist/renderers/pixi-polygon-layer.d.ts +7 -2
- package/dist/renderers/pixi-polygon-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-region-coverage-mask.d.ts +91 -0
- package/dist/renderers/pixi-region-coverage-mask.d.ts.map +1 -0
- package/dist/renderers/pixi-region-effect.d.ts +42 -0
- package/dist/renderers/pixi-region-effect.d.ts.map +1 -0
- package/dist/renderers/pixi-region-layer.d.ts +68 -2
- package/dist/renderers/pixi-region-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-vector-layer.d.ts.map +1 -1
- package/dist/renderers/prepared-annotation-window.d.ts +47 -0
- package/dist/renderers/prepared-annotation-window.d.ts.map +1 -0
- package/dist/renderers/presented-frame-channel.d.ts +107 -0
- package/dist/renderers/presented-frame-channel.d.ts.map +1 -0
- package/dist/renderers/scene-render-scheduler.d.ts +20 -0
- package/dist/renderers/scene-render-scheduler.d.ts.map +1 -0
- package/dist/sessions/media-session-defaults.d.ts +10 -6
- package/dist/sessions/media-session-defaults.d.ts.map +1 -1
- package/dist/sessions/media-session-media.d.ts.map +1 -1
- package/dist/sessions/media-session-state.d.ts.map +1 -1
- package/dist/sessions/media-session.d.ts.map +1 -1
- package/dist/tracking.worker.js +58 -3
- package/dist/tracking.worker.js.map +1 -1
- package/dist/types/media-conditions.d.ts +149 -0
- package/dist/types/media-conditions.d.ts.map +1 -0
- package/dist/types/media-normalization.d.ts +34 -0
- package/dist/types/media-normalization.d.ts.map +1 -1
- package/dist/types/media-renderer.d.ts +31 -1
- package/dist/types/media-renderer.d.ts.map +1 -1
- package/dist/types/media-session.d.ts +89 -8
- package/dist/types/media-session.d.ts.map +1 -1
- package/dist/types/render-preparation.d.ts +101 -4
- package/dist/types/render-preparation.d.ts.map +1 -1
- package/dist/web-video-engine/analysis-session.d.ts +76 -0
- package/dist/web-video-engine/analysis-session.d.ts.map +1 -0
- package/dist/web-video-engine/analysis.d.ts +7 -0
- package/dist/web-video-engine/analysis.d.ts.map +1 -0
- package/dist/web-video-engine/analysis.js +1678 -0
- package/dist/web-video-engine/analysis.js.map +1 -0
- package/dist/web-video-engine/cache-budget.d.ts +19 -0
- package/dist/web-video-engine/cache-budget.d.ts.map +1 -0
- package/dist/web-video-engine/canvas-sink-scrub-cursor.d.ts +90 -0
- package/dist/web-video-engine/canvas-sink-scrub-cursor.d.ts.map +1 -0
- package/dist/web-video-engine/clock.d.ts +83 -0
- package/dist/web-video-engine/clock.d.ts.map +1 -0
- package/dist/web-video-engine/constants.d.ts +253 -0
- package/dist/web-video-engine/constants.d.ts.map +1 -0
- package/dist/web-video-engine/create-scrub-cursor.d.ts +62 -0
- package/dist/web-video-engine/create-scrub-cursor.d.ts.map +1 -0
- package/dist/web-video-engine/decode-resolution.d.ts +115 -0
- package/dist/web-video-engine/decode-resolution.d.ts.map +1 -0
- package/dist/web-video-engine/decode-scheduler.d.ts +356 -0
- package/dist/web-video-engine/decode-scheduler.d.ts.map +1 -0
- package/dist/web-video-engine/decode-session.d.ts +276 -0
- package/dist/web-video-engine/decode-session.d.ts.map +1 -0
- package/dist/web-video-engine/decode-source.d.ts +250 -0
- package/dist/web-video-engine/decode-source.d.ts.map +1 -0
- package/dist/web-video-engine/diagnostics-store.d.ts +18 -0
- package/dist/web-video-engine/diagnostics-store.d.ts.map +1 -0
- package/dist/web-video-engine/diagnostics.d.ts +316 -0
- package/dist/web-video-engine/diagnostics.d.ts.map +1 -0
- package/dist/web-video-engine/embedded-engine-worker.d.ts +2 -0
- package/dist/web-video-engine/embedded-engine-worker.d.ts.map +1 -0
- package/dist/web-video-engine/engine-core.d.ts +258 -0
- package/dist/web-video-engine/engine-core.d.ts.map +1 -0
- package/dist/web-video-engine/engine.d.ts +26 -0
- package/dist/web-video-engine/engine.d.ts.map +1 -0
- package/dist/web-video-engine/engine.js +873 -0
- package/dist/web-video-engine/engine.js.map +1 -0
- package/dist/web-video-engine/engine.worker.d.ts +2 -0
- package/dist/web-video-engine/engine.worker.d.ts.map +1 -0
- package/dist/web-video-engine/engine.worker.js +31320 -0
- package/dist/web-video-engine/engine.worker.js.map +1 -0
- package/dist/web-video-engine/frame-cache.d.ts +129 -0
- package/dist/web-video-engine/frame-cache.d.ts.map +1 -0
- package/dist/web-video-engine/frame-extractor.d.ts +28 -0
- package/dist/web-video-engine/frame-extractor.d.ts.map +1 -0
- package/dist/web-video-engine/frame-timeline-GINI8Gum.js +560 -0
- package/dist/web-video-engine/frame-timeline-GINI8Gum.js.map +1 -0
- package/dist/web-video-engine/frame-timeline.d.ts +71 -0
- package/dist/web-video-engine/frame-timeline.d.ts.map +1 -0
- package/dist/web-video-engine/frame-walker.d.ts +74 -0
- package/dist/web-video-engine/frame-walker.d.ts.map +1 -0
- package/dist/web-video-engine/index.d.ts +3 -0
- package/dist/web-video-engine/index.d.ts.map +1 -0
- package/dist/web-video-engine/index.js +3 -0
- package/dist/web-video-engine/index.js.map +1 -0
- package/dist/web-video-engine/key-packet.d.ts +65 -0
- package/dist/web-video-engine/key-packet.d.ts.map +1 -0
- package/dist/web-video-engine/keyframe-index.d.ts +91 -0
- package/dist/web-video-engine/keyframe-index.d.ts.map +1 -0
- package/dist/web-video-engine/mirror-store.d.ts +56 -0
- package/dist/web-video-engine/mirror-store.d.ts.map +1 -0
- package/dist/web-video-engine/renderer.d.ts +94 -0
- package/dist/web-video-engine/renderer.d.ts.map +1 -0
- package/dist/web-video-engine/rotation.d.ts +35 -0
- package/dist/web-video-engine/rotation.d.ts.map +1 -0
- package/dist/web-video-engine/scrub-controller.d.ts +376 -0
- package/dist/web-video-engine/scrub-controller.d.ts.map +1 -0
- package/dist/web-video-engine/scrub-cursor.d.ts +342 -0
- package/dist/web-video-engine/scrub-cursor.d.ts.map +1 -0
- package/dist/web-video-engine/scrub-trajectory.d.ts +30 -0
- package/dist/web-video-engine/scrub-trajectory.d.ts.map +1 -0
- package/dist/web-video-engine/source-residency.d.ts +57 -0
- package/dist/web-video-engine/source-residency.d.ts.map +1 -0
- package/dist/web-video-engine/trace-recorder.d.ts +164 -0
- package/dist/web-video-engine/trace-recorder.d.ts.map +1 -0
- package/dist/web-video-engine/types.d.ts +204 -0
- package/dist/web-video-engine/types.d.ts.map +1 -0
- package/dist/web-video-engine/video-engine.d.ts +426 -0
- package/dist/web-video-engine/video-engine.d.ts.map +1 -0
- package/dist/web-video-engine/webgpu-renderer.d.ts +62 -0
- package/dist/web-video-engine/webgpu-renderer.d.ts.map +1 -0
- package/dist/web-video-engine/worker-bridge.d.ts +12 -0
- package/dist/web-video-engine/worker-bridge.d.ts.map +1 -0
- package/dist/web-video-engine/worker-dispatch.d.ts +17 -0
- package/dist/web-video-engine/worker-dispatch.d.ts.map +1 -0
- package/dist/web-video-engine/worker-protocol.d.ts +267 -0
- package/dist/web-video-engine/worker-protocol.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/detections/buffered-detection-timeline.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/detections/composite-detection-frame-source.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/index.d.ts +4 -3
- package/node_modules/supervision-js-core/dist/index.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/index.js +1075 -266
- package/node_modules/supervision-js-core/dist/index.js.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/default-annotation-presentation.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/interaction-style.d.ts +4 -36
- package/node_modules/supervision-js-core/dist/styles/interaction-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/polyline-style.d.ts +5 -0
- package/node_modules/supervision-js-core/dist/styles/polyline-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/annotation-renderer.d.ts +92 -7
- package/node_modules/supervision-js-core/dist/types/annotation-renderer.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/detection-timeline.d.ts +179 -17
- package/node_modules/supervision-js-core/dist/types/detection-timeline.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/media-rendering.d.ts +78 -2
- package/node_modules/supervision-js-core/dist/types/media-rendering.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/polyline-style.d.ts +2 -0
- package/node_modules/supervision-js-core/dist/types/polyline-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/session-lifecycle.d.ts +16 -0
- package/node_modules/supervision-js-core/dist/types/session-lifecycle.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/utils/detection-conversions.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/utils/detection-frames.d.ts +5 -0
- package/node_modules/supervision-js-core/dist/utils/detection-frames.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/utils/detection-masks.d.ts +9 -0
- package/node_modules/supervision-js-core/dist/utils/detection-masks.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/utils/detection-ranges.d.ts +18 -0
- package/node_modules/supervision-js-core/dist/utils/detection-ranges.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/utils/id-mask-frame.d.ts +15 -2
- package/node_modules/supervision-js-core/dist/utils/id-mask-frame.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/utils/wait-bound.d.ts +7 -0
- package/node_modules/supervision-js-core/dist/utils/wait-bound.d.ts.map +1 -0
- package/package.json +22 -1
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import type { CreateScrubCursorOptions } from "./create-scrub-cursor";
|
|
2
|
+
import type { FrameCacheStats } from "./frame-cache";
|
|
3
|
+
import type { FrameId, FrameTimeline } from "./frame-timeline";
|
|
4
|
+
import type { GopStats } from "./keyframe-index";
|
|
5
|
+
import type { Rotation } from "./rotation";
|
|
6
|
+
import type { DecodePath, Sec } from "./types";
|
|
7
|
+
/**
|
|
8
|
+
* How good a painted frame is. "exact" is a full decode-resolution frame;
|
|
9
|
+
* "preview" is the coarse downscaled stand-in the cache serves at once while a
|
|
10
|
+
* crisp one decodes. The two look materially different on screen, so anything
|
|
11
|
+
* reporting what was painted has to say which it was.
|
|
12
|
+
*/
|
|
13
|
+
export type FrameQuality = "exact" | "preview";
|
|
14
|
+
export declare enum ScrubCursorState {
|
|
15
|
+
Idle = "idle",
|
|
16
|
+
Seeking = "seeking",
|
|
17
|
+
Closed = "closed"
|
|
18
|
+
}
|
|
19
|
+
/** Fields every paint-ready frame carries, independent of how its pixels reach
|
|
20
|
+
* the renderer. */
|
|
21
|
+
export interface ScrubFrameBase {
|
|
22
|
+
readonly timestampS: Sec;
|
|
23
|
+
readonly width: number;
|
|
24
|
+
readonly height: number;
|
|
25
|
+
readonly isKeyFrame: boolean;
|
|
26
|
+
readonly quality: FrameQuality;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The structural slice of mediabunny's VideoSample the runtime touches: enough
|
|
30
|
+
* to draw it into a 2D canvas, hand its pixels to WebGPU zero-copy, and release
|
|
31
|
+
* it. Kept as a slice rather than the concrete class so the runtime never
|
|
32
|
+
* imports mediabunny and stays fake-injectable under test.
|
|
33
|
+
*
|
|
34
|
+
* close() is the caller's obligation and is made idempotent at the cursor
|
|
35
|
+
* boundary, so a sample drawn into the cache, painted, and then closed on
|
|
36
|
+
* teardown is closed at most once for real.
|
|
37
|
+
*/
|
|
38
|
+
export interface VideoSampleLike {
|
|
39
|
+
/**
|
|
40
|
+
* A fresh VideoFrame per call; the caller closes the returned frame.
|
|
41
|
+
*
|
|
42
|
+
* The frame carries the stored pixels and NOT the track's rotation, on this
|
|
43
|
+
* and on mediabunny's own implementation, which drops it deliberately. So
|
|
44
|
+
* whoever takes one owes it the turn named by `rotation` below.
|
|
45
|
+
*/
|
|
46
|
+
toVideoFrame(): VideoFrame;
|
|
47
|
+
/** The turn the pixels still need, already applied by draw() and dropped by
|
|
48
|
+
* toVideoFrame(). */
|
|
49
|
+
readonly rotation: Rotation;
|
|
50
|
+
draw(context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, dx: number, dy: number, dWidth?: number, dHeight?: number): void;
|
|
51
|
+
close(): void;
|
|
52
|
+
readonly timestamp: number;
|
|
53
|
+
readonly duration: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A paint-ready frame yielded by the cursor, tagged by how its pixels reach the
|
|
57
|
+
* renderer.
|
|
58
|
+
*
|
|
59
|
+
* A canvas frame carries a canvas and no close obligation: it is a cache blit
|
|
60
|
+
* or a CanvasSink decode. WebGPU uploads it with copyExternalImageToTexture,
|
|
61
|
+
* which accepts neither an SVG image nor a video element. A sample frame carries a live VideoSample
|
|
62
|
+
* the zero-copy path imports straight into WebGPU; whoever stashes it owns its
|
|
63
|
+
* close, so only fresh decodes on the sample source produce one.
|
|
64
|
+
*/
|
|
65
|
+
export interface CanvasScrubFrame extends ScrubFrameBase {
|
|
66
|
+
readonly kind: "canvas";
|
|
67
|
+
readonly source: OffscreenCanvas | HTMLCanvasElement;
|
|
68
|
+
}
|
|
69
|
+
export interface SampleScrubFrame extends ScrubFrameBase {
|
|
70
|
+
readonly kind: "sample";
|
|
71
|
+
readonly sample: VideoSampleLike;
|
|
72
|
+
}
|
|
73
|
+
export type ScrubFrame = CanvasScrubFrame | SampleScrubFrame;
|
|
74
|
+
/**
|
|
75
|
+
* The turn a frame's raw pixels still need. A canvas frame has none left: a
|
|
76
|
+
* CanvasSink decode arrives upright, and a cache blit was drawn through a
|
|
77
|
+
* sample's own draw, which applies it. Only a live sample still owes one.
|
|
78
|
+
*/
|
|
79
|
+
export declare function frameRotation(frame: ScrubFrame): Rotation;
|
|
80
|
+
/**
|
|
81
|
+
* Wraps a raw sample so its close() runs at most once, then no-ops. The
|
|
82
|
+
* lifetime is hard to keep linear: a sample is drawn into the cache, stashed for
|
|
83
|
+
* paint, then closed after paint, and may be closed again on teardown if a
|
|
84
|
+
* gesture left it unpainted. An idempotent close lets every path call it
|
|
85
|
+
* defensively without double-free.
|
|
86
|
+
*/
|
|
87
|
+
export declare function idempotentSample(sample: VideoSampleLike): VideoSampleLike;
|
|
88
|
+
export type ScrubFrameListener = (frame: ScrubFrame) => void;
|
|
89
|
+
/** A frame considered for the screen, and what is already on it. */
|
|
90
|
+
export interface ScreenCandidate {
|
|
91
|
+
readonly timestampMs: number;
|
|
92
|
+
readonly quality: FrameQuality;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Whether a frame earns the screen over what is already showing, judged from
|
|
96
|
+
* where the user is pointing rather than from what happens to be up. Closer
|
|
97
|
+
* wins; equally close wins only by being sharper, since repainting the same
|
|
98
|
+
* ground with the same or worse pixels is a visible change for no information.
|
|
99
|
+
*
|
|
100
|
+
* Both painters share this. They used to disagree: one applied it to coarse
|
|
101
|
+
* frames only and the other to everything, so which rule you got depended on
|
|
102
|
+
* which path served the frame.
|
|
103
|
+
*/
|
|
104
|
+
export declare function earnsScreen(candidate: ScreenCandidate, showing: ScreenCandidate | null, targetMs: number): boolean;
|
|
105
|
+
/** Rolling scrub-decode latency, in milliseconds, since the cursor opened.
|
|
106
|
+
* p50Ms/p95Ms are percentiles over a bounded recent-sample ring, so a single
|
|
107
|
+
* slow region shows up in p95 without dragging the all-time avg. targetVsLandedMs
|
|
108
|
+
* is how far the last exact seek landed from where it aimed (long-GOP forces a
|
|
109
|
+
* distant anchor); timeToCrispMs is the gap between a preview paint and the crisp
|
|
110
|
+
* decode that replaced it on the same seek. */
|
|
111
|
+
export interface ScrubLatencyStats {
|
|
112
|
+
readonly samples: number;
|
|
113
|
+
readonly lastMs: number;
|
|
114
|
+
readonly avgMs: number;
|
|
115
|
+
readonly maxMs: number;
|
|
116
|
+
readonly p50Ms: number;
|
|
117
|
+
readonly p95Ms: number;
|
|
118
|
+
readonly targetVsLandedMs: number;
|
|
119
|
+
readonly timeToCrispMs: number;
|
|
120
|
+
}
|
|
121
|
+
/** Decodes the scheduler has run, split by why. foreground is a gesture-driven
|
|
122
|
+
* seek/step/play pull; the prefetch counts are background sweep fills per tier;
|
|
123
|
+
* keyframeAnchored is a key-only seek landing on its anchor. Counters only, never
|
|
124
|
+
* reset, so ratios over a session describe where decode bandwidth went. */
|
|
125
|
+
export interface DecodeCounters {
|
|
126
|
+
readonly foreground: number;
|
|
127
|
+
readonly prefetchExact: number;
|
|
128
|
+
readonly prefetchPreview: number;
|
|
129
|
+
readonly keyframeAnchored: number;
|
|
130
|
+
/** Frames the decode machinery has produced since open, all paths, walk
|
|
131
|
+
* pre-roll included where the path can see it. The pipeline ledger's
|
|
132
|
+
* decoded column. */
|
|
133
|
+
readonly framesOut: number;
|
|
134
|
+
/** Forward-playback pulls in flight (0 or 1); a free read of the drain latch. */
|
|
135
|
+
readonly nextPending: number;
|
|
136
|
+
}
|
|
137
|
+
/** Seeks the scheduler has serviced. exact is a full-resolution scrub; key is a
|
|
138
|
+
* key-only navigation seek; coalesceDepth counts how often a pending target was
|
|
139
|
+
* overwritten before it drained (the decoder falling behind a fast drag). */
|
|
140
|
+
export interface SeekCounters {
|
|
141
|
+
readonly exact: number;
|
|
142
|
+
readonly key: number;
|
|
143
|
+
readonly coalesceDepth: number;
|
|
144
|
+
}
|
|
145
|
+
/** Background prefetch sweep liveness: whether a sweep is decoding right now and
|
|
146
|
+
* the generation token (bumped by every foreground gesture, so a jumping value
|
|
147
|
+
* is a churning sweep that never warms the cache). */
|
|
148
|
+
export interface PrefetchState {
|
|
149
|
+
readonly inFlight: boolean;
|
|
150
|
+
readonly generation: number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Observability snapshot a caching cursor can report: how often the cache
|
|
154
|
+
* answered a scrub, and how long the misses took to decode. Cache hit-rate and
|
|
155
|
+
* decode latency together describe perceived scrub responsiveness.
|
|
156
|
+
*/
|
|
157
|
+
/**
|
|
158
|
+
* Why the playhead is moving. A hand on a timeline keeps feeding positions, so
|
|
159
|
+
* the runtime reads their direction and speed to decide what to prepare next.
|
|
160
|
+
* A jump produces one position and no motion to read, so prediction from the
|
|
161
|
+
* positions around it would be prediction from a gesture nobody is making.
|
|
162
|
+
*/
|
|
163
|
+
export type SeekIntent = "gesture" | "jump";
|
|
164
|
+
/** The decode window the scheduler is filling around the playhead, in ms. */
|
|
165
|
+
/** The decode targets the next background sweep would aim at, given what the
|
|
166
|
+
* runtime currently knows. A bounds pair cannot represent a hole, and holes
|
|
167
|
+
* are what a coverage instrument exists to show. */
|
|
168
|
+
export interface PrefetchPlan {
|
|
169
|
+
readonly targetsMs: number[];
|
|
170
|
+
}
|
|
171
|
+
export interface SchedulerStats {
|
|
172
|
+
/** The runtime's live read of how the consumer is moving (idle/scrubbing/
|
|
173
|
+
* stepping/playing). The single highest-signal field for a human watching
|
|
174
|
+
* the engine interpret their gesture. */
|
|
175
|
+
readonly mode: string;
|
|
176
|
+
/** Which decode machinery this source was opened through. Resolved once at
|
|
177
|
+
* open from the track and the realm; a hang-recovery rebuild re-resolves
|
|
178
|
+
* it, so a path change here means the source was re-opened. */
|
|
179
|
+
readonly decodePath: DecodePath;
|
|
180
|
+
readonly cache: FrameCacheStats;
|
|
181
|
+
readonly scrub: ScrubLatencyStats;
|
|
182
|
+
readonly decode: DecodeCounters;
|
|
183
|
+
readonly seek: SeekCounters;
|
|
184
|
+
/** GOP-gap distribution over the keyframes discovered so far. A long maxGopS
|
|
185
|
+
* is the badly-encoded-source tell every off-anchor scrub pays for. */
|
|
186
|
+
readonly gop: GopStats;
|
|
187
|
+
/** Container round-trips the keyframe index has made resolving anchors; the
|
|
188
|
+
* rest resolve from memory. */
|
|
189
|
+
readonly probeRoundTrips: number;
|
|
190
|
+
/** Discovered keyframe timestamps (ms), ascending. Lazy: grows as the source
|
|
191
|
+
* is scrubbed/swept, so it shows what the runtime actually knows. */
|
|
192
|
+
readonly keyframesMs: number[];
|
|
193
|
+
/** The targets the scheduler would prefetch around the playhead, or null
|
|
194
|
+
* while playing (the forward stream iterator covers ahead). */
|
|
195
|
+
readonly prefetch: PrefetchPlan | null;
|
|
196
|
+
/** Background sweep liveness (in-flight + generation token). */
|
|
197
|
+
readonly prefetchState: PrefetchState;
|
|
198
|
+
/** Cache lookup tolerances, so a timeline can draw the "served" bands. */
|
|
199
|
+
readonly exactToleranceMs: number;
|
|
200
|
+
readonly previewToleranceMs: number;
|
|
201
|
+
/** True after a decode hung on a non-re-openable source: the decoder could
|
|
202
|
+
* not be rebuilt, so the runtime is degraded (decodes no-op) but not frozen.
|
|
203
|
+
* Lets a consumer surface the state rather than show a silent freeze. */
|
|
204
|
+
readonly decoderDead: boolean;
|
|
205
|
+
/** True once the decoder is judged unable to decode this source at all: it
|
|
206
|
+
* refused to configure, it errored, or it acknowledged decode requests and
|
|
207
|
+
* produced nothing. Distinct from decoderDead, which is a rebuild the
|
|
208
|
+
* source made impossible; this one survives every rebuild, so the runtime
|
|
209
|
+
* stops rebuilding. The transport reads Errored at the same moment. */
|
|
210
|
+
readonly decoderStalled: boolean;
|
|
211
|
+
/** State of the seek drain. Every play pull is refused while a seek drains,
|
|
212
|
+
* so a drain that never finishes shows on screen as playback dying with no
|
|
213
|
+
* other symptom: without this the panel can say the pump is dead but not
|
|
214
|
+
* that a seek is the reason. */
|
|
215
|
+
readonly drain: DrainState;
|
|
216
|
+
}
|
|
217
|
+
export interface DrainState {
|
|
218
|
+
/** A seek is being serviced right now, which refuses every play pull. */
|
|
219
|
+
readonly draining: boolean;
|
|
220
|
+
/** Target waiting behind the one being serviced, in ms, or null. */
|
|
221
|
+
readonly pendingTargetMs: number | null;
|
|
222
|
+
/** A hung-decode rebuild is in progress. */
|
|
223
|
+
readonly recovering: boolean;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Resolved track facts the engine reads after open(). width/height are the
|
|
227
|
+
* source's native resolution (used for aspect, metadata, cache sizing).
|
|
228
|
+
* decodeWidth/decodeHeight are the resolution frames are actually decoded to
|
|
229
|
+
* after the decode-resolution strategy runs, and size the visible canvas
|
|
230
|
+
* backing store. They equal native unless a downscaling strategy is in play.
|
|
231
|
+
*/
|
|
232
|
+
export interface ScrubTrackInfo {
|
|
233
|
+
readonly width: number;
|
|
234
|
+
readonly height: number;
|
|
235
|
+
readonly decodeWidth: number;
|
|
236
|
+
readonly decodeHeight: number;
|
|
237
|
+
/**
|
|
238
|
+
* The track's quarter turn. Every dimension above is the display size, so all
|
|
239
|
+
* four already account for it. This exists for the pixels, which do not.
|
|
240
|
+
*/
|
|
241
|
+
readonly rotation: Rotation;
|
|
242
|
+
readonly nativeFps: number | null;
|
|
243
|
+
readonly durationS: Sec;
|
|
244
|
+
/**
|
|
245
|
+
* Timestamp of the track's first sample, in seconds. Usually near zero but
|
|
246
|
+
* may be positive (a trimmed clip) or negative (offset timing). The seed
|
|
247
|
+
* seek and seek clamping use it as the origin so a non-zero start does not
|
|
248
|
+
* mis-seek to t=0.
|
|
249
|
+
*/
|
|
250
|
+
readonly firstTimestampS: Sec;
|
|
251
|
+
/** Every real frame of this track, by its container tick timestamp. The one
|
|
252
|
+
* place a frame's identity is defined; everything else snaps into it. */
|
|
253
|
+
readonly timeline: FrameTimeline;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Random-access cursor over a video source: the seam between the engine and
|
|
257
|
+
* the mediabunny primitives it wraps.
|
|
258
|
+
*
|
|
259
|
+
* The implementation (CanvasSinkScrubCursor) rides CanvasSink.getCanvas(t)
|
|
260
|
+
* for random-access seeks, which does the keyframe walk and GOP decode
|
|
261
|
+
* internally, and a sink.canvases(start) iterator for forward playback that
|
|
262
|
+
* lives only between attachPlay and detachPlay. The interface is kept as a
|
|
263
|
+
* seam so a future mediabunny SampleCursor backend can replace the
|
|
264
|
+
* implementation without touching consumers.
|
|
265
|
+
*
|
|
266
|
+
* Contract notes consumers rely on:
|
|
267
|
+
* - seekTo coalesces concurrent seeks latest-wins, so rapid pointermove
|
|
268
|
+
* scrubs collapse to the most recent target.
|
|
269
|
+
* - seekToKey lands on the sample at or before t and marks the emitted
|
|
270
|
+
* frame as a keyframe result.
|
|
271
|
+
* - next is VFR-correct and a no-op while paused (no iterator attached),
|
|
272
|
+
* so it never advances media time across a paused canvas. The 1/fps step
|
|
273
|
+
* approximation lives in VideoEngine.step, not here.
|
|
274
|
+
* - isIdle is true only when no seek is draining and no pull is in flight.
|
|
275
|
+
* - subscribe replays the most recent frame to a new listener so the seed
|
|
276
|
+
* frame from open() is never dropped.
|
|
277
|
+
* - close is final; reusing a closed cursor is a programming error.
|
|
278
|
+
*/
|
|
279
|
+
export interface ScrubCursor {
|
|
280
|
+
readonly state: ScrubCursorState;
|
|
281
|
+
readonly track: ScrubTrackInfo;
|
|
282
|
+
readonly isIdle: boolean;
|
|
283
|
+
open(): Promise<void>;
|
|
284
|
+
seekTo(timestamp: Sec, intent?: SeekIntent): void;
|
|
285
|
+
seekToKey(timestamp: Sec): void;
|
|
286
|
+
next(): void;
|
|
287
|
+
/**
|
|
288
|
+
* Attach a forward-playback iterator anchored at startS. Required for
|
|
289
|
+
* next() to advance; paused mode keeps no iterator.
|
|
290
|
+
*/
|
|
291
|
+
attachPlay(startS: number): void;
|
|
292
|
+
/** Detach the forward-playback iterator. */
|
|
293
|
+
detachPlay(): void;
|
|
294
|
+
/**
|
|
295
|
+
* Decode the named frame of the source and emit it through the listener
|
|
296
|
+
* chain. Returns the emitted ScrubFrame, or null at a boundary or once
|
|
297
|
+
* closed. Steps are index arithmetic on the frame table, so a caller names
|
|
298
|
+
* the frame it wants and not a time near it.
|
|
299
|
+
*/
|
|
300
|
+
seekToFrame(frame: FrameId): Promise<ScrubFrame | null>;
|
|
301
|
+
idle(): Promise<void>;
|
|
302
|
+
/**
|
|
303
|
+
* Resolves at the seek drain's next settle: whichever target it is servicing
|
|
304
|
+
* has landed. The wait spans one decode. idle() spans the whole gesture,
|
|
305
|
+
* since a drag re-arms the drain on every pointer move, so a caller that has
|
|
306
|
+
* to answer while the hand is still down asks this one.
|
|
307
|
+
*/
|
|
308
|
+
seekSettled(): Promise<void>;
|
|
309
|
+
/**
|
|
310
|
+
* Registers a frame listener. The cache replays the most recently emitted
|
|
311
|
+
* frame synchronously on subscribe so the seed frame from open() is
|
|
312
|
+
* delivered to controllers that wire up afterwards.
|
|
313
|
+
*/
|
|
314
|
+
subscribe(listener: ScrubFrameListener): () => void;
|
|
315
|
+
/**
|
|
316
|
+
* Synchronous best-effort cache lookup the render loop calls on scrub to
|
|
317
|
+
* paint a frame this same tick, before the full-res decode resolves. The
|
|
318
|
+
* uncached implementation returns null; the caching scheduler returns the
|
|
319
|
+
* closest cached frame within tolerance, or null on a miss.
|
|
320
|
+
*/
|
|
321
|
+
peekCached(timeMs: number): ScrubFrame | null;
|
|
322
|
+
/**
|
|
323
|
+
* Observability snapshot (cache hit-rate, scrub-decode latency). Present
|
|
324
|
+
* only on the caching backend; the uncached cursor omits it.
|
|
325
|
+
*/
|
|
326
|
+
/** Decoded frames the consumer may hold ahead of the playhead; see
|
|
327
|
+
* FrameProvider.playReadAhead. Absent on cursors with no decode path of
|
|
328
|
+
* their own, where the caller falls back to the canvas depth. */
|
|
329
|
+
readonly playReadAhead?: number;
|
|
330
|
+
getStats?(): SchedulerStats;
|
|
331
|
+
/**
|
|
332
|
+
* Eagerly walks the whole track's keyframes into the index, metadata only,
|
|
333
|
+
* so the diagnostics keyframe lane reflects the entire file rather than just
|
|
334
|
+
* the swept regions. Idempotent and off the hot seek path. Present only on
|
|
335
|
+
* the caching backend (the uncached cursor keeps no index); callers invoke
|
|
336
|
+
* it from the diagnostics layer, never during a gesture.
|
|
337
|
+
*/
|
|
338
|
+
ensureKeyframeIndex?(): Promise<void>;
|
|
339
|
+
close(): Promise<void>;
|
|
340
|
+
}
|
|
341
|
+
export type ScrubCursorFactory = (options: CreateScrubCursorOptions) => Promise<ScrubCursor>;
|
|
342
|
+
//# sourceMappingURL=scrub-cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrub-cursor.d.ts","sourceRoot":"","sources":["../src/scrub-cursor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Sec } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Reads which way a scrub gesture is travelling, so a prefetch window can spend
|
|
4
|
+
* its budget on the side of the playhead the hand is moving toward.
|
|
5
|
+
*
|
|
6
|
+
* The heading spans a bounded ring of recent samples, so one jittery pointer
|
|
7
|
+
* move cannot swing it. A step opposing the ring's heading drops the samples
|
|
8
|
+
* behind it, leaving the reversal as the only evidence of where the gesture is
|
|
9
|
+
* going.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ScrubTrajectory {
|
|
12
|
+
private readonly capacity;
|
|
13
|
+
private readonly positionsS;
|
|
14
|
+
private readonly timesMs;
|
|
15
|
+
private count;
|
|
16
|
+
private writeIndex;
|
|
17
|
+
constructor(capacity?: number);
|
|
18
|
+
sample(positionS: Sec, atMs: number): void;
|
|
19
|
+
/**
|
|
20
|
+
* Which way the gesture is travelling: 1 forward, -1 backward, 0 when there
|
|
21
|
+
* is not enough of a gesture to say. The direction survives being uncertain
|
|
22
|
+
* about how far, which is all a window split needs.
|
|
23
|
+
*/
|
|
24
|
+
heading(): -1 | 0 | 1;
|
|
25
|
+
reset(): void;
|
|
26
|
+
private netDisplacementS;
|
|
27
|
+
private indexFromNewest;
|
|
28
|
+
private indexFromOldest;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=scrub-trajectory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrub-trajectory.d.ts","sourceRoot":"","sources":["../src/scrub-trajectory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AASnC;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,UAAU,CAAK;gBAEX,QAAQ,GAAE,MAAgC;IAMtD,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAgC1C;;;;OAIG;IACH,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAUrB,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,eAAe;CAKxB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Byte residency for a URL source: the bytes this process holds, the fetch that
|
|
3
|
+
* serves them to the demuxer, and a background walk that fills the rest in.
|
|
4
|
+
*
|
|
5
|
+
* The browser HTTP cache does not do this job for media. A 200 response is
|
|
6
|
+
* stored whole and read back in about a millisecond, but the demuxer never
|
|
7
|
+
* issues one: it opens the file with `Range: bytes=N-` and abandons the
|
|
8
|
+
* response once it has what it wanted, so every read is stored as sparse data
|
|
9
|
+
* against a single cache entry. Sparse data is evicted long before a hundred
|
|
10
|
+
* megabytes of it accumulates, and a whole-file fetch issued after the demuxer
|
|
11
|
+
* has already touched the URL lands in that same sparse entry and is discarded
|
|
12
|
+
* with it. Bytes held here are held for as long as this session wants them,
|
|
13
|
+
* whatever the cache does.
|
|
14
|
+
*/
|
|
15
|
+
/** A held run of the source file, `end` exclusive. */
|
|
16
|
+
export interface ResidentRange {
|
|
17
|
+
readonly start: number;
|
|
18
|
+
readonly end: number;
|
|
19
|
+
}
|
|
20
|
+
export interface ResidencySnapshot {
|
|
21
|
+
/** Held runs, ascending, never touching or overlapping. */
|
|
22
|
+
readonly ranges: readonly ResidentRange[];
|
|
23
|
+
readonly residentBytes: number;
|
|
24
|
+
/** Source length once a response has disclosed it, else null. */
|
|
25
|
+
readonly totalBytes: number | null;
|
|
26
|
+
/** Bytes the background walk has pulled, excluding what playback pulled. */
|
|
27
|
+
readonly prefetchedBytes: number;
|
|
28
|
+
readonly warming: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface SourceResidencyOptions {
|
|
31
|
+
readonly url: string;
|
|
32
|
+
/** Ceiling on held bytes. Runs furthest from the focus offset are dropped first. */
|
|
33
|
+
readonly budgetBytes: number;
|
|
34
|
+
/** Largest single background request. */
|
|
35
|
+
readonly chunkBytes?: number;
|
|
36
|
+
readonly requestInit?: RequestInit;
|
|
37
|
+
readonly fetchImpl?: typeof fetch;
|
|
38
|
+
}
|
|
39
|
+
export interface SourceResidency {
|
|
40
|
+
/** Hand to mediabunny's `UrlSource` as its `fetchFn`. */
|
|
41
|
+
readonly fetchFn: typeof fetch;
|
|
42
|
+
snapshot(): ResidencySnapshot;
|
|
43
|
+
/**
|
|
44
|
+
* Offset the background walk works outward from, so the bytes nearest the
|
|
45
|
+
* playhead arrive first and a viewer who seeks nearby stops waiting soonest.
|
|
46
|
+
*/
|
|
47
|
+
focusAt(offset: number): void;
|
|
48
|
+
startWarming(): void;
|
|
49
|
+
stopWarming(): void;
|
|
50
|
+
dispose(): void;
|
|
51
|
+
}
|
|
52
|
+
/** Granularity at which a streaming read is banked. Mediabunny never asks
|
|
53
|
+
* the network for less than half a mebibyte, so every read it makes banks
|
|
54
|
+
* at least one block. */
|
|
55
|
+
export declare const READ_BLOCK_BYTES: number;
|
|
56
|
+
export declare function createSourceResidency(options: SourceResidencyOptions): SourceResidency;
|
|
57
|
+
//# sourceMappingURL=source-residency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-residency.d.ts","sourceRoot":"","sources":["../src/source-residency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,OAAO,KAAK,CAAC;IAC/B,QAAQ,IAAI,iBAAiB,CAAC;IAC9B;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,IAAI,IAAI,CAAC;IACrB,WAAW,IAAI,IAAI,CAAC;IACpB,OAAO,IAAI,IAAI,CAAC;CACjB;AAQD;;0BAE0B;AAC1B,eAAO,MAAM,gBAAgB,QAAa,CAAC;AAwI3C,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CA8KjB"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import type { FrameQuality } from "./scrub-cursor";
|
|
2
|
+
import { type DiagnosticsSnapshot, type Warning } from "./diagnostics";
|
|
3
|
+
/**
|
|
4
|
+
* Worker-realm trace recorder. Two fixed-capacity ring buffers capture a rolling
|
|
5
|
+
* window of what the runtime did: an EVENT ring (paints, scrubs, seeks, and
|
|
6
|
+
* status transitions, the moments EngineCore drives directly) and a SNAPSHOT
|
|
7
|
+
* ring (the same DiagnosticsSnapshot references already assembled for the
|
|
8
|
+
* broadcast). Both overwrite oldest in place, so a long session has a constant,
|
|
9
|
+
* predictable footprint and the appends are O(1) with no growth or GC churn.
|
|
10
|
+
*
|
|
11
|
+
* Stall and decode-spike depth are not separate events: stalls ride the snapshot
|
|
12
|
+
* ring (realtime.stalls), and per-decode latency rides the scrub stats, so the
|
|
13
|
+
* event ring stays to the moments the engine itself initiates.
|
|
14
|
+
*
|
|
15
|
+
* Allocated on arm, freed on disarm or export, so a disarmed recorder costs
|
|
16
|
+
* zero memory. assemble() walks both rings ascending into one self-describing
|
|
17
|
+
* versioned JSON document an agent or a human can read cold: the summary carries
|
|
18
|
+
* the exact Warning diagnoses the UI shows, so the trace explains itself.
|
|
19
|
+
*
|
|
20
|
+
* Pure data. It never touches decode, the sink, or the cursor.
|
|
21
|
+
*/
|
|
22
|
+
export declare const TRACE_SCHEMA = "roboflow.videoEngine.trace/2";
|
|
23
|
+
/** One captured runtime event. type is the moment ("paint", "scrub", "seek",
|
|
24
|
+
* "status"); tMs is worker-clock relative to arm; the rest are optional payload
|
|
25
|
+
* fields the relevant moment fills. All plain data. */
|
|
26
|
+
export interface TraceEvent {
|
|
27
|
+
readonly type: "paint" | "scrub" | "seek" | "status" | "rate";
|
|
28
|
+
readonly tMs: number;
|
|
29
|
+
readonly mediaTimeMs?: number;
|
|
30
|
+
readonly paintSeq?: number;
|
|
31
|
+
/** paint: which frame of the source these pixels are, by the engine's frame
|
|
32
|
+
* table. The snapshot ring samples at 10Hz and paints outrun it, so without
|
|
33
|
+
* this the frame most paints put up is named nowhere in the trace. */
|
|
34
|
+
readonly frameIndex?: number;
|
|
35
|
+
readonly catchUpMs?: number;
|
|
36
|
+
/** paint: whether a full decode or the coarse stand-in reached the canvas.
|
|
37
|
+
* Paints come from sources with materially different pixel quality, so a
|
|
38
|
+
* trace without this cannot tell a crisp frame from a blurry one. */
|
|
39
|
+
readonly quality?: FrameQuality;
|
|
40
|
+
/** seek/scrub: the target the gesture aimed at, and where it landed.
|
|
41
|
+
* paint: the position the paint was serving (the engine clock at paint). */
|
|
42
|
+
readonly targetMs?: number;
|
|
43
|
+
readonly landedMs?: number;
|
|
44
|
+
/** seek: whether it was a key-only navigation seek. */
|
|
45
|
+
readonly keyOnly?: boolean;
|
|
46
|
+
/** status: the new playback status string. */
|
|
47
|
+
readonly status?: string;
|
|
48
|
+
/** rate: the new playback rate. Every paint after it is served by a clock
|
|
49
|
+
* running at a different slope, which the timestamps alone do not show. */
|
|
50
|
+
readonly rate?: number;
|
|
51
|
+
}
|
|
52
|
+
/** A broadcast snapshot with the moment it was taken, in the same worker-clock
|
|
53
|
+
* milliseconds since arm that every event carries, so the two series line up. */
|
|
54
|
+
export type TracedSnapshot = DiagnosticsSnapshot & {
|
|
55
|
+
readonly tMs: number;
|
|
56
|
+
};
|
|
57
|
+
/** Environment facts captured once at export, so a trace read elsewhere carries
|
|
58
|
+
* the device context that shaped the numbers. */
|
|
59
|
+
export interface TraceEnvironment {
|
|
60
|
+
readonly userAgent: string;
|
|
61
|
+
readonly webgpuAvailable: boolean;
|
|
62
|
+
/** Null when nobody measured one: the engine has no window to read it off, so
|
|
63
|
+
* it knows the ratio only when a host hands it a display box or a canvas. */
|
|
64
|
+
readonly devicePixelRatio: number | null;
|
|
65
|
+
readonly hardwareConcurrency: number;
|
|
66
|
+
}
|
|
67
|
+
/** Rolled-up totals for a glanceable read, with the same Warning diagnoses the
|
|
68
|
+
* UI shows so the trace is self-explaining. effectivePaintFps is measured across
|
|
69
|
+
* every snapshot pushed since arm, so it covers more than the snapshots the ring
|
|
70
|
+
* still holds; no snapshot carries such a reading. cacheHitRatePct is null until
|
|
71
|
+
* something looks the cache up, and cacheLookups is its denominator, so a reader
|
|
72
|
+
* can tell a cold cache from a failing one. */
|
|
73
|
+
export interface TraceSummary {
|
|
74
|
+
readonly scrubP50Ms: number;
|
|
75
|
+
readonly scrubP95Ms: number;
|
|
76
|
+
readonly scrubMaxMs: number;
|
|
77
|
+
readonly effectivePaintFps: number | null;
|
|
78
|
+
readonly lateFrames: number;
|
|
79
|
+
readonly stalls: number;
|
|
80
|
+
readonly maxCatchUpMs: number;
|
|
81
|
+
readonly cacheHitRatePct: number | null;
|
|
82
|
+
readonly cacheLookups: number;
|
|
83
|
+
readonly exactEvictions: number;
|
|
84
|
+
readonly warnings: Warning[];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* How much of the capture one ring can still answer for. A capture older than a
|
|
88
|
+
* ring's capacity keeps only its tail, so durationMs describes the session and
|
|
89
|
+
* this describes the evidence: coveredMs runs from the oldest entry still held,
|
|
90
|
+
* and dropped counts what was overwritten to make room.
|
|
91
|
+
*/
|
|
92
|
+
export interface TraceRingCoverage {
|
|
93
|
+
readonly capacity: number;
|
|
94
|
+
readonly retained: number;
|
|
95
|
+
readonly dropped: number;
|
|
96
|
+
readonly oldestTMs: number | null;
|
|
97
|
+
readonly newestTMs: number | null;
|
|
98
|
+
readonly coveredMs: number;
|
|
99
|
+
}
|
|
100
|
+
/** Per-ring coverage. The two rings fill at different rates, so they reach back
|
|
101
|
+
* different distances and neither one is "the captured window". */
|
|
102
|
+
export interface TraceCoverage {
|
|
103
|
+
readonly events: TraceRingCoverage;
|
|
104
|
+
readonly snapshots: TraceRingCoverage;
|
|
105
|
+
}
|
|
106
|
+
/** The assembled trace document. Versioned by schema so a reader knows the shape. */
|
|
107
|
+
export interface EngineTrace {
|
|
108
|
+
readonly schema: typeof TRACE_SCHEMA;
|
|
109
|
+
readonly capturedAt: number;
|
|
110
|
+
readonly armOriginMs: number;
|
|
111
|
+
readonly durationMs: number;
|
|
112
|
+
readonly coverage: TraceCoverage;
|
|
113
|
+
/** Why the capture stopped early, or null when a reader closed it. */
|
|
114
|
+
readonly truncatedReason: string | null;
|
|
115
|
+
readonly environment: TraceEnvironment;
|
|
116
|
+
readonly events: TraceEvent[];
|
|
117
|
+
readonly snapshots: TracedSnapshot[];
|
|
118
|
+
readonly summary: TraceSummary;
|
|
119
|
+
}
|
|
120
|
+
export interface TraceRecorderEnvironment {
|
|
121
|
+
readonly userAgent: string;
|
|
122
|
+
readonly webgpuAvailable: boolean;
|
|
123
|
+
readonly devicePixelRatio: number | null;
|
|
124
|
+
readonly hardwareConcurrency: number;
|
|
125
|
+
}
|
|
126
|
+
export declare class TraceRecorder {
|
|
127
|
+
private readonly env;
|
|
128
|
+
private readonly now;
|
|
129
|
+
private readonly events;
|
|
130
|
+
private readonly snapshots;
|
|
131
|
+
private readonly armOriginMs;
|
|
132
|
+
private paintedFrames;
|
|
133
|
+
private playingMs;
|
|
134
|
+
private lastSnapshotAtMs;
|
|
135
|
+
private lastPaints;
|
|
136
|
+
private lastSnapshotPlaying;
|
|
137
|
+
private truncatedReason;
|
|
138
|
+
constructor(env: TraceRecorderEnvironment, now?: () => number, eventCap?: number, snapshotCap?: number);
|
|
139
|
+
pushEvent(event: TraceEvent): void;
|
|
140
|
+
/**
|
|
141
|
+
* Stamps the broadcast snapshot with when it was taken and rings it. The
|
|
142
|
+
* stamp is the whole point of keeping a series: without it the snapshots are
|
|
143
|
+
* an unordered pile with no way to line them up against the events, which
|
|
144
|
+
* carry one, or to tell a freeze from a slow stretch.
|
|
145
|
+
*/
|
|
146
|
+
pushSnapshot(snapshot: DiagnosticsSnapshot): void;
|
|
147
|
+
/** Records that the capture was cut short by something other than a reader
|
|
148
|
+
* closing it, so an assembled trace says why it ends where it does. The
|
|
149
|
+
* first reason sticks: it is the one that ended the capture. */
|
|
150
|
+
truncate(reason: string): void;
|
|
151
|
+
/**
|
|
152
|
+
* Paints between two consecutive snapshots over the wall time between them.
|
|
153
|
+
* An interval counts only when playback was up at both ends, since one
|
|
154
|
+
* folded-in pause paints nothing and sinks the rate far below what the user
|
|
155
|
+
* watched. The paint counter restarts with each play session, so a negative
|
|
156
|
+
* delta means a new session began and that interval is dropped.
|
|
157
|
+
*/
|
|
158
|
+
private accumulatePaintRate;
|
|
159
|
+
/** Worker-clock milliseconds since arm; the stamp every pushed event uses. */
|
|
160
|
+
elapsedMs(): number;
|
|
161
|
+
assemble(): EngineTrace;
|
|
162
|
+
private summarize;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=trace-recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-recorder.d.ts","sourceRoot":"","sources":["../src/trace-recorder.ts"],"names":[],"mappings":"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"}
|