unbikit 0.7.0 → 0.9.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/README.md +5 -7
- package/dist/unbikit.d.ts +90 -52
- package/dist/unbikit.js +233 -216
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -3,13 +3,10 @@
|
|
|
3
3
|
[](https://bundlephobia.com/package/unbikit)
|
|
4
4
|
[](https://www.npmjs.com/package/unbikit)
|
|
5
5
|
|
|
6
|
-
> ⚠️
|
|
7
|
-
> This package is at an early development stage. Expect API changes!
|
|
8
|
-
|
|
9
6
|
<img src="/app/src/images/unbikit-logo.svg" alt="logo of unbikit" width="24" height="24"> unbikit
|
|
10
7
|
(_un-bik-ɪt_) is a decoder for `.bik` ([Bink Video](https://en.wikipedia.org/wiki/Bink_Video))
|
|
11
|
-
files that can be used to play or transcode videos
|
|
12
|
-
|
|
8
|
+
files that can be used to play or transcode videos. The format was first released in 1999 and has
|
|
9
|
+
since been used in many classic computer games.
|
|
13
10
|
|
|
14
11
|
⭐ [Documentation](https://blennies.github.io/unbikit/) and a
|
|
15
12
|
⭐ [video player demo](https://blennies.github.io/unbikit/demo/)
|
|
@@ -20,9 +17,10 @@ are available, as well as a
|
|
|
20
17
|
|
|
21
18
|
- Supports Bink 1, revisions `c` to `i` inclusive
|
|
22
19
|
- Handles demuxing and decompression of audio and video streams
|
|
23
|
-
- TypeScript/JavaScript
|
|
20
|
+
- TypeScript/JavaScript (no WASM or native code)
|
|
24
21
|
- No dependencies
|
|
25
|
-
-
|
|
22
|
+
- Straightforward API: supply a video via `Blob`, `File`, `Request` or `URL`
|
|
23
|
+
- the Web Streams API will be used where possible for efficient reading of video data
|
|
26
24
|
- Isomorphic
|
|
27
25
|
- runs on client/server runtimes that support at least ES2022
|
|
28
26
|
- can be run with older runtimes by using the syntax lowering feature of some bundlers
|
package/dist/unbikit.d.ts
CHANGED
|
@@ -4,31 +4,48 @@
|
|
|
4
4
|
* not used by the decoder for any subsequent processing, so can be used by an application freely.
|
|
5
5
|
*/
|
|
6
6
|
interface BikVideoFrame {
|
|
7
|
+
/**
|
|
8
|
+
* Coded width of the video frame (in pixels).
|
|
9
|
+
*/
|
|
7
10
|
width: number;
|
|
11
|
+
/**
|
|
12
|
+
* Coded height of the video frame (in pixels).
|
|
13
|
+
*/
|
|
8
14
|
height: number;
|
|
15
|
+
/**
|
|
16
|
+
* Pixel data for the video frame, encoded in Planar YUV 4:2:0 format with an optional alpha
|
|
17
|
+
* channel. The planes are stored in the order: Y, U, V, alpha. Each of the Y and alpha planes
|
|
18
|
+
* occupy 4 times as much space in the buffer as either the U or V plane (as would be expected
|
|
19
|
+
* given the encoding format), and the total buffer size is set to be just enough to hold all
|
|
20
|
+
* of the planes.
|
|
21
|
+
*/
|
|
9
22
|
yuv: Uint8Array<ArrayBuffer>;
|
|
23
|
+
/**
|
|
24
|
+
* The number of pixels per line of the video frame, stored as an array of per-plane values in
|
|
25
|
+
* the order: Y, U, V, alpha.
|
|
26
|
+
*/
|
|
10
27
|
lineSize: number[];
|
|
11
28
|
}
|
|
12
29
|
//#endregion
|
|
13
30
|
//#region src/bik-decoder.d.ts
|
|
14
31
|
/**
|
|
15
|
-
* Decoded header of a BIK
|
|
32
|
+
* Decoded header of a BIK data source.
|
|
16
33
|
*/
|
|
17
34
|
interface BikHeader {
|
|
18
35
|
/**
|
|
19
|
-
* Version of the
|
|
36
|
+
* Version of the encoding format.
|
|
20
37
|
*/
|
|
21
38
|
version: 1 | 2;
|
|
22
39
|
/**
|
|
23
|
-
* Sub-version of the
|
|
40
|
+
* Sub-version of the encoding format.
|
|
24
41
|
*/
|
|
25
42
|
subVersion: number;
|
|
26
43
|
/**
|
|
27
|
-
* Total size of the encoded
|
|
44
|
+
* Total size of the encoded video data (in bytes).
|
|
28
45
|
*/
|
|
29
|
-
|
|
46
|
+
totalSize: number;
|
|
30
47
|
/**
|
|
31
|
-
* Number of
|
|
48
|
+
* Number of frames in the video.
|
|
32
49
|
*
|
|
33
50
|
* Note that audio is stored with each frame but doesn't necessarily correspond to the audio
|
|
34
51
|
* that should be played when the video frame is shown.
|
|
@@ -48,20 +65,20 @@ interface BikHeader {
|
|
|
48
65
|
*/
|
|
49
66
|
height: number;
|
|
50
67
|
/**
|
|
51
|
-
* Number of frames per second that the video
|
|
68
|
+
* Number of frames per second that the video should be played at.
|
|
52
69
|
*/
|
|
53
70
|
fps: number;
|
|
54
71
|
/**
|
|
55
|
-
* Flags providing additional information about the encoded
|
|
72
|
+
* Flags providing additional information about the encoded video.
|
|
56
73
|
*/
|
|
57
74
|
videoFlags: {
|
|
58
75
|
/**
|
|
59
|
-
* When `true`, the encoded
|
|
76
|
+
* When `true`, the encoded video contains an alpha plane for each frame. Otherwise the video
|
|
60
77
|
* contains no alpha information.
|
|
61
78
|
*/
|
|
62
79
|
hasAlpha: boolean;
|
|
63
80
|
/**
|
|
64
|
-
* When `true`, the U and V planes in the encoded
|
|
81
|
+
* When `true`, the U and V planes in the encoded video should be swapped during the decoding
|
|
65
82
|
* process.
|
|
66
83
|
*
|
|
67
84
|
* This is a value intended for internal use by the decoder and should not be needed by
|
|
@@ -69,7 +86,7 @@ interface BikHeader {
|
|
|
69
86
|
*/
|
|
70
87
|
hasSwappedUVPlanes: boolean;
|
|
71
88
|
/**
|
|
72
|
-
* When `true`, the encoded
|
|
89
|
+
* When `true`, the encoded video doesn't contain U or V planes. Otherwise the video contains
|
|
73
90
|
* both U and V planes.
|
|
74
91
|
*/
|
|
75
92
|
isGrayscale: boolean;
|
|
@@ -87,55 +104,84 @@ interface BikHeader {
|
|
|
87
104
|
scaling: number;
|
|
88
105
|
};
|
|
89
106
|
/**
|
|
90
|
-
* Total number of audio tracks stored in the encoded
|
|
107
|
+
* Total number of audio tracks stored in the encoded video.
|
|
91
108
|
*
|
|
92
109
|
* Each track can have one or more channels (e.g. for stereo or surround sound).
|
|
93
110
|
*/
|
|
94
111
|
numAudioTracks: number;
|
|
95
112
|
/**
|
|
96
113
|
* Array containing decoded header information for each individual audio track stored in the
|
|
97
|
-
* encoded
|
|
114
|
+
* encoded video.
|
|
98
115
|
*/
|
|
99
116
|
audioTracks: BikAudioTrackHeader[];
|
|
100
117
|
/**
|
|
101
118
|
* Array containing decoded header information for each individual video frame stored in the
|
|
102
|
-
* encoded
|
|
119
|
+
* encoded video.
|
|
103
120
|
*/
|
|
104
121
|
frames: BikFrameHeader[];
|
|
105
122
|
}
|
|
106
123
|
/**
|
|
107
|
-
* Decoded header of an audio track of a BIK
|
|
124
|
+
* Decoded header of an audio track of a BIK video.
|
|
108
125
|
*/
|
|
109
126
|
interface BikAudioTrackHeader {
|
|
127
|
+
/**
|
|
128
|
+
* Identifier for the audio track. This may not match the index of the track in the
|
|
129
|
+
* {@link BikFrame.audioTracks} array.
|
|
130
|
+
*/
|
|
110
131
|
trackId: number;
|
|
132
|
+
/**
|
|
133
|
+
* Number of separate audio channels stored by the track.
|
|
134
|
+
*
|
|
135
|
+
* Stereo channels (when {@link flags stereo} is `true`) are separate planes for audio
|
|
136
|
+
* encoded via DCTs (when {@link flags usesDCT} is `true`), so the value of {@link numChannels}
|
|
137
|
+
* will include the number of stereo channels.
|
|
138
|
+
*
|
|
139
|
+
* When audio is encoded via RDFTs (when {@link flags usesDCT} is `false`) then stereo channels
|
|
140
|
+
* are interleaved, so the value of {@link numChannels} will _not_ include the number of
|
|
141
|
+
* channels. This means that for a regular stereo track (when {@link flags stereo} is `true`),
|
|
142
|
+
* {@link numChannels} will have the value `1`.
|
|
143
|
+
*/
|
|
111
144
|
numChannels: number;
|
|
145
|
+
/**
|
|
146
|
+
* Sample rate/frequency of the audio data (in Hz).
|
|
147
|
+
*/
|
|
112
148
|
sampleRate: number;
|
|
149
|
+
/**
|
|
150
|
+
* Flags indicating whether specific features apply to the audio track.
|
|
151
|
+
*/
|
|
113
152
|
flags: {
|
|
153
|
+
/**
|
|
154
|
+
* `true` when the audio track is stereo, otherwise `false` (usually indicating mono audio).
|
|
155
|
+
*/
|
|
114
156
|
stereo: boolean;
|
|
115
|
-
|
|
157
|
+
/**
|
|
158
|
+
* `true` when the audio data is encoded using DCTs (discrete cosine transforms), otherwise
|
|
159
|
+
* `false` when the audio data is encoded using RDFTs (real discrete Fourier transforms).
|
|
160
|
+
*/
|
|
161
|
+
usesDCT: boolean;
|
|
116
162
|
};
|
|
117
163
|
}
|
|
118
164
|
/**
|
|
119
|
-
* Decoded header of a
|
|
165
|
+
* Decoded header of a frame of a BIK video.
|
|
120
166
|
*/
|
|
121
167
|
interface BikFrameHeader {
|
|
122
168
|
/**
|
|
123
|
-
* Offset of the start of the frame in the encoded
|
|
169
|
+
* Offset of the start of the frame in the encoded video.
|
|
124
170
|
*/
|
|
125
171
|
offset: number;
|
|
126
172
|
/**
|
|
127
|
-
* Total size (in bytes) of the frame in the encoded
|
|
173
|
+
* Total size (in bytes) of the frame in the encoded video, including both audio and video that
|
|
128
174
|
* are stored with the frame.
|
|
129
175
|
*/
|
|
130
176
|
size: number;
|
|
131
177
|
/**
|
|
132
178
|
* When `true`, this frame is a "key frame" that can be used as a starting point for random
|
|
133
|
-
* access decoding.
|
|
179
|
+
* access decoding. Must be `true` for the first frame.
|
|
134
180
|
*/
|
|
135
181
|
keyframe: boolean;
|
|
136
182
|
}
|
|
137
183
|
/**
|
|
138
|
-
* Decoded contents of a single frame of a BIK
|
|
184
|
+
* Decoded contents of a single frame of a BIK video.
|
|
139
185
|
*/
|
|
140
186
|
interface BikFrame {
|
|
141
187
|
/**
|
|
@@ -148,7 +194,7 @@ interface BikFrame {
|
|
|
148
194
|
videoFrame: BikVideoFrame | null;
|
|
149
195
|
}
|
|
150
196
|
/**
|
|
151
|
-
* Decoded contents of a single "packet" of data for an audio track in a BIK
|
|
197
|
+
* Decoded contents of a single "packet" of data for an audio track in a BIK video.
|
|
152
198
|
*
|
|
153
199
|
* In each packet, audio samples are stored in one or more blocks, each block containing one or
|
|
154
200
|
* more stereo-interleaved channels (so the number of stereo-interleaved channels in a stereo
|
|
@@ -174,62 +220,54 @@ interface BikAudioTrack {
|
|
|
174
220
|
blocks: Float32Array[][];
|
|
175
221
|
}
|
|
176
222
|
/**
|
|
177
|
-
* Function for returning a Web Streams API readable stream for reading sequential data
|
|
178
|
-
* from a BIK file.
|
|
179
|
-
*
|
|
180
|
-
* Currently `len` is always undefined, so the function should just return a stream for
|
|
181
|
-
* accessing the rest of the file from the given start position.
|
|
182
|
-
*
|
|
183
|
-
* **Advance deprecation warning:** It is intended that this function will soon be replaced with
|
|
184
|
-
* a more flexible and easier to use system for accessing streams.
|
|
185
|
-
*
|
|
186
|
-
* @experimental
|
|
187
|
-
*/
|
|
188
|
-
type GetReadStreamFn = (offset: number, len?: number | undefined) => ReadableStream<Uint8Array> | Promise<ReadableStream<Uint8Array>>;
|
|
189
|
-
/**
|
|
190
223
|
* Main class for managing the state of a BIK decoder instance. One instance can decode a single
|
|
191
|
-
*
|
|
224
|
+
* video from a single data source at a time.
|
|
192
225
|
*/
|
|
193
226
|
declare class BikDecoder {
|
|
194
227
|
#private;
|
|
195
228
|
private constructor();
|
|
196
229
|
/**
|
|
197
|
-
* Decoded header of the
|
|
230
|
+
* Decoded header of the video.
|
|
198
231
|
* @returns Decoded header.
|
|
199
232
|
*/
|
|
200
233
|
get header(): BikHeader | null;
|
|
201
234
|
/**
|
|
202
|
-
* Whether the audio/
|
|
203
|
-
* @returns `true` when the audio/
|
|
204
|
-
* `false`.
|
|
235
|
+
* Whether the audio/images in the video can be processed by the decoder or not.
|
|
236
|
+
* @returns `true` when the audio/images can be processed by the decoder, otherwise `false`.
|
|
205
237
|
*/
|
|
206
238
|
get isSupported(): boolean;
|
|
207
239
|
/**
|
|
208
|
-
* Get the next frame of the
|
|
240
|
+
* Get the next frame of the video and decode it.
|
|
209
241
|
* @param prevFrame Optional data structure for a previously decoded frame to re-use (to reduce
|
|
210
242
|
* garbage collection).
|
|
211
243
|
* @returns Next decoded frame (audio and video).
|
|
212
244
|
*/
|
|
213
245
|
getNextFrame(prevFrame?: BikFrame | null): Promise<BikFrame | null>;
|
|
214
246
|
/**
|
|
215
|
-
* Skip the specified number of frames of the
|
|
216
|
-
*
|
|
247
|
+
* Skip the specified number of frames of the video. They will still be decoded as decoding a
|
|
248
|
+
* frame can effectively require data from any number of earlier frames.
|
|
217
249
|
* @param numFrames Number of frames to skip, but still decode.
|
|
218
250
|
*/
|
|
219
251
|
skipFrames(numFrames: number): Promise<void>;
|
|
220
252
|
/**
|
|
221
|
-
* Reset the
|
|
222
|
-
*
|
|
253
|
+
* Reset the state of the decoder so it is ready to start decoding the video from the beginning.
|
|
254
|
+
* Note that this will result in the decoder streaming the video again from the data source.
|
|
223
255
|
*/
|
|
224
256
|
reset(): void;
|
|
225
257
|
/**
|
|
226
|
-
* Attempt to read and parse the headers of a BIK
|
|
227
|
-
* {@link BikDecoder} for decoding the rest of the
|
|
228
|
-
* @param
|
|
229
|
-
*
|
|
230
|
-
* @returns Decoder instance. Use {@link header} to access the parsed headers.
|
|
258
|
+
* Attempt to read and parse the headers of a BIK video. If successful, return an instance of
|
|
259
|
+
* {@link BikDecoder} for decoding the rest of the video from the data source.
|
|
260
|
+
* @param source Data source that will provide the encoded video data.
|
|
261
|
+
* @returns Decoder instance. Use {@link BikDecoder.header} to access the parsed headers.
|
|
231
262
|
*/
|
|
232
|
-
static
|
|
263
|
+
static open_(source: Blob | File | URL | Request): Promise<BikDecoder>;
|
|
233
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* Attempt to read and parse the headers of a BIK video. If successful, return an instance of
|
|
267
|
+
* {@link BikDecoder} for decoding the rest of the video from the data source.
|
|
268
|
+
* @param source Data source that will provide the encoded video data.
|
|
269
|
+
* @returns Decoder instance. Use {@link BikDecoder.header} to access the parsed headers.
|
|
270
|
+
*/
|
|
271
|
+
declare const createBikDecoder: (source: Blob | File | URL | Request) => Promise<BikDecoder>;
|
|
234
272
|
//#endregion
|
|
235
|
-
export { type BikAudioTrack, type BikAudioTrackHeader, BikDecoder, type BikFrame, type BikFrameHeader, type BikHeader, type BikVideoFrame,
|
|
273
|
+
export { type BikAudioTrack, type BikAudioTrackHeader, type BikDecoder, type BikFrame, type BikFrameHeader, type BikHeader, type BikVideoFrame, createBikDecoder };
|
package/dist/unbikit.js
CHANGED
|
@@ -46,72 +46,60 @@ const BIK_QUANT = generateQuantTables(BASE_QUANT);
|
|
|
46
46
|
//#region src/bik-decoder-utils.ts
|
|
47
47
|
var BitReader = class {
|
|
48
48
|
#buffer;
|
|
49
|
-
#
|
|
49
|
+
#bufferBitLength;
|
|
50
50
|
#bitPos = 0;
|
|
51
51
|
constructor(buffer) {
|
|
52
52
|
this.#buffer = buffer;
|
|
53
|
+
this.#bufferBitLength = buffer.length << 3;
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
+
n(buffer) {
|
|
55
56
|
this.#buffer = buffer;
|
|
56
|
-
this.#
|
|
57
|
+
this.#bufferBitLength = buffer.length << 3;
|
|
57
58
|
this.#bitPos = 0;
|
|
58
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Read the specified number of bits from the bit-stream.
|
|
62
|
+
* @param n Number of bits to read. Must be less than or equal to 32.
|
|
63
|
+
* @param peek When `true`, do not update the bit position in the bit-stream, otherwise do
|
|
64
|
+
* update it.
|
|
65
|
+
* @returns The bits read from the bit-stream.
|
|
66
|
+
*/
|
|
59
67
|
a(n, peek = false) {
|
|
60
68
|
let result = 0;
|
|
61
|
-
let pos = this.#pos;
|
|
62
69
|
let bitPos = this.#bitPos;
|
|
63
|
-
let bitsRead = 0;
|
|
64
70
|
let bitsRemaining = n;
|
|
65
71
|
do {
|
|
66
72
|
const mask = (1 << bitsRemaining) - 1 & 255;
|
|
67
|
-
const bits = (this.#buffer[
|
|
68
|
-
result |= bits <<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
bitsRemaining -= bitChange;
|
|
74
|
-
pos++;
|
|
75
|
-
bitPos = 0;
|
|
73
|
+
const bits = (this.#buffer[bitPos >>> 3] ?? 0) >>> (bitPos & 7) & mask;
|
|
74
|
+
result |= bits << n - bitsRemaining;
|
|
75
|
+
if ((bitPos & 7) + bitsRemaining > 7) {
|
|
76
|
+
const posChange = 8 - (bitPos & 7);
|
|
77
|
+
bitsRemaining -= posChange;
|
|
78
|
+
bitPos += posChange;
|
|
76
79
|
} else {
|
|
77
|
-
bitPos
|
|
80
|
+
bitPos += bitsRemaining;
|
|
78
81
|
break;
|
|
79
82
|
}
|
|
80
|
-
} while (
|
|
81
|
-
if (!peek)
|
|
82
|
-
this.#pos = pos;
|
|
83
|
-
this.#bitPos = bitPos;
|
|
84
|
-
}
|
|
83
|
+
} while (bitsRemaining);
|
|
84
|
+
if (!peek) this.#bitPos = bitPos;
|
|
85
85
|
return result;
|
|
86
86
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (this.#bitPos > 7) {
|
|
90
|
-
this.#pos++;
|
|
91
|
-
this.#bitPos = 0;
|
|
92
|
-
}
|
|
93
|
-
return bit;
|
|
94
|
-
}
|
|
95
|
-
q() {
|
|
96
|
-
return (this.#pos << 3) + this.#bitPos;
|
|
87
|
+
c() {
|
|
88
|
+
return (this.#buffer[this.#bitPos >>> 3] ?? 0) >>> (this.#bitPos++ & 7) & 1;
|
|
97
89
|
}
|
|
98
|
-
|
|
90
|
+
i(n) {
|
|
99
91
|
if (n < 1) return;
|
|
100
92
|
this.#bitPos += n;
|
|
101
|
-
while (this.#bitPos > 7) {
|
|
102
|
-
this.#pos++;
|
|
103
|
-
this.#bitPos -= 8;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
n() {
|
|
107
|
-
const n = 32 - (this.q() & 31) & 31;
|
|
108
|
-
this.j(n);
|
|
109
93
|
}
|
|
110
94
|
o() {
|
|
111
|
-
|
|
95
|
+
const n = 32 - (this.#bitPos & 31) & 31;
|
|
96
|
+
this.i(n);
|
|
97
|
+
}
|
|
98
|
+
get p() {
|
|
99
|
+
return this.#bufferBitLength - this.#bitPos;
|
|
112
100
|
}
|
|
113
101
|
e(v) {
|
|
114
|
-
return this.
|
|
102
|
+
return this.c() ? -v : v;
|
|
115
103
|
}
|
|
116
104
|
};
|
|
117
105
|
|
|
@@ -130,15 +118,15 @@ var BikAudioDecoder = class {
|
|
|
130
118
|
#bands;
|
|
131
119
|
#output;
|
|
132
120
|
#overlapWindow = [];
|
|
133
|
-
#
|
|
121
|
+
#usesDCT;
|
|
134
122
|
#idt;
|
|
135
|
-
constructor(sampleRate, numChannels,
|
|
123
|
+
constructor(sampleRate, numChannels, usesDCT) {
|
|
136
124
|
let frameLenBits;
|
|
137
125
|
if (sampleRate < 22050) frameLenBits = 9;
|
|
138
126
|
else if (sampleRate < 44100) frameLenBits = 10;
|
|
139
127
|
else frameLenBits = 11;
|
|
140
128
|
let numInternalChannels = numChannels;
|
|
141
|
-
if (!
|
|
129
|
+
if (!usesDCT) {
|
|
142
130
|
sampleRate *= numChannels;
|
|
143
131
|
frameLenBits += Math.ceil(Math.log2(numChannels)) & 3;
|
|
144
132
|
frameLenBits = frameLenBits;
|
|
@@ -150,7 +138,7 @@ var BikAudioDecoder = class {
|
|
|
150
138
|
this.#overlapLen = this.#frameLen / 16;
|
|
151
139
|
this.#blockSize = (this.#frameLen - this.#overlapLen) * numInternalChannels;
|
|
152
140
|
const sampleRateHalf = sampleRate + 1 >>> 1;
|
|
153
|
-
this.#baseQuant = (
|
|
141
|
+
this.#baseQuant = (usesDCT ? this.#frameLen : 2) / (Math.sqrt(this.#frameLen) * 32768);
|
|
154
142
|
const expMultiplier = .0664 / Math.log10(Math.E);
|
|
155
143
|
for (let i = 0; i < 96; i++) this.#quantTable[i] = Math.exp(i * expMultiplier) * this.#baseQuant;
|
|
156
144
|
let numBands = AUDIO_CRITICAL_FREQS.findIndex((x) => sampleRateHalf <= x);
|
|
@@ -163,8 +151,8 @@ var BikAudioDecoder = class {
|
|
|
163
151
|
this.#output = new Array(this.#numInternalChannels);
|
|
164
152
|
for (const [index] of this.#output.entries()) this.#output[index] = new Float32Array(this.#frameLen);
|
|
165
153
|
for (let i = 0; i < numInternalChannels; i++) this.#overlapWindow.push(new Float32Array(this.#overlapLen));
|
|
166
|
-
this.#
|
|
167
|
-
this.#idt =
|
|
154
|
+
this.#usesDCT = usesDCT;
|
|
155
|
+
this.#idt = usesDCT ? new IDCT(frameLenBits) : new IRDFT(frameLenBits);
|
|
168
156
|
}
|
|
169
157
|
/**
|
|
170
158
|
* Read a 29-bit floating point value (5 bits exponent, 23 bits mantissa, 1 bit sign) from a
|
|
@@ -174,20 +162,19 @@ var BikAudioDecoder = class {
|
|
|
174
162
|
*/
|
|
175
163
|
#getFloat(reader) {
|
|
176
164
|
const power = reader.a(5);
|
|
177
|
-
|
|
178
|
-
return reader.d() ? -f : f;
|
|
165
|
+
return reader.e(reader.a(23) * 2 ** (power - 23));
|
|
179
166
|
}
|
|
180
167
|
/**
|
|
181
168
|
* Decode all blocks and channels of a frame of audio data.
|
|
182
169
|
* @param data Encoded frame audio data.
|
|
183
170
|
* @returns Decoded data indexed by block number and then by channel number.
|
|
184
171
|
*/
|
|
185
|
-
|
|
172
|
+
s(data) {
|
|
186
173
|
const reader = new BitReader(data);
|
|
187
174
|
const output = this.#output;
|
|
188
175
|
const allOutput = [];
|
|
189
|
-
while (reader.
|
|
190
|
-
if (this.#
|
|
176
|
+
while (reader.p > 0) {
|
|
177
|
+
if (this.#usesDCT) reader.i(2);
|
|
191
178
|
for (let ch = 0; ch < this.#numInternalChannels; ch++) {
|
|
192
179
|
const coeffs = output[ch];
|
|
193
180
|
coeffs[0] = this.#getFloat(reader) * this.#baseQuant;
|
|
@@ -199,7 +186,7 @@ var BikAudioDecoder = class {
|
|
|
199
186
|
let i = 2;
|
|
200
187
|
while (i < this.#frameLen) {
|
|
201
188
|
let j;
|
|
202
|
-
if (reader.
|
|
189
|
+
if (reader.c()) {
|
|
203
190
|
const v = reader.a(4);
|
|
204
191
|
j = i + AUDIO_RLE_LENGTH_TABLE[v];
|
|
205
192
|
} else j = i + 8;
|
|
@@ -212,13 +199,13 @@ var BikAudioDecoder = class {
|
|
|
212
199
|
} else while (i < j) {
|
|
213
200
|
if (this.#bands[k] === i) q = quant[k++] ?? 0;
|
|
214
201
|
const coeff = reader.a(width);
|
|
215
|
-
if (coeff) coeffs[i] = reader.
|
|
202
|
+
if (coeff) coeffs[i] = reader.c() ? -q * coeff : q * coeff;
|
|
216
203
|
else coeffs[i] = 0;
|
|
217
204
|
i++;
|
|
218
205
|
}
|
|
219
206
|
}
|
|
220
207
|
this.#idt.k(coeffs);
|
|
221
|
-
if (this.#
|
|
208
|
+
if (this.#usesDCT) {
|
|
222
209
|
const dctModifier = 4 * this.#baseQuant;
|
|
223
210
|
for (let i2 = 0; i2 < coeffs.length; i2++) coeffs[i2] *= dctModifier;
|
|
224
211
|
}
|
|
@@ -255,7 +242,7 @@ var BikAudioDecoder = class {
|
|
|
255
242
|
}
|
|
256
243
|
allOutput.push(outputBlock);
|
|
257
244
|
this.#first = false;
|
|
258
|
-
reader.
|
|
245
|
+
reader.o();
|
|
259
246
|
}
|
|
260
247
|
return allOutput;
|
|
261
248
|
}
|
|
@@ -443,27 +430,22 @@ var FFT = class {
|
|
|
443
430
|
//#region src/bik-video-decoder.ts
|
|
444
431
|
const EMPTY_UINT8_ARRAY = new Uint8Array();
|
|
445
432
|
var HuffTable = class HuffTable {
|
|
446
|
-
#
|
|
447
|
-
#lens;
|
|
433
|
+
#symbolsLens;
|
|
448
434
|
#maxBits;
|
|
449
|
-
static
|
|
435
|
+
static l = new Array(16).fill(null).map((_, bikTreeIndex) => new HuffTable(bikTreeIndex));
|
|
450
436
|
constructor(bikTreeIndex) {
|
|
451
437
|
const referenceTableOffset = bikTreeIndex << 4;
|
|
452
438
|
const maxBits = BIK_TREE_LENS[referenceTableOffset + 15];
|
|
453
439
|
this.#maxBits = maxBits;
|
|
454
440
|
const tableSize = 1 << maxBits;
|
|
455
|
-
this.#
|
|
456
|
-
this.#lens = new Array(tableSize);
|
|
441
|
+
this.#symbolsLens = new Uint8Array(tableSize);
|
|
457
442
|
for (let i = 0; i < 16; i++) {
|
|
458
443
|
const code = BIK_TREE_CODES[referenceTableOffset + i];
|
|
459
444
|
const len = BIK_TREE_LENS[referenceTableOffset + i];
|
|
460
445
|
const numEntries = 1 << maxBits - len;
|
|
461
446
|
for (let j = 0; j < numEntries; j++) {
|
|
462
447
|
const index = j << len | code;
|
|
463
|
-
if (index < tableSize)
|
|
464
|
-
this.#symbols[index] = i;
|
|
465
|
-
this.#lens[index] = len;
|
|
466
|
-
}
|
|
448
|
+
if (index < tableSize) this.#symbolsLens[index] = i << 4 | len;
|
|
467
449
|
}
|
|
468
450
|
}
|
|
469
451
|
}
|
|
@@ -474,12 +456,11 @@ var HuffTable = class HuffTable {
|
|
|
474
456
|
* @returns 4-bit value, Huffman-decoded from the bit-stream.
|
|
475
457
|
*/
|
|
476
458
|
static f(reader, tree) {
|
|
477
|
-
const table =
|
|
459
|
+
const table = tree.m;
|
|
478
460
|
const peek = reader.a(table.#maxBits, true);
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
return tree.g[symbol];
|
|
461
|
+
const entry = table.#symbolsLens[peek];
|
|
462
|
+
reader.i(entry & 15);
|
|
463
|
+
return tree.g[entry >>> 4];
|
|
483
464
|
}
|
|
484
465
|
};
|
|
485
466
|
var BikVideoDecoder = class {
|
|
@@ -490,8 +471,6 @@ var BikVideoDecoder = class {
|
|
|
490
471
|
#hasSwappedUVPlanes;
|
|
491
472
|
#numPixels;
|
|
492
473
|
#uvSize;
|
|
493
|
-
#blockXPos = 0;
|
|
494
|
-
#blockYPos = 0;
|
|
495
474
|
#stride = 0;
|
|
496
475
|
#data = EMPTY_UINT8_ARRAY;
|
|
497
476
|
#prevData = EMPTY_UINT8_ARRAY;
|
|
@@ -519,19 +498,19 @@ var BikVideoDecoder = class {
|
|
|
519
498
|
this.#numPixels = numPixels;
|
|
520
499
|
this.#uvSize = uvSize;
|
|
521
500
|
this.#prevData = new Uint8Array(frameSize);
|
|
522
|
-
const
|
|
501
|
+
const numBlockPixels = numPixels + 63 >>> 6 << 6;
|
|
523
502
|
for (let i = 0; i < 9; i++) this.#blockParams[i] = {
|
|
524
|
-
|
|
503
|
+
q: 0,
|
|
525
504
|
h: {
|
|
526
|
-
|
|
505
|
+
m: HuffTable.l[0],
|
|
527
506
|
g: new Uint8Array(16)
|
|
528
507
|
},
|
|
529
|
-
|
|
508
|
+
d: i > 3 && i < 8 ? new Int16Array(numBlockPixels) : new Uint8Array(numBlockPixels),
|
|
530
509
|
b: 0,
|
|
531
|
-
|
|
510
|
+
j: 0
|
|
532
511
|
};
|
|
533
512
|
for (let i = 0; i < 16; i++) this.#colHigh[i] = {
|
|
534
|
-
|
|
513
|
+
m: HuffTable.l[0],
|
|
535
514
|
g: new Uint8Array(16)
|
|
536
515
|
};
|
|
537
516
|
}
|
|
@@ -563,12 +542,15 @@ var BikVideoDecoder = class {
|
|
|
563
542
|
const planeOffset = planeIndex === 0 ? 0 : planeIndex === 1 ? numPixels : planeIndex === 2 ? numPixels + uvSize : numPixels + (uvSize << 1);
|
|
564
543
|
const blockLineIncr = this.#stride * 7;
|
|
565
544
|
const mainDataBuf = this.#data;
|
|
566
|
-
this.#data = new Uint8Array(
|
|
545
|
+
this.#data = new Uint8Array(mainDataBuf.buffer, planeOffset, isChroma ? uvSize : numPixels);
|
|
567
546
|
this.#dataPtr = 0;
|
|
568
547
|
const prevMainDataBuf = this.#prevData;
|
|
569
|
-
this.#prevData = new Uint8Array(
|
|
570
|
-
|
|
571
|
-
|
|
548
|
+
this.#prevData = new Uint8Array(prevMainDataBuf.buffer, planeOffset, isChroma ? uvSize : numPixels);
|
|
549
|
+
const blockTypeParam = blockParams[0];
|
|
550
|
+
const blockTypes = blockTypeParam.d;
|
|
551
|
+
let blockYPos = 0;
|
|
552
|
+
while (blockYPos++ < blockHeight) {
|
|
553
|
+
this.#readBlockTypes(blockTypeParam);
|
|
572
554
|
this.#readBlockTypes(blockParams[1]);
|
|
573
555
|
this.#readColors(blockParams[2]);
|
|
574
556
|
this.#readPatterns(blockParams[3]);
|
|
@@ -577,14 +559,16 @@ var BikVideoDecoder = class {
|
|
|
577
559
|
this.#readDCs(blockParams[6], false);
|
|
578
560
|
this.#readDCs(blockParams[7], true);
|
|
579
561
|
this.#readRuns(blockParams[8]);
|
|
580
|
-
|
|
581
|
-
|
|
562
|
+
let blockXPos = 0;
|
|
563
|
+
while (blockXPos++ < blockWidth) {
|
|
564
|
+
const blockType = blockTypes[blockTypeParam.j++];
|
|
582
565
|
switch (blockType) {
|
|
583
566
|
case 0: break;
|
|
584
567
|
case 1:
|
|
585
|
-
this.#decodeScaledBlock();
|
|
586
|
-
|
|
587
|
-
|
|
568
|
+
if (blockYPos & 1) this.#decodeScaledBlock();
|
|
569
|
+
blockXPos++;
|
|
570
|
+
this.#dataPtr += 16;
|
|
571
|
+
continue;
|
|
588
572
|
case 2:
|
|
589
573
|
this.#decodeMotionBlock();
|
|
590
574
|
break;
|
|
@@ -615,18 +599,22 @@ var BikVideoDecoder = class {
|
|
|
615
599
|
}
|
|
616
600
|
this.#dataPtr += blockLineIncr;
|
|
617
601
|
}
|
|
618
|
-
this.#reader.
|
|
602
|
+
this.#reader.o();
|
|
619
603
|
this.#prevData = prevMainDataBuf;
|
|
620
604
|
this.#data = mainDataBuf;
|
|
621
605
|
}
|
|
622
606
|
#copyBlock(srcOffset) {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
607
|
+
const indexDiff = this.#dataPtr - srcOffset;
|
|
608
|
+
if (!indexDiff) return;
|
|
609
|
+
const strideMinusBlock = this.#stride - 8;
|
|
610
|
+
let lineCount = 8;
|
|
611
|
+
while (lineCount--) {
|
|
612
|
+
const srcOffsetMax = srcOffset + 8;
|
|
613
|
+
while (srcOffset < srcOffsetMax) {
|
|
614
|
+
this.#data[srcOffset + indexDiff] = this.#prevData[srcOffset];
|
|
615
|
+
srcOffset++;
|
|
616
|
+
}
|
|
617
|
+
srcOffset += strideMinusBlock;
|
|
630
618
|
}
|
|
631
619
|
}
|
|
632
620
|
#decodeMotionBlock() {
|
|
@@ -641,7 +629,7 @@ var BikVideoDecoder = class {
|
|
|
641
629
|
do {
|
|
642
630
|
const run = this.#getValue(8) + 1;
|
|
643
631
|
i += run;
|
|
644
|
-
if (this.#reader.
|
|
632
|
+
if (this.#reader.c()) {
|
|
645
633
|
const v = this.#getValue(2);
|
|
646
634
|
for (let j = 0; j < run; j++) {
|
|
647
635
|
const pos = BIK_PATTERNS[scanIndex++] ?? 0;
|
|
@@ -701,16 +689,14 @@ var BikVideoDecoder = class {
|
|
|
701
689
|
}
|
|
702
690
|
#decodeRawBlock() {
|
|
703
691
|
const blockParamValues = this.#blockParams[2];
|
|
704
|
-
for (let y = 0; y < 8; y++) for (let x = 0; x < 8; x++) this.#data[this.#dataPtr + y * this.#stride + x] = blockParamValues.
|
|
692
|
+
for (let y = 0; y < 8; y++) for (let x = 0; x < 8; x++) this.#data[this.#dataPtr + y * this.#stride + x] = blockParamValues.d[blockParamValues.j++];
|
|
705
693
|
}
|
|
706
694
|
#decodeScaledBlock() {
|
|
707
|
-
this.#blockXPos++;
|
|
708
|
-
if (this.#blockYPos & 1) return;
|
|
709
695
|
const tmpScalingBuf = this.#tmpScalingBuf;
|
|
710
696
|
const subBlk = this.#getValue(1);
|
|
711
697
|
switch (subBlk) {
|
|
712
|
-
case
|
|
713
|
-
this.#
|
|
698
|
+
case 9:
|
|
699
|
+
for (let i = 0; i < 64; i++) tmpScalingBuf[i] = this.#getValue(2);
|
|
714
700
|
break;
|
|
715
701
|
case 5:
|
|
716
702
|
this.#decodeIntraBlock(tmpScalingBuf);
|
|
@@ -718,30 +704,25 @@ var BikVideoDecoder = class {
|
|
|
718
704
|
case 6:
|
|
719
705
|
this.#decodeFillBlock(16);
|
|
720
706
|
return;
|
|
707
|
+
case 3:
|
|
708
|
+
this.#decodeRunBlock(tmpScalingBuf);
|
|
709
|
+
break;
|
|
721
710
|
case 8:
|
|
722
711
|
this.#decodePatternBlock(tmpScalingBuf);
|
|
723
712
|
break;
|
|
724
|
-
case 9:
|
|
725
|
-
for (let j = 0; j < 8; j++) for (let i = 0; i < 8; i++) tmpScalingBuf[i + (j << 3)] = this.#getValue(2);
|
|
726
|
-
break;
|
|
727
713
|
default: throw new Error(`Invalid sub-block type ${subBlk}`);
|
|
728
714
|
}
|
|
729
715
|
const dest = this.#data;
|
|
716
|
+
const stride = this.#stride;
|
|
730
717
|
let srcPos = 0;
|
|
731
|
-
let
|
|
732
|
-
|
|
733
|
-
const lineIncrement =
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
dest[destPosLine1 + halfWordOffset++] = v;
|
|
740
|
-
dest[destPosLine0 + halfWordOffset] = v;
|
|
741
|
-
dest[destPosLine1 + halfWordOffset++] = v;
|
|
742
|
-
}
|
|
743
|
-
destPosLine0 += lineIncrement;
|
|
744
|
-
destPosLine1 += lineIncrement;
|
|
718
|
+
let destPosLine = this.#dataPtr;
|
|
719
|
+
const maxDestPosLine = destPosLine + (stride << 4);
|
|
720
|
+
const lineIncrement = (stride << 1) - 15;
|
|
721
|
+
while (destPosLine < maxDestPosLine) {
|
|
722
|
+
const value = tmpScalingBuf[srcPos++];
|
|
723
|
+
dest[destPosLine] = dest[stride + destPosLine++] = value;
|
|
724
|
+
dest[destPosLine] = dest[stride + destPosLine] = value;
|
|
725
|
+
destPosLine += srcPos & 7 ? 1 : lineIncrement;
|
|
745
726
|
}
|
|
746
727
|
}
|
|
747
728
|
/**
|
|
@@ -751,17 +732,18 @@ var BikVideoDecoder = class {
|
|
|
751
732
|
*/
|
|
752
733
|
#readTree(tree) {
|
|
753
734
|
const reader = this.#reader;
|
|
754
|
-
|
|
755
|
-
|
|
735
|
+
const tableNum = reader.a(4);
|
|
736
|
+
tree.m = HuffTable.l[tableNum];
|
|
737
|
+
if (!tableNum) {
|
|
756
738
|
for (let i = 0; i < 16; i++) tree.g[i] = i;
|
|
757
739
|
return;
|
|
758
740
|
}
|
|
759
|
-
if (reader.
|
|
741
|
+
if (reader.c()) {
|
|
760
742
|
let len = reader.a(3);
|
|
761
743
|
const tmp = this.#inputTreeBuf.fill(0);
|
|
762
744
|
for (let i = 0; i <= len; i++) {
|
|
763
745
|
tree.g[i] = reader.a(4);
|
|
764
|
-
tmp[tree.g[i]
|
|
746
|
+
tmp[tree.g[i]] = 1;
|
|
765
747
|
}
|
|
766
748
|
for (let i = 0; i < 16; i++) if (!tmp[i]) tree.g[++len] = i;
|
|
767
749
|
} else {
|
|
@@ -769,7 +751,7 @@ var BikVideoDecoder = class {
|
|
|
769
751
|
let input = this.#inputTreeBuf;
|
|
770
752
|
let output = this.#outputTreeBuf;
|
|
771
753
|
for (let i = 0; i < 16; i += 2) {
|
|
772
|
-
const bit = this.#reader.
|
|
754
|
+
const bit = this.#reader.c();
|
|
773
755
|
input[i] = i + bit;
|
|
774
756
|
input[i + 1] = i + (bit ^ 1);
|
|
775
757
|
}
|
|
@@ -785,15 +767,15 @@ var BikVideoDecoder = class {
|
|
|
785
767
|
let src2Index = src1Index + size1;
|
|
786
768
|
let size2 = size1;
|
|
787
769
|
let destIndex = src1Index;
|
|
788
|
-
while (size1 && size2) if (this.#reader.
|
|
789
|
-
dest[destIndex++] = src[src2Index++]
|
|
770
|
+
while (size1 && size2) if (this.#reader.c()) {
|
|
771
|
+
dest[destIndex++] = src[src2Index++];
|
|
790
772
|
size2--;
|
|
791
773
|
} else {
|
|
792
|
-
dest[destIndex++] = src[src1Index++]
|
|
774
|
+
dest[destIndex++] = src[src1Index++];
|
|
793
775
|
size1--;
|
|
794
776
|
}
|
|
795
|
-
while (size1--) dest[destIndex++] = src[src1Index++]
|
|
796
|
-
while (size2--) dest[destIndex++] = src[src2Index++]
|
|
777
|
+
while (size1--) dest[destIndex++] = src[src1Index++];
|
|
778
|
+
while (size2--) dest[destIndex++] = src[src2Index++];
|
|
797
779
|
}
|
|
798
780
|
/**
|
|
799
781
|
* Read Huffman tree information from the bit-stream for each block type in the current
|
|
@@ -806,7 +788,7 @@ var BikVideoDecoder = class {
|
|
|
806
788
|
const extraLen = 511;
|
|
807
789
|
const commonLen = (adjustedWidth >>> 3) + extraLen;
|
|
808
790
|
for (const [blockParamNum, blockParamValues] of this.#blockParams.entries()) {
|
|
809
|
-
blockParamValues.
|
|
791
|
+
blockParamValues.q = ~~Math.log2([
|
|
810
792
|
commonLen,
|
|
811
793
|
(adjustedWidth >>> 4) + extraLen,
|
|
812
794
|
(blockWidth << 6) + extraLen,
|
|
@@ -822,7 +804,7 @@ var BikVideoDecoder = class {
|
|
|
822
804
|
this.#colLastValue = 0;
|
|
823
805
|
}
|
|
824
806
|
if (blockParamNum < 6 || blockParamNum > 7) this.#readTree(blockParamValues.h);
|
|
825
|
-
blockParamValues.b = blockParamValues.
|
|
807
|
+
blockParamValues.b = blockParamValues.j = 0;
|
|
826
808
|
}
|
|
827
809
|
}
|
|
828
810
|
/**
|
|
@@ -831,8 +813,8 @@ var BikVideoDecoder = class {
|
|
|
831
813
|
* @returns Number of block parameter values.
|
|
832
814
|
*/
|
|
833
815
|
#readCodedDataCount(blockParamValues) {
|
|
834
|
-
if (blockParamValues.b < 0 || blockParamValues.b > blockParamValues.
|
|
835
|
-
const count = this.#reader.a(blockParamValues.
|
|
816
|
+
if (blockParamValues.b < 0 || blockParamValues.b > blockParamValues.j) return 0;
|
|
817
|
+
const count = this.#reader.a(blockParamValues.q);
|
|
836
818
|
if (count === 0) blockParamValues.b = -1;
|
|
837
819
|
return count;
|
|
838
820
|
}
|
|
@@ -840,19 +822,19 @@ var BikVideoDecoder = class {
|
|
|
840
822
|
const count = this.#readCodedDataCount(blockParamValues);
|
|
841
823
|
if (!count) return;
|
|
842
824
|
const reader = this.#reader;
|
|
843
|
-
if (reader.
|
|
825
|
+
if (reader.c()) {
|
|
844
826
|
const v = reader.a(4);
|
|
845
|
-
for (let i = 0; i < count; i++) blockParamValues.
|
|
827
|
+
for (let i = 0; i < count; i++) blockParamValues.d[blockParamValues.b++] = v;
|
|
846
828
|
} else {
|
|
847
829
|
let prevValue = 0;
|
|
848
830
|
for (let i = 0; i < count; i++) {
|
|
849
831
|
const v = HuffTable.f(reader, blockParamValues.h);
|
|
850
832
|
if (v < 12) {
|
|
851
833
|
prevValue = v;
|
|
852
|
-
blockParamValues.
|
|
834
|
+
blockParamValues.d[blockParamValues.b++] = v;
|
|
853
835
|
} else {
|
|
854
836
|
const runLength = RLE_LENGTHS[v - 12];
|
|
855
|
-
for (let j = 0; j < runLength; j++) blockParamValues.
|
|
837
|
+
for (let j = 0; j < runLength; j++) blockParamValues.d[blockParamValues.b++] = prevValue;
|
|
856
838
|
i += runLength - 1;
|
|
857
839
|
}
|
|
858
840
|
}
|
|
@@ -862,7 +844,7 @@ var BikVideoDecoder = class {
|
|
|
862
844
|
const count = this.#readCodedDataCount(blockParamValues);
|
|
863
845
|
if (!count) return;
|
|
864
846
|
const reader = this.#reader;
|
|
865
|
-
const isRun = reader.
|
|
847
|
+
const isRun = reader.c();
|
|
866
848
|
let loopCount = isRun ? 1 : count;
|
|
867
849
|
do {
|
|
868
850
|
const colHighValue = HuffTable.f(reader, this.#colHigh[this.#colLastValue]);
|
|
@@ -870,9 +852,9 @@ var BikVideoDecoder = class {
|
|
|
870
852
|
this.#colLastValue = colHighValue;
|
|
871
853
|
if (this.#version < 105) v = v > 127 ? 256 - v : v + 128;
|
|
872
854
|
if (isRun) {
|
|
873
|
-
blockParamValues.
|
|
855
|
+
blockParamValues.d.fill(v, blockParamValues.b, blockParamValues.b + count);
|
|
874
856
|
blockParamValues.b += count;
|
|
875
|
-
} else blockParamValues.
|
|
857
|
+
} else blockParamValues.d[blockParamValues.b++] = v;
|
|
876
858
|
} while (--loopCount);
|
|
877
859
|
}
|
|
878
860
|
#readPatterns(blockParamValues) {
|
|
@@ -881,23 +863,25 @@ var BikVideoDecoder = class {
|
|
|
881
863
|
const reader = this.#reader;
|
|
882
864
|
for (let i = 0; i < count; i++) {
|
|
883
865
|
const v = HuffTable.f(reader, blockParamValues.h) | HuffTable.f(reader, blockParamValues.h) << 4;
|
|
884
|
-
blockParamValues.
|
|
866
|
+
blockParamValues.d[blockParamValues.b++] = v;
|
|
885
867
|
}
|
|
886
868
|
}
|
|
887
869
|
#readMotionValues(blockParamValues) {
|
|
888
870
|
const count = this.#readCodedDataCount(blockParamValues);
|
|
889
871
|
if (!count) return;
|
|
890
872
|
const reader = this.#reader;
|
|
891
|
-
const items = blockParamValues.
|
|
873
|
+
const items = blockParamValues.d;
|
|
892
874
|
const maxDec = blockParamValues.b + count;
|
|
893
875
|
let v;
|
|
894
|
-
if (reader.
|
|
876
|
+
if (reader.c()) {
|
|
895
877
|
v = reader.a(4);
|
|
896
878
|
if (v) v = reader.e(v);
|
|
879
|
+
v = v << 24 >> 24;
|
|
897
880
|
items.fill(v, blockParamValues.b, maxDec);
|
|
898
881
|
} else while (blockParamValues.b < maxDec) {
|
|
899
882
|
v = HuffTable.f(reader, blockParamValues.h);
|
|
900
883
|
if (v) v = reader.e(v);
|
|
884
|
+
v = v << 24 >> 24;
|
|
901
885
|
items[blockParamValues.b++] = v;
|
|
902
886
|
}
|
|
903
887
|
blockParamValues.b = maxDec;
|
|
@@ -906,25 +890,21 @@ var BikVideoDecoder = class {
|
|
|
906
890
|
const count = this.#readCodedDataCount(blockParamValues);
|
|
907
891
|
if (!count) return;
|
|
908
892
|
const reader = this.#reader;
|
|
909
|
-
const view = new DataView(blockParamValues.c.buffer, blockParamValues.c.byteOffset, blockParamValues.c.byteLength);
|
|
910
893
|
let v = reader.a(hasSign ? 10 : 11);
|
|
911
894
|
if (v && hasSign) v = reader.e(v);
|
|
912
|
-
|
|
913
|
-
blockParamValues.b
|
|
914
|
-
|
|
895
|
+
const items = blockParamValues.d;
|
|
896
|
+
items[blockParamValues.b++] = v;
|
|
897
|
+
let i = 1;
|
|
898
|
+
while (i < count) {
|
|
915
899
|
const len = Math.min(count - i, 8);
|
|
916
|
-
const
|
|
917
|
-
if (
|
|
918
|
-
let v2 = reader.a(
|
|
900
|
+
const v2Size = reader.a(4);
|
|
901
|
+
if (v2Size) for (let j = 0; j < len; j++) {
|
|
902
|
+
let v2 = reader.a(v2Size);
|
|
919
903
|
if (v2) v2 = reader.e(v2);
|
|
920
904
|
v += v2;
|
|
921
|
-
|
|
922
|
-
blockParamValues.b += 2;
|
|
923
|
-
}
|
|
924
|
-
else for (let j = 0; j < len; j++) {
|
|
925
|
-
view.setInt16(blockParamValues.b, v, true);
|
|
926
|
-
blockParamValues.b += 2;
|
|
905
|
+
items[blockParamValues.b++] = v;
|
|
927
906
|
}
|
|
907
|
+
else for (let j = 0; j < len; j++) items[blockParamValues.b++] = v;
|
|
928
908
|
i += len;
|
|
929
909
|
}
|
|
930
910
|
}
|
|
@@ -932,10 +912,10 @@ var BikVideoDecoder = class {
|
|
|
932
912
|
const count = this.#readCodedDataCount(blockParamValues);
|
|
933
913
|
if (!count) return;
|
|
934
914
|
const reader = this.#reader;
|
|
935
|
-
if (reader.
|
|
915
|
+
if (reader.c()) {
|
|
936
916
|
const v = reader.a(4);
|
|
937
|
-
for (let i = 0; i < count; i++) blockParamValues.
|
|
938
|
-
} else for (let i = 0; i < count; i++) blockParamValues.
|
|
917
|
+
for (let i = 0; i < count; i++) blockParamValues.d[blockParamValues.b++] = v;
|
|
918
|
+
} else for (let i = 0; i < count; i++) blockParamValues.d[blockParamValues.b++] = HuffTable.f(reader, blockParamValues.h);
|
|
939
919
|
}
|
|
940
920
|
/**
|
|
941
921
|
* Get the next block parameter value for the current line.
|
|
@@ -944,11 +924,7 @@ var BikVideoDecoder = class {
|
|
|
944
924
|
*/
|
|
945
925
|
#getValue(blockParamNum) {
|
|
946
926
|
const blockParamValues = this.#blockParams[blockParamNum];
|
|
947
|
-
|
|
948
|
-
if (blockParamNum < 6) return (blockParamValues.c[blockParamValues.i++] ?? 0) << 24 >> 24;
|
|
949
|
-
const val = new DataView(blockParamValues.c.buffer, blockParamValues.c.byteOffset, blockParamValues.c.byteLength).getInt16(blockParamValues.i, true);
|
|
950
|
-
blockParamValues.i += 2;
|
|
951
|
-
return val;
|
|
927
|
+
return blockParamValues.d[blockParamValues.j++] ?? 0;
|
|
952
928
|
}
|
|
953
929
|
/**
|
|
954
930
|
* Mini-VM (virtual machine) to decode and optionally unquantize a block of integer values.
|
|
@@ -992,10 +968,10 @@ var BikVideoDecoder = class {
|
|
|
992
968
|
let bits = isResidue ? 1 << reader.a(3) : reader.a(4) - 1;
|
|
993
969
|
while (isResidue ? bits : bits >= 0) {
|
|
994
970
|
if (isResidue) {
|
|
995
|
-
for (i = 0; i < coeffCount; i++) if (reader.
|
|
971
|
+
for (i = 0; i < coeffCount; i++) if (reader.c()) {
|
|
996
972
|
const curNzCoeff = coeffIndex[i] ?? 0;
|
|
997
|
-
|
|
998
|
-
|
|
973
|
+
const value = block[curNzCoeff] ?? 0;
|
|
974
|
+
block[curNzCoeff] = value < 0 ? value - bits : value + bits;
|
|
999
975
|
if (!masksCount--) return;
|
|
1000
976
|
}
|
|
1001
977
|
}
|
|
@@ -1003,7 +979,7 @@ var BikVideoDecoder = class {
|
|
|
1003
979
|
while (listPos < listEnd) {
|
|
1004
980
|
const ccoeff = coeffList[listPos] ?? 0;
|
|
1005
981
|
const mode = modeList[listPos] ?? 0;
|
|
1006
|
-
if (!(mode | ccoeff) || !reader.
|
|
982
|
+
if (!(mode | ccoeff) || !reader.c()) {
|
|
1007
983
|
listPos++;
|
|
1008
984
|
continue;
|
|
1009
985
|
}
|
|
@@ -1017,7 +993,7 @@ var BikVideoDecoder = class {
|
|
|
1017
993
|
coeffList[listPos] = 0;
|
|
1018
994
|
modeList[listPos++] = 0;
|
|
1019
995
|
}
|
|
1020
|
-
for (i = ccoeff; i < ccoeff + 4; i++) if (reader.
|
|
996
|
+
for (i = ccoeff; i < ccoeff + 4; i++) if (reader.c()) {
|
|
1021
997
|
coeffList[--listStart] = i;
|
|
1022
998
|
modeList[listStart] = 3;
|
|
1023
999
|
} else if (isResidue) {
|
|
@@ -1026,7 +1002,7 @@ var BikVideoDecoder = class {
|
|
|
1026
1002
|
block[offset] = reader.e(bits);
|
|
1027
1003
|
if (!masksCount--) return;
|
|
1028
1004
|
} else {
|
|
1029
|
-
const offset = bits ? reader.e(reader.a(bits) | 1 << bits) : 1 - (reader.
|
|
1005
|
+
const offset = bits ? reader.e(reader.a(bits) | 1 << bits) : 1 - (reader.c() << 1);
|
|
1030
1006
|
block[BIK_SCAN[i] ?? 0] = offset;
|
|
1031
1007
|
coeffIndex[coeffCount++] = i;
|
|
1032
1008
|
}
|
|
@@ -1047,7 +1023,7 @@ var BikVideoDecoder = class {
|
|
|
1047
1023
|
block[offset] = reader.e(bits);
|
|
1048
1024
|
if (!masksCount--) return;
|
|
1049
1025
|
} else {
|
|
1050
|
-
const offset = bits ? reader.e(reader.a(bits) | 1 << bits) : 1 - (reader.
|
|
1026
|
+
const offset = bits ? reader.e(reader.a(bits) | 1 << bits) : 1 - (reader.c() << 1);
|
|
1051
1027
|
block[BIK_SCAN[ccoeff] ?? 0] = offset;
|
|
1052
1028
|
coeffIndex[coeffCount++] = ccoeff;
|
|
1053
1029
|
}
|
|
@@ -1058,11 +1034,11 @@ var BikVideoDecoder = class {
|
|
|
1058
1034
|
}
|
|
1059
1035
|
if (!isResidue) {
|
|
1060
1036
|
const quantOffset = (reader.a(4) << 6) + quantStartIndex;
|
|
1061
|
-
block[0] =
|
|
1037
|
+
block[0] = (block[0] ?? 0) * (BIK_QUANT[quantOffset] ?? 0) >> 11;
|
|
1062
1038
|
while (coeffCount--) {
|
|
1063
1039
|
const index = coeffIndex[coeffCount] ?? 0;
|
|
1064
1040
|
const blockIndex = BIK_SCAN[index] ?? 0;
|
|
1065
|
-
block[blockIndex] =
|
|
1041
|
+
block[blockIndex] = (block[blockIndex] ?? 0) * (BIK_QUANT[quantOffset + index] ?? 0) >> 11;
|
|
1066
1042
|
}
|
|
1067
1043
|
}
|
|
1068
1044
|
}
|
|
@@ -1152,11 +1128,15 @@ var BikVideoDecoder = class {
|
|
|
1152
1128
|
this.#addPixels8x8(block, dest, destOffset, stride);
|
|
1153
1129
|
}
|
|
1154
1130
|
#addPixels8x8(block, dest, destOffset, stride) {
|
|
1155
|
-
|
|
1156
|
-
let
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1131
|
+
stride -= 8;
|
|
1132
|
+
let i = -1;
|
|
1133
|
+
let iMax = 6;
|
|
1134
|
+
while (i++ < 63) {
|
|
1135
|
+
dest[destOffset + i] += block[i];
|
|
1136
|
+
if (i > iMax) {
|
|
1137
|
+
destOffset += stride;
|
|
1138
|
+
iMax += 8;
|
|
1139
|
+
}
|
|
1160
1140
|
}
|
|
1161
1141
|
}
|
|
1162
1142
|
/**
|
|
@@ -1165,9 +1145,9 @@ var BikVideoDecoder = class {
|
|
|
1165
1145
|
* @param existingFrame Decoded frame to re-use for the returned value.
|
|
1166
1146
|
* @returns Decoded frame.
|
|
1167
1147
|
*/
|
|
1168
|
-
|
|
1148
|
+
t(data, existingFrame = null) {
|
|
1169
1149
|
const reader = this.#reader;
|
|
1170
|
-
reader.
|
|
1150
|
+
reader.n(data);
|
|
1171
1151
|
let frame;
|
|
1172
1152
|
if (existingFrame) {
|
|
1173
1153
|
frame = existingFrame;
|
|
@@ -1175,18 +1155,18 @@ var BikVideoDecoder = class {
|
|
|
1175
1155
|
} else frame = this.#createFrame();
|
|
1176
1156
|
this.#data = frame.yuv;
|
|
1177
1157
|
if (this.#hasAlpha) {
|
|
1178
|
-
if (this.#version > 104) reader.
|
|
1158
|
+
if (this.#version > 104) reader.i(32);
|
|
1179
1159
|
this.#decodePlane(frame, 3);
|
|
1180
1160
|
}
|
|
1181
|
-
if (this.#version > 104) reader.
|
|
1161
|
+
if (this.#version > 104) reader.i(32);
|
|
1182
1162
|
for (let plane = 0; plane < 3; plane++) {
|
|
1183
1163
|
const planeIndex = plane && this.#hasSwappedUVPlanes ? plane ^ 3 : plane;
|
|
1184
1164
|
this.#decodePlane(frame, planeIndex);
|
|
1185
|
-
if (reader.
|
|
1165
|
+
if (reader.p < 1) break;
|
|
1186
1166
|
}
|
|
1187
1167
|
this.#prevData.set(frame.yuv);
|
|
1188
1168
|
this.#data = EMPTY_UINT8_ARRAY;
|
|
1189
|
-
this.#reader.
|
|
1169
|
+
this.#reader.n(EMPTY_UINT8_ARRAY);
|
|
1190
1170
|
return frame;
|
|
1191
1171
|
}
|
|
1192
1172
|
};
|
|
@@ -1194,35 +1174,69 @@ var BikVideoDecoder = class {
|
|
|
1194
1174
|
//#endregion
|
|
1195
1175
|
//#region src/bik-decoder.ts
|
|
1196
1176
|
var BikDecoder = class BikDecoder {
|
|
1197
|
-
|
|
1177
|
+
/**
|
|
1178
|
+
* Source of the video.
|
|
1179
|
+
*/
|
|
1180
|
+
#dataSource;
|
|
1181
|
+
/**
|
|
1182
|
+
* A {@link ReadableStreamDefaultReader} for the current position in the encoded video data.
|
|
1183
|
+
*/
|
|
1198
1184
|
#streamReader = null;
|
|
1185
|
+
/**
|
|
1186
|
+
* Buffer of encoded video data being processed by the decoder.
|
|
1187
|
+
*/
|
|
1199
1188
|
#bufBytes = null;
|
|
1189
|
+
/**
|
|
1190
|
+
* Start of the {@link #bufBytes} buffer relative to the start of the encoded video data.
|
|
1191
|
+
*/
|
|
1200
1192
|
#bufPos = 0;
|
|
1201
1193
|
#curFrame = -1;
|
|
1202
1194
|
#audioTrackDecoders = [];
|
|
1203
1195
|
#videoDecoder = null;
|
|
1204
1196
|
#header = null;
|
|
1205
1197
|
#isSupported = false;
|
|
1206
|
-
constructor(
|
|
1207
|
-
this.#
|
|
1198
|
+
constructor(source) {
|
|
1199
|
+
this.#dataSource = source;
|
|
1208
1200
|
}
|
|
1209
1201
|
/**
|
|
1210
|
-
* Set the current
|
|
1211
|
-
* potentially
|
|
1212
|
-
*
|
|
1202
|
+
* Set the current video data read position to the specified position, updating the read
|
|
1203
|
+
* buffer and potentially creating a new readable stream if the read position actually
|
|
1204
|
+
* changes.
|
|
1205
|
+
* @param pos Position in the video to seek to. Specified in bytes from the start of the
|
|
1206
|
+
* video.
|
|
1213
1207
|
*/
|
|
1214
1208
|
async #seek(pos) {
|
|
1215
|
-
if (
|
|
1216
|
-
this.#
|
|
1217
|
-
|
|
1209
|
+
if (pos < 0) return;
|
|
1210
|
+
if (this.#bufBytes) {
|
|
1211
|
+
if (pos === this.#bufPos) return;
|
|
1212
|
+
if (pos > this.#bufPos && pos < this.#bufPos + this.#bufBytes.byteLength) {
|
|
1213
|
+
this.#bufBytes = this.#bufBytes.subarray(pos - this.#bufPos);
|
|
1214
|
+
this.#bufPos = pos;
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
1218
|
if (this.#streamReader) {
|
|
1219
1219
|
await this.#streamReader.cancel();
|
|
1220
1220
|
this.#streamReader.releaseLock();
|
|
1221
1221
|
this.#streamReader = null;
|
|
1222
1222
|
}
|
|
1223
|
-
const
|
|
1223
|
+
const dataSource = this.#dataSource;
|
|
1224
|
+
let streamReader;
|
|
1225
|
+
if (dataSource instanceof Blob) streamReader = dataSource.slice(pos).stream()?.getReader();
|
|
1226
|
+
else {
|
|
1227
|
+
const isRequest = dataSource instanceof Request;
|
|
1228
|
+
if (dataSource instanceof URL || isRequest) {
|
|
1229
|
+
const request = isRequest ? dataSource : new Request(dataSource);
|
|
1230
|
+
const headers = request.headers;
|
|
1231
|
+
headers.delete("range");
|
|
1232
|
+
if (pos) headers.set("range", `bytes=${pos}-`);
|
|
1233
|
+
streamReader = (await fetch(request))?.body?.getReader();
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1224
1236
|
if (!streamReader) throw new Error("Invalid stream reader");
|
|
1225
1237
|
this.#streamReader = streamReader;
|
|
1238
|
+
this.#bufBytes = null;
|
|
1239
|
+
this.#bufPos = pos;
|
|
1226
1240
|
}
|
|
1227
1241
|
/**
|
|
1228
1242
|
* Read data from the readable stream.
|
|
@@ -1274,9 +1288,13 @@ var BikDecoder = class BikDecoder {
|
|
|
1274
1288
|
*/
|
|
1275
1289
|
async #ensureReadBytes(len) {
|
|
1276
1290
|
const bufBytes = await this.#readBytes(len);
|
|
1277
|
-
if (bufBytes?.byteLength !== len) throw new Error(`Read ${bufBytes?.byteLength
|
|
1291
|
+
if (bufBytes?.byteLength !== len) throw new Error(`Read ${bufBytes?.byteLength} bytes but expected ${len}`);
|
|
1278
1292
|
return bufBytes;
|
|
1279
1293
|
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Initialize the decoder by parsing the header from the readable stream to get the required
|
|
1296
|
+
* information about the encoded video, including the offsets of all the frames.
|
|
1297
|
+
*/
|
|
1280
1298
|
async #init() {
|
|
1281
1299
|
await this.#seek(0);
|
|
1282
1300
|
const headerBytes = await this.#ensureReadBytes(44);
|
|
@@ -1310,12 +1328,12 @@ var BikDecoder = class BikDecoder {
|
|
|
1310
1328
|
sampleRate: audioHeaderDataView.getUint16((numAudioTracks << 2) + (index << 2), true),
|
|
1311
1329
|
flags: {
|
|
1312
1330
|
stereo: isStereo,
|
|
1313
|
-
|
|
1331
|
+
usesDCT: !!(flags & 4096)
|
|
1314
1332
|
}
|
|
1315
1333
|
};
|
|
1316
1334
|
});
|
|
1317
1335
|
audioTracks.forEach((audioTrack) => {
|
|
1318
|
-
this.#audioTrackDecoders.push(new BikAudioDecoder(audioTrack.sampleRate, audioTrack.numChannels, audioTrack.flags.
|
|
1336
|
+
this.#audioTrackDecoders.push(new BikAudioDecoder(audioTrack.sampleRate, audioTrack.numChannels, audioTrack.flags.usesDCT));
|
|
1319
1337
|
});
|
|
1320
1338
|
}
|
|
1321
1339
|
const videoHeaderBytes = await this.#ensureReadBytes(frameListSize);
|
|
@@ -1334,7 +1352,7 @@ var BikDecoder = class BikDecoder {
|
|
|
1334
1352
|
this.#header = {
|
|
1335
1353
|
version,
|
|
1336
1354
|
subVersion,
|
|
1337
|
-
|
|
1355
|
+
totalSize: headerWords[1] + 8,
|
|
1338
1356
|
numFrames,
|
|
1339
1357
|
largestFrameSize: headerWords[3],
|
|
1340
1358
|
width,
|
|
@@ -1352,22 +1370,21 @@ var BikDecoder = class BikDecoder {
|
|
|
1352
1370
|
};
|
|
1353
1371
|
}
|
|
1354
1372
|
/**
|
|
1355
|
-
* Decoded header of the
|
|
1373
|
+
* Decoded header of the video.
|
|
1356
1374
|
* @returns Decoded header.
|
|
1357
1375
|
*/
|
|
1358
1376
|
get header() {
|
|
1359
1377
|
return this.#header;
|
|
1360
1378
|
}
|
|
1361
1379
|
/**
|
|
1362
|
-
* Whether the audio/
|
|
1363
|
-
* @returns `true` when the audio/
|
|
1364
|
-
* `false`.
|
|
1380
|
+
* Whether the audio/images in the video can be processed by the decoder or not.
|
|
1381
|
+
* @returns `true` when the audio/images can be processed by the decoder, otherwise `false`.
|
|
1365
1382
|
*/
|
|
1366
1383
|
get isSupported() {
|
|
1367
1384
|
return this.#isSupported;
|
|
1368
1385
|
}
|
|
1369
1386
|
/**
|
|
1370
|
-
* Get the next frame of the
|
|
1387
|
+
* Get the next frame of the video and decode it.
|
|
1371
1388
|
* @param prevFrame Optional data structure for a previously decoded frame to re-use (to reduce
|
|
1372
1389
|
* garbage collection).
|
|
1373
1390
|
* @returns Next decoded frame (audio and video).
|
|
@@ -1407,7 +1424,7 @@ var BikDecoder = class BikDecoder {
|
|
|
1407
1424
|
header: audioHeader,
|
|
1408
1425
|
size: audioTrackFrame.size,
|
|
1409
1426
|
numSamples: audioTrackFrame.numSamples,
|
|
1410
|
-
blocks: audioDecoder.
|
|
1427
|
+
blocks: audioDecoder.s(audioTrackFrame.bytes)
|
|
1411
1428
|
});
|
|
1412
1429
|
}
|
|
1413
1430
|
}
|
|
@@ -1416,12 +1433,12 @@ var BikDecoder = class BikDecoder {
|
|
|
1416
1433
|
const videoFrameBytes = frameBytes.subarray(videoFramePos, videoFramePos + videoFrameSize);
|
|
1417
1434
|
return {
|
|
1418
1435
|
audioTracks,
|
|
1419
|
-
videoFrame: this.#videoDecoder?.
|
|
1436
|
+
videoFrame: this.#videoDecoder?.t(videoFrameBytes, prevFrame?.videoFrame) ?? null
|
|
1420
1437
|
};
|
|
1421
1438
|
}
|
|
1422
1439
|
/**
|
|
1423
|
-
* Skip the specified number of frames of the
|
|
1424
|
-
*
|
|
1440
|
+
* Skip the specified number of frames of the video. They will still be decoded as decoding a
|
|
1441
|
+
* frame can effectively require data from any number of earlier frames.
|
|
1425
1442
|
* @param numFrames Number of frames to skip, but still decode.
|
|
1426
1443
|
*/
|
|
1427
1444
|
async skipFrames(numFrames) {
|
|
@@ -1432,25 +1449,25 @@ var BikDecoder = class BikDecoder {
|
|
|
1432
1449
|
}
|
|
1433
1450
|
}
|
|
1434
1451
|
/**
|
|
1435
|
-
* Reset the
|
|
1436
|
-
*
|
|
1452
|
+
* Reset the state of the decoder so it is ready to start decoding the video from the beginning.
|
|
1453
|
+
* Note that this will result in the decoder streaming the video again from the data source.
|
|
1437
1454
|
*/
|
|
1438
1455
|
reset() {
|
|
1439
1456
|
this.#curFrame = -1;
|
|
1440
1457
|
}
|
|
1441
1458
|
/**
|
|
1442
|
-
* Attempt to read and parse the headers of a BIK
|
|
1443
|
-
* {@link BikDecoder} for decoding the rest of the
|
|
1444
|
-
* @param
|
|
1445
|
-
*
|
|
1446
|
-
* @returns Decoder instance. Use {@link header} to access the parsed headers.
|
|
1459
|
+
* Attempt to read and parse the headers of a BIK video. If successful, return an instance of
|
|
1460
|
+
* {@link BikDecoder} for decoding the rest of the video from the data source.
|
|
1461
|
+
* @param source Data source that will provide the encoded video data.
|
|
1462
|
+
* @returns Decoder instance. Use {@link BikDecoder.header} to access the parsed headers.
|
|
1447
1463
|
*/
|
|
1448
|
-
static async
|
|
1449
|
-
const decoder = new BikDecoder(
|
|
1464
|
+
static async u(source) {
|
|
1465
|
+
const decoder = new BikDecoder(source);
|
|
1450
1466
|
await decoder.#init();
|
|
1451
1467
|
return decoder;
|
|
1452
1468
|
}
|
|
1453
1469
|
};
|
|
1470
|
+
const createBikDecoder = BikDecoder.u;
|
|
1454
1471
|
|
|
1455
1472
|
//#endregion
|
|
1456
|
-
export {
|
|
1473
|
+
export { createBikDecoder };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unbikit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Decoder for `.bik` video files.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"audio",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@arethetypeswrong/core": "0.18.2",
|
|
35
35
|
"@astrojs/check": "0.9.5",
|
|
36
36
|
"@astrojs/mdx": "4.3.12",
|
|
37
|
-
"@astrojs/starlight": "0.36.
|
|
37
|
+
"@astrojs/starlight": "0.36.3",
|
|
38
38
|
"@biomejs/biome": "2.3.7",
|
|
39
39
|
"@commitlint/config-conventional": "20.0.0",
|
|
40
40
|
"@commitlint/types": "20.0.0",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"@types/audioworklet": "0.0.91",
|
|
43
43
|
"@types/node": "24.10.1",
|
|
44
44
|
"@types/pngjs": "6.0.5",
|
|
45
|
-
"@vitest/coverage-v8": "4.0.
|
|
46
|
-
"@vitest/ui": "4.0.
|
|
45
|
+
"@vitest/coverage-v8": "4.0.14",
|
|
46
|
+
"@vitest/ui": "4.0.14",
|
|
47
47
|
"astro": "5.16.0",
|
|
48
48
|
"commitlint": "20.1.0",
|
|
49
49
|
"globals": "16.5.0",
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
"starlight-typedoc": "0.21.4",
|
|
59
59
|
"tinybench": "5.1.0",
|
|
60
60
|
"ts-extras": "0.16.0",
|
|
61
|
-
"tsdown": "0.16.
|
|
61
|
+
"tsdown": "0.16.7",
|
|
62
62
|
"type-fest": "5.2.0",
|
|
63
63
|
"typedoc": "0.28.14",
|
|
64
64
|
"typedoc-plugin-markdown": "4.9.0",
|
|
65
65
|
"typescript": "5.9.3",
|
|
66
66
|
"unplugin-unused": "0.5.6",
|
|
67
67
|
"vite": "npm:rolldown-vite@7.2.7",
|
|
68
|
-
"vitest": "4.0.
|
|
68
|
+
"vitest": "4.0.14"
|
|
69
69
|
},
|
|
70
70
|
"exports": {
|
|
71
71
|
".": {
|