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,74 @@
|
|
|
1
|
+
import { type WalkFrameSource, type WalkSourceHandle } from "./decode-source";
|
|
2
|
+
import type { VideoSampleLike } from "./scrub-cursor";
|
|
3
|
+
import type { VideoSource } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* One frame of a walk.
|
|
6
|
+
*
|
|
7
|
+
* `frameIndex` counts real frames from the start of the walked range, so the
|
|
8
|
+
* same frame carries the same number whatever stride was taken, and
|
|
9
|
+
* `timestampMs` is the sample's own.
|
|
10
|
+
*
|
|
11
|
+
* `sample` is live and closing it is the caller's, the obligation every
|
|
12
|
+
* VideoSampleLike carries. One dropped without close holds a decoder frame until
|
|
13
|
+
* garbage collection, which WebCodecs complains about on the console and which
|
|
14
|
+
* starves the decoder long before that.
|
|
15
|
+
*/
|
|
16
|
+
export interface WalkedFrame {
|
|
17
|
+
readonly frameIndex: number;
|
|
18
|
+
readonly timestampMs: number;
|
|
19
|
+
readonly durationMs: number;
|
|
20
|
+
readonly sample: VideoSampleLike;
|
|
21
|
+
}
|
|
22
|
+
export interface FrameWalkRange {
|
|
23
|
+
/** Inclusive start; the track's first timestamp when omitted. */
|
|
24
|
+
readonly startMs?: number;
|
|
25
|
+
/** Exclusive end, so two abutting ranges walk every frame once between them;
|
|
26
|
+
* the end of the source when omitted. */
|
|
27
|
+
readonly endMs?: number;
|
|
28
|
+
/** Yield every Nth real frame. Counted in frames, not in time, so the spacing
|
|
29
|
+
* holds on a variable-rate source and cannot accumulate drift. */
|
|
30
|
+
readonly stride?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface FrameWalkMetadata {
|
|
33
|
+
readonly durationS: number;
|
|
34
|
+
readonly width: number;
|
|
35
|
+
readonly height: number;
|
|
36
|
+
readonly nativeFps: number | null;
|
|
37
|
+
readonly firstTimestampS: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Every real decoded frame of a range, in presentation order, exactly once.
|
|
41
|
+
*
|
|
42
|
+
* Nothing here is synthesized: the walk reads the source's own frames and counts
|
|
43
|
+
* them. Timestamps built from a frame rate and resolved through at-or-before
|
|
44
|
+
* extraction cannot promise that. One falling a float's width short of a sample
|
|
45
|
+
* lands on the frame before it, so the caller gets that frame twice and never
|
|
46
|
+
* sees the one it was aiming at.
|
|
47
|
+
*
|
|
48
|
+
* Every sample the walk decodes and does not yield is closed here: the frames
|
|
49
|
+
* before the range, the ones stride skips, and the first one past the end.
|
|
50
|
+
* Breaking out of the walk returns the underlying stream, which releases the
|
|
51
|
+
* decoder's read of the source; the sample in the caller's hand at that moment
|
|
52
|
+
* is still the caller's to close.
|
|
53
|
+
*/
|
|
54
|
+
export declare function walkFrames(source: WalkFrameSource, range?: FrameWalkRange): AsyncGenerator<WalkedFrame, void, unknown>;
|
|
55
|
+
/**
|
|
56
|
+
* A batch consumer's entry to the runtime: opens a source, walks its real
|
|
57
|
+
* frames, and disposes what it opened. It spins no worker, binds no canvas, and
|
|
58
|
+
* runs no clock, and it decodes on an input of its own, so a walk and a playing
|
|
59
|
+
* engine never contend for one decoder's read head.
|
|
60
|
+
*
|
|
61
|
+
* A walk in flight ends when the walker is closed, the same way extraction does,
|
|
62
|
+
* so a consumer that abandons a job mid-range has one call to make.
|
|
63
|
+
*/
|
|
64
|
+
export declare class FrameWalker {
|
|
65
|
+
private readonly handle;
|
|
66
|
+
private closed;
|
|
67
|
+
constructor(handle: WalkSourceHandle);
|
|
68
|
+
/** Opens a source for walking; the returned walker owns it. */
|
|
69
|
+
static open(source: VideoSource): Promise<FrameWalker>;
|
|
70
|
+
get metadata(): FrameWalkMetadata;
|
|
71
|
+
walkFrames(range?: FrameWalkRange): AsyncGenerator<WalkedFrame, void, unknown>;
|
|
72
|
+
close(): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=frame-walker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-walker.d.ts","sourceRoot":"","sources":["../src/frame-walker.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAQ3C;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;8CAC0C;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;uEACmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAuB,UAAU,CAC/B,MAAM,EAAE,eAAe,EACvB,KAAK,GAAE,cAAmB,GACzB,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,CA8C5C;AAED;;;;;;;;GAQG;AACH,qBAAa,WAAW;IAGV,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,MAAM,CAAS;gBAEM,MAAM,EAAE,gBAAgB;IAErD,+DAA+D;WAClD,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAI5D,IAAI,QAAQ,IAAI,iBAAiB,CAShC;IAEM,UAAU,CACf,KAAK,GAAE,cAAmB,GACzB,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC;IAoBvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web-video-engine/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,oCAAoC,EACpC,0BAA0B,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,6BAA6B,GACnC,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An H.264 sync sample that is not an IDR frame cannot open a WebCodecs decode
|
|
3
|
+
* session: Chrome rejects the chunk with "An EncodedVideoChunk was marked as
|
|
4
|
+
* type key but wasn't a key frame" and emits no frames. Adding a recovery-point
|
|
5
|
+
* SEI to the access unit declares it a valid entry point, which is enough for the
|
|
6
|
+
* decoder to accept it and decode forward from there.
|
|
7
|
+
*
|
|
8
|
+
* The decoder demands an entry point for exactly one chunk, the first after
|
|
9
|
+
* configure() or flush(), and putting the SEI on any other chunk misdescribes
|
|
10
|
+
* the stream. KeyPacketRequirement is what tracks which chunk that is.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Width of the AVCC length prefix this track frames every NAL with, read from
|
|
14
|
+
* its avcC record, or null when the description names no usable width. Files
|
|
15
|
+
* carry 1, 2, and 4, so nothing downstream may assume one of them.
|
|
16
|
+
*/
|
|
17
|
+
export declare function nalPrefixWidth(description: VideoDecoderConfig["description"]): number | null;
|
|
18
|
+
/**
|
|
19
|
+
* Whether this access unit carries an IDR slice.
|
|
20
|
+
*
|
|
21
|
+
* A container's sync table names sync samples, and an H.264 sync sample is
|
|
22
|
+
* usually an ordinary I picture rather than an IDR. The two differ in what a
|
|
23
|
+
* decoder may assume about the pictures that follow: an IDR empties the
|
|
24
|
+
* reference list, so nothing after it can name a picture from before it, while
|
|
25
|
+
* an I picture leaves the list standing and the next reference frame is free to
|
|
26
|
+
* name pictures the entry point never decoded. Only the IDR is an entry point
|
|
27
|
+
* the bitstream cannot invalidate.
|
|
28
|
+
*
|
|
29
|
+
* Unreadable framing reads as not-IDR: the caller's fallback is to enter
|
|
30
|
+
* further back, which costs a walk and is never wrong.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isIdrAccessUnit(packetBytes: Uint8Array, prefixWidth: number): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The access unit as the chunk that opens a decode, carrying the recovery-point
|
|
35
|
+
* SEI that makes it a legal entry point.
|
|
36
|
+
*
|
|
37
|
+
* Where the SEI goes is the whole of it: an access unit delimiter, when the
|
|
38
|
+
* packet has one, is required to be the access unit's first NAL, so the SEI goes
|
|
39
|
+
* behind it. Ahead of it the access unit is malformed, and a decoder reading the
|
|
40
|
+
* opening chunk to decide whether it is really a key frame is entitled to say it
|
|
41
|
+
* is not.
|
|
42
|
+
*/
|
|
43
|
+
export declare function openingKeyPacket(packetBytes: Uint8Array, prefixWidth: number): Uint8Array;
|
|
44
|
+
/**
|
|
45
|
+
* WebCodecs' standing demand for a key frame, which configure() and flush()
|
|
46
|
+
* both arm and the next submitted chunk clears.
|
|
47
|
+
*/
|
|
48
|
+
export declare class KeyPacketRequirement {
|
|
49
|
+
private readonly prefixWidth;
|
|
50
|
+
private pending;
|
|
51
|
+
constructor(prefixWidth: number);
|
|
52
|
+
/** Whether the demand still stands, so the chunk about to satisfy it can
|
|
53
|
+
* also be typed as the key chunk the decoder is waiting for. */
|
|
54
|
+
get armed(): boolean;
|
|
55
|
+
/** Call after every configure() and flush(). */
|
|
56
|
+
rearm(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Bytes to submit for the next packet in decode order, carrying the
|
|
59
|
+
* recovery-point SEI while the demand stands. The container reports sync
|
|
60
|
+
* samples, never IDR frames, so the SEI goes on without inspecting the
|
|
61
|
+
* packet; ahead of a true IDR it is a NAL the decoder ignores.
|
|
62
|
+
*/
|
|
63
|
+
satisfy(packetBytes: Uint8Array): Uint8Array;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=key-packet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-packet.d.ts","sourceRoot":"","sources":["../src/key-packet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAyCH;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,kBAAkB,CAAC,aAAa,CAAC,GAC7C,MAAM,GAAG,IAAI,CAOf;AAqED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,UAAU,EACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAIT;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,UAAU,EACvB,WAAW,EAAE,MAAM,GAClB,UAAU,CAWZ;AAaD;;;GAGG;AACH,qBAAa,oBAAoB;IAGnB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAFxC,OAAO,CAAC,OAAO,CAAQ;gBAEM,WAAW,EAAE,MAAM;IAEhD;qEACiE;IACjE,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,gDAAgD;IAChD,KAAK,IAAI,IAAI;IAIb;;;;;OAKG;IACH,OAAO,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU;CAK7C"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy index of a video track's keyframe timestamps, in seconds.
|
|
3
|
+
*
|
|
4
|
+
* Seeking decodes forward from the keyframe at-or-before the target, so every
|
|
5
|
+
* seek needs that anchor. Resolving one costs a container round-trip, so the
|
|
6
|
+
* index remembers each keyframe it discovers; repeated seeks around the same
|
|
7
|
+
* region then resolve synchronously through `cachedAtOrBefore`.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Opaque packet handle. Only `timestamp` is read; the object is threaded back
|
|
11
|
+
* into `getNextKeyPacket` unchanged so the probe's hidden packet fields survive.
|
|
12
|
+
*/
|
|
13
|
+
export interface KeyframePacketLike {
|
|
14
|
+
readonly timestamp: number;
|
|
15
|
+
}
|
|
16
|
+
interface KeyframeRetrievalOptions {
|
|
17
|
+
readonly metadataOnly?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** The slice of mediabunny's `EncodedPacketSink` the index depends on. */
|
|
20
|
+
export interface KeyframeProbe {
|
|
21
|
+
getKeyPacket(timestamp: number, options?: KeyframeRetrievalOptions): Promise<KeyframePacketLike | null>;
|
|
22
|
+
getNextKeyPacket(packet: KeyframePacketLike, options?: KeyframeRetrievalOptions): Promise<KeyframePacketLike | null>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Distribution of the gaps between discovered keyframes, in seconds. A long
|
|
26
|
+
* maxGopS (or a high stddev) is the badly-encoded-source tell: an off-anchor
|
|
27
|
+
* seek must decode forward from the prior keyframe, so a long GOP is a wall of
|
|
28
|
+
* frames every scrub pays for. Zeros when fewer than two keyframes are known.
|
|
29
|
+
*/
|
|
30
|
+
export interface GopStats {
|
|
31
|
+
readonly count: number;
|
|
32
|
+
readonly avgGopS: number;
|
|
33
|
+
readonly maxGopS: number;
|
|
34
|
+
readonly minGopS: number;
|
|
35
|
+
readonly stddevS: number;
|
|
36
|
+
readonly densityPerS: number;
|
|
37
|
+
}
|
|
38
|
+
export declare class KeyframeIndex {
|
|
39
|
+
private readonly probe;
|
|
40
|
+
private readonly times;
|
|
41
|
+
private probeRoundTrips;
|
|
42
|
+
/** Set once a full walk has completed, so a second call is a free no-op. */
|
|
43
|
+
private fullyIndexed;
|
|
44
|
+
constructor(probe: KeyframeProbe);
|
|
45
|
+
/** Keyframe timestamps discovered so far, ascending and deduplicated. */
|
|
46
|
+
get known(): readonly number[];
|
|
47
|
+
/** Container queries the index has made; the rest resolve from memory. */
|
|
48
|
+
get probeCount(): number;
|
|
49
|
+
/**
|
|
50
|
+
* GOP-gap distribution over the keyframes discovered so far. Pass the track
|
|
51
|
+
* duration so density reflects keyframes across the whole clip, not just the
|
|
52
|
+
* clustered swept span; without it a few discovered keyframes in one region
|
|
53
|
+
* would read as a high density that does not hold track-wide.
|
|
54
|
+
*/
|
|
55
|
+
gopStats(durationS?: number): GopStats;
|
|
56
|
+
/**
|
|
57
|
+
* Nearest keyframe at or before `tSec`, the anchor a seek decodes forward
|
|
58
|
+
* from. Null when `tSec` precedes the first keyframe.
|
|
59
|
+
*/
|
|
60
|
+
keyframeAtOrBefore(tSec: number): Promise<number | null>;
|
|
61
|
+
/**
|
|
62
|
+
* First keyframe strictly after `tSec`, the boundary a forward decode runs
|
|
63
|
+
* up to. Null when no keyframe follows, or when `tSec` precedes the first
|
|
64
|
+
* keyframe (no anchor to step from).
|
|
65
|
+
*/
|
|
66
|
+
nextKeyframeAfter(tSec: number): Promise<number | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Every keyframe needed to decode the window `[startS, endS]`: the anchor at
|
|
69
|
+
* or before `startS` plus each keyframe up to `endS`. Empty when `startS`
|
|
70
|
+
* precedes the first keyframe.
|
|
71
|
+
*/
|
|
72
|
+
keyframesCovering(startS: number, endS: number): Promise<readonly number[]>;
|
|
73
|
+
/**
|
|
74
|
+
* Walks the whole track once, recording every keyframe timestamp. Metadata
|
|
75
|
+
* only: it threads the same getKeyPacket / getNextKeyPacket pattern as the
|
|
76
|
+
* lazy probes, so it never decodes a pixel. Idempotent: a second call after a
|
|
77
|
+
* completed walk returns at once. Meant for the diagnostics lane, off the hot
|
|
78
|
+
* seek path, so the purple lane reflects the whole file rather than only the
|
|
79
|
+
* regions a scrub has visited.
|
|
80
|
+
*/
|
|
81
|
+
ensureFullyIndexed(fromS?: number): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Largest discovered keyframe at or before `tSec`, resolved synchronously
|
|
84
|
+
* from memory. Null when nothing at or before `tSec` has been discovered
|
|
85
|
+
* yet; callers fall back to the async probes above.
|
|
86
|
+
*/
|
|
87
|
+
cachedAtOrBefore(tSec: number): number | null;
|
|
88
|
+
private record;
|
|
89
|
+
}
|
|
90
|
+
export {};
|
|
91
|
+
//# sourceMappingURL=keyframe-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyframe-index.d.ts","sourceRoot":"","sources":["../src/keyframe-index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,UAAU,wBAAwB;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,YAAY,CACV,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACtC,gBAAgB,CACd,MAAM,EAAE,kBAAkB,EAC1B,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACvC;AAKD;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,qBAAa,aAAa;IAMZ,OAAO,CAAC,QAAQ,CAAC,KAAK;IALlC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,eAAe,CAAK;IAC5B,4EAA4E;IAC5E,OAAO,CAAC,YAAY,CAAS;gBAEA,KAAK,EAAE,aAAa;IAEjD,yEAAyE;IACzE,IAAI,KAAK,IAAI,SAAS,MAAM,EAAE,CAE7B;IAED,0EAA0E;IAC1E,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ;IAwCtC;;;OAGG;IACG,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQ9D;;;;OAIG;IACG,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAY7D;;;;OAIG;IACG,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC;IAc7B;;;;;;;OAOG;IACG,kBAAkB,CAAC,KAAK,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD;;;;OAIG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAK7C,OAAO,CAAC,MAAM;CAKf"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { FrameId, FrameLanding } from "./frame-timeline";
|
|
2
|
+
import { type EngineChannel, type PaintSeq, type PlaybackState, PlaybackStatus } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Tiny external store powering useSyncExternalStore subscriptions. Five
|
|
5
|
+
* emit channels by mutation cadence:
|
|
6
|
+
*
|
|
7
|
+
* - time: emits when the playhead moves to a different frame. Consumers
|
|
8
|
+
* wanting a slower rerender cadence apply their own selector.
|
|
9
|
+
* - frame: emits on every settled cursor-yielded frame, for marker rails.
|
|
10
|
+
* - state: status transitions only. Rare. Driven by load, play, pause,
|
|
11
|
+
* seek, end, error.
|
|
12
|
+
* - duration: emits once per loaded source.
|
|
13
|
+
* - seeking: emits when the cursor transitions in/out of an in-flight
|
|
14
|
+
* scrub. Powers an opt-in scrub-in-flight indicator. Cache-hit
|
|
15
|
+
* scrubs typically don't trip this because the cache paint is
|
|
16
|
+
* synchronous, so the engine writes true only when the cursor
|
|
17
|
+
* is actually doing a decode walk.
|
|
18
|
+
* - rate: emits on a playback-rate change. Rarest channel of the six.
|
|
19
|
+
*
|
|
20
|
+
* Channels are separate so a status-only consumer does not wake up at
|
|
21
|
+
* 60Hz when only time advances.
|
|
22
|
+
*/
|
|
23
|
+
export declare class MirrorStore {
|
|
24
|
+
private playhead;
|
|
25
|
+
private paintSeq;
|
|
26
|
+
private durationMs;
|
|
27
|
+
private status;
|
|
28
|
+
private error;
|
|
29
|
+
private seeking;
|
|
30
|
+
private rate;
|
|
31
|
+
private playbackStateSnapshot;
|
|
32
|
+
private readonly channelListeners;
|
|
33
|
+
getPlayhead(): FrameLanding;
|
|
34
|
+
getDurationMs(): number;
|
|
35
|
+
getStatus(): PlaybackStatus;
|
|
36
|
+
getError(): PlaybackState["error"];
|
|
37
|
+
getPaintSeq(): PaintSeq;
|
|
38
|
+
getPlaybackState(): PlaybackState;
|
|
39
|
+
getSeeking(): boolean;
|
|
40
|
+
getRate(): number;
|
|
41
|
+
/**
|
|
42
|
+
* Moves the playhead onto a frame. Ticks are integers, so the same frame
|
|
43
|
+
* arriving twice is recognised as the same frame and wakes nobody; the
|
|
44
|
+
* millisecond plane this replaced could not tell two positions apart at all,
|
|
45
|
+
* and emitted on every paint.
|
|
46
|
+
*/
|
|
47
|
+
writePlayhead(frame: FrameId, mediaTimeS: number): void;
|
|
48
|
+
writePaintSeq(value: PaintSeq): void;
|
|
49
|
+
writeDurationMs(value: number): void;
|
|
50
|
+
writeStatus(status: PlaybackStatus, error?: PlaybackState["error"]): void;
|
|
51
|
+
writeSeeking(isSeeking: boolean): void;
|
|
52
|
+
writeRate(value: number): void;
|
|
53
|
+
subscribe(channel: EngineChannel, listener: () => void): () => void;
|
|
54
|
+
private emit;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=mirror-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror-store.d.ts","sourceRoot":"","sources":["../src/mirror-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAGd;IACF,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,IAAI,CAAK;IAIjB,OAAO,CAAC,qBAAqB,CAG3B;IAEF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAO/B;IAEF,WAAW,IAAI,YAAY;IAG3B,aAAa,IAAI,MAAM;IAGvB,SAAS,IAAI,cAAc;IAG3B,QAAQ,IAAI,aAAa,CAAC,OAAO,CAAC;IAGlC,WAAW,IAAI,QAAQ;IAGvB,gBAAgB,IAAI,aAAa;IAGjC,UAAU,IAAI,OAAO;IAGrB,OAAO,IAAI,MAAM;IAIjB;;;;;OAKG;IACH,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAMvD,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAMpC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMpC,WAAW,CACT,MAAM,EAAE,cAAc,EACtB,KAAK,GAAE,aAAa,CAAC,OAAO,CAAQ,GACnC,IAAI;IAQP,YAAY,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAMtC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9B,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAOnE,OAAO,CAAC,IAAI;CAGb"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { RendererName } from "./diagnostics";
|
|
2
|
+
import type { ScrubFrame } from "./scrub-cursor";
|
|
3
|
+
/**
|
|
4
|
+
* The colour space every render surface declares. A decoded frame carries its
|
|
5
|
+
* own and the browser converts it into whatever the destination names, but only
|
|
6
|
+
* on the canvas routes: the zero-copy import converts to sRGB whatever colour
|
|
7
|
+
* space it is asked for. A wider value here would therefore reach some routes
|
|
8
|
+
* and not others, on the same frame.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DISPLAY_COLOR_SPACE: PredefinedColorSpace;
|
|
11
|
+
/**
|
|
12
|
+
* The render seam: turns a decoded frame into pixels on the display canvas. The
|
|
13
|
+
* render loop owns timing and frame selection; a Renderer owns only how a frame
|
|
14
|
+
* reaches the screen, so the 2D and WebGPU paths are interchangeable behind it
|
|
15
|
+
* without the loop knowing which is in play.
|
|
16
|
+
*/
|
|
17
|
+
export interface Renderer {
|
|
18
|
+
/** Which backend this is, for diagnostics. */
|
|
19
|
+
readonly name: RendererName;
|
|
20
|
+
/**
|
|
21
|
+
* Paint one frame to fill the canvas, replacing whatever it last showed.
|
|
22
|
+
* A canvas frame carries a CanvasImageSource (a CanvasSink decode or a cache
|
|
23
|
+
* blit); a sample frame carries a live VideoSample the WebGPU path can import
|
|
24
|
+
* zero-copy. The controller owns the sample's lifetime and close, so a
|
|
25
|
+
* renderer never closes the frame it is handed.
|
|
26
|
+
*/
|
|
27
|
+
draw(frame: ScrubFrame): void;
|
|
28
|
+
dispose(): void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 2D-canvas renderer: one blit of an already-decoded frame through a 2D context.
|
|
32
|
+
* It is the graceful-degradation fallback wherever WebGPU is unavailable and the
|
|
33
|
+
* path prefer2d pins. Per the Renderer contract the loop owns cadence, so a draw
|
|
34
|
+
* happens only when a new frame is decoded. This is not a re-decode and not a
|
|
35
|
+
* per-tick repaint; it differs from the WebGPU path only in compositing a frame
|
|
36
|
+
* through a 2D context rather than on the GPU. Canvas dimensions are read live,
|
|
37
|
+
* so a resize between draws is picked up on the next frame.
|
|
38
|
+
*/
|
|
39
|
+
export declare class CanvasRenderer implements Renderer {
|
|
40
|
+
private readonly canvas;
|
|
41
|
+
readonly name: "2d";
|
|
42
|
+
private readonly ctx;
|
|
43
|
+
constructor(canvas: OffscreenCanvas);
|
|
44
|
+
draw(frame: ScrubFrame): void;
|
|
45
|
+
dispose(): void;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The presentation seam: what one paint does with a frame's pixels. The render
|
|
49
|
+
* loop decides which frame is presented and when, and keeps the same books
|
|
50
|
+
* either way; a sink decides only where the pixels go, so the engine's own
|
|
51
|
+
* display canvas and a host compositor are interchangeable behind it.
|
|
52
|
+
*
|
|
53
|
+
* present returns a frame when the pixels left the worker instead of reaching a
|
|
54
|
+
* canvas. That frame has exactly one owner from then on: the sink keeps no
|
|
55
|
+
* reference and never closes it.
|
|
56
|
+
*/
|
|
57
|
+
export interface FrameSink {
|
|
58
|
+
/** The render backend behind this sink, for diagnostics; null when the sink
|
|
59
|
+
* renders nothing. */
|
|
60
|
+
readonly name: RendererName | null;
|
|
61
|
+
present(frame: ScrubFrame): VideoFrame | null;
|
|
62
|
+
dispose(): void;
|
|
63
|
+
}
|
|
64
|
+
/** Pixels to the engine's display canvas, through the resolved Renderer. */
|
|
65
|
+
export declare class RendererFrameSink implements FrameSink {
|
|
66
|
+
private readonly renderer;
|
|
67
|
+
constructor(renderer: Renderer);
|
|
68
|
+
get name(): RendererName;
|
|
69
|
+
present(frame: ScrubFrame): null;
|
|
70
|
+
dispose(): void;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Pixels out of the worker as a VideoFrame, for a host that owns the canvas.
|
|
74
|
+
* A sample hands over its own frame, so a live decode reaches the host without
|
|
75
|
+
* a detour through a canvas. A cache blit has only canvas pixels to give, and
|
|
76
|
+
* the wrap has to be told the media time, which canvas pixels do not carry.
|
|
77
|
+
*/
|
|
78
|
+
export declare class TransferFrameSink implements FrameSink {
|
|
79
|
+
readonly name: null;
|
|
80
|
+
present(frame: ScrubFrame): VideoFrame;
|
|
81
|
+
dispose(): void;
|
|
82
|
+
}
|
|
83
|
+
export interface RendererOptions {
|
|
84
|
+
/** Pin the 2D renderer. Unset, WebGPU is preferred and used when available,
|
|
85
|
+
* falling back to 2D otherwise, so it is not a guarantee of WebGPU. */
|
|
86
|
+
prefer2d?: boolean;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Chooses the render backend for a canvas. WebGPU is the default and probed at
|
|
90
|
+
* runtime; an explicit prefer2d, or any failure to acquire a device, yields the
|
|
91
|
+
* 2D renderer instead, so a caller always gets a working renderer.
|
|
92
|
+
*/
|
|
93
|
+
export declare function createRenderer(canvas: OffscreenCanvas, options?: RendererOptions): Promise<Renderer>;
|
|
94
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,oBAA6B,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;;;;OAMG;IACH,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAIjC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,QAAQ,CAAC,IAAI,EAAG,IAAI,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA2C;gBAElC,MAAM,EAAE,eAAe;IAQpD,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAc7B,OAAO,IAAI,IAAI;CAChB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB;2BACuB;IACvB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAAC;IAC9C,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,4EAA4E;AAC5E,qBAAa,iBAAkB,YAAW,SAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,QAAQ;IAE/C,IAAI,IAAI,IAAI,YAAY,CAEvB;IAED,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAKhC,OAAO,IAAI,IAAI;CAGhB;AAED;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,SAAS;IACjD,QAAQ,CAAC,IAAI,OAAQ;IAErB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU;IAOtC,OAAO,IAAI,IAAI;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B;4EACwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,eAAe,EACvB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,QAAQ,CAAC,CASnB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A quarter turn, in degrees clockwise, that stored pixels still need before
|
|
3
|
+
* they face the way the container says they should. Every phone recording held
|
|
4
|
+
* in portrait carries one: the sensor stores landscape and the track's display
|
|
5
|
+
* matrix names the turn.
|
|
6
|
+
*
|
|
7
|
+
* The sign is mediabunny's, read straight off the track. ffprobe prints the
|
|
8
|
+
* opposite sign for the same file, so a clip ffprobe calls +90 is 270 here.
|
|
9
|
+
*/
|
|
10
|
+
export type Rotation = 0 | 90 | 180 | 270;
|
|
11
|
+
/**
|
|
12
|
+
* Draws an image upright into a destination box, mirroring the transform
|
|
13
|
+
* mediabunny's own VideoSample.draw applies so a frame decoded by the runtime
|
|
14
|
+
* and a frame decoded by a mediabunny sink land the same pixels.
|
|
15
|
+
*
|
|
16
|
+
* dWidth and dHeight name the destination AFTER the turn, which is what the
|
|
17
|
+
* track's display size already is. So on a quarter turn the source is drawn at
|
|
18
|
+
* swapped extents inside the turned frame, and the scale below undoes the
|
|
19
|
+
* aspect that swap introduces.
|
|
20
|
+
*/
|
|
21
|
+
export declare function drawRotated(context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, image: CanvasImageSource, rotation: Rotation, dx: number, dy: number, dWidth: number, dHeight: number): void;
|
|
22
|
+
/**
|
|
23
|
+
* The 2x2 rotation, row-major, that turns a destination texture coordinate
|
|
24
|
+
* about (0.5, 0.5) into the source coordinate to sample. Each entry is
|
|
25
|
+
* [cos -sin; sin cos] evaluated at MINUS the rotation, written out because a
|
|
26
|
+
* quarter turn is exact and trig at these angles is not.
|
|
27
|
+
*
|
|
28
|
+
* The negation is the whole point: sampling turns opposite to the picture, so
|
|
29
|
+
* showing a frame turned clockwise by R means reading it counter-clockwise by
|
|
30
|
+
* R. The unit square is closed under quarter turns about its centre, so the
|
|
31
|
+
* whole source still maps onto the whole destination and the shader's existing
|
|
32
|
+
* stretch-to-fill absorbs the aspect change for free.
|
|
33
|
+
*/
|
|
34
|
+
export declare function uvRotationMatrix(rotation: Rotation): readonly [number, number, number, number];
|
|
35
|
+
//# sourceMappingURL=rotation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../src/rotation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC;AAE1C;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,wBAAwB,GAAG,iCAAiC,EACrE,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,IAAI,CAYN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,GACjB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAE3C"}
|