alpha-video-gpu-web 0.0.0-stage → 1.0.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/LICENSE +21 -0
- package/README.md +123 -2
- package/THIRD_PARTY_NOTICES.md +12 -0
- package/dist/chunk-P3MJ6UC3.mjs +1770 -0
- package/dist/index.d.mts +268 -0
- package/dist/index.d.ts +268 -0
- package/dist/index.js +1895 -0
- package/dist/index.mjs +43 -0
- package/dist/react.d.mts +75 -0
- package/dist/react.d.ts +75 -0
- package/dist/react.js +1994 -0
- package/dist/react.mjs +133 -0
- package/dist/software-astc-G42RTJ34.mjs +57 -0
- package/dist/types-C6J2fa98.d.mts +96 -0
- package/dist/types-C6J2fa98.d.ts +96 -0
- package/licenses/Apache-2.0.txt +208 -0
- package/licenses/zstddec-LICENSE.txt +54 -0
- package/package.json +82 -4
|
@@ -0,0 +1,1770 @@
|
|
|
1
|
+
// src/ktx2-parser.ts
|
|
2
|
+
var DEFAULT_FRAME_RATE = 30;
|
|
3
|
+
function extractKTX2Metadata(ktx2Data) {
|
|
4
|
+
var _a;
|
|
5
|
+
if (ktx2Data.byteLength < 80 || ktx2Data[0] !== 171 || ktx2Data[1] !== 75 || ktx2Data[2] !== 84 || ktx2Data[3] !== 88) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
const view = new DataView(ktx2Data.buffer, ktx2Data.byteOffset, ktx2Data.byteLength);
|
|
9
|
+
return {
|
|
10
|
+
frameWidth: view.getUint32(20, true),
|
|
11
|
+
frameHeight: view.getUint32(24, true),
|
|
12
|
+
frameCount: view.getUint32(32, true),
|
|
13
|
+
frameRate: (_a = readAnimFrameRate(ktx2Data, view)) != null ? _a : DEFAULT_FRAME_RATE
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function readAnimFrameRate(ktx2Data, view) {
|
|
17
|
+
const kvdEnd = Math.min(view.getUint32(56, true) + view.getUint32(60, true), ktx2Data.byteLength);
|
|
18
|
+
let pos = view.getUint32(56, true);
|
|
19
|
+
while (pos + 4 <= kvdEnd) {
|
|
20
|
+
const entryLength = view.getUint32(pos, true);
|
|
21
|
+
const entryStart = pos + 4;
|
|
22
|
+
if (entryLength === 0 || entryStart + entryLength > kvdEnd) break;
|
|
23
|
+
let keyEnd = entryStart;
|
|
24
|
+
while (keyEnd < entryStart + entryLength && ktx2Data[keyEnd] !== 0) keyEnd++;
|
|
25
|
+
const key = new TextDecoder().decode(ktx2Data.subarray(entryStart, keyEnd));
|
|
26
|
+
if (key === "KTXanimData" && entryStart + entryLength - (keyEnd + 1) >= 12) {
|
|
27
|
+
const duration = view.getUint32(keyEnd + 1, true);
|
|
28
|
+
const timescale = view.getUint32(keyEnd + 5, true);
|
|
29
|
+
return duration > 0 && timescale > 0 ? timescale / duration : null;
|
|
30
|
+
}
|
|
31
|
+
pos = entryStart + entryLength + (4 - entryLength % 4) % 4;
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
var ASTC_FORMAT_MAP = {
|
|
36
|
+
// 4x4
|
|
37
|
+
157: 37808,
|
|
38
|
+
158: 37840,
|
|
39
|
+
// 5x4
|
|
40
|
+
159: 37809,
|
|
41
|
+
160: 37841,
|
|
42
|
+
// 5x5
|
|
43
|
+
161: 37810,
|
|
44
|
+
162: 37842,
|
|
45
|
+
// 6x5
|
|
46
|
+
163: 37811,
|
|
47
|
+
164: 37843,
|
|
48
|
+
// 6x6
|
|
49
|
+
165: 37812,
|
|
50
|
+
166: 37844,
|
|
51
|
+
// 8x5
|
|
52
|
+
167: 37813,
|
|
53
|
+
168: 37845,
|
|
54
|
+
// 8x6
|
|
55
|
+
169: 37814,
|
|
56
|
+
170: 37846,
|
|
57
|
+
// 8x8
|
|
58
|
+
171: 37815,
|
|
59
|
+
172: 37847,
|
|
60
|
+
// 10x5
|
|
61
|
+
173: 37816,
|
|
62
|
+
174: 37848,
|
|
63
|
+
// 10x6
|
|
64
|
+
175: 37817,
|
|
65
|
+
176: 37849,
|
|
66
|
+
// 10x8
|
|
67
|
+
177: 37818,
|
|
68
|
+
178: 37850,
|
|
69
|
+
// 10x10
|
|
70
|
+
179: 37819,
|
|
71
|
+
180: 37851,
|
|
72
|
+
// 12x10
|
|
73
|
+
181: 37820,
|
|
74
|
+
182: 37852,
|
|
75
|
+
// 12x12
|
|
76
|
+
183: 37821,
|
|
77
|
+
184: 37853
|
|
78
|
+
};
|
|
79
|
+
function getASTCBlockSize(vkFormat) {
|
|
80
|
+
const base = vkFormat % 2 === 0 ? vkFormat - 1 : vkFormat;
|
|
81
|
+
switch (base) {
|
|
82
|
+
case 157:
|
|
83
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
84
|
+
case 159:
|
|
85
|
+
return { blockWidth: 5, blockHeight: 4 };
|
|
86
|
+
case 161:
|
|
87
|
+
return { blockWidth: 5, blockHeight: 5 };
|
|
88
|
+
case 163:
|
|
89
|
+
return { blockWidth: 6, blockHeight: 5 };
|
|
90
|
+
case 165:
|
|
91
|
+
return { blockWidth: 6, blockHeight: 6 };
|
|
92
|
+
case 167:
|
|
93
|
+
return { blockWidth: 8, blockHeight: 5 };
|
|
94
|
+
case 169:
|
|
95
|
+
return { blockWidth: 8, blockHeight: 6 };
|
|
96
|
+
case 171:
|
|
97
|
+
return { blockWidth: 8, blockHeight: 8 };
|
|
98
|
+
case 173:
|
|
99
|
+
return { blockWidth: 10, blockHeight: 5 };
|
|
100
|
+
case 175:
|
|
101
|
+
return { blockWidth: 10, blockHeight: 6 };
|
|
102
|
+
case 177:
|
|
103
|
+
return { blockWidth: 10, blockHeight: 8 };
|
|
104
|
+
case 179:
|
|
105
|
+
return { blockWidth: 10, blockHeight: 10 };
|
|
106
|
+
case 181:
|
|
107
|
+
return { blockWidth: 12, blockHeight: 10 };
|
|
108
|
+
case 183:
|
|
109
|
+
return { blockWidth: 12, blockHeight: 12 };
|
|
110
|
+
default:
|
|
111
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function getASTCBytesPerLayer(width, height, vkFormat) {
|
|
115
|
+
const { blockWidth, blockHeight } = getASTCBlockSize(vkFormat);
|
|
116
|
+
const blocksX = Math.ceil(width / blockWidth);
|
|
117
|
+
const blocksY = Math.ceil(height / blockHeight);
|
|
118
|
+
return blocksX * blocksY * 16;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/errors.ts
|
|
122
|
+
var AlphaVideoGpuError = class extends Error {
|
|
123
|
+
constructor(code, message) {
|
|
124
|
+
super(message);
|
|
125
|
+
this.name = "AlphaVideoGpuError";
|
|
126
|
+
this.code = code;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/source.ts
|
|
131
|
+
import {
|
|
132
|
+
blobSource,
|
|
133
|
+
createStore,
|
|
134
|
+
httpSource,
|
|
135
|
+
isByteSource,
|
|
136
|
+
openReader
|
|
137
|
+
} from "range-source-web";
|
|
138
|
+
var STORAGE_NAMESPACE = "alpha-video-gpu";
|
|
139
|
+
function resolveWebUri(uri) {
|
|
140
|
+
return uri.startsWith("asset://") ? "/" + uri.slice("asset://".length).replace(/^\/+/, "") : uri;
|
|
141
|
+
}
|
|
142
|
+
function sourceIdentity(source, cacheKey) {
|
|
143
|
+
return typeof source === "string" ? cacheKey || source : source;
|
|
144
|
+
}
|
|
145
|
+
async function openKtx2Source(source, options = {}) {
|
|
146
|
+
var _a, _b, _c;
|
|
147
|
+
if (source instanceof ArrayBuffer || source instanceof Uint8Array) {
|
|
148
|
+
return memoryReader(source instanceof Uint8Array ? source : new Uint8Array(source));
|
|
149
|
+
}
|
|
150
|
+
let byteSource;
|
|
151
|
+
let key;
|
|
152
|
+
let storage;
|
|
153
|
+
if (typeof source === "string") {
|
|
154
|
+
const uri = resolveWebUri(source);
|
|
155
|
+
byteSource = httpSource(uri, { headers: options.headers });
|
|
156
|
+
key = options.cacheKey || uri;
|
|
157
|
+
storage = (_a = options.storage) != null ? _a : "auto";
|
|
158
|
+
} else if (typeof Blob !== "undefined" && source instanceof Blob) {
|
|
159
|
+
byteSource = blobSource(source);
|
|
160
|
+
key = options.cacheKey;
|
|
161
|
+
storage = (_b = options.storage) != null ? _b : "none";
|
|
162
|
+
} else if (isByteSource(source)) {
|
|
163
|
+
byteSource = source;
|
|
164
|
+
key = options.cacheKey;
|
|
165
|
+
storage = (_c = options.storage) != null ? _c : "none";
|
|
166
|
+
} else {
|
|
167
|
+
throw new TypeError("setSource takes a URL, a Blob, an ArrayBuffer, a Uint8Array or a ByteSource");
|
|
168
|
+
}
|
|
169
|
+
const store = key ? createStore(storage, { namespace: STORAGE_NAMESPACE, maxBytes: options.maxStorageBytes }) : null;
|
|
170
|
+
return openReader(byteSource, { store, key, signal: options.signal });
|
|
171
|
+
}
|
|
172
|
+
function memoryReader(data) {
|
|
173
|
+
return {
|
|
174
|
+
size: data.byteLength,
|
|
175
|
+
async read(offset, length) {
|
|
176
|
+
return data.subarray(offset, Math.min(offset + length, data.byteLength));
|
|
177
|
+
},
|
|
178
|
+
close() {
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// src/webgl-context.ts
|
|
184
|
+
var sharedGLResources = null;
|
|
185
|
+
var VERT_ARRAY = `#version 300 es
|
|
186
|
+
in vec2 a_position;
|
|
187
|
+
in vec2 a_texCoord;
|
|
188
|
+
out vec2 v_texCoord;
|
|
189
|
+
void main() {
|
|
190
|
+
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
191
|
+
v_texCoord = a_texCoord;
|
|
192
|
+
}
|
|
193
|
+
`;
|
|
194
|
+
var FRAG_ARRAY = `#version 300 es
|
|
195
|
+
precision mediump float;
|
|
196
|
+
precision mediump sampler2DArray;
|
|
197
|
+
in vec2 v_texCoord;
|
|
198
|
+
out vec4 fragColor;
|
|
199
|
+
uniform sampler2DArray u_textureArray;
|
|
200
|
+
uniform float u_layer;
|
|
201
|
+
void main() {
|
|
202
|
+
fragColor = texture(u_textureArray, vec3(v_texCoord, u_layer));
|
|
203
|
+
}
|
|
204
|
+
`;
|
|
205
|
+
var QUAD_POSITIONS = new Float32Array([
|
|
206
|
+
-1,
|
|
207
|
+
-1,
|
|
208
|
+
1,
|
|
209
|
+
-1,
|
|
210
|
+
-1,
|
|
211
|
+
1,
|
|
212
|
+
-1,
|
|
213
|
+
1,
|
|
214
|
+
1,
|
|
215
|
+
-1,
|
|
216
|
+
1,
|
|
217
|
+
1
|
|
218
|
+
]);
|
|
219
|
+
var QUAD_TEXCOORDS = new Float32Array([
|
|
220
|
+
0,
|
|
221
|
+
1,
|
|
222
|
+
1,
|
|
223
|
+
1,
|
|
224
|
+
0,
|
|
225
|
+
0,
|
|
226
|
+
0,
|
|
227
|
+
0,
|
|
228
|
+
1,
|
|
229
|
+
1,
|
|
230
|
+
1,
|
|
231
|
+
0
|
|
232
|
+
]);
|
|
233
|
+
function compileShader(gl, type, source) {
|
|
234
|
+
const shader = gl.createShader(type);
|
|
235
|
+
gl.shaderSource(shader, source);
|
|
236
|
+
gl.compileShader(shader);
|
|
237
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
238
|
+
const info = gl.getShaderInfoLog(shader);
|
|
239
|
+
gl.deleteShader(shader);
|
|
240
|
+
throw new Error(`Shader compile error: ${info}`);
|
|
241
|
+
}
|
|
242
|
+
return shader;
|
|
243
|
+
}
|
|
244
|
+
function linkProgram(gl, vs, fs) {
|
|
245
|
+
const program = gl.createProgram();
|
|
246
|
+
gl.attachShader(program, vs);
|
|
247
|
+
gl.attachShader(program, fs);
|
|
248
|
+
gl.linkProgram(program);
|
|
249
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
250
|
+
const info = gl.getProgramInfoLog(program);
|
|
251
|
+
gl.deleteProgram(program);
|
|
252
|
+
throw new Error(`Program link error: ${info}`);
|
|
253
|
+
}
|
|
254
|
+
return program;
|
|
255
|
+
}
|
|
256
|
+
function ensureSharedCanvasSize(width, height) {
|
|
257
|
+
if (!sharedGLResources) return;
|
|
258
|
+
const needsResize = width > sharedGLResources.maxWidth || height > sharedGLResources.maxHeight;
|
|
259
|
+
if (!needsResize) return;
|
|
260
|
+
const newWidth = Math.max(sharedGLResources.maxWidth, width);
|
|
261
|
+
const newHeight = Math.max(sharedGLResources.maxHeight, height);
|
|
262
|
+
sharedGLResources.canvas.width = newWidth;
|
|
263
|
+
sharedGLResources.canvas.height = newHeight;
|
|
264
|
+
sharedGLResources.maxWidth = newWidth;
|
|
265
|
+
sharedGLResources.maxHeight = newHeight;
|
|
266
|
+
console.debug(`[AlphaVideoGpu] Shared canvas resized to ${newWidth}x${newHeight}`);
|
|
267
|
+
}
|
|
268
|
+
function getSharedGL() {
|
|
269
|
+
if (sharedGLResources) {
|
|
270
|
+
sharedGLResources.refCount++;
|
|
271
|
+
return sharedGLResources;
|
|
272
|
+
}
|
|
273
|
+
const canvas = document.createElement("canvas");
|
|
274
|
+
canvas.width = 512;
|
|
275
|
+
canvas.height = 512;
|
|
276
|
+
const gl = canvas.getContext("webgl2", {
|
|
277
|
+
alpha: true,
|
|
278
|
+
premultipliedAlpha: true,
|
|
279
|
+
preserveDrawingBuffer: true
|
|
280
|
+
}) || canvas.getContext("webgl", {
|
|
281
|
+
alpha: true,
|
|
282
|
+
premultipliedAlpha: true,
|
|
283
|
+
preserveDrawingBuffer: true
|
|
284
|
+
});
|
|
285
|
+
if (!gl) {
|
|
286
|
+
console.warn("[AlphaVideoGpu] Failed to create shared WebGL context");
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
let arrayProgram = null;
|
|
290
|
+
if (gl instanceof WebGL2RenderingContext) {
|
|
291
|
+
try {
|
|
292
|
+
const vsArr = compileShader(gl, gl.VERTEX_SHADER, VERT_ARRAY);
|
|
293
|
+
const fsArr = compileShader(gl, gl.FRAGMENT_SHADER, FRAG_ARRAY);
|
|
294
|
+
arrayProgram = linkProgram(gl, vsArr, fsArr);
|
|
295
|
+
} catch (e) {
|
|
296
|
+
console.warn("[AlphaVideoGpu] Texture array shader failed:", e);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const positionBuffer = gl.createBuffer();
|
|
300
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
|
301
|
+
gl.bufferData(gl.ARRAY_BUFFER, QUAD_POSITIONS, gl.STATIC_DRAW);
|
|
302
|
+
const texCoordBuffer = gl.createBuffer();
|
|
303
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
|
|
304
|
+
gl.bufferData(gl.ARRAY_BUFFER, QUAD_TEXCOORDS, gl.STATIC_DRAW);
|
|
305
|
+
gl.enable(gl.BLEND);
|
|
306
|
+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
307
|
+
sharedGLResources = {
|
|
308
|
+
gl,
|
|
309
|
+
canvas,
|
|
310
|
+
arrayProgram,
|
|
311
|
+
positionBuffer,
|
|
312
|
+
texCoordBuffer,
|
|
313
|
+
refCount: 1,
|
|
314
|
+
maxWidth: 512,
|
|
315
|
+
maxHeight: 512
|
|
316
|
+
};
|
|
317
|
+
console.debug("[AlphaVideoGpu] Created shared WebGL context");
|
|
318
|
+
return sharedGLResources;
|
|
319
|
+
}
|
|
320
|
+
function releaseSharedGL() {
|
|
321
|
+
if (!sharedGLResources) return;
|
|
322
|
+
sharedGLResources.refCount--;
|
|
323
|
+
if (sharedGLResources.refCount <= 0) {
|
|
324
|
+
const { gl, arrayProgram, positionBuffer, texCoordBuffer } = sharedGLResources;
|
|
325
|
+
if (arrayProgram) gl.deleteProgram(arrayProgram);
|
|
326
|
+
gl.deleteBuffer(positionBuffer);
|
|
327
|
+
gl.deleteBuffer(texCoordBuffer);
|
|
328
|
+
const ext = gl.getExtension("WEBGL_lose_context");
|
|
329
|
+
if (ext) ext.loseContext();
|
|
330
|
+
sharedGLResources = null;
|
|
331
|
+
console.debug("[AlphaVideoGpu] Released shared WebGL context");
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function getSharedGLResources() {
|
|
335
|
+
return sharedGLResources;
|
|
336
|
+
}
|
|
337
|
+
function createDedicatedGL(canvas) {
|
|
338
|
+
const gl = canvas.getContext("webgl2") || canvas.getContext("webgl");
|
|
339
|
+
if (!gl) return null;
|
|
340
|
+
let arrayProgram = null;
|
|
341
|
+
if (gl instanceof WebGL2RenderingContext) {
|
|
342
|
+
try {
|
|
343
|
+
const vsArr = compileShader(gl, gl.VERTEX_SHADER, VERT_ARRAY);
|
|
344
|
+
const fsArr = compileShader(gl, gl.FRAGMENT_SHADER, FRAG_ARRAY);
|
|
345
|
+
arrayProgram = linkProgram(gl, vsArr, fsArr);
|
|
346
|
+
} catch {
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
const positionBuffer = gl.createBuffer();
|
|
350
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
|
351
|
+
gl.bufferData(gl.ARRAY_BUFFER, QUAD_POSITIONS, gl.STATIC_DRAW);
|
|
352
|
+
const texCoordBuffer = gl.createBuffer();
|
|
353
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
|
|
354
|
+
gl.bufferData(gl.ARRAY_BUFFER, QUAD_TEXCOORDS, gl.STATIC_DRAW);
|
|
355
|
+
gl.enable(gl.BLEND);
|
|
356
|
+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
357
|
+
return { gl, arrayProgram, positionBuffer, texCoordBuffer };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// src/zstd-seek-table.ts
|
|
361
|
+
var SEEK_TABLE_MAGIC = 407710302;
|
|
362
|
+
var SEEKABLE_FOOTER_MAGIC = 2408770225;
|
|
363
|
+
var FOOTER_SIZE = 9;
|
|
364
|
+
var SKIPPABLE_HEADER_SIZE = 8;
|
|
365
|
+
var CHECKSUM_FLAG = 128;
|
|
366
|
+
var RESERVED_BITS = 124;
|
|
367
|
+
function parseZstdSeekTable(level, decompressedLength, tailOffset = 0) {
|
|
368
|
+
if (level.length < SKIPPABLE_HEADER_SIZE + FOOTER_SIZE) return null;
|
|
369
|
+
const view = new DataView(level.buffer, level.byteOffset, level.byteLength);
|
|
370
|
+
const end = level.length;
|
|
371
|
+
if (view.getUint32(end - 4, true) !== SEEKABLE_FOOTER_MAGIC) return null;
|
|
372
|
+
const descriptor = level[end - 5];
|
|
373
|
+
if (descriptor & RESERVED_BITS) return null;
|
|
374
|
+
const frameCount = view.getUint32(end - FOOTER_SIZE, true);
|
|
375
|
+
const entrySize = descriptor & CHECKSUM_FLAG ? 12 : 8;
|
|
376
|
+
const tableSize = frameCount * entrySize + FOOTER_SIZE;
|
|
377
|
+
const tableStart = end - SKIPPABLE_HEADER_SIZE - tableSize;
|
|
378
|
+
if (frameCount === 0 || tableStart < 0) return null;
|
|
379
|
+
if (view.getUint32(tableStart, true) !== SEEK_TABLE_MAGIC) return null;
|
|
380
|
+
if (view.getUint32(tableStart + 4, true) !== tableSize) return null;
|
|
381
|
+
const compressedOffsets = [];
|
|
382
|
+
const decompressedOffsets = [];
|
|
383
|
+
let compressed = 0;
|
|
384
|
+
let decompressed = 0;
|
|
385
|
+
for (let i = 0; i < frameCount; i++) {
|
|
386
|
+
const entry = tableStart + SKIPPABLE_HEADER_SIZE + i * entrySize;
|
|
387
|
+
compressedOffsets.push(compressed);
|
|
388
|
+
decompressedOffsets.push(decompressed);
|
|
389
|
+
compressed += view.getUint32(entry, true);
|
|
390
|
+
decompressed += view.getUint32(entry + 4, true);
|
|
391
|
+
}
|
|
392
|
+
if (compressed !== tailOffset + tableStart) return null;
|
|
393
|
+
if (decompressedLength !== void 0 && decompressed !== decompressedLength) return null;
|
|
394
|
+
return { compressedOffsets, decompressedOffsets };
|
|
395
|
+
}
|
|
396
|
+
async function readZstdSeekTable(read, levelLength, decompressedLength) {
|
|
397
|
+
if (levelLength < SKIPPABLE_HEADER_SIZE + FOOTER_SIZE) return null;
|
|
398
|
+
const footer = await read(levelLength - FOOTER_SIZE, FOOTER_SIZE);
|
|
399
|
+
if (footer.length < FOOTER_SIZE) return null;
|
|
400
|
+
const view = new DataView(footer.buffer, footer.byteOffset, footer.byteLength);
|
|
401
|
+
if (view.getUint32(5, true) !== SEEKABLE_FOOTER_MAGIC || footer[4] & RESERVED_BITS) return null;
|
|
402
|
+
const entrySize = footer[4] & CHECKSUM_FLAG ? 12 : 8;
|
|
403
|
+
const tableStart = levelLength - SKIPPABLE_HEADER_SIZE - (view.getUint32(0, true) * entrySize + FOOTER_SIZE);
|
|
404
|
+
if (tableStart < 0) return null;
|
|
405
|
+
return parseZstdSeekTable(await read(tableStart, levelLength - tableStart), decompressedLength, tableStart);
|
|
406
|
+
}
|
|
407
|
+
function seekPointBefore(table, decompressedOffset) {
|
|
408
|
+
if (!table) return { compressedOffset: 0, decompressedOffset: 0 };
|
|
409
|
+
const starts = table.decompressedOffsets;
|
|
410
|
+
let low = 0;
|
|
411
|
+
let high = starts.length - 1;
|
|
412
|
+
while (low < high) {
|
|
413
|
+
const mid = low + high + 1 >> 1;
|
|
414
|
+
if (starts[mid] <= decompressedOffset) low = mid;
|
|
415
|
+
else high = mid - 1;
|
|
416
|
+
}
|
|
417
|
+
return { compressedOffset: table.compressedOffsets[low], decompressedOffset: starts[low] };
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// src/zstd-layer-stream.ts
|
|
421
|
+
var INPUT_CHUNK_SIZE = 256 * 1024;
|
|
422
|
+
var PushPump = class {
|
|
423
|
+
constructor(decoder, _level, _inputPos) {
|
|
424
|
+
this._level = _level;
|
|
425
|
+
this._inputPos = _inputPos;
|
|
426
|
+
this._output = null;
|
|
427
|
+
this._controller = new AbortController();
|
|
428
|
+
this._closed = false;
|
|
429
|
+
this._decoder = decoder.createStreamingDecoder();
|
|
430
|
+
}
|
|
431
|
+
async next() {
|
|
432
|
+
for (; ; ) {
|
|
433
|
+
if (this._closed) return null;
|
|
434
|
+
if (this._output) {
|
|
435
|
+
const piece = this._output.next();
|
|
436
|
+
if (!piece.done) return piece.value;
|
|
437
|
+
this._output = null;
|
|
438
|
+
}
|
|
439
|
+
if (this._inputPos >= this._level.length) {
|
|
440
|
+
if (!this._decoder.finished()) throw new Error("zstd: the level ends partway through a frame");
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
const length = Math.min(INPUT_CHUNK_SIZE, this._level.length - this._inputPos);
|
|
444
|
+
let input;
|
|
445
|
+
try {
|
|
446
|
+
input = await this._level.read(this._inputPos, length, this._controller.signal);
|
|
447
|
+
} catch (error) {
|
|
448
|
+
if (this._closed) return null;
|
|
449
|
+
throw error;
|
|
450
|
+
}
|
|
451
|
+
if (this._closed) return null;
|
|
452
|
+
if (input.byteLength === 0) throw new Error(`the level ends at ${this._inputPos} of ${this._level.length} bytes`);
|
|
453
|
+
this._inputPos += input.byteLength;
|
|
454
|
+
this._output = this._decoder.decode(input);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
close() {
|
|
458
|
+
var _a;
|
|
459
|
+
if (this._closed) return;
|
|
460
|
+
this._closed = true;
|
|
461
|
+
this._controller.abort();
|
|
462
|
+
try {
|
|
463
|
+
(_a = this._output) == null ? void 0 : _a.return(void 0);
|
|
464
|
+
} catch {
|
|
465
|
+
}
|
|
466
|
+
this._decoder.free();
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
var WholeLevelPump = class {
|
|
470
|
+
constructor(decoder, level, offset) {
|
|
471
|
+
this._generator = decoder.decodeStreaming(chunksFrom(level, offset));
|
|
472
|
+
}
|
|
473
|
+
async next() {
|
|
474
|
+
var _a;
|
|
475
|
+
const piece = (_a = this._generator) == null ? void 0 : _a.next();
|
|
476
|
+
return !piece || piece.done ? null : piece.value;
|
|
477
|
+
}
|
|
478
|
+
close() {
|
|
479
|
+
var _a;
|
|
480
|
+
try {
|
|
481
|
+
(_a = this._generator) == null ? void 0 : _a.return(void 0);
|
|
482
|
+
} catch {
|
|
483
|
+
}
|
|
484
|
+
this._generator = null;
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
function* chunksFrom(data, offset) {
|
|
488
|
+
for (let start = offset; start < data.length; start += INPUT_CHUNK_SIZE) {
|
|
489
|
+
yield data.subarray(start, Math.min(start + INPUT_CHUNK_SIZE, data.length));
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
var ZstdLayerStream = class _ZstdLayerStream {
|
|
493
|
+
constructor(_decoder, _level, _bytesPerLayer, seekTable, _wholeLevel) {
|
|
494
|
+
this._decoder = _decoder;
|
|
495
|
+
this._level = _level;
|
|
496
|
+
this._bytesPerLayer = _bytesPerLayer;
|
|
497
|
+
this.seekTable = seekTable;
|
|
498
|
+
this._wholeLevel = _wholeLevel;
|
|
499
|
+
this._pump = null;
|
|
500
|
+
this._chunk = new Uint8Array(0);
|
|
501
|
+
this._chunkPos = 0;
|
|
502
|
+
// Decompressed bytes taken from the decoder, counted from the level's start
|
|
503
|
+
this._decoded = 0;
|
|
504
|
+
this._skipBytes = 0;
|
|
505
|
+
this._position = 0;
|
|
506
|
+
// Changes on every moveTo and close, so a read they interrupt can tell
|
|
507
|
+
this._epoch = 0;
|
|
508
|
+
this._atEnd = false;
|
|
509
|
+
this._startAt(0, 0);
|
|
510
|
+
}
|
|
511
|
+
/** Reads the level's seek table (and the whole level, for a decoder that needs it), then starts at layer 0. */
|
|
512
|
+
static async open(decoder, level, bytesPerLayer, decompressedLength) {
|
|
513
|
+
const seekTable = await readZstdSeekTable((offset, length) => level.read(offset, length), level.length, decompressedLength);
|
|
514
|
+
const whole = decoder.createStreamingDecoder ? null : await level.read(0, level.length);
|
|
515
|
+
return new _ZstdLayerStream(decoder, level, bytesPerLayer, seekTable, whole);
|
|
516
|
+
}
|
|
517
|
+
get position() {
|
|
518
|
+
return this._position;
|
|
519
|
+
}
|
|
520
|
+
get skipping() {
|
|
521
|
+
return this._skipBytes > 0;
|
|
522
|
+
}
|
|
523
|
+
get atEnd() {
|
|
524
|
+
return this._atEnd;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Makes layer the next one read. Decoding carries on from where it is when that is no further
|
|
528
|
+
* from the target than the nearest seek point, and starts at that seek point otherwise.
|
|
529
|
+
*/
|
|
530
|
+
moveTo(layer) {
|
|
531
|
+
this._epoch++;
|
|
532
|
+
this._atEnd = false;
|
|
533
|
+
const target = layer * this._bytesPerLayer;
|
|
534
|
+
const point = seekPointBefore(this.seekTable, target);
|
|
535
|
+
if (this._decoded < point.decompressedOffset || this._decoded > target) {
|
|
536
|
+
this._startAt(point.compressedOffset, point.decompressedOffset);
|
|
537
|
+
}
|
|
538
|
+
this._skipBytes = target - this._decoded;
|
|
539
|
+
this._position = layer;
|
|
540
|
+
}
|
|
541
|
+
/** Throws away decoded bytes toward position until done or the deadline (performance.now()). */
|
|
542
|
+
async skip(deadline = Infinity) {
|
|
543
|
+
while (this._skipBytes > 0 && performance.now() < deadline) {
|
|
544
|
+
if (!await this._fillChunk()) return;
|
|
545
|
+
const taken = Math.min(this._skipBytes, this._chunk.length - this._chunkPos);
|
|
546
|
+
this._chunkPos += taken;
|
|
547
|
+
this._decoded += taken;
|
|
548
|
+
this._skipBytes -= taken;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
async readLayer() {
|
|
552
|
+
const epoch = this._epoch;
|
|
553
|
+
await this.skip();
|
|
554
|
+
if (epoch !== this._epoch) return null;
|
|
555
|
+
if (this._skipBytes > 0) {
|
|
556
|
+
this._atEnd = true;
|
|
557
|
+
return null;
|
|
558
|
+
}
|
|
559
|
+
const layer = new Uint8Array(this._bytesPerLayer);
|
|
560
|
+
let filled = 0;
|
|
561
|
+
while (filled < layer.length) {
|
|
562
|
+
const more = await this._fillChunk();
|
|
563
|
+
if (epoch !== this._epoch) return null;
|
|
564
|
+
if (!more) {
|
|
565
|
+
this._atEnd = true;
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
const taken = Math.min(layer.length - filled, this._chunk.length - this._chunkPos);
|
|
569
|
+
layer.set(this._chunk.subarray(this._chunkPos, this._chunkPos + taken), filled);
|
|
570
|
+
this._chunkPos += taken;
|
|
571
|
+
this._decoded += taken;
|
|
572
|
+
filled += taken;
|
|
573
|
+
}
|
|
574
|
+
this._position++;
|
|
575
|
+
return layer;
|
|
576
|
+
}
|
|
577
|
+
/** Frees the decoder's WASM buffers and stops reading. */
|
|
578
|
+
close() {
|
|
579
|
+
var _a;
|
|
580
|
+
this._epoch++;
|
|
581
|
+
(_a = this._pump) == null ? void 0 : _a.close();
|
|
582
|
+
this._pump = null;
|
|
583
|
+
}
|
|
584
|
+
_startAt(compressedOffset, decompressedOffset) {
|
|
585
|
+
var _a;
|
|
586
|
+
(_a = this._pump) == null ? void 0 : _a.close();
|
|
587
|
+
this._pump = this._wholeLevel ? new WholeLevelPump(this._decoder, this._wholeLevel, compressedOffset) : new PushPump(this._decoder, this._level, compressedOffset);
|
|
588
|
+
this._chunk = new Uint8Array(0);
|
|
589
|
+
this._chunkPos = 0;
|
|
590
|
+
this._decoded = decompressedOffset;
|
|
591
|
+
}
|
|
592
|
+
/** False when the decoder has no more output, or its pump was replaced or closed meanwhile. */
|
|
593
|
+
async _fillChunk() {
|
|
594
|
+
while (this._chunkPos >= this._chunk.length) {
|
|
595
|
+
const pump = this._pump;
|
|
596
|
+
if (!pump) return false;
|
|
597
|
+
const piece = await pump.next();
|
|
598
|
+
if (pump !== this._pump || !piece) return false;
|
|
599
|
+
this._chunk = piece;
|
|
600
|
+
this._chunkPos = 0;
|
|
601
|
+
}
|
|
602
|
+
return true;
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
// src/layer-stream.ts
|
|
607
|
+
var UncompressedLayerStream = class {
|
|
608
|
+
constructor(_level, _bytesPerLayer, _layerCount) {
|
|
609
|
+
this._level = _level;
|
|
610
|
+
this._bytesPerLayer = _bytesPerLayer;
|
|
611
|
+
this._layerCount = _layerCount;
|
|
612
|
+
this._position = 0;
|
|
613
|
+
this._epoch = 0;
|
|
614
|
+
this._atEnd = false;
|
|
615
|
+
this._controller = new AbortController();
|
|
616
|
+
}
|
|
617
|
+
get position() {
|
|
618
|
+
return this._position;
|
|
619
|
+
}
|
|
620
|
+
get skipping() {
|
|
621
|
+
return false;
|
|
622
|
+
}
|
|
623
|
+
get atEnd() {
|
|
624
|
+
return this._atEnd;
|
|
625
|
+
}
|
|
626
|
+
moveTo(layer) {
|
|
627
|
+
this._epoch++;
|
|
628
|
+
this._position = layer;
|
|
629
|
+
this._atEnd = false;
|
|
630
|
+
}
|
|
631
|
+
async skip() {
|
|
632
|
+
}
|
|
633
|
+
async readLayer() {
|
|
634
|
+
const layer = this._position;
|
|
635
|
+
if (layer >= this._layerCount) {
|
|
636
|
+
this._atEnd = true;
|
|
637
|
+
return null;
|
|
638
|
+
}
|
|
639
|
+
const epoch = this._epoch;
|
|
640
|
+
const data = await this._level.read(layer * this._bytesPerLayer, this._bytesPerLayer, this._controller.signal);
|
|
641
|
+
if (epoch !== this._epoch) return null;
|
|
642
|
+
if (data.byteLength < this._bytesPerLayer) {
|
|
643
|
+
this._atEnd = true;
|
|
644
|
+
return null;
|
|
645
|
+
}
|
|
646
|
+
this._position = layer + 1;
|
|
647
|
+
return data;
|
|
648
|
+
}
|
|
649
|
+
close() {
|
|
650
|
+
this._epoch++;
|
|
651
|
+
this._controller.abort();
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
// src/KTX2PlayerCore.ts
|
|
656
|
+
function clampInt(value, min, max) {
|
|
657
|
+
return Math.max(min, Math.min(max, Math.round(value)));
|
|
658
|
+
}
|
|
659
|
+
var HEADER_READ_BYTES = 16 * 1024;
|
|
660
|
+
async function readKtx2Header(reader) {
|
|
661
|
+
let header = await reader.read(0, Math.min(reader.size, HEADER_READ_BYTES));
|
|
662
|
+
if (header.byteLength < 80) throw new Error(`Not a KTX2 file: ${header.byteLength} bytes`);
|
|
663
|
+
const view = new DataView(header.buffer, header.byteOffset, header.byteLength);
|
|
664
|
+
const levelIndexEnd = 80 + Math.max(1, view.getUint32(40, true)) * 24;
|
|
665
|
+
const kvdEnd = view.getUint32(56, true) + view.getUint32(60, true);
|
|
666
|
+
const needed = Math.max(levelIndexEnd, kvdEnd);
|
|
667
|
+
if (needed > header.byteLength) header = await reader.read(0, needed);
|
|
668
|
+
return header;
|
|
669
|
+
}
|
|
670
|
+
var SupersededLoad = class extends Error {
|
|
671
|
+
};
|
|
672
|
+
function isAbortError(error) {
|
|
673
|
+
return (error == null ? void 0 : error.name) === "AbortError";
|
|
674
|
+
}
|
|
675
|
+
var DECODE_SLICE_MS = 8;
|
|
676
|
+
var RAM_RING_SIZE = 4;
|
|
677
|
+
function yieldToEventLoop() {
|
|
678
|
+
const scheduler = globalThis.scheduler;
|
|
679
|
+
if (typeof (scheduler == null ? void 0 : scheduler.yield) === "function") return scheduler.yield();
|
|
680
|
+
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
681
|
+
}
|
|
682
|
+
var KTX2PlayerCore = class {
|
|
683
|
+
// ======== Constructor ========
|
|
684
|
+
constructor(canvas, options = {}) {
|
|
685
|
+
this._ctx2d = null;
|
|
686
|
+
this._usingSharedGL = false;
|
|
687
|
+
this._gl = null;
|
|
688
|
+
this._arrayProgram = null;
|
|
689
|
+
this._positionBuffer = null;
|
|
690
|
+
this._texCoordBuffer = null;
|
|
691
|
+
// -- Textures --
|
|
692
|
+
this._textureArray = null;
|
|
693
|
+
// Set when the browser has no ASTC: layers are decoded to RGBA and the textures are RGBA8
|
|
694
|
+
this._softwareAstc = null;
|
|
695
|
+
this._blockWidth = 4;
|
|
696
|
+
this._blockHeight = 4;
|
|
697
|
+
// -- Playback --
|
|
698
|
+
this._metadata = null;
|
|
699
|
+
this._state = "idle";
|
|
700
|
+
this._currentFrame = 0;
|
|
701
|
+
this._animationFrameId = null;
|
|
702
|
+
this._lastFrameTime = 0;
|
|
703
|
+
this._loadedSource = null;
|
|
704
|
+
// Counts loads, so one that a newer setSource or destroy replaced can stop
|
|
705
|
+
this._loadId = 0;
|
|
706
|
+
this._reader = null;
|
|
707
|
+
// -- Decoders --
|
|
708
|
+
this._zstdDecoder = null;
|
|
709
|
+
// -- Streaming --
|
|
710
|
+
this._streamingMode = false;
|
|
711
|
+
this._streamingCancelled = false;
|
|
712
|
+
this._streamingFrameCache = /* @__PURE__ */ new Map();
|
|
713
|
+
this._useVramStrategy = false;
|
|
714
|
+
this._streamingRingBuffer = null;
|
|
715
|
+
this._streamingRingSlots = [];
|
|
716
|
+
this._streamingRingActualSize = 0;
|
|
717
|
+
this._streamingDecodePos = 0;
|
|
718
|
+
this._streamingFramesReady = 0;
|
|
719
|
+
this._streamingLoopCount = 0;
|
|
720
|
+
// Reads the level's layers: zstd-decoded, or straight from the file when uncompressed
|
|
721
|
+
this._layerStream = null;
|
|
722
|
+
this._streamingBytesPerLayer = 0;
|
|
723
|
+
this._streamingWidth = 0;
|
|
724
|
+
this._streamingHeight = 0;
|
|
725
|
+
this._streamingLayerCount = 0;
|
|
726
|
+
this._streamingLevel0Offset = 0;
|
|
727
|
+
this._streamingAstcFormat = 0;
|
|
728
|
+
// The stream the background decode loop is reading, while it runs
|
|
729
|
+
this._backgroundDecodeStream = null;
|
|
730
|
+
// A clip that doesn't loop has reached its last frame; playing again starts it over
|
|
731
|
+
this._ended = false;
|
|
732
|
+
this._pausedByProp = false;
|
|
733
|
+
// Polls for a frame a seek owes while not playing, until it is decoded
|
|
734
|
+
this._owedFrameId = null;
|
|
735
|
+
// -- RAM mode (non-streaming texture arrays with memoryStrategy='ram') --
|
|
736
|
+
this._ramHeavyMode = false;
|
|
737
|
+
this._ramFrameData = null;
|
|
738
|
+
this._ramBytesPerFrame = 0;
|
|
739
|
+
this._ramFrameCount = 0;
|
|
740
|
+
this._ramUploadedFrame = -1;
|
|
741
|
+
this._ramAstcFormat = 0;
|
|
742
|
+
this._ramWidth = 0;
|
|
743
|
+
this._ramHeight = 0;
|
|
744
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
745
|
+
this._canvas = canvas;
|
|
746
|
+
this._autoPlay = (_a = options.autoPlay) != null ? _a : true;
|
|
747
|
+
this._loop = (_b = options.loop) != null ? _b : true;
|
|
748
|
+
this._playbackSpeed = (_c = options.playbackSpeed) != null ? _c : 1;
|
|
749
|
+
this._stream = (_d = options.stream) != null ? _d : true;
|
|
750
|
+
this._streamingPrefetchAhead = clampInt((_e = options.streamingPrefetchAhead) != null ? _e : 8, 1, 100);
|
|
751
|
+
this._memoryStrategy = options.memoryStrategy === "ram" ? "ram" : "vram";
|
|
752
|
+
this._verbose = (_f = options.verbose) != null ? _f : false;
|
|
753
|
+
this._storage = options.storage;
|
|
754
|
+
this._maxStorageBytes = options.maxStorageBytes;
|
|
755
|
+
this._ZSTDDecoderClass = (_g = options.ZSTDDecoderClass) != null ? _g : null;
|
|
756
|
+
this._onStateChange = (_h = options.onStateChange) != null ? _h : null;
|
|
757
|
+
this._onLoad = (_i = options.onLoad) != null ? _i : null;
|
|
758
|
+
this._onFrameUpdate = (_j = options.onFrameUpdate) != null ? _j : null;
|
|
759
|
+
this._onFinished = (_k = options.onFinished) != null ? _k : null;
|
|
760
|
+
this._onError = (_l = options.onError) != null ? _l : null;
|
|
761
|
+
this._frameEvents = (_m = options.frameEvents) != null ? _m : true;
|
|
762
|
+
}
|
|
763
|
+
// ======== Public API ========
|
|
764
|
+
get state() {
|
|
765
|
+
return this._state;
|
|
766
|
+
}
|
|
767
|
+
get currentFrame() {
|
|
768
|
+
return this._currentFrame;
|
|
769
|
+
}
|
|
770
|
+
get totalFrames() {
|
|
771
|
+
var _a, _b;
|
|
772
|
+
return (_b = (_a = this._metadata) == null ? void 0 : _a.frameCount) != null ? _b : 0;
|
|
773
|
+
}
|
|
774
|
+
get frameRate() {
|
|
775
|
+
var _a, _b;
|
|
776
|
+
return (_b = (_a = this._metadata) == null ? void 0 : _a.frameRate) != null ? _b : 30;
|
|
777
|
+
}
|
|
778
|
+
get duration() {
|
|
779
|
+
return this.totalFrames / this.frameRate;
|
|
780
|
+
}
|
|
781
|
+
get currentTime() {
|
|
782
|
+
return this._currentFrame / this.frameRate;
|
|
783
|
+
}
|
|
784
|
+
get metadataInfo() {
|
|
785
|
+
return this._metadata;
|
|
786
|
+
}
|
|
787
|
+
/** Whether a source starts playing once loaded. */
|
|
788
|
+
set autoPlay(v) {
|
|
789
|
+
this._autoPlay = v;
|
|
790
|
+
}
|
|
791
|
+
get autoPlay() {
|
|
792
|
+
return this._autoPlay;
|
|
793
|
+
}
|
|
794
|
+
/** Whether onFrameUpdate fires for every frame played, not only for seeks. */
|
|
795
|
+
set frameEvents(v) {
|
|
796
|
+
this._frameEvents = v;
|
|
797
|
+
}
|
|
798
|
+
get frameEvents() {
|
|
799
|
+
return this._frameEvents;
|
|
800
|
+
}
|
|
801
|
+
set loop(v) {
|
|
802
|
+
this._loop = v;
|
|
803
|
+
}
|
|
804
|
+
get loop() {
|
|
805
|
+
return this._loop;
|
|
806
|
+
}
|
|
807
|
+
set playbackSpeed(v) {
|
|
808
|
+
this._playbackSpeed = v;
|
|
809
|
+
if (this._state === "playing") {
|
|
810
|
+
this._stopAnimationLoop();
|
|
811
|
+
this._startAnimationLoop();
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
get playbackSpeed() {
|
|
815
|
+
return this._playbackSpeed;
|
|
816
|
+
}
|
|
817
|
+
/** Update callbacks after construction (useful for wrappers where callbacks change). */
|
|
818
|
+
updateCallbacks(cbs) {
|
|
819
|
+
if (cbs.onStateChange !== void 0) this._onStateChange = cbs.onStateChange;
|
|
820
|
+
if (cbs.onLoad !== void 0) this._onLoad = cbs.onLoad;
|
|
821
|
+
if (cbs.onFrameUpdate !== void 0) this._onFrameUpdate = cbs.onFrameUpdate;
|
|
822
|
+
if (cbs.onFinished !== void 0) this._onFinished = cbs.onFinished;
|
|
823
|
+
if (cbs.onError !== void 0) this._onError = cbs.onError;
|
|
824
|
+
}
|
|
825
|
+
/** Plays from the shown frame, or from the start once a clip that doesn't loop has ended. */
|
|
826
|
+
play() {
|
|
827
|
+
if (this._state === "paused") {
|
|
828
|
+
this.resume();
|
|
829
|
+
} else if (this._state === "ready" || this._state === "stopped") {
|
|
830
|
+
if (this._ended) this.seekToFrame(0);
|
|
831
|
+
this._streamingCancelled = false;
|
|
832
|
+
this._setState("playing");
|
|
833
|
+
this._kickStreamingDecode();
|
|
834
|
+
this._lastFrameTime = performance.now();
|
|
835
|
+
this._startAnimationLoop();
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
pause() {
|
|
839
|
+
if (this._state === "playing") {
|
|
840
|
+
this._setState("paused");
|
|
841
|
+
this._streamingCancelled = true;
|
|
842
|
+
this._stopAnimationLoop();
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
resume() {
|
|
846
|
+
if (this._state === "paused") {
|
|
847
|
+
this._streamingCancelled = false;
|
|
848
|
+
this._setState("playing");
|
|
849
|
+
this._kickStreamingDecode();
|
|
850
|
+
this._lastFrameTime = performance.now();
|
|
851
|
+
this._startAnimationLoop();
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Holds playback and decoding, keeping the frames (the `paused` prop, for screen focus and
|
|
856
|
+
* blur). Unpausing plays again only when autoPlay is on; a source loaded while paused waits.
|
|
857
|
+
*/
|
|
858
|
+
setPaused(paused) {
|
|
859
|
+
this._pausedByProp = paused;
|
|
860
|
+
if (paused) {
|
|
861
|
+
this.pause();
|
|
862
|
+
} else if (this._autoPlay && (this._state === "paused" || this._state === "ready")) {
|
|
863
|
+
this.play();
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
/** Pauses on the first frame. */
|
|
867
|
+
stop() {
|
|
868
|
+
this._setState("stopped");
|
|
869
|
+
this._stopAnimationLoop();
|
|
870
|
+
this.seekToFrame(0);
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Shows that frame (clamped to the clip) and keeps playing or stays paused. Ignored until
|
|
874
|
+
* the source has loaded. While streaming, a seek outside the buffered frames decodes again.
|
|
875
|
+
*/
|
|
876
|
+
seekToFrame(frame) {
|
|
877
|
+
var _a, _b, _c;
|
|
878
|
+
const total = (_b = (_a = this._metadata) == null ? void 0 : _a.frameCount) != null ? _b : 0;
|
|
879
|
+
if (!total || this._state === "idle" || this._state === "loading" || this._state === "error") return;
|
|
880
|
+
const target = Math.max(0, Math.min(Math.floor(frame) || 0, total - 1));
|
|
881
|
+
this._ended = false;
|
|
882
|
+
if (this._streamingMode) this._moveStreamTo(target);
|
|
883
|
+
this._currentFrame = target;
|
|
884
|
+
this._lastFrameTime = performance.now();
|
|
885
|
+
(_c = this._onFrameUpdate) == null ? void 0 : _c.call(this, target, total);
|
|
886
|
+
if (this._state !== "playing") this._drawWhenReady();
|
|
887
|
+
}
|
|
888
|
+
/** Seeks to the frame showing at that time, in seconds. */
|
|
889
|
+
seekToTime(seconds) {
|
|
890
|
+
this.seekToFrame(Math.floor((seconds > 0 ? seconds : 0) * this.frameRate + 1e-6));
|
|
891
|
+
}
|
|
892
|
+
set verbose(v) {
|
|
893
|
+
this._verbose = v;
|
|
894
|
+
}
|
|
895
|
+
/** Reset loaded source tracking so next setSource will reload even the same URI. */
|
|
896
|
+
resetSource() {
|
|
897
|
+
this._loadedSource = null;
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Loads an ASTC KTX2 texture array from a URL (http(s), relative, or asset://path, served from
|
|
901
|
+
* the site root), a Blob or File, bytes in memory, or a ByteSource. Files are read by range:
|
|
902
|
+
* streaming playback starts once the first frames have arrived, and a URL's bytes are kept in
|
|
903
|
+
* the storage option's store for the next play.
|
|
904
|
+
*
|
|
905
|
+
* @param options cacheKey and headers; a string is taken as the cacheKey
|
|
906
|
+
*/
|
|
907
|
+
async setSource(source, options = {}) {
|
|
908
|
+
var _a;
|
|
909
|
+
const { cacheKey, headers } = typeof options === "string" ? { cacheKey: options, headers: void 0 } : options;
|
|
910
|
+
const identity = sourceIdentity(source, cacheKey);
|
|
911
|
+
if (this._loadedSource === identity) return;
|
|
912
|
+
this._loadedSource = identity;
|
|
913
|
+
const loadId = ++this._loadId;
|
|
914
|
+
try {
|
|
915
|
+
this._setState("loading");
|
|
916
|
+
this._stopAnimationLoop();
|
|
917
|
+
this._streamingCancelled = false;
|
|
918
|
+
this._currentFrame = 0;
|
|
919
|
+
this._ended = false;
|
|
920
|
+
const gl = this._gl || this._initGL();
|
|
921
|
+
if (!gl) return;
|
|
922
|
+
this._cleanupTextures(gl);
|
|
923
|
+
this._cleanupStreamingState(gl);
|
|
924
|
+
this._cleanupRamState();
|
|
925
|
+
this._closeReader();
|
|
926
|
+
const reader = await openKtx2Source(source, {
|
|
927
|
+
cacheKey,
|
|
928
|
+
headers,
|
|
929
|
+
storage: this._storage,
|
|
930
|
+
maxStorageBytes: this._maxStorageBytes
|
|
931
|
+
});
|
|
932
|
+
if (loadId !== this._loadId) {
|
|
933
|
+
reader.close();
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
this._reader = reader;
|
|
937
|
+
const header = await readKtx2Header(reader);
|
|
938
|
+
this._checkLoad(loadId);
|
|
939
|
+
await this._loadKTX2Source(gl, header, reader, loadId);
|
|
940
|
+
this._checkLoad(loadId);
|
|
941
|
+
this._currentFrame = 0;
|
|
942
|
+
this._finishLoad();
|
|
943
|
+
} catch (error) {
|
|
944
|
+
if (loadId !== this._loadId) return;
|
|
945
|
+
console.error("[AlphaVideoGpu] Load error:", error);
|
|
946
|
+
this._setState("error");
|
|
947
|
+
(_a = this._onError) == null ? void 0 : _a.call(this, error);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
_log(...args) {
|
|
951
|
+
if (this._verbose) console.log(...args);
|
|
952
|
+
}
|
|
953
|
+
/** Tear down all resources. Call when the player is no longer needed. */
|
|
954
|
+
destroy() {
|
|
955
|
+
this._loadId++;
|
|
956
|
+
this._streamingCancelled = true;
|
|
957
|
+
this._stopAnimationLoop();
|
|
958
|
+
if (this._owedFrameId !== null) cancelAnimationFrame(this._owedFrameId);
|
|
959
|
+
this._owedFrameId = null;
|
|
960
|
+
const gl = this._gl;
|
|
961
|
+
if (gl) {
|
|
962
|
+
if (this._textureArray) gl.deleteTexture(this._textureArray);
|
|
963
|
+
if (this._streamingRingBuffer) gl.deleteTexture(this._streamingRingBuffer);
|
|
964
|
+
if (!this._usingSharedGL) {
|
|
965
|
+
if (this._arrayProgram) gl.deleteProgram(this._arrayProgram);
|
|
966
|
+
if (this._positionBuffer) gl.deleteBuffer(this._positionBuffer);
|
|
967
|
+
if (this._texCoordBuffer) gl.deleteBuffer(this._texCoordBuffer);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
if (this._usingSharedGL) {
|
|
971
|
+
releaseSharedGL();
|
|
972
|
+
this._usingSharedGL = false;
|
|
973
|
+
}
|
|
974
|
+
this._streamingMode = false;
|
|
975
|
+
this._streamingFrameCache.clear();
|
|
976
|
+
this._closeLayerStream();
|
|
977
|
+
this._closeReader();
|
|
978
|
+
this._ramFrameData = null;
|
|
979
|
+
this._ramHeavyMode = false;
|
|
980
|
+
this._loadedSource = null;
|
|
981
|
+
this._state = "idle";
|
|
982
|
+
}
|
|
983
|
+
/** Stops a load that a newer setSource or destroy has replaced. */
|
|
984
|
+
_checkLoad(loadId) {
|
|
985
|
+
if (loadId !== this._loadId) throw new SupersededLoad();
|
|
986
|
+
}
|
|
987
|
+
_closeReader() {
|
|
988
|
+
var _a;
|
|
989
|
+
(_a = this._reader) == null ? void 0 : _a.close();
|
|
990
|
+
this._reader = null;
|
|
991
|
+
}
|
|
992
|
+
// ======== Private: State ========
|
|
993
|
+
_setState(newState) {
|
|
994
|
+
var _a;
|
|
995
|
+
if (this._state === newState) return;
|
|
996
|
+
this._state = newState;
|
|
997
|
+
(_a = this._onStateChange) == null ? void 0 : _a.call(this, newState);
|
|
998
|
+
}
|
|
999
|
+
_finishLoad() {
|
|
1000
|
+
this._setState("ready");
|
|
1001
|
+
if (this._autoPlay && !this._pausedByProp) {
|
|
1002
|
+
this._setState("playing");
|
|
1003
|
+
this._lastFrameTime = performance.now();
|
|
1004
|
+
this._startAnimationLoop();
|
|
1005
|
+
} else {
|
|
1006
|
+
this._drawWhenReady();
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
// ======== Private: GL Init ========
|
|
1010
|
+
_initGL() {
|
|
1011
|
+
var _a;
|
|
1012
|
+
const shared = getSharedGL();
|
|
1013
|
+
if (shared) {
|
|
1014
|
+
const ctx2d = this._canvas.getContext("2d", { alpha: true });
|
|
1015
|
+
if (ctx2d) {
|
|
1016
|
+
this._ctx2d = ctx2d;
|
|
1017
|
+
this._usingSharedGL = true;
|
|
1018
|
+
this._gl = shared.gl;
|
|
1019
|
+
this._arrayProgram = shared.arrayProgram;
|
|
1020
|
+
this._positionBuffer = shared.positionBuffer;
|
|
1021
|
+
this._texCoordBuffer = shared.texCoordBuffer;
|
|
1022
|
+
return shared.gl;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
const dedicated = createDedicatedGL(this._canvas);
|
|
1026
|
+
if (!dedicated) {
|
|
1027
|
+
(_a = this._onError) == null ? void 0 : _a.call(this, new AlphaVideoGpuError("WEBGL_UNSUPPORTED", "WebGL is not supported"));
|
|
1028
|
+
return null;
|
|
1029
|
+
}
|
|
1030
|
+
this._usingSharedGL = false;
|
|
1031
|
+
this._gl = dedicated.gl;
|
|
1032
|
+
this._arrayProgram = dedicated.arrayProgram;
|
|
1033
|
+
this._positionBuffer = dedicated.positionBuffer;
|
|
1034
|
+
this._texCoordBuffer = dedicated.texCoordBuffer;
|
|
1035
|
+
return dedicated.gl;
|
|
1036
|
+
}
|
|
1037
|
+
// ======== Private: ZSTD ========
|
|
1038
|
+
async _ensureZstdDecoder() {
|
|
1039
|
+
if (this._zstdDecoder) return this._zstdDecoder;
|
|
1040
|
+
if (this._ZSTDDecoderClass) {
|
|
1041
|
+
this._zstdDecoder = new this._ZSTDDecoderClass();
|
|
1042
|
+
} else if (typeof globalThis.ZSTDDecoder !== "undefined") {
|
|
1043
|
+
this._zstdDecoder = new globalThis.ZSTDDecoder();
|
|
1044
|
+
} else {
|
|
1045
|
+
throw new Error("ZSTDDecoder not available");
|
|
1046
|
+
}
|
|
1047
|
+
await this._zstdDecoder.init();
|
|
1048
|
+
return this._zstdDecoder;
|
|
1049
|
+
}
|
|
1050
|
+
// ======== Private: ASTC on the GPU, or decoded in software ========
|
|
1051
|
+
/** Uses the GPU's ASTC where the browser has it, and loads the software decoder where not. */
|
|
1052
|
+
async _prepareAstc(gl, vkFormat) {
|
|
1053
|
+
({ blockWidth: this._blockWidth, blockHeight: this._blockHeight } = getASTCBlockSize(vkFormat));
|
|
1054
|
+
if (gl.getExtension("WEBGL_compressed_texture_astc")) {
|
|
1055
|
+
this._softwareAstc = null;
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
try {
|
|
1059
|
+
const { loadSoftwareAstcDecoder } = await import("./software-astc-G42RTJ34.mjs");
|
|
1060
|
+
this._softwareAstc = await loadSoftwareAstcDecoder();
|
|
1061
|
+
} catch (error) {
|
|
1062
|
+
throw new AlphaVideoGpuError(
|
|
1063
|
+
"ASTC_UNSUPPORTED",
|
|
1064
|
+
`This browser has no ASTC texture support (WEBGL_compressed_texture_astc), and the software decoder failed to load: ${error.message}`
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
this._log("[AlphaVideoGpu] No GPU ASTC support: decoding frames to RGBA in software");
|
|
1068
|
+
}
|
|
1069
|
+
/** Allocates the bound texture array: ASTC, or RGBA8 when decoding in software. */
|
|
1070
|
+
_allocateLayers(gl, width, height, layers, astcFormat) {
|
|
1071
|
+
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, this._softwareAstc ? gl.RGBA8 : astcFormat, width, height, layers);
|
|
1072
|
+
}
|
|
1073
|
+
/** Uploads one layer of ASTC blocks to the bound texture array, decoding it first in software. */
|
|
1074
|
+
_uploadLayer(gl, layer, width, height, astcFormat, astc) {
|
|
1075
|
+
if (this._softwareAstc) {
|
|
1076
|
+
const rgba = this._softwareAstc.decode(astc, width, height, this._blockWidth, this._blockHeight);
|
|
1077
|
+
gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, layer, width, height, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba);
|
|
1078
|
+
} else {
|
|
1079
|
+
gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, layer, width, height, 1, astcFormat, astc);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
// ======== Private: Cleanup ========
|
|
1083
|
+
_cleanupTextures(gl) {
|
|
1084
|
+
if (this._textureArray) {
|
|
1085
|
+
gl.deleteTexture(this._textureArray);
|
|
1086
|
+
this._textureArray = null;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
_cleanupStreamingState(gl) {
|
|
1090
|
+
if (this._streamingRingBuffer) {
|
|
1091
|
+
gl.deleteTexture(this._streamingRingBuffer);
|
|
1092
|
+
this._streamingRingBuffer = null;
|
|
1093
|
+
}
|
|
1094
|
+
this._streamingMode = false;
|
|
1095
|
+
this._streamingFrameCache.clear();
|
|
1096
|
+
this._closeLayerStream();
|
|
1097
|
+
}
|
|
1098
|
+
_cleanupRamState() {
|
|
1099
|
+
this._ramFrameData = null;
|
|
1100
|
+
this._ramHeavyMode = false;
|
|
1101
|
+
this._ramBytesPerFrame = 0;
|
|
1102
|
+
this._ramFrameCount = 0;
|
|
1103
|
+
this._ramUploadedFrame = -1;
|
|
1104
|
+
}
|
|
1105
|
+
// ======== Private: Emit ========
|
|
1106
|
+
_emitLoad(metadata) {
|
|
1107
|
+
var _a;
|
|
1108
|
+
(_a = this._onLoad) == null ? void 0 : _a.call(this, {
|
|
1109
|
+
width: metadata.frameWidth,
|
|
1110
|
+
height: metadata.frameHeight,
|
|
1111
|
+
frameCount: metadata.frameCount,
|
|
1112
|
+
frameRate: metadata.frameRate,
|
|
1113
|
+
duration: metadata.frameCount / metadata.frameRate
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
// ======== Private: Load KTX2 Source ========
|
|
1117
|
+
async _loadKTX2Source(gl, header, reader, loadId) {
|
|
1118
|
+
const metadata = extractKTX2Metadata(header);
|
|
1119
|
+
if (!metadata) throw new Error("Not a KTX2 file");
|
|
1120
|
+
const vkFormat = new DataView(header.buffer, header.byteOffset, header.byteLength).getUint32(12, true);
|
|
1121
|
+
if (!(vkFormat in ASTC_FORMAT_MAP) || metadata.frameCount < 1) {
|
|
1122
|
+
throw new Error(`Only ASTC texture arrays play (this file has vkFormat ${vkFormat} and ${metadata.frameCount} layers); encode it with texenc`);
|
|
1123
|
+
}
|
|
1124
|
+
if (!(gl instanceof WebGL2RenderingContext) || !this._arrayProgram) {
|
|
1125
|
+
throw new AlphaVideoGpuError("WEBGL_UNSUPPORTED", "Texture arrays need WebGL2");
|
|
1126
|
+
}
|
|
1127
|
+
this._log(`[AlphaVideoGpu] Metadata: ${metadata.frameCount} frames, ${metadata.frameWidth}x${metadata.frameHeight}`);
|
|
1128
|
+
this._metadata = metadata;
|
|
1129
|
+
this._emitLoad(metadata);
|
|
1130
|
+
const view = new DataView(header.buffer, header.byteOffset, header.byteLength);
|
|
1131
|
+
const supercompressionScheme = view.getUint32(44, true);
|
|
1132
|
+
if (supercompressionScheme !== 0 && supercompressionScheme !== 2) {
|
|
1133
|
+
throw new Error(`Unsupported supercompressionScheme: ${supercompressionScheme}`);
|
|
1134
|
+
}
|
|
1135
|
+
if (this._stream) {
|
|
1136
|
+
this._log(`[AlphaVideoGpu] Streaming ${supercompressionScheme === 2 ? "zstd" : "uncompressed"} layers (stream=true)`);
|
|
1137
|
+
await this._loadStreamingTextureArray(gl, header, reader, metadata, loadId);
|
|
1138
|
+
} else {
|
|
1139
|
+
const level0Offset = Number(view.getBigUint64(80, true));
|
|
1140
|
+
const level0Length = Number(view.getBigUint64(88, true));
|
|
1141
|
+
const level = await reader.read(level0Offset, level0Length);
|
|
1142
|
+
this._checkLoad(loadId);
|
|
1143
|
+
if (level.byteLength < level0Length) throw new Error(`The file ends ${level0Length - level.byteLength} bytes into its texture data`);
|
|
1144
|
+
this._closeReader();
|
|
1145
|
+
const success = await this._loadTextureArray(gl, header, level, metadata, loadId);
|
|
1146
|
+
if (!success) throw new Error("Failed to load texture array");
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
// ======== Private: Load Texture Array (non-streaming) ========
|
|
1150
|
+
async _loadTextureArray(gl, header, level, metadata, loadId) {
|
|
1151
|
+
try {
|
|
1152
|
+
const view = new DataView(header.buffer, header.byteOffset, header.byteLength);
|
|
1153
|
+
const vkFormat = view.getUint32(12, true);
|
|
1154
|
+
const width = view.getUint32(20, true);
|
|
1155
|
+
const height = view.getUint32(24, true);
|
|
1156
|
+
const layerCount = view.getUint32(32, true);
|
|
1157
|
+
const supercompressionScheme = view.getUint32(44, true);
|
|
1158
|
+
const astcFormat = ASTC_FORMAT_MAP[vkFormat];
|
|
1159
|
+
if (!astcFormat) throw new Error(`Unsupported ASTC VkFormat: ${vkFormat}`);
|
|
1160
|
+
await this._prepareAstc(gl, vkFormat);
|
|
1161
|
+
this._checkLoad(loadId);
|
|
1162
|
+
const useRamMode = this._memoryStrategy === "ram" || this._softwareAstc !== null;
|
|
1163
|
+
this._log(`[AlphaVideoGpu] Texture array: ${width}x${height}, ${layerCount} layers (${useRamMode ? "RAM" : "VRAM"} mode)`);
|
|
1164
|
+
const level0UncompressedLength = Number(view.getBigUint64(96, true));
|
|
1165
|
+
let compressedData;
|
|
1166
|
+
if (supercompressionScheme === 2) {
|
|
1167
|
+
const decoder = await this._ensureZstdDecoder();
|
|
1168
|
+
this._checkLoad(loadId);
|
|
1169
|
+
compressedData = decoder.decode(level, level0UncompressedLength);
|
|
1170
|
+
this._log(`[AlphaVideoGpu] WASM zstd decompressed ${level.length} -> ${compressedData.length} bytes`);
|
|
1171
|
+
} else {
|
|
1172
|
+
compressedData = level;
|
|
1173
|
+
}
|
|
1174
|
+
const textureArray = gl.createTexture();
|
|
1175
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, textureArray);
|
|
1176
|
+
if (useRamMode) {
|
|
1177
|
+
const gpuRingSize = 2;
|
|
1178
|
+
const bytesPerLayer = getASTCBytesPerLayer(width, height, vkFormat);
|
|
1179
|
+
this._allocateLayers(gl, width, height, gpuRingSize, astcFormat);
|
|
1180
|
+
this._ramFrameData = compressedData;
|
|
1181
|
+
this._ramBytesPerFrame = bytesPerLayer;
|
|
1182
|
+
this._ramFrameCount = layerCount;
|
|
1183
|
+
this._ramUploadedFrame = -1;
|
|
1184
|
+
this._ramAstcFormat = astcFormat;
|
|
1185
|
+
this._ramWidth = width;
|
|
1186
|
+
this._ramHeight = height;
|
|
1187
|
+
this._ramHeavyMode = true;
|
|
1188
|
+
const cpuMB = (compressedData.length / (1024 * 1024)).toFixed(1);
|
|
1189
|
+
const gpuMB = (bytesPerLayer * gpuRingSize / (1024 * 1024)).toFixed(2);
|
|
1190
|
+
this._log(`[AlphaVideoGpu] RAM mode: ${layerCount} frames in CPU (${cpuMB}MB), ${gpuRingSize} slots in GPU (${gpuMB}MB)`);
|
|
1191
|
+
} else {
|
|
1192
|
+
this._ramHeavyMode = false;
|
|
1193
|
+
gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, astcFormat, width, height, layerCount, 0, compressedData);
|
|
1194
|
+
const glError = gl.getError();
|
|
1195
|
+
if (glError !== gl.NO_ERROR) {
|
|
1196
|
+
console.error("[AlphaVideoGpu] WebGL error after texture array upload:", glError);
|
|
1197
|
+
return false;
|
|
1198
|
+
}
|
|
1199
|
+
const dataMB = (compressedData.length / (1024 * 1024)).toFixed(1);
|
|
1200
|
+
this._log(`[AlphaVideoGpu] VRAM mode: ${dataMB}MB uploaded to GPU`);
|
|
1201
|
+
}
|
|
1202
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1203
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1204
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
1205
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1206
|
+
this._textureArray = textureArray;
|
|
1207
|
+
this._log(`[AlphaVideoGpu] \u2713 Texture array loaded: ${width}x${height}, ${layerCount} layers`);
|
|
1208
|
+
return true;
|
|
1209
|
+
} catch (error) {
|
|
1210
|
+
if (error instanceof AlphaVideoGpuError || error instanceof SupersededLoad) throw error;
|
|
1211
|
+
console.error("[AlphaVideoGpu] Failed to load texture array:", error);
|
|
1212
|
+
return false;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
// ======== Private: Streaming Ring Buffer Init ========
|
|
1216
|
+
_initStreamingRingBuffer(gl, width, height, astcFormat, layerCount, vkFormat) {
|
|
1217
|
+
const useVram = this._memoryStrategy !== "ram";
|
|
1218
|
+
this._useVramStrategy = useVram;
|
|
1219
|
+
const gpuCacheSize = useVram ? this._streamingPrefetchAhead + 2 : RAM_RING_SIZE;
|
|
1220
|
+
const ringSize = Math.min(gpuCacheSize, layerCount);
|
|
1221
|
+
this._log(`[AlphaVideoGpu] Memory strategy: ${this._memoryStrategy} (useVram=${useVram}), GPU cache: ${ringSize} slots`);
|
|
1222
|
+
const bytesPerLayer = vkFormat != null ? getASTCBytesPerLayer(width, height, vkFormat) : Math.ceil(width / 4) * Math.ceil(height / 4) * 16;
|
|
1223
|
+
const ringBuffer = gl.createTexture();
|
|
1224
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, ringBuffer);
|
|
1225
|
+
this._allocateLayers(gl, width, height, ringSize, astcFormat);
|
|
1226
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1227
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1228
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
1229
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1230
|
+
this._streamingRingBuffer = ringBuffer;
|
|
1231
|
+
this._streamingRingActualSize = ringSize;
|
|
1232
|
+
this._streamingRingSlots = new Array(ringSize).fill(-1);
|
|
1233
|
+
this._streamingBytesPerLayer = bytesPerLayer;
|
|
1234
|
+
this._streamingWidth = width;
|
|
1235
|
+
this._streamingHeight = height;
|
|
1236
|
+
this._streamingAstcFormat = astcFormat;
|
|
1237
|
+
this._log(`[AlphaVideoGpu] Ring buffer initialized: ${ringSize} slots, ${bytesPerLayer} bytes/layer`);
|
|
1238
|
+
}
|
|
1239
|
+
// ======== Private: Streaming ========
|
|
1240
|
+
/**
|
|
1241
|
+
* Plays the level a layer at a time: zstd-decoded, or read straight from the file when
|
|
1242
|
+
* uncompressed. The first frames are read before the load finishes; the rest are read
|
|
1243
|
+
* ahead of playback by the background decode loop.
|
|
1244
|
+
*/
|
|
1245
|
+
async _loadStreamingTextureArray(gl, header, reader, metadata, loadId) {
|
|
1246
|
+
const view = new DataView(header.buffer, header.byteOffset, header.byteLength);
|
|
1247
|
+
const vkFormat = view.getUint32(12, true);
|
|
1248
|
+
const width = view.getUint32(20, true);
|
|
1249
|
+
const height = view.getUint32(24, true);
|
|
1250
|
+
const layerCount = view.getUint32(32, true);
|
|
1251
|
+
const supercompressionScheme = view.getUint32(44, true);
|
|
1252
|
+
const level0Offset = Number(view.getBigUint64(80, true));
|
|
1253
|
+
const level0Length = Number(view.getBigUint64(88, true));
|
|
1254
|
+
const level0UncompressedLength = Number(view.getBigUint64(96, true));
|
|
1255
|
+
const bytesPerLayer = getASTCBytesPerLayer(width, height, vkFormat);
|
|
1256
|
+
this._log(`[AlphaVideoGpu] Streaming: ${width}x${height}, ${layerCount} layers, level ${level0Length} bytes (${level0UncompressedLength} decoded), ${bytesPerLayer} bytes/layer`);
|
|
1257
|
+
const astcFormat = ASTC_FORMAT_MAP[vkFormat];
|
|
1258
|
+
if (!astcFormat) throw new Error(`Unsupported ASTC VkFormat: ${vkFormat}`);
|
|
1259
|
+
await this._prepareAstc(gl, vkFormat);
|
|
1260
|
+
this._checkLoad(loadId);
|
|
1261
|
+
const level = {
|
|
1262
|
+
length: level0Length,
|
|
1263
|
+
read: (offset, length, signal) => reader.read(level0Offset + offset, Math.min(length, level0Length - offset), signal)
|
|
1264
|
+
};
|
|
1265
|
+
let stream;
|
|
1266
|
+
if (supercompressionScheme === 2) {
|
|
1267
|
+
const decoder = await this._ensureZstdDecoder();
|
|
1268
|
+
this._checkLoad(loadId);
|
|
1269
|
+
const zstdStream = await ZstdLayerStream.open(decoder, level, bytesPerLayer, level0UncompressedLength);
|
|
1270
|
+
if (loadId !== this._loadId) {
|
|
1271
|
+
zstdStream.close();
|
|
1272
|
+
throw new SupersededLoad();
|
|
1273
|
+
}
|
|
1274
|
+
this._log(zstdStream.seekTable ? `[AlphaVideoGpu] Seek table: ${zstdStream.seekTable.compressedOffsets.length} seek points` : "[AlphaVideoGpu] No seek table: seeks decode from the start");
|
|
1275
|
+
stream = zstdStream;
|
|
1276
|
+
} else {
|
|
1277
|
+
stream = new UncompressedLayerStream(level, bytesPerLayer, layerCount);
|
|
1278
|
+
}
|
|
1279
|
+
this._initStreamingRingBuffer(gl, width, height, astcFormat, layerCount, vkFormat);
|
|
1280
|
+
this._streamingMode = true;
|
|
1281
|
+
this._streamingLayerCount = layerCount;
|
|
1282
|
+
this._streamingLevel0Offset = level0Offset;
|
|
1283
|
+
this._streamingFrameCache = /* @__PURE__ */ new Map();
|
|
1284
|
+
this._streamingDecodePos = 0;
|
|
1285
|
+
this._streamingFramesReady = 0;
|
|
1286
|
+
this._layerStream = stream;
|
|
1287
|
+
const actualRingSize = this._streamingRingActualSize;
|
|
1288
|
+
const prefetchCount = Math.min(this._streamingPrefetchAhead, layerCount);
|
|
1289
|
+
this._log(`[AlphaVideoGpu] Pre-decoding ${prefetchCount} frames...`);
|
|
1290
|
+
for (let i = 0; i < prefetchCount && !this._streamingCancelled; i++) {
|
|
1291
|
+
const frameData = await stream.readLayer();
|
|
1292
|
+
this._checkLoad(loadId);
|
|
1293
|
+
if (!frameData) break;
|
|
1294
|
+
this._streamingFrameCache.set(i, frameData);
|
|
1295
|
+
this._streamingDecodePos = i + 1;
|
|
1296
|
+
this._streamingFramesReady = i + 1;
|
|
1297
|
+
if (i < actualRingSize) {
|
|
1298
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, this._streamingRingBuffer);
|
|
1299
|
+
this._uploadLayer(gl, i, width, height, astcFormat, frameData);
|
|
1300
|
+
this._streamingRingSlots[i] = i;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
this._textureArray = this._streamingRingBuffer;
|
|
1304
|
+
this._startBackgroundDecompression();
|
|
1305
|
+
this._log(`[AlphaVideoGpu] \u2713 Streaming ready: ${metadata.frameCount} frames @ ${metadata.frameRate} fps`);
|
|
1306
|
+
}
|
|
1307
|
+
// ======== Private: Background Decode ========
|
|
1308
|
+
/**
|
|
1309
|
+
* Reads and decodes ahead of playback, and catches up to a seek target, in slices of
|
|
1310
|
+
* DECODE_SLICE_MS so a long catch-up doesn't hold up drawing or input. A seek during a read
|
|
1311
|
+
* interrupts it (readLayer returns null) and the loop carries on from the new position.
|
|
1312
|
+
*/
|
|
1313
|
+
_startBackgroundDecompression() {
|
|
1314
|
+
const stream = this._layerStream;
|
|
1315
|
+
if (!stream || this._backgroundDecodeStream === stream) return;
|
|
1316
|
+
this._backgroundDecodeStream = stream;
|
|
1317
|
+
const decompressLoop = async () => {
|
|
1318
|
+
var _a;
|
|
1319
|
+
const layerCount = this._streamingLayerCount;
|
|
1320
|
+
const aheadLimit = this._streamingPrefetchAhead;
|
|
1321
|
+
let sliceEnd = performance.now() + DECODE_SLICE_MS;
|
|
1322
|
+
try {
|
|
1323
|
+
while (!this._streamingCancelled && this._layerStream === stream && stream.position < layerCount) {
|
|
1324
|
+
if (performance.now() >= sliceEnd) {
|
|
1325
|
+
await yieldToEventLoop();
|
|
1326
|
+
sliceEnd = performance.now() + DECODE_SLICE_MS;
|
|
1327
|
+
} else if (stream.skipping) {
|
|
1328
|
+
await stream.skip(sliceEnd);
|
|
1329
|
+
} else if (stream.position - this._currentFrame <= aheadLimit) {
|
|
1330
|
+
const frameIndex = stream.position;
|
|
1331
|
+
const frameData = await stream.readLayer();
|
|
1332
|
+
if (this._layerStream !== stream) break;
|
|
1333
|
+
if (!frameData) {
|
|
1334
|
+
if (stream.atEnd) break;
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1337
|
+
this._streamingFrameCache.set(frameIndex, frameData);
|
|
1338
|
+
this._streamingDecodePos = stream.position;
|
|
1339
|
+
this._streamingFramesReady = stream.position;
|
|
1340
|
+
this._evictOldFramesFromCache(this._currentFrame);
|
|
1341
|
+
} else {
|
|
1342
|
+
await new Promise((resolve) => setTimeout(resolve, 16));
|
|
1343
|
+
sliceEnd = performance.now() + DECODE_SLICE_MS;
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
} catch (error) {
|
|
1347
|
+
if (this._layerStream === stream && !isAbortError(error)) {
|
|
1348
|
+
console.error("[AlphaVideoGpu] Streaming decode failed:", error);
|
|
1349
|
+
this._setState("error");
|
|
1350
|
+
(_a = this._onError) == null ? void 0 : _a.call(this, error);
|
|
1351
|
+
}
|
|
1352
|
+
} finally {
|
|
1353
|
+
if (this._backgroundDecodeStream === stream) this._backgroundDecodeStream = null;
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
decompressLoop();
|
|
1357
|
+
}
|
|
1358
|
+
// ======== Private: Ensure Frame In Ring Buffer ========
|
|
1359
|
+
_ensureFrameInRingBuffer(frameIndex) {
|
|
1360
|
+
const gl = this._gl;
|
|
1361
|
+
if (!gl || !this._streamingRingBuffer) return -1;
|
|
1362
|
+
const ringSize = this._streamingRingActualSize;
|
|
1363
|
+
const ringSlots = this._streamingRingSlots;
|
|
1364
|
+
const frameCache = this._streamingFrameCache;
|
|
1365
|
+
const existingSlot = ringSlots.indexOf(frameIndex);
|
|
1366
|
+
if (existingSlot !== -1) return existingSlot;
|
|
1367
|
+
const frameData = frameCache.get(frameIndex);
|
|
1368
|
+
if (!frameData) return -1;
|
|
1369
|
+
const slot = frameIndex % ringSize;
|
|
1370
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, this._streamingRingBuffer);
|
|
1371
|
+
this._uploadLayer(gl, slot, this._streamingWidth, this._streamingHeight, this._streamingAstcFormat, frameData);
|
|
1372
|
+
ringSlots[slot] = frameIndex;
|
|
1373
|
+
return slot;
|
|
1374
|
+
}
|
|
1375
|
+
// ======== Private: Evict Old Frames From Cache ========
|
|
1376
|
+
_evictOldFramesFromCache(currentPlaybackFrame) {
|
|
1377
|
+
const frameCache = this._streamingFrameCache;
|
|
1378
|
+
const metadata = this._metadata;
|
|
1379
|
+
if (!metadata) return;
|
|
1380
|
+
const toRemove = [];
|
|
1381
|
+
if (this._useVramStrategy) {
|
|
1382
|
+
for (const frameIndex of frameCache.keys()) {
|
|
1383
|
+
if (frameIndex < currentPlaybackFrame - 2) toRemove.push(frameIndex);
|
|
1384
|
+
}
|
|
1385
|
+
if (frameCache.size - toRemove.length > 5) {
|
|
1386
|
+
const sorted = Array.from(frameCache.keys()).sort((a, b) => a - b);
|
|
1387
|
+
for (const frameIndex of sorted) {
|
|
1388
|
+
if (frameIndex < currentPlaybackFrame && !toRemove.includes(frameIndex)) {
|
|
1389
|
+
toRemove.push(frameIndex);
|
|
1390
|
+
if (frameCache.size - toRemove.length <= 5) break;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
} else {
|
|
1395
|
+
const minFrame = currentPlaybackFrame - 2;
|
|
1396
|
+
const maxFrame = currentPlaybackFrame + this._streamingPrefetchAhead;
|
|
1397
|
+
for (const frameIndex of frameCache.keys()) {
|
|
1398
|
+
if (frameIndex < minFrame || frameIndex > maxFrame) toRemove.push(frameIndex);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
for (const frameIndex of toRemove) frameCache.delete(frameIndex);
|
|
1402
|
+
if (frameCache.size > this._streamingPrefetchAhead + 10) {
|
|
1403
|
+
console.warn(`[AlphaVideoGpu] Frame cache too large: ${frameCache.size} frames (max: ${this._streamingPrefetchAhead}), playback: ${currentPlaybackFrame}`);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
// ======== Private: Handle Streaming Loop ========
|
|
1407
|
+
_handleStreamingLoop() {
|
|
1408
|
+
if (!this._layerStream) return;
|
|
1409
|
+
this._streamingLoopCount++;
|
|
1410
|
+
this._log(`[AlphaVideoGpu] \u{1F504} Loop #${this._streamingLoopCount}`);
|
|
1411
|
+
this._moveStreamTo(0);
|
|
1412
|
+
}
|
|
1413
|
+
/** Starts the streaming decoder, unless it is already running. */
|
|
1414
|
+
_kickStreamingDecode() {
|
|
1415
|
+
if (!this._streamingMode || !this._layerStream || this._streamingCancelled) return;
|
|
1416
|
+
this._startBackgroundDecompression();
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Points the streaming decoder at target. Frames from target up to the decoder that are all
|
|
1420
|
+
* still buffered are kept; otherwise decoding carries on or starts at a seek point, whichever
|
|
1421
|
+
* reaches target sooner (see ZstdLayerStream.moveTo).
|
|
1422
|
+
*/
|
|
1423
|
+
_moveStreamTo(target) {
|
|
1424
|
+
if (!this._layerStream) return;
|
|
1425
|
+
const decodePos = this._streamingDecodePos;
|
|
1426
|
+
let buffered = target < decodePos;
|
|
1427
|
+
for (let f = target; buffered && f < decodePos; f++) {
|
|
1428
|
+
buffered = this._streamingFrameCache.has(f) || this._streamingRingSlots.includes(f);
|
|
1429
|
+
}
|
|
1430
|
+
if (!buffered) this._decodeFrom(target);
|
|
1431
|
+
}
|
|
1432
|
+
/** Stops the stream's reads and frees the zstd decoder's WASM buffers. */
|
|
1433
|
+
_closeLayerStream() {
|
|
1434
|
+
var _a;
|
|
1435
|
+
(_a = this._layerStream) == null ? void 0 : _a.close();
|
|
1436
|
+
this._layerStream = null;
|
|
1437
|
+
}
|
|
1438
|
+
/** Drops the decoded frames and has the decoder produce target next. */
|
|
1439
|
+
_decodeFrom(target) {
|
|
1440
|
+
const stream = this._layerStream;
|
|
1441
|
+
if (!stream) return;
|
|
1442
|
+
this._streamingFrameCache.clear();
|
|
1443
|
+
stream.moveTo(target);
|
|
1444
|
+
this._streamingDecodePos = target;
|
|
1445
|
+
this._streamingFramesReady = target;
|
|
1446
|
+
this._kickStreamingDecode();
|
|
1447
|
+
}
|
|
1448
|
+
/** Draws the shown frame once it is decoded, for a seek while not playing. */
|
|
1449
|
+
_drawWhenReady() {
|
|
1450
|
+
if (this._owedFrameId !== null) cancelAnimationFrame(this._owedFrameId);
|
|
1451
|
+
this._owedFrameId = null;
|
|
1452
|
+
const pauseDecodeAfter = this._state === "paused";
|
|
1453
|
+
this._streamingCancelled = false;
|
|
1454
|
+
this._kickStreamingDecode();
|
|
1455
|
+
const attempt = () => {
|
|
1456
|
+
this._owedFrameId = null;
|
|
1457
|
+
if (this._state === "playing") return;
|
|
1458
|
+
if (this._render()) {
|
|
1459
|
+
if (pauseDecodeAfter && this._state === "paused") this._streamingCancelled = true;
|
|
1460
|
+
return;
|
|
1461
|
+
}
|
|
1462
|
+
this._owedFrameId = requestAnimationFrame(attempt);
|
|
1463
|
+
};
|
|
1464
|
+
attempt();
|
|
1465
|
+
}
|
|
1466
|
+
// ======== Private: Render Frame ========
|
|
1467
|
+
/** Draws the current frame; false when it isn't decoded yet, leaving the last one showing. */
|
|
1468
|
+
_render() {
|
|
1469
|
+
const gl = this._gl;
|
|
1470
|
+
const metadata = this._metadata;
|
|
1471
|
+
const arrayProgram = this._arrayProgram;
|
|
1472
|
+
if (!gl || !metadata || !arrayProgram || !this._textureArray) return false;
|
|
1473
|
+
const currentFrame = this._currentFrame;
|
|
1474
|
+
if (currentFrame >= metadata.frameCount) return false;
|
|
1475
|
+
const prepareTarget = () => {
|
|
1476
|
+
if (this._usingSharedGL && getSharedGLResources()) {
|
|
1477
|
+
const frameWidth = metadata.frameWidth;
|
|
1478
|
+
const frameHeight = metadata.frameHeight;
|
|
1479
|
+
ensureSharedCanvasSize(frameWidth, frameHeight);
|
|
1480
|
+
gl.viewport(0, 0, frameWidth, frameHeight);
|
|
1481
|
+
}
|
|
1482
|
+
gl.clearColor(0, 0, 0, 0);
|
|
1483
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
1484
|
+
};
|
|
1485
|
+
const gl2 = gl;
|
|
1486
|
+
let layerIndex;
|
|
1487
|
+
if (this._streamingMode) {
|
|
1488
|
+
const slot = currentFrame < this._streamingFramesReady ? this._ensureFrameInRingBuffer(currentFrame) : -1;
|
|
1489
|
+
if (slot === -1) return false;
|
|
1490
|
+
layerIndex = slot;
|
|
1491
|
+
for (let i = 1; i <= 3 && i < this._streamingRingActualSize; i++) {
|
|
1492
|
+
const nextFrame = currentFrame + i;
|
|
1493
|
+
if (nextFrame < metadata.frameCount) {
|
|
1494
|
+
this._ensureFrameInRingBuffer(nextFrame);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
} else if (this._ramHeavyMode && this._ramFrameData) {
|
|
1498
|
+
if (currentFrame !== this._ramUploadedFrame) {
|
|
1499
|
+
const offset = currentFrame * this._ramBytesPerFrame;
|
|
1500
|
+
const frameData = new Uint8Array(
|
|
1501
|
+
this._ramFrameData.buffer,
|
|
1502
|
+
this._ramFrameData.byteOffset + offset,
|
|
1503
|
+
this._ramBytesPerFrame
|
|
1504
|
+
);
|
|
1505
|
+
gl2.bindTexture(gl2.TEXTURE_2D_ARRAY, this._textureArray);
|
|
1506
|
+
this._uploadLayer(gl2, 0, this._ramWidth, this._ramHeight, this._ramAstcFormat, frameData);
|
|
1507
|
+
this._ramUploadedFrame = currentFrame;
|
|
1508
|
+
}
|
|
1509
|
+
layerIndex = 0;
|
|
1510
|
+
} else {
|
|
1511
|
+
layerIndex = currentFrame;
|
|
1512
|
+
}
|
|
1513
|
+
prepareTarget();
|
|
1514
|
+
gl2.useProgram(arrayProgram);
|
|
1515
|
+
gl2.activeTexture(gl2.TEXTURE0);
|
|
1516
|
+
gl2.bindTexture(gl2.TEXTURE_2D_ARRAY, this._textureArray);
|
|
1517
|
+
gl2.uniform1i(gl2.getUniformLocation(arrayProgram, "u_textureArray"), 0);
|
|
1518
|
+
gl2.uniform1f(gl2.getUniformLocation(arrayProgram, "u_layer"), layerIndex);
|
|
1519
|
+
const posLoc = gl2.getAttribLocation(arrayProgram, "a_position");
|
|
1520
|
+
gl2.bindBuffer(gl2.ARRAY_BUFFER, this._positionBuffer);
|
|
1521
|
+
gl2.enableVertexAttribArray(posLoc);
|
|
1522
|
+
gl2.vertexAttribPointer(posLoc, 2, gl2.FLOAT, false, 0, 0);
|
|
1523
|
+
const texLoc = gl2.getAttribLocation(arrayProgram, "a_texCoord");
|
|
1524
|
+
gl2.bindBuffer(gl2.ARRAY_BUFFER, this._texCoordBuffer);
|
|
1525
|
+
gl2.enableVertexAttribArray(texLoc);
|
|
1526
|
+
gl2.vertexAttribPointer(texLoc, 2, gl2.FLOAT, false, 0, 0);
|
|
1527
|
+
gl2.drawArrays(gl2.TRIANGLES, 0, 6);
|
|
1528
|
+
if (this._usingSharedGL && this._ctx2d) {
|
|
1529
|
+
const sharedRes = getSharedGLResources();
|
|
1530
|
+
if (sharedRes) {
|
|
1531
|
+
const canvas = this._canvas;
|
|
1532
|
+
const ctx2d = this._ctx2d;
|
|
1533
|
+
const sharedCanvas = sharedRes.canvas;
|
|
1534
|
+
const frameWidth = metadata.frameWidth;
|
|
1535
|
+
const frameHeight = metadata.frameHeight;
|
|
1536
|
+
const srcY = sharedCanvas.height - frameHeight;
|
|
1537
|
+
ctx2d.clearRect(0, 0, canvas.width, canvas.height);
|
|
1538
|
+
ctx2d.drawImage(
|
|
1539
|
+
sharedCanvas,
|
|
1540
|
+
0,
|
|
1541
|
+
srcY,
|
|
1542
|
+
frameWidth,
|
|
1543
|
+
frameHeight,
|
|
1544
|
+
0,
|
|
1545
|
+
0,
|
|
1546
|
+
canvas.width,
|
|
1547
|
+
canvas.height
|
|
1548
|
+
);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
return true;
|
|
1552
|
+
}
|
|
1553
|
+
// ======== Private: Animation Loop ========
|
|
1554
|
+
_startAnimationLoop() {
|
|
1555
|
+
if (this._animationFrameId) return;
|
|
1556
|
+
const metadata = this._metadata;
|
|
1557
|
+
if (!metadata) return;
|
|
1558
|
+
const frameInterval = 1e3 / metadata.frameRate;
|
|
1559
|
+
const animate = (timestamp) => {
|
|
1560
|
+
var _a, _b;
|
|
1561
|
+
this._animationFrameId = null;
|
|
1562
|
+
if (this._state !== "playing") return;
|
|
1563
|
+
const elapsed = timestamp - this._lastFrameTime;
|
|
1564
|
+
if (elapsed >= frameInterval / this._playbackSpeed && this._render()) {
|
|
1565
|
+
this._lastFrameTime = timestamp - elapsed % (frameInterval / this._playbackSpeed);
|
|
1566
|
+
if (this._frameEvents) (_a = this._onFrameUpdate) == null ? void 0 : _a.call(this, this._currentFrame, metadata.frameCount);
|
|
1567
|
+
if (this._currentFrame + 1 < metadata.frameCount) {
|
|
1568
|
+
this._currentFrame++;
|
|
1569
|
+
} else if (this._loop) {
|
|
1570
|
+
this._currentFrame = 0;
|
|
1571
|
+
if (this._streamingMode && this._streamingFrameCache) {
|
|
1572
|
+
this._handleStreamingLoop();
|
|
1573
|
+
}
|
|
1574
|
+
} else {
|
|
1575
|
+
this._ended = true;
|
|
1576
|
+
this._setState("stopped");
|
|
1577
|
+
(_b = this._onFinished) == null ? void 0 : _b.call(this);
|
|
1578
|
+
return;
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
this._animationFrameId = requestAnimationFrame(animate);
|
|
1582
|
+
};
|
|
1583
|
+
this._animationFrameId = requestAnimationFrame(animate);
|
|
1584
|
+
}
|
|
1585
|
+
_stopAnimationLoop() {
|
|
1586
|
+
if (this._animationFrameId) {
|
|
1587
|
+
cancelAnimationFrame(this._animationFrameId);
|
|
1588
|
+
this._animationFrameId = null;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
};
|
|
1592
|
+
|
|
1593
|
+
// src/zstddec-stream-bundled.js
|
|
1594
|
+
function _arrayLikeToArray(r, a) {
|
|
1595
|
+
(null == a || a > r.length) && (a = r.length);
|
|
1596
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
1597
|
+
return n;
|
|
1598
|
+
}
|
|
1599
|
+
function _createForOfIteratorHelperLoose(r, e) {
|
|
1600
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
1601
|
+
if (t) return (t = t.call(r)).next.bind(t);
|
|
1602
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
|
|
1603
|
+
t && (r = t);
|
|
1604
|
+
var o = 0;
|
|
1605
|
+
return function() {
|
|
1606
|
+
return o >= r.length ? {
|
|
1607
|
+
done: true
|
|
1608
|
+
} : {
|
|
1609
|
+
done: false,
|
|
1610
|
+
value: r[o++]
|
|
1611
|
+
};
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1615
|
+
}
|
|
1616
|
+
function _unsupportedIterableToArray(r, a) {
|
|
1617
|
+
if (r) {
|
|
1618
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
1619
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
1620
|
+
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
var _init;
|
|
1624
|
+
var instance;
|
|
1625
|
+
var heap;
|
|
1626
|
+
var heapView;
|
|
1627
|
+
var IMPORT_OBJECT = {
|
|
1628
|
+
env: {
|
|
1629
|
+
emscripten_notify_memory_growth: function emscripten_notify_memory_growth(_) {
|
|
1630
|
+
heap = new Uint8Array(instance.exports.memory.buffer);
|
|
1631
|
+
heapView = new DataView(heap.buffer);
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
};
|
|
1635
|
+
var ZSTDDecoder = /* @__PURE__ */ (function() {
|
|
1636
|
+
function ZSTDDecoder2() {
|
|
1637
|
+
}
|
|
1638
|
+
var _proto = ZSTDDecoder2.prototype;
|
|
1639
|
+
_proto.init = function init() {
|
|
1640
|
+
if (_init) return _init;
|
|
1641
|
+
if (typeof fetch !== "undefined") {
|
|
1642
|
+
_init = fetch("data:application/wasm;base64," + wasm).then(function(response) {
|
|
1643
|
+
return response.arrayBuffer();
|
|
1644
|
+
}).then(function(arrayBuffer) {
|
|
1645
|
+
return WebAssembly.instantiate(arrayBuffer, IMPORT_OBJECT);
|
|
1646
|
+
}).then(this._init);
|
|
1647
|
+
} else {
|
|
1648
|
+
_init = WebAssembly.instantiate(Buffer.from(wasm, "base64"), IMPORT_OBJECT).then(this._init);
|
|
1649
|
+
}
|
|
1650
|
+
return _init;
|
|
1651
|
+
};
|
|
1652
|
+
_proto._init = function _init2(result) {
|
|
1653
|
+
instance = result.instance;
|
|
1654
|
+
IMPORT_OBJECT.env.emscripten_notify_memory_growth(0);
|
|
1655
|
+
};
|
|
1656
|
+
_proto.decode = function decode(array, uncompressedSize) {
|
|
1657
|
+
if (uncompressedSize === void 0) {
|
|
1658
|
+
uncompressedSize = 0;
|
|
1659
|
+
}
|
|
1660
|
+
if (!instance) throw new Error("ZSTDDecoder: Await .init() before decoding.");
|
|
1661
|
+
var compressedSize = array.byteLength;
|
|
1662
|
+
var compressedPtr = instance.exports.malloc(compressedSize);
|
|
1663
|
+
heap.set(array, compressedPtr);
|
|
1664
|
+
if (uncompressedSize === 0) {
|
|
1665
|
+
uncompressedSize = Number(instance.exports.ZSTD_findDecompressedSize(compressedPtr, compressedSize));
|
|
1666
|
+
}
|
|
1667
|
+
if (uncompressedSize === -1) {
|
|
1668
|
+
instance.exports.free(compressedPtr);
|
|
1669
|
+
var parts = [];
|
|
1670
|
+
for (var _iterator = _createForOfIteratorHelperLoose(this.decodeStreaming([array])), _step; !(_step = _iterator()).done; ) {
|
|
1671
|
+
var out = _step.value;
|
|
1672
|
+
parts.push(out);
|
|
1673
|
+
}
|
|
1674
|
+
if (parts.length === 1) {
|
|
1675
|
+
return parts[0];
|
|
1676
|
+
}
|
|
1677
|
+
var fullByteLength = parts.reduce(function(acc, arr) {
|
|
1678
|
+
return acc + arr.byteLength;
|
|
1679
|
+
}, 0);
|
|
1680
|
+
var result = new Uint8Array(fullByteLength);
|
|
1681
|
+
var offset = 0;
|
|
1682
|
+
for (var _i = 0, _parts = parts; _i < _parts.length; _i++) {
|
|
1683
|
+
var part = _parts[_i];
|
|
1684
|
+
result.set(part, offset);
|
|
1685
|
+
offset += part.byteLength;
|
|
1686
|
+
}
|
|
1687
|
+
return result;
|
|
1688
|
+
}
|
|
1689
|
+
var uncompressedPtr = instance.exports.malloc(uncompressedSize);
|
|
1690
|
+
var actualSize = instance.exports.ZSTD_decompress(uncompressedPtr, uncompressedSize, compressedPtr, compressedSize);
|
|
1691
|
+
var dec = heap.slice(uncompressedPtr, uncompressedPtr + actualSize);
|
|
1692
|
+
instance.exports.free(compressedPtr);
|
|
1693
|
+
instance.exports.free(uncompressedPtr);
|
|
1694
|
+
return dec;
|
|
1695
|
+
};
|
|
1696
|
+
_proto.createStreamingDecoder = function createStreamingDecoder() {
|
|
1697
|
+
if (!instance) throw new Error("ZSTDDecoder: Await .init() before decoding.");
|
|
1698
|
+
var buffOutSize = instance.exports.ZSTD_DStreamOutSize();
|
|
1699
|
+
var buffOut = instance.exports.malloc(buffOutSize);
|
|
1700
|
+
var dctxPtr = instance.exports.ZSTD_createDCtx();
|
|
1701
|
+
var sizeOfPointer = 4;
|
|
1702
|
+
var sizeOfSizeT = 4;
|
|
1703
|
+
var inputPtr = instance.exports.malloc(sizeOfPointer + sizeOfSizeT * 2);
|
|
1704
|
+
var outputPtr = instance.exports.malloc(sizeOfPointer + sizeOfSizeT * 2);
|
|
1705
|
+
var lastRet = 0;
|
|
1706
|
+
var freed = false;
|
|
1707
|
+
function* decode(array) {
|
|
1708
|
+
if (freed) throw new Error("ZSTDDecoder: the streaming decoder was freed");
|
|
1709
|
+
var compressedPtr = instance.exports.malloc(array.byteLength);
|
|
1710
|
+
try {
|
|
1711
|
+
heap.set(array, compressedPtr);
|
|
1712
|
+
heapView.setInt32(inputPtr, compressedPtr, true);
|
|
1713
|
+
heapView.setInt32(inputPtr + sizeOfPointer, array.byteLength, true);
|
|
1714
|
+
heapView.setInt32(inputPtr + sizeOfPointer + sizeOfSizeT, 0, true);
|
|
1715
|
+
var outputFull = false;
|
|
1716
|
+
while (outputFull || heapView.getUint32(inputPtr + sizeOfPointer + sizeOfSizeT, true) < heapView.getUint32(inputPtr + sizeOfPointer, true)) {
|
|
1717
|
+
heapView.setInt32(outputPtr, buffOut, true);
|
|
1718
|
+
heapView.setInt32(outputPtr + sizeOfPointer, buffOutSize, true);
|
|
1719
|
+
heapView.setInt32(outputPtr + sizeOfPointer + sizeOfSizeT, 0, true);
|
|
1720
|
+
lastRet = instance.exports.ZSTD_decompressStream(dctxPtr, outputPtr, inputPtr);
|
|
1721
|
+
if (lastRet < 0) throw new Error("zstd: corrupt or unsupported data");
|
|
1722
|
+
var outputPos = heapView.getUint32(outputPtr + sizeOfPointer + sizeOfSizeT, true);
|
|
1723
|
+
outputFull = outputPos === buffOutSize && lastRet !== 0;
|
|
1724
|
+
if (outputPos > 0) yield heap.slice(buffOut, buffOut + outputPos);
|
|
1725
|
+
if (freed) return;
|
|
1726
|
+
}
|
|
1727
|
+
} finally {
|
|
1728
|
+
instance.exports.free(compressedPtr);
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
return {
|
|
1732
|
+
decode,
|
|
1733
|
+
finished: function finished() {
|
|
1734
|
+
return lastRet === 0;
|
|
1735
|
+
},
|
|
1736
|
+
free: function free() {
|
|
1737
|
+
if (freed) return;
|
|
1738
|
+
freed = true;
|
|
1739
|
+
instance.exports.ZSTD_freeDCtx(dctxPtr);
|
|
1740
|
+
instance.exports.free(buffOut);
|
|
1741
|
+
instance.exports.free(inputPtr);
|
|
1742
|
+
instance.exports.free(outputPtr);
|
|
1743
|
+
}
|
|
1744
|
+
};
|
|
1745
|
+
};
|
|
1746
|
+
_proto.decodeStreaming = function* decodeStreaming(arrays) {
|
|
1747
|
+
var stream = this.createStreamingDecoder();
|
|
1748
|
+
try {
|
|
1749
|
+
for (var _iterator2 = _createForOfIteratorHelperLoose(arrays), _step2; !(_step2 = _iterator2()).done; ) {
|
|
1750
|
+
yield* stream.decode(_step2.value);
|
|
1751
|
+
}
|
|
1752
|
+
if (!stream.finished()) throw new Error("Incomplete stream, more data expected.");
|
|
1753
|
+
} finally {
|
|
1754
|
+
stream.free();
|
|
1755
|
+
}
|
|
1756
|
+
};
|
|
1757
|
+
return ZSTDDecoder2;
|
|
1758
|
+
})();
|
|
1759
|
+
var wasm = "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QQhyIQBBACEDA0AgACADTQ0DIANBQGshAwwACwALQWwhCiAOIA5B/ABqIA5B+ABqIAUgBhAGIgJBiH9LDQEgDigCeCIDIARLDQEgACAOIA4oAnwgByAIIAMgDRAlIAEgADYCACACIQoMAQtBbCEKCyAOQYABaiQAIAoLcAEEfyAAQgA3AgAgAgRAIAFBCmohBiABKAIEIQRBACECQQAhAQNAIAEgBHZFBEAgAiAGIAFBA3RqLQAAIgUgAiAFSxshAiABQQFqIQEgAyAFQRZLaiEDDAELCyAAIAI2AgQgACADQQggBGt0NgIACwuuAQEEfyABIAIoAgQiAyABKAIEaiIENgIEIAAgA0ECdEGwGWooAgAgASgCAEEAIARrdnE2AgACQCAEQSFPBEAgAUGwGjYCCAwBCyABKAIIIgMgASgCEE8EQCABEAwMAQsgAyABKAIMIgVGDQAgASADIAMgBWsgBEEDdiIGIAMgBmsgBUkbIgNrIgU2AgggASAEIANBA3RrNgIEIAEgBSgAADYCAAsgACACQQhqNgIEC40CAgN/AX4gACACaiEEAkACQCACQQhOBEAgACABayICQXlIDQELA0AgACAETw0CIAAgAS0AADoAACAAQQFqIQAgAUEBaiEBDAALAAsCQAJAIAJBb0sNACAAIARBIGsiAksNACABKQAAIQYgACABKQAINwAIIAAgBjcAACACIABrIgVBEU4EQCAAQRBqIQAgASEDA0AgAykAECEGIAAgAykAGDcACCAAIAY3AAAgAykAICEGIAAgAykAKDcAGCAAIAY3ABAgA0EgaiEDIABBIGoiACACSQ0ACwsgASAFaiEBDAELIAAhAgsDQCACIARPDQEgAiABLQAAOgAAIAJBAWohAiABQQFqIQEMAAsACwvfAQEGf0G6fyEKAkAgAigCBCIIIAIoAgAiCWoiDSABIABrSw0AQWwhCiAJIAQgAygCACILa0sNACAAIAlqIgQgAigCCCIMayECIAAgAUEgayIBIAsgCUEAEDMgAyAJIAtqNgIAAkACQCAEIAVrIAxPBEAgAiEFDAELIAwgBCAGa0sNAiAHIAcgAiAFayIDaiICIAhqTwRAIAhFDQIgBCACIAj8CgAADAILQQAgA2siAARAIAQgAiAA/AoAAAsgAyAIaiEIIAQgA2shBAsgBCABIAUgCEEBEDML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";
|
|
1760
|
+
|
|
1761
|
+
export {
|
|
1762
|
+
extractKTX2Metadata,
|
|
1763
|
+
ASTC_FORMAT_MAP,
|
|
1764
|
+
getASTCBlockSize,
|
|
1765
|
+
getASTCBytesPerLayer,
|
|
1766
|
+
AlphaVideoGpuError,
|
|
1767
|
+
STORAGE_NAMESPACE,
|
|
1768
|
+
KTX2PlayerCore,
|
|
1769
|
+
ZSTDDecoder
|
|
1770
|
+
};
|