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.
Files changed (215) hide show
  1. package/dist/detections/chunked-detection-frame-source.d.ts.map +1 -1
  2. package/dist/index.d.ts +11 -4
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +8856 -4559
  5. package/dist/index.js.map +1 -1
  6. package/dist/mask-preparation.worker.js +310 -164
  7. package/dist/mask-preparation.worker.js.map +1 -1
  8. package/dist/media/display-pixel-ratio.d.ts +15 -0
  9. package/dist/media/display-pixel-ratio.d.ts.map +1 -0
  10. package/dist/media/engine-import-failure.d.ts +16 -0
  11. package/dist/media/engine-import-failure.d.ts.map +1 -0
  12. package/dist/media/media-condition-probe.d.ts +51 -0
  13. package/dist/media/media-condition-probe.d.ts.map +1 -0
  14. package/dist/media/media-conditions.d.ts +28 -0
  15. package/dist/media/media-conditions.d.ts.map +1 -0
  16. package/dist/media/media-errors.d.ts +6 -0
  17. package/dist/media/media-errors.d.ts.map +1 -1
  18. package/dist/media/media-normalization.d.ts.map +1 -1
  19. package/dist/media/media-probe.d.ts.map +1 -1
  20. package/dist/media/media-source.d.ts +17 -0
  21. package/dist/media/media-source.d.ts.map +1 -1
  22. package/dist/media/mediabunny-media-source.d.ts.map +1 -1
  23. package/dist/media/video-engine-media-source.d.ts +44 -0
  24. package/dist/media/video-engine-media-source.d.ts.map +1 -0
  25. package/dist/render-preparation/mask-frame-artifact.d.ts +46 -12
  26. package/dist/render-preparation/mask-frame-artifact.d.ts.map +1 -1
  27. package/dist/render-preparation/mask-frame-compositor.d.ts +5 -5
  28. package/dist/render-preparation/mask-frame-compositor.d.ts.map +1 -1
  29. package/dist/render-preparation/mask-frame-preparer.d.ts.map +1 -1
  30. package/dist/render-preparation/mask-preparation-worker-count.d.ts +4 -4
  31. package/dist/render-preparation/mask-preparation-worker-protocol.d.ts +12 -3
  32. package/dist/render-preparation/mask-preparation-worker-protocol.d.ts.map +1 -1
  33. package/dist/render-preparation/prepared-render-window.d.ts +23 -0
  34. package/dist/render-preparation/prepared-render-window.d.ts.map +1 -1
  35. package/dist/render-preparation/prepared-window-timeline.d.ts +2 -6
  36. package/dist/render-preparation/prepared-window-timeline.d.ts.map +1 -1
  37. package/dist/renderers/mask-palette.d.ts +14 -0
  38. package/dist/renderers/mask-palette.d.ts.map +1 -0
  39. package/dist/renderers/mask-vertex.d.ts +14 -0
  40. package/dist/renderers/mask-vertex.d.ts.map +1 -0
  41. package/dist/renderers/media-renderer-core.d.ts.map +1 -1
  42. package/dist/renderers/media-renderer-scene.d.ts +37 -0
  43. package/dist/renderers/media-renderer-scene.d.ts.map +1 -1
  44. package/dist/renderers/media-renderer-state.d.ts +11 -1
  45. package/dist/renderers/media-renderer-state.d.ts.map +1 -1
  46. package/dist/renderers/media-renderer-transport.d.ts +59 -0
  47. package/dist/renderers/media-renderer-transport.d.ts.map +1 -0
  48. package/dist/renderers/pixi-box-layer.d.ts +5 -0
  49. package/dist/renderers/pixi-box-layer.d.ts.map +1 -1
  50. package/dist/renderers/pixi-focus-layer.d.ts +18 -2
  51. package/dist/renderers/pixi-focus-layer.d.ts.map +1 -1
  52. package/dist/renderers/pixi-frame-present.d.ts +77 -0
  53. package/dist/renderers/pixi-frame-present.d.ts.map +1 -0
  54. package/dist/renderers/pixi-id-mask-shader.d.ts +12 -2
  55. package/dist/renderers/pixi-id-mask-shader.d.ts.map +1 -1
  56. package/dist/renderers/pixi-interaction-layer.d.ts.map +1 -1
  57. package/dist/renderers/pixi-interaction-presentation-layer.d.ts +13 -2
  58. package/dist/renderers/pixi-interaction-presentation-layer.d.ts.map +1 -1
  59. package/dist/renderers/pixi-mask-halo.d.ts +24 -0
  60. package/dist/renderers/pixi-mask-halo.d.ts.map +1 -1
  61. package/dist/renderers/pixi-mask-layer.d.ts +71 -8
  62. package/dist/renderers/pixi-mask-layer.d.ts.map +1 -1
  63. package/dist/renderers/pixi-media-scene.d.ts +67 -0
  64. package/dist/renderers/pixi-media-scene.d.ts.map +1 -1
  65. package/dist/renderers/pixi-polygon-layer.d.ts +7 -2
  66. package/dist/renderers/pixi-polygon-layer.d.ts.map +1 -1
  67. package/dist/renderers/pixi-region-coverage-mask.d.ts +91 -0
  68. package/dist/renderers/pixi-region-coverage-mask.d.ts.map +1 -0
  69. package/dist/renderers/pixi-region-effect.d.ts +42 -0
  70. package/dist/renderers/pixi-region-effect.d.ts.map +1 -0
  71. package/dist/renderers/pixi-region-layer.d.ts +68 -2
  72. package/dist/renderers/pixi-region-layer.d.ts.map +1 -1
  73. package/dist/renderers/pixi-vector-layer.d.ts.map +1 -1
  74. package/dist/renderers/prepared-annotation-window.d.ts +47 -0
  75. package/dist/renderers/prepared-annotation-window.d.ts.map +1 -0
  76. package/dist/renderers/presented-frame-channel.d.ts +107 -0
  77. package/dist/renderers/presented-frame-channel.d.ts.map +1 -0
  78. package/dist/renderers/scene-render-scheduler.d.ts +20 -0
  79. package/dist/renderers/scene-render-scheduler.d.ts.map +1 -0
  80. package/dist/sessions/media-session-defaults.d.ts +10 -6
  81. package/dist/sessions/media-session-defaults.d.ts.map +1 -1
  82. package/dist/sessions/media-session-media.d.ts.map +1 -1
  83. package/dist/sessions/media-session-state.d.ts.map +1 -1
  84. package/dist/sessions/media-session.d.ts.map +1 -1
  85. package/dist/tracking.worker.js +58 -3
  86. package/dist/tracking.worker.js.map +1 -1
  87. package/dist/types/media-conditions.d.ts +149 -0
  88. package/dist/types/media-conditions.d.ts.map +1 -0
  89. package/dist/types/media-normalization.d.ts +34 -0
  90. package/dist/types/media-normalization.d.ts.map +1 -1
  91. package/dist/types/media-renderer.d.ts +31 -1
  92. package/dist/types/media-renderer.d.ts.map +1 -1
  93. package/dist/types/media-session.d.ts +89 -8
  94. package/dist/types/media-session.d.ts.map +1 -1
  95. package/dist/types/render-preparation.d.ts +101 -4
  96. package/dist/types/render-preparation.d.ts.map +1 -1
  97. package/dist/web-video-engine/analysis-session.d.ts +76 -0
  98. package/dist/web-video-engine/analysis-session.d.ts.map +1 -0
  99. package/dist/web-video-engine/analysis.d.ts +7 -0
  100. package/dist/web-video-engine/analysis.d.ts.map +1 -0
  101. package/dist/web-video-engine/analysis.js +1678 -0
  102. package/dist/web-video-engine/analysis.js.map +1 -0
  103. package/dist/web-video-engine/cache-budget.d.ts +19 -0
  104. package/dist/web-video-engine/cache-budget.d.ts.map +1 -0
  105. package/dist/web-video-engine/canvas-sink-scrub-cursor.d.ts +90 -0
  106. package/dist/web-video-engine/canvas-sink-scrub-cursor.d.ts.map +1 -0
  107. package/dist/web-video-engine/clock.d.ts +83 -0
  108. package/dist/web-video-engine/clock.d.ts.map +1 -0
  109. package/dist/web-video-engine/constants.d.ts +253 -0
  110. package/dist/web-video-engine/constants.d.ts.map +1 -0
  111. package/dist/web-video-engine/create-scrub-cursor.d.ts +62 -0
  112. package/dist/web-video-engine/create-scrub-cursor.d.ts.map +1 -0
  113. package/dist/web-video-engine/decode-resolution.d.ts +115 -0
  114. package/dist/web-video-engine/decode-resolution.d.ts.map +1 -0
  115. package/dist/web-video-engine/decode-scheduler.d.ts +356 -0
  116. package/dist/web-video-engine/decode-scheduler.d.ts.map +1 -0
  117. package/dist/web-video-engine/decode-session.d.ts +276 -0
  118. package/dist/web-video-engine/decode-session.d.ts.map +1 -0
  119. package/dist/web-video-engine/decode-source.d.ts +250 -0
  120. package/dist/web-video-engine/decode-source.d.ts.map +1 -0
  121. package/dist/web-video-engine/diagnostics-store.d.ts +18 -0
  122. package/dist/web-video-engine/diagnostics-store.d.ts.map +1 -0
  123. package/dist/web-video-engine/diagnostics.d.ts +316 -0
  124. package/dist/web-video-engine/diagnostics.d.ts.map +1 -0
  125. package/dist/web-video-engine/embedded-engine-worker.d.ts +2 -0
  126. package/dist/web-video-engine/embedded-engine-worker.d.ts.map +1 -0
  127. package/dist/web-video-engine/engine-core.d.ts +258 -0
  128. package/dist/web-video-engine/engine-core.d.ts.map +1 -0
  129. package/dist/web-video-engine/engine.d.ts +26 -0
  130. package/dist/web-video-engine/engine.d.ts.map +1 -0
  131. package/dist/web-video-engine/engine.js +873 -0
  132. package/dist/web-video-engine/engine.js.map +1 -0
  133. package/dist/web-video-engine/engine.worker.d.ts +2 -0
  134. package/dist/web-video-engine/engine.worker.d.ts.map +1 -0
  135. package/dist/web-video-engine/engine.worker.js +31320 -0
  136. package/dist/web-video-engine/engine.worker.js.map +1 -0
  137. package/dist/web-video-engine/frame-cache.d.ts +129 -0
  138. package/dist/web-video-engine/frame-cache.d.ts.map +1 -0
  139. package/dist/web-video-engine/frame-extractor.d.ts +28 -0
  140. package/dist/web-video-engine/frame-extractor.d.ts.map +1 -0
  141. package/dist/web-video-engine/frame-timeline-GINI8Gum.js +560 -0
  142. package/dist/web-video-engine/frame-timeline-GINI8Gum.js.map +1 -0
  143. package/dist/web-video-engine/frame-timeline.d.ts +71 -0
  144. package/dist/web-video-engine/frame-timeline.d.ts.map +1 -0
  145. package/dist/web-video-engine/frame-walker.d.ts +74 -0
  146. package/dist/web-video-engine/frame-walker.d.ts.map +1 -0
  147. package/dist/web-video-engine/index.d.ts +3 -0
  148. package/dist/web-video-engine/index.d.ts.map +1 -0
  149. package/dist/web-video-engine/index.js +3 -0
  150. package/dist/web-video-engine/index.js.map +1 -0
  151. package/dist/web-video-engine/key-packet.d.ts +65 -0
  152. package/dist/web-video-engine/key-packet.d.ts.map +1 -0
  153. package/dist/web-video-engine/keyframe-index.d.ts +91 -0
  154. package/dist/web-video-engine/keyframe-index.d.ts.map +1 -0
  155. package/dist/web-video-engine/mirror-store.d.ts +56 -0
  156. package/dist/web-video-engine/mirror-store.d.ts.map +1 -0
  157. package/dist/web-video-engine/renderer.d.ts +94 -0
  158. package/dist/web-video-engine/renderer.d.ts.map +1 -0
  159. package/dist/web-video-engine/rotation.d.ts +35 -0
  160. package/dist/web-video-engine/rotation.d.ts.map +1 -0
  161. package/dist/web-video-engine/scrub-controller.d.ts +376 -0
  162. package/dist/web-video-engine/scrub-controller.d.ts.map +1 -0
  163. package/dist/web-video-engine/scrub-cursor.d.ts +342 -0
  164. package/dist/web-video-engine/scrub-cursor.d.ts.map +1 -0
  165. package/dist/web-video-engine/scrub-trajectory.d.ts +30 -0
  166. package/dist/web-video-engine/scrub-trajectory.d.ts.map +1 -0
  167. package/dist/web-video-engine/source-residency.d.ts +57 -0
  168. package/dist/web-video-engine/source-residency.d.ts.map +1 -0
  169. package/dist/web-video-engine/trace-recorder.d.ts +164 -0
  170. package/dist/web-video-engine/trace-recorder.d.ts.map +1 -0
  171. package/dist/web-video-engine/types.d.ts +204 -0
  172. package/dist/web-video-engine/types.d.ts.map +1 -0
  173. package/dist/web-video-engine/video-engine.d.ts +426 -0
  174. package/dist/web-video-engine/video-engine.d.ts.map +1 -0
  175. package/dist/web-video-engine/webgpu-renderer.d.ts +62 -0
  176. package/dist/web-video-engine/webgpu-renderer.d.ts.map +1 -0
  177. package/dist/web-video-engine/worker-bridge.d.ts +12 -0
  178. package/dist/web-video-engine/worker-bridge.d.ts.map +1 -0
  179. package/dist/web-video-engine/worker-dispatch.d.ts +17 -0
  180. package/dist/web-video-engine/worker-dispatch.d.ts.map +1 -0
  181. package/dist/web-video-engine/worker-protocol.d.ts +267 -0
  182. package/dist/web-video-engine/worker-protocol.d.ts.map +1 -0
  183. package/node_modules/supervision-js-core/dist/detections/buffered-detection-timeline.d.ts.map +1 -1
  184. package/node_modules/supervision-js-core/dist/detections/composite-detection-frame-source.d.ts.map +1 -1
  185. package/node_modules/supervision-js-core/dist/index.d.ts +4 -3
  186. package/node_modules/supervision-js-core/dist/index.d.ts.map +1 -1
  187. package/node_modules/supervision-js-core/dist/index.js +1075 -266
  188. package/node_modules/supervision-js-core/dist/index.js.map +1 -1
  189. package/node_modules/supervision-js-core/dist/styles/default-annotation-presentation.d.ts.map +1 -1
  190. package/node_modules/supervision-js-core/dist/styles/interaction-style.d.ts +4 -36
  191. package/node_modules/supervision-js-core/dist/styles/interaction-style.d.ts.map +1 -1
  192. package/node_modules/supervision-js-core/dist/styles/polyline-style.d.ts +5 -0
  193. package/node_modules/supervision-js-core/dist/styles/polyline-style.d.ts.map +1 -1
  194. package/node_modules/supervision-js-core/dist/types/annotation-renderer.d.ts +92 -7
  195. package/node_modules/supervision-js-core/dist/types/annotation-renderer.d.ts.map +1 -1
  196. package/node_modules/supervision-js-core/dist/types/detection-timeline.d.ts +179 -17
  197. package/node_modules/supervision-js-core/dist/types/detection-timeline.d.ts.map +1 -1
  198. package/node_modules/supervision-js-core/dist/types/media-rendering.d.ts +78 -2
  199. package/node_modules/supervision-js-core/dist/types/media-rendering.d.ts.map +1 -1
  200. package/node_modules/supervision-js-core/dist/types/polyline-style.d.ts +2 -0
  201. package/node_modules/supervision-js-core/dist/types/polyline-style.d.ts.map +1 -1
  202. package/node_modules/supervision-js-core/dist/types/session-lifecycle.d.ts +16 -0
  203. package/node_modules/supervision-js-core/dist/types/session-lifecycle.d.ts.map +1 -1
  204. package/node_modules/supervision-js-core/dist/utils/detection-conversions.d.ts.map +1 -1
  205. package/node_modules/supervision-js-core/dist/utils/detection-frames.d.ts +5 -0
  206. package/node_modules/supervision-js-core/dist/utils/detection-frames.d.ts.map +1 -1
  207. package/node_modules/supervision-js-core/dist/utils/detection-masks.d.ts +9 -0
  208. package/node_modules/supervision-js-core/dist/utils/detection-masks.d.ts.map +1 -1
  209. package/node_modules/supervision-js-core/dist/utils/detection-ranges.d.ts +18 -0
  210. package/node_modules/supervision-js-core/dist/utils/detection-ranges.d.ts.map +1 -0
  211. package/node_modules/supervision-js-core/dist/utils/id-mask-frame.d.ts +15 -2
  212. package/node_modules/supervision-js-core/dist/utils/id-mask-frame.d.ts.map +1 -1
  213. package/node_modules/supervision-js-core/dist/utils/wait-bound.d.ts +7 -0
  214. package/node_modules/supervision-js-core/dist/utils/wait-bound.d.ts.map +1 -0
  215. package/package.json +22 -1
@@ -0,0 +1,560 @@
1
+ /**
2
+ * READ_AHEAD_CANVAS is the playback decode-ahead depth: how many decoded frames
3
+ * the controller keeps queued ahead of the playhead so a decode that overruns a
4
+ * frame interval does not starve the next tick (the cause of stutter even on
5
+ * small, well-encoded clips, where playback otherwise pulls one frame per paint
6
+ * with no cushion). Applies to canvas blits, which are independent and cheap to
7
+ * hold; sample (zero-copy) frames pin a decoder slot each, so the controller
8
+ * keeps those at a depth of one to spare the WebCodecs pool.
9
+ *
10
+ * REANCHOR_STALL_MS is the wall time past which a picture standing still stops
11
+ * being a hitch to work through and becomes a stretch to re-anchor across. Two
12
+ * gaps are measured against it, and they settle in opposite directions.
13
+ *
14
+ * A gap between playing render ticks is a loop nothing was driving, which a
15
+ * hidden tab produces. Nobody was watching, so the clock is the truth and the
16
+ * walk seeks forward onto the playhead.
17
+ *
18
+ * A gap between the walk's deliveries is a pipeline with nothing to show while
19
+ * the loop ran, which a seek onto unbuffered ground produces. The viewer sat
20
+ * through it waiting on a position they asked for, so the frame is the truth
21
+ * and the clock is pulled back onto it. Left to catch up instead, the walk
22
+ * replays the whole wait at decode speed on its way to the playhead: measured
23
+ * against the deployed demo over six seeks, a mean 2.4x for a second, peaking
24
+ * at 24x, with 44 source frames flashed past.
25
+ *
26
+ * Wall time is the reading in both, so a high rate legitimately moving the
27
+ * media clock several frames per gap is not read as an absence.
28
+ *
29
+ * Half a second is where the tick-gap costs cross at 1x. A backlog costs one
30
+ * decode per source frame in it, measured at 240 frames a second on the 30fps
31
+ * demo clip (4.2ms each), against a keyframe-anchored seek at p95 47ms on the
32
+ * same clip: half a second of 30fps backlog is 15 frames, so 63ms of decode
33
+ * against that 47ms, and every higher rate puts more frames in the same gap. It
34
+ * clears the worst legitimate gap of either kind by the same order: a foreground
35
+ * loop leaves a long task or a GC pause to the frame-by-frame path, and forty
36
+ * seconds of network-fed playback of the demo clip held its picture still for at
37
+ * most 51ms.
38
+ *
39
+ * The present cadence is how often playback puts a frame on screen: the rate's
40
+ * whole demand cut to the share of it the machine has been paying for, and never
41
+ * under the source's own frame rate. At a full share the pump declines nothing,
42
+ * which is where a machine with headroom stays at every rate.
43
+ * A step moves the share by PRESENT_CADENCE_STEP, taking a quarter off it when
44
+ * the pipeline has fallen behind the playhead and putting that same quarter back
45
+ * when it has room to spare. The share bottoms out at one over
46
+ * PLAYBACK_RATE.MAX, which is the deepest cut that means anything: below it even
47
+ * the fastest rate asks for less than the source rate the cadence floors at.
48
+ *
49
+ * What takes the share down is a running bill, in frames, between what the clock
50
+ * asked the pipeline for and what the play walk delivered. The bill accumulates
51
+ * rather than being read per tick, which is what tells a shortfall from noise:
52
+ * counting whole frames against a fractional demand leaves every tick out by up
53
+ * to one either way and those cancel, while a machine that cannot sustain the
54
+ * rate falls short every tick and adds up. Measured over 100ms windows on an M3
55
+ * Max at rates 2x to 8x, a pipeline with headroom stayed inside 1.5 frames of
56
+ * its demand either way, so a bill of PRESENT_CADENCE_EVIDENCE_FRAMES frames is
57
+ * one it cannot run up.
58
+ *
59
+ * What puts the share back is the walk holding a frame the clock has not run
60
+ * past, unbroken for the wall time the source takes to produce that many frames.
61
+ * That is the only evidence a pipeline can offer that it has room to spare: a
62
+ * machine at equilibrium delivers exactly what the clock asks for however much
63
+ * headroom it has, so waiting for a surplus in the bill would leave every
64
+ * machine at whatever its worst stretch measured. It is a live reading and the
65
+ * bill is a cumulative one, which is why each takes one direction: ground lost
66
+ * still reads lost once the walk is keeping up again, and catch-up pulls are
67
+ * what carry the walk back onto the playhead.
68
+ *
69
+ * Neither reading is the depth of the decode-ahead queue, which belongs to the
70
+ * decode path and not to the machine: on the zero-copy path, which pins a
71
+ * decoder slot per queued frame and so buffers one, a single frame in hand is
72
+ * full depth and one tick from empty alike.
73
+ *
74
+ * How far behind the machine is therefore sets the pace rather than the size of
75
+ * the step: the bigger the shortfall the sooner the bill reaches that figure and
76
+ * the sooner the next step lands. Zeroing on each step makes the next one gather
77
+ * its own evidence, which is what stops a share sitting at the machine's limit
78
+ * from pulsing.
79
+ *
80
+ * Frames the clock passed, frames the walk delivered and wall time on the
81
+ * playhead: nothing either reading is made of knows what the panel refreshes at,
82
+ * so one machine lands on one cadence on any panel. A faster panel offers more
83
+ * slots and a machine with the headroom fills them; what it cannot do is hold
84
+ * the pump above what the machine pays for, because the share comes down until
85
+ * the pipeline is back on the playhead.
86
+ *
87
+ * PRESENT_CADENCE_SLACK is how far under the interval still counts as a full
88
+ * one. Presents land on display ticks, so a panel refreshing at the ceiling
89
+ * measures each gap as one interval give or take rAF jitter, and an exact
90
+ * comparison would decline every second frame there. A quarter leaves 4.2ms of
91
+ * jitter room at 60Hz.
92
+ *
93
+ * PRESENT_CADENCE_HZ is the demand above which frames the pump culled or
94
+ * declined dominate the dropped-frame ledger, so the discarded-frames rule in
95
+ * evaluateWarnings stands down rather than reading a count it cannot attribute.
96
+ */
97
+ const PLAYBACK = {
98
+ READ_AHEAD_CANVAS: 3};
99
+ /**
100
+ * Forward playback-rate range the engine accepts. Reverse playback needs a
101
+ * backwards decode strategy the runtime does not have, so zero and negative
102
+ * rates are refused rather than approximated.
103
+ *
104
+ * MAX is an API bound, not a promise that every source plays smoothly there.
105
+ * Sustaining rate r means decoding r x nativeFps frames a second, and the
106
+ * decode-ahead cushion is fixed at PLAYBACK.READ_AHEAD_CANVAS frames (raising it
107
+ * would outrun the CanvasSink pool and tear), so how high a given source really
108
+ * goes is a property of that source's frame size and encode. The engine measures
109
+ * it instead of guessing: DiagnosticsSnapshot carries the commanded rate beside
110
+ * the presented one, and PLAYBACK_RATE_NOT_SUSTAINED fires when they diverge.
111
+ * SUSTAINED_SHORTFALL is the share of the commanded rate the presented one has
112
+ * to hold to count as sustained.
113
+ */
114
+ const PLAYBACK_RATE = {
115
+ MIN: 0.25,
116
+ MAX: 8,
117
+ SUSTAINED_SHORTFALL: 0.8,
118
+ };
119
+ /**
120
+ * CanvasSink frame-pool size: how many decoded canvases the sink recycles
121
+ * round-robin. The pool has no backpressure (a new decode overwrites the oldest
122
+ * slot rather than blocking), and the playback queue hands the raw pool canvas
123
+ * straight to the painter, so the pool must outnumber every canvas outstanding at
124
+ * once: the full play read-ahead, the one in flight, and the one being painted.
125
+ * Sized below that, a fresh decode stomps the pixels of a still-queued frame
126
+ * before it paints (silent tearing). The cache is unaffected; it copies into its
127
+ * own OffscreenCanvas. Derived from the read-ahead so the two cannot drift.
128
+ */
129
+ const SCRUB = {
130
+ DEFAULT_POOL_SIZE: PLAYBACK.READ_AHEAD_CANVAS + 2,
131
+ };
132
+ /**
133
+ * Bounds on building a track's frame timeline, the presentation-order table of
134
+ * every frame's timestamp in the container's own integer grain.
135
+ *
136
+ * MAX_FRAMES caps the metadata walk that builds it. A 70-second 30fps source
137
+ * walks 2113 packets in a measured 5.7ms; the cap is four hundred times that,
138
+ * which no ordinary file reaches and a fragmented or endless source does. Past
139
+ * it the load fails, so nothing silently runs without frame identity.
140
+ *
141
+ * FALLBACK_TICK_RATE is for a track backing that cannot state its grain. A
142
+ * microsecond is the finest timestamp WebCodecs carries, so no real timestamp is
143
+ * lost at that rate; what is lost is the guarantee that every timestamp is a
144
+ * whole tick.
145
+ */
146
+ const FRAME_TIMELINE = {
147
+ MAX_FRAMES: 1_000_000,
148
+ FALLBACK_TICK_RATE: 1e6,
149
+ };
150
+ /**
151
+ * Diagnostics instrument tunables. Inert unless a consumer opts in: the worker
152
+ * broadcasts a snapshot at BROADCAST_HZ only while subscribed, the trace rings
153
+ * allocate only while armed, and SCRUB_LATENCY_RING bounds the percentile sample.
154
+ */
155
+ const DIAGNOSTICS = {
156
+ BROADCAST_HZ: 10,
157
+ TRACE_EVENT_CAP: 2000,
158
+ TRACE_SNAPSHOT_CAP: 600,
159
+ SCRUB_LATENCY_RING: 64,
160
+ };
161
+ /**
162
+ * What an armed capture actually keeps. The snapshot ring is fed at the fixed
163
+ * broadcast rate, so its capacity converts to a wall-clock window; the event
164
+ * ring is fed by paints and gestures at no fixed rate, so its bound is a count
165
+ * and nothing more. A readout that states one number for "the capture" is
166
+ * describing neither ring.
167
+ */
168
+ const TRACE_RING_BOUNDS = {
169
+ snapshotWindowMs: (DIAGNOSTICS.TRACE_SNAPSHOT_CAP / DIAGNOSTICS.BROADCAST_HZ) * 1000,
170
+ snapshotCap: DIAGNOSTICS.TRACE_SNAPSHOT_CAP,
171
+ eventCap: DIAGNOSTICS.TRACE_EVENT_CAP,
172
+ };
173
+ /**
174
+ * Hang-recovery bounds for the worker video runtime. mediabunny's getCanvas/
175
+ * getSample take no AbortSignal, so a decode that never settles cannot be
176
+ * cancelled. These two timeouts bound the damage: a decode that outruns its
177
+ * ceiling is abandoned and its provider rebuilt, and a main-thread caller
178
+ * blocked on a wedged worker surfaces an error.
179
+ *
180
+ * DECODE_HANG_TIMEOUT_MS bounds a random-access decode operation, not a single
181
+ * frame. A seek or a play-start lands mid-GOP and decodes the whole
182
+ * keyframe-to-target prefix, so an 8-second GOP of 8MP frames legitimately runs
183
+ * tens of seconds. A ceiling sized for one frame fires on healthy progress and
184
+ * kills the decode it exists to protect.
185
+ *
186
+ * SEED_HANG_TIMEOUT_MS bounds the first-frame seed alone, which is why it is a
187
+ * fraction of the figure above: the seed anchors on the track's own first
188
+ * sample, so it walks no GOP prefix, and the one cost it carries that a later
189
+ * decode does not is the decoder's cold hardware configuration. A re-anchored
190
+ * decode of a 2840x2840 source measured 49ms mean / 80ms worst, so this leaves
191
+ * two orders of magnitude of headroom over the decode plus its cold start, and
192
+ * SEED_DECODE_ATTEMPTS of it still finish inside WORKER_COMMAND_TIMEOUT_MS with
193
+ * the rebuilds between them. That is what lets a decoder which never starts
194
+ * reach the caller as an error rather than as the facade giving up.
195
+ *
196
+ * That budget is the mediabunny sink paths', which carry no ceiling of their
197
+ * own. The long-lived decode session bounds its own wait for output more
198
+ * tightly and can tell a decoder that never started from one that went quiet
199
+ * after working, so on that path the seed ends on the session's word and these
200
+ * attempts go unspent.
201
+ *
202
+ * WORKER_COMMAND_TIMEOUT_MS is the main-thread backstop for an awaitable command
203
+ * (load, commit, step). It derives from the decode ceiling so the two cannot
204
+ * drift: the worker has to be able to reach its own hang path, recover, and
205
+ * reply before the facade gives up on it.
206
+ */
207
+ const DECODE_HANG_TIMEOUT_MS = 30_000;
208
+ const HANG_RECOVERY = {
209
+ WORKER_COMMAND_TIMEOUT_MS: DECODE_HANG_TIMEOUT_MS + 15_000,
210
+ };
211
+
212
+ const asSec = (n) => n;
213
+ const asFps = (n) => n;
214
+ const asPaintSeq = (n) => n;
215
+ var SourceKind;
216
+ (function (SourceKind) {
217
+ SourceKind["Url"] = "url";
218
+ SourceKind["Blob"] = "blob";
219
+ SourceKind["Stream"] = "stream";
220
+ })(SourceKind || (SourceKind = {}));
221
+ /**
222
+ * Coarse-grained engine status. Updates rarely (load, play, pause, end,
223
+ * error). Sits on its own emit channel so subscribers do not wake up on
224
+ * 60Hz time ticks.
225
+ */
226
+ var PlaybackStatus;
227
+ (function (PlaybackStatus) {
228
+ PlaybackStatus["Idle"] = "IDLE";
229
+ PlaybackStatus["Loading"] = "LOADING";
230
+ PlaybackStatus["Ready"] = "READY";
231
+ PlaybackStatus["Playing"] = "PLAYING";
232
+ PlaybackStatus["Paused"] = "PAUSED";
233
+ PlaybackStatus["Seeking"] = "SEEKING";
234
+ PlaybackStatus["Ended"] = "ENDED";
235
+ PlaybackStatus["Errored"] = "ERRORED";
236
+ })(PlaybackStatus || (PlaybackStatus = {}));
237
+ var VideoEngineErrorCode;
238
+ (function (VideoEngineErrorCode) {
239
+ VideoEngineErrorCode["DecodeUnsupported"] = "DECODE_UNSUPPORTED";
240
+ VideoEngineErrorCode["SourceUnreadable"] = "SOURCE_UNREADABLE";
241
+ /**
242
+ * The demuxer refused the file outright: its container is not one this build
243
+ * reads, so no track was ever listed and no decoder was ever asked.
244
+ */
245
+ VideoEngineErrorCode["ContainerUnreadable"] = "CONTAINER_UNREADABLE";
246
+ /**
247
+ * The container opened and the demuxer parsed no track at all out of it. The
248
+ * file's streams are in formats it does not carry, so their video cannot be
249
+ * reached even though it is there.
250
+ */
251
+ VideoEngineErrorCode["VideoTrackUnreadable"] = "VIDEO_TRACK_UNREADABLE";
252
+ /**
253
+ * The container opened, its tracks listed, and none of them is video. This
254
+ * is the only case where the file itself is what lacks video.
255
+ */
256
+ VideoEngineErrorCode["NoVideoTrack"] = "NO_VIDEO_TRACK";
257
+ VideoEngineErrorCode["BackendCrashed"] = "BACKEND_CRASHED";
258
+ VideoEngineErrorCode["Aborted"] = "ABORTED";
259
+ /** A canvas was offered to an engine loaded in "frames" presentation mode,
260
+ * where the host owns the only canvas. */
261
+ VideoEngineErrorCode["PresentationMismatch"] = "PRESENTATION_MISMATCH";
262
+ /**
263
+ * The decoder cannot decode this source at all: it refused to configure, it
264
+ * errored, or it acknowledged decode requests and never produced a frame.
265
+ * Distinct from BackendCrashed, which a rebuild can recover; this one
266
+ * survives every rebuild, so the runtime stops rebuilding and says so. The
267
+ * usual cause is outside the page: another tab holding every hardware
268
+ * decoder session the machine has.
269
+ */
270
+ VideoEngineErrorCode["DecoderStalled"] = "DECODER_STALLED";
271
+ /** A playback rate outside the forward range the engine supports. */
272
+ VideoEngineErrorCode["RateUnsupported"] = "RATE_UNSUPPORTED";
273
+ })(VideoEngineErrorCode || (VideoEngineErrorCode = {}));
274
+ /**
275
+ * Thrown by createScrubCursor / VideoEngine.load when decode is unsupported
276
+ * or the source is unreadable. Branch on `error.code` (VideoEngineErrorCode)
277
+ * to differentiate decode failures from network failures.
278
+ */
279
+ class VideoEngineError extends Error {
280
+ code;
281
+ cause;
282
+ constructor(code, message, cause) {
283
+ super(message);
284
+ this.code = code;
285
+ this.cause = cause;
286
+ }
287
+ }
288
+ /** Shared by the facade and the core so a host gets the same refusal wherever
289
+ * its canvas is caught. */
290
+ function canvasBindingRefused() {
291
+ return new VideoEngineError(VideoEngineErrorCode.PresentationMismatch, 'presentation "frames" leaves the canvas to the host: this engine paints nothing and hands out VideoFrames instead');
292
+ }
293
+ /**
294
+ * Validates a requested playback rate and returns it. The facade and the core
295
+ * both call it, so a rate is refused at whichever boundary it arrives at and
296
+ * with the same message: the facade posts fire-and-forget, so a refusal raised
297
+ * only in the worker would reach nobody.
298
+ *
299
+ * Reverse is rejected, not clamped: backwards playback is a different decode
300
+ * problem, and a -1 quietly serviced as +0.25 plays the wrong direction while
301
+ * reporting success.
302
+ */
303
+ function resolvePlaybackRate(rate) {
304
+ if (!Number.isFinite(rate) ||
305
+ rate < PLAYBACK_RATE.MIN ||
306
+ rate > PLAYBACK_RATE.MAX) {
307
+ throw new VideoEngineError(VideoEngineErrorCode.RateUnsupported, `playback rate ${rate} is outside the supported forward range ${PLAYBACK_RATE.MIN}-${PLAYBACK_RATE.MAX}; reverse playback is not supported`);
308
+ }
309
+ return rate;
310
+ }
311
+
312
+ /**
313
+ * Decode-resolution strategies. A strategy decides the pixel width each video
314
+ * frame is decoded to, independent of the source's native resolution. Height
315
+ * follows from native aspect, so a strategy only ever returns a width.
316
+ *
317
+ * Decoding below native trades preview sharpness for paint cost and frame-cache
318
+ * memory. It does NOT cut decode cost: the codec decodes the full coded frame
319
+ * regardless of target width, and CanvasSink resizes the result afterward. The
320
+ * win scales with the gap between source resolution and the on-screen box: a 4K
321
+ * source shown in a 640px surface still pays full 4K decode, but the smaller
322
+ * surface cuts the per-frame paint work and the cached blit size.
323
+ *
324
+ * A strategy applies wherever frames decode through this seam: the live scrub
325
+ * surface and the analysis / extraction path alike. AnalysisSession decodes at
326
+ * whatever strategy it is given (native when omitted), so a thumbnail pass can
327
+ * cache a small blit instead of a native-size one.
328
+ */
329
+ /** Decode at native resolution. The conservative default. */
330
+ function nativeResolution() {
331
+ return { kind: "native" };
332
+ }
333
+ /**
334
+ * Decode at the on-screen size: canvas CSS width times devicePixelRatio. Best
335
+ * for fixed-size surfaces fed by a much larger source (frame sampler, inline
336
+ * players). Falls back to native while the box is unmeasured.
337
+ *
338
+ * The box it reads is the one bindCanvas measures, so this strategy resolves to
339
+ * native under presentation "frames", where the engine holds no canvas and
340
+ * nothing ever measures one. A frames-mode consumer passes displayBoxResolution
341
+ * instead.
342
+ */
343
+ function viewportResolution(options = {}) {
344
+ return {
345
+ kind: "viewport",
346
+ maxDevicePixelRatio: options.maxDevicePixelRatio ?? 2,
347
+ };
348
+ }
349
+ /**
350
+ * Decode at no more than maxWidth regardless of display size. For consumers
351
+ * with a hard throughput or memory ceiling (batch surfaces, thumbnail farms).
352
+ */
353
+ function cappedResolution(maxWidth) {
354
+ return { kind: "capped", maxWidth };
355
+ }
356
+ /**
357
+ * Decode at the size the frame will actually occupy inside a box the consumer
358
+ * describes: native aspect fitted into boxWidth x boxHeight, times the clamped
359
+ * device pixel ratio. Letterboxing is why the box is two numbers and not one,
360
+ * since a portrait source in a landscape box paints far narrower than the box.
361
+ *
362
+ * This is the strategy for presentation "frames". There the consumer owns the
363
+ * compositor, so it is the only side that knows the box, and viewportResolution
364
+ * has nothing to read.
365
+ */
366
+ function displayBoxResolution(options) {
367
+ return {
368
+ kind: "displayBox",
369
+ boxWidth: options.boxWidth,
370
+ boxHeight: options.boxHeight,
371
+ devicePixelRatio: options.devicePixelRatio,
372
+ maxDevicePixelRatio: options.maxDevicePixelRatio ?? 2,
373
+ };
374
+ }
375
+ /** Runs the descriptor against a context to produce a target decode width. */
376
+ function strategyWidth(strategy, ctx) {
377
+ switch (strategy.kind) {
378
+ case "native":
379
+ return ctx.nativeWidth;
380
+ case "viewport": {
381
+ if (ctx.displayWidth === null || ctx.displayWidth <= 0)
382
+ return ctx.nativeWidth;
383
+ const dpr = clampDpr(ctx.devicePixelRatio, strategy.maxDevicePixelRatio);
384
+ return Math.ceil(ctx.displayWidth * dpr);
385
+ }
386
+ case "capped":
387
+ return Math.min(strategy.maxWidth, ctx.nativeWidth);
388
+ case "displayBox": {
389
+ const { boxWidth, boxHeight } = strategy;
390
+ if (!(boxWidth > 0) || !(boxHeight > 0))
391
+ return ctx.nativeWidth;
392
+ const fit = Math.min(boxWidth / ctx.nativeWidth, boxHeight / ctx.nativeHeight);
393
+ const dpr = clampDpr(strategy.devicePixelRatio, strategy.maxDevicePixelRatio);
394
+ return Math.ceil(ctx.nativeWidth * fit * dpr);
395
+ }
396
+ }
397
+ }
398
+ /**
399
+ * Runs a strategy and returns native-bounded, aspect-preserving integer
400
+ * dimensions safe to hand to CanvasSink and to size a canvas backing store.
401
+ * A strategy that returns garbage (non-finite, non-positive) falls back to
402
+ * native rather than producing a broken surface.
403
+ */
404
+ function resolveDecodeDimensions(strategy, ctx) {
405
+ const nativeWidth = Math.max(1, Math.round(ctx.nativeWidth));
406
+ const nativeHeight = Math.max(1, Math.round(ctx.nativeHeight));
407
+ const raw = strategyWidth(strategy, ctx);
408
+ const width = Number.isFinite(raw) && raw > 0
409
+ ? Math.min(Math.round(raw), nativeWidth)
410
+ : nativeWidth;
411
+ const height = Math.max(1, Math.round((width * nativeHeight) / nativeWidth));
412
+ return { width, height };
413
+ }
414
+ function clampDpr(dpr, maxDpr) {
415
+ if (!Number.isFinite(dpr) || dpr <= 0)
416
+ return 1;
417
+ return Math.min(dpr, maxDpr);
418
+ }
419
+
420
+ /**
421
+ * One entry per presentation instant.
422
+ *
423
+ * A container may carry several coded pictures on one timestamp, and they
424
+ * occupy no time between them: a decode for that instant answers with a single
425
+ * picture, so the rest are frames no reader can reach or name. Counting them
426
+ * would leave a step across the group moving the picture nowhere, and a search
427
+ * for a time inside it answering with the group's last entry whatever it was
428
+ * asked.
429
+ */
430
+ function oneEntryPerInstant(data) {
431
+ const { ticks } = data;
432
+ let at = 1;
433
+ while (at < ticks.length && ticks[at] !== ticks[at - 1])
434
+ at += 1;
435
+ if (at === ticks.length)
436
+ return data;
437
+ const distinct = new Float64Array(ticks.length);
438
+ distinct.set(ticks.subarray(0, at));
439
+ let size = at;
440
+ for (let i = at + 1; i < ticks.length; i += 1) {
441
+ if (ticks[i] === distinct[size - 1])
442
+ continue;
443
+ distinct[size] = ticks[i];
444
+ size += 1;
445
+ }
446
+ return { ...data, ticks: distinct.slice(0, size) };
447
+ }
448
+ /**
449
+ * Every real frame of one track, in presentation order, by its container tick
450
+ * timestamp.
451
+ *
452
+ * A container states its timestamps as integer multiples of 1/tickRate, so a
453
+ * frame's tick count is exact and comparisons between two readers of the same
454
+ * container are integer comparisons. `timeAt` is the same division of the same
455
+ * two integers the demuxer itself performs, which is what lets a consumer
456
+ * holding only seconds match a producer's frame with `===`.
457
+ */
458
+ class FrameTimeline {
459
+ data;
460
+ ticksArray;
461
+ constructor(data) {
462
+ this.data = data;
463
+ this.ticksArray = data.ticks;
464
+ }
465
+ static from(data) {
466
+ if (data.ticks.length === 0) {
467
+ throw new RangeError("FrameTimeline: a track with no frames has no timeline");
468
+ }
469
+ if (!(data.tickRate > 0)) {
470
+ throw new RangeError(`FrameTimeline: tick rate ${data.tickRate} is not positive`);
471
+ }
472
+ return new FrameTimeline(oneEntryPerInstant(data));
473
+ }
474
+ /** A synthetic constant-rate table. Tests and fakes only. The default tick
475
+ * rate is a whole multiple of `fps`, so no test table needs rounding. */
476
+ static uniform(fps, frameCount, tickRate = fps * 1000) {
477
+ const step = tickRate / fps;
478
+ const ticks = Float64Array.from({ length: frameCount }, (_, index) => index * step);
479
+ return FrameTimeline.from({ lastDurationTicks: step, tickRate, ticks });
480
+ }
481
+ get tickRate() {
482
+ return this.data.tickRate;
483
+ }
484
+ get frameCount() {
485
+ return this.ticksArray.length;
486
+ }
487
+ toData() {
488
+ return this.data;
489
+ }
490
+ ticksAt(index) {
491
+ return this.ticksArray[this.clampIndex(index)];
492
+ }
493
+ timeAt(index) {
494
+ return asSec(this.ticksAt(index) / this.data.tickRate);
495
+ }
496
+ idAt(index) {
497
+ const at = this.clampIndex(index);
498
+ return { index: at, ticks: this.ticksArray[at] };
499
+ }
500
+ landingAt(index) {
501
+ const at = this.clampIndex(index);
502
+ return { frame: this.idAt(at), mediaTimeS: this.timeAt(at) };
503
+ }
504
+ /** Ticks the frame at `index` ends at, which is where the next one starts. */
505
+ endTicksAt(index) {
506
+ const at = this.clampIndex(index);
507
+ return at + 1 < this.ticksArray.length
508
+ ? this.ticksArray[at + 1]
509
+ : this.ticksArray[at] + this.data.lastDurationTicks;
510
+ }
511
+ /**
512
+ * The frame covering `timeS`, which is what a decode for it returns.
513
+ *
514
+ * The comparison divides, as `timeAt` does, so a frame's own published
515
+ * second answers with that frame.
516
+ */
517
+ indexAtOrBefore(timeS) {
518
+ let low = 0;
519
+ let high = this.ticksArray.length - 1;
520
+ let found = 0;
521
+ while (low <= high) {
522
+ const mid = (low + high) >> 1;
523
+ if (this.ticksArray[mid] / this.data.tickRate <= timeS) {
524
+ found = mid;
525
+ low = mid + 1;
526
+ }
527
+ else {
528
+ high = mid - 1;
529
+ }
530
+ }
531
+ return found;
532
+ }
533
+ /**
534
+ * The frame a decoded sample is.
535
+ *
536
+ * A decoded timestamp has been through the WebCodecs microsecond plane, so
537
+ * it can miss its own tick by up to half a microsecond. Snapping to the
538
+ * nearer neighbour absorbs that by four orders of magnitude, since the
539
+ * narrowest real frame gap measured across the fixtures is 31667 us.
540
+ */
541
+ indexOfDecoded(timeS) {
542
+ const wanted = Math.round(timeS * this.data.tickRate);
543
+ const at = this.indexAtOrBefore(wanted / this.data.tickRate);
544
+ const next = at + 1;
545
+ if (next >= this.ticksArray.length)
546
+ return at;
547
+ return wanted - this.ticksArray[at] <= this.ticksArray[next] - wanted
548
+ ? at
549
+ : next;
550
+ }
551
+ clampIndex(index) {
552
+ if (index < 0)
553
+ return 0;
554
+ const last = this.ticksArray.length - 1;
555
+ return index > last ? last : index;
556
+ }
557
+ }
558
+
559
+ export { DIAGNOSTICS as D, FRAME_TIMELINE as F, HANG_RECOVERY as H, PlaybackStatus as P, SCRUB as S, TRACE_RING_BOUNDS as T, VideoEngineError as V, VideoEngineErrorCode as a, asSec as b, SourceKind as c, FrameTimeline as d, asPaintSeq as e, canvasBindingRefused as f, resolvePlaybackRate as g, PLAYBACK_RATE as h, asFps as i, cappedResolution as j, displayBoxResolution as k, nativeResolution as n, resolveDecodeDimensions as r, viewportResolution as v };
560
+ //# sourceMappingURL=frame-timeline-GINI8Gum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-timeline-GINI8Gum.js","sources":["../src/constants.ts","../src/types.ts","../src/decode-resolution.ts","../src/frame-timeline.ts"],"sourcesContent":[null,null,null,null],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import { type Sec } from "./types";
2
+ /** Ticks per second, from the container's own timing grain. */
3
+ export type TickRate = number;
4
+ /**
5
+ * A frame of the source, named twice: by its position in presentation order and
6
+ * by its presentation timestamp in the track's own integer grain.
7
+ */
8
+ export interface FrameId {
9
+ readonly index: number;
10
+ readonly ticks: number;
11
+ }
12
+ /**
13
+ * Where the transport has settled: the frame, and the one seconds value anyone
14
+ * publishes for it. Nothing else on the wire carries a media position.
15
+ */
16
+ export interface FrameLanding {
17
+ readonly frame: FrameId;
18
+ readonly mediaTimeS: number;
19
+ }
20
+ /** The clone-safe shape the timeline crosses a worker boundary as. */
21
+ export interface FrameTimelineData {
22
+ readonly tickRate: TickRate;
23
+ readonly ticks: Float64Array;
24
+ readonly lastDurationTicks: number;
25
+ }
26
+ /**
27
+ * Every real frame of one track, in presentation order, by its container tick
28
+ * timestamp.
29
+ *
30
+ * A container states its timestamps as integer multiples of 1/tickRate, so a
31
+ * frame's tick count is exact and comparisons between two readers of the same
32
+ * container are integer comparisons. `timeAt` is the same division of the same
33
+ * two integers the demuxer itself performs, which is what lets a consumer
34
+ * holding only seconds match a producer's frame with `===`.
35
+ */
36
+ export declare class FrameTimeline {
37
+ private readonly data;
38
+ private readonly ticksArray;
39
+ private constructor();
40
+ static from(data: FrameTimelineData): FrameTimeline;
41
+ /** A synthetic constant-rate table. Tests and fakes only. The default tick
42
+ * rate is a whole multiple of `fps`, so no test table needs rounding. */
43
+ static uniform(fps: number, frameCount: number, tickRate?: TickRate): FrameTimeline;
44
+ get tickRate(): TickRate;
45
+ get frameCount(): number;
46
+ toData(): FrameTimelineData;
47
+ ticksAt(index: number): number;
48
+ timeAt(index: number): Sec;
49
+ idAt(index: number): FrameId;
50
+ landingAt(index: number): FrameLanding;
51
+ /** Ticks the frame at `index` ends at, which is where the next one starts. */
52
+ endTicksAt(index: number): number;
53
+ /**
54
+ * The frame covering `timeS`, which is what a decode for it returns.
55
+ *
56
+ * The comparison divides, as `timeAt` does, so a frame's own published
57
+ * second answers with that frame.
58
+ */
59
+ indexAtOrBefore(timeS: number): number;
60
+ /**
61
+ * The frame a decoded sample is.
62
+ *
63
+ * A decoded timestamp has been through the WebCodecs microsecond plane, so
64
+ * it can miss its own tick by up to half a microsecond. Snapping to the
65
+ * nearer neighbour absorbs that by four orders of magnitude, since the
66
+ * narrowest real frame gap measured across the fixtures is 31667 us.
67
+ */
68
+ indexOfDecoded(timeS: number): number;
69
+ private clampIndex;
70
+ }
71
+ //# sourceMappingURL=frame-timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-timeline.d.ts","sourceRoot":"","sources":["../src/frame-timeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,GAAG,EAAE,MAAM,SAAS,CAAC;AAE1C,+DAA+D;AAC/D,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,sEAAsE;AACtE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AA4BD;;;;;;;;;GASG;AACH,qBAAa,aAAa;IAGJ,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAE1C,OAAO;IAIP,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa;IAcnD;8EAC0E;IAC1E,MAAM,CAAC,OAAO,CACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,QAAqB,GAC9B,aAAa;IAShB,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,MAAM,IAAI,iBAAiB;IAI3B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI9B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG;IAI1B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAK5B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY;IAKtC,8EAA8E;IAC9E,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAOjC;;;;;OAKG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAgBtC;;;;;;;OAOG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAUrC,OAAO,CAAC,UAAU;CAKnB"}