@invintusmedia/tomp4 1.4.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tomp4.js +2 -2
- package/package.json +1 -1
- package/src/codecs/smart-render.js +374 -96
- package/src/hls-clip.js +177 -429
- package/src/index.js +1 -6
- package/src/codecs/REFERENCE.md +0 -885
- package/src/codecs/h264-cabac-init.js +0 -546
- package/src/codecs/h264-cabac.js +0 -322
- package/src/codecs/h264-cavlc-tables.js +0 -628
- package/src/codecs/h264-decoder.js +0 -940
- package/src/codecs/h264-encoder.js +0 -502
- package/src/codecs/h264-intra.js +0 -292
- package/src/codecs/h264-sps-pps.js +0 -483
- package/src/codecs/h264-tables.js +0 -217
- package/src/codecs/h264-transform.js +0 -268
package/src/codecs/h264-intra.js
DELETED
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* H.264 Intra Prediction
|
|
3
|
-
*
|
|
4
|
-
* Implements Intra 4x4, Intra 8x8, and Intra 16x16 prediction modes
|
|
5
|
-
* for luma and chroma. Used during macroblock decoding to reconstruct
|
|
6
|
-
* the predicted block from neighboring samples.
|
|
7
|
-
*
|
|
8
|
-
* Reference: ITU-T H.264, Section 8.3
|
|
9
|
-
*
|
|
10
|
-
* @module codecs/h264-intra
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { clip255 } from './h264-transform.js';
|
|
14
|
-
|
|
15
|
-
// ══════════════════════════════════════════════════════════
|
|
16
|
-
// Intra 4x4 Prediction (Section 8.3.1.2)
|
|
17
|
-
// 9 modes for each 4x4 luma block
|
|
18
|
-
// ══════════════════════════════════════════════════════════
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Perform Intra 4x4 prediction.
|
|
22
|
-
* @param {number} mode - Prediction mode (0-8)
|
|
23
|
-
* @param {Int32Array|null} above - 8 samples above (indices 0-3 = directly above, 4-7 = above-right)
|
|
24
|
-
* @param {Int32Array|null} left - 4 samples to the left
|
|
25
|
-
* @param {number} aboveLeft - Above-left corner sample
|
|
26
|
-
* @param {boolean} hasAbove - Whether above samples are available
|
|
27
|
-
* @param {boolean} hasLeft - Whether left samples are available
|
|
28
|
-
* @param {boolean} hasAboveRight - Whether above-right samples are available
|
|
29
|
-
* @returns {Int32Array} 16-element predicted block in raster order
|
|
30
|
-
*/
|
|
31
|
-
export function intra4x4Predict(mode, above, left, aboveLeft, hasAbove, hasLeft, hasAboveRight) {
|
|
32
|
-
const pred = new Int32Array(16);
|
|
33
|
-
|
|
34
|
-
// Extend above samples: if above-right not available, repeat the last above sample
|
|
35
|
-
const p = new Int32Array(13); // p[-1..7] mapped to p[0..12] (index offset: +1)
|
|
36
|
-
// p[0] = above-left, p[1..4] = above[0..3], p[5..8] = above-right[0..3]
|
|
37
|
-
if (hasAbove) {
|
|
38
|
-
for (let i = 0; i < 4; i++) p[i + 1] = above[i];
|
|
39
|
-
if (hasAboveRight) {
|
|
40
|
-
for (let i = 0; i < 4; i++) p[i + 5] = above[i + 4];
|
|
41
|
-
} else {
|
|
42
|
-
for (let i = 0; i < 4; i++) p[i + 5] = above[3];
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
p[0] = hasAbove && hasLeft ? aboveLeft : hasAbove ? above[0] : hasLeft ? left[0] : 128;
|
|
46
|
-
|
|
47
|
-
const l = left || new Int32Array(4); // left[0..3]
|
|
48
|
-
|
|
49
|
-
switch (mode) {
|
|
50
|
-
case 0: // Vertical
|
|
51
|
-
for (let y = 0; y < 4; y++)
|
|
52
|
-
for (let x = 0; x < 4; x++)
|
|
53
|
-
pred[y * 4 + x] = p[x + 1];
|
|
54
|
-
break;
|
|
55
|
-
|
|
56
|
-
case 1: // Horizontal
|
|
57
|
-
for (let y = 0; y < 4; y++)
|
|
58
|
-
for (let x = 0; x < 4; x++)
|
|
59
|
-
pred[y * 4 + x] = l[y];
|
|
60
|
-
break;
|
|
61
|
-
|
|
62
|
-
case 2: { // DC
|
|
63
|
-
let sum = 0, count = 0;
|
|
64
|
-
if (hasAbove) { for (let i = 0; i < 4; i++) sum += p[i + 1]; count += 4; }
|
|
65
|
-
if (hasLeft) { for (let i = 0; i < 4; i++) sum += l[i]; count += 4; }
|
|
66
|
-
const dc = count > 0 ? (sum + (count >> 1)) / count | 0 : 128;
|
|
67
|
-
pred.fill(dc);
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
case 3: // Diagonal Down-Left
|
|
72
|
-
for (let y = 0; y < 4; y++)
|
|
73
|
-
for (let x = 0; x < 4; x++) {
|
|
74
|
-
if (x === 3 && y === 3)
|
|
75
|
-
pred[y * 4 + x] = (p[6] + 3 * p[7] + 2) >> 2;
|
|
76
|
-
else
|
|
77
|
-
pred[y * 4 + x] = (p[x + y + 1] + 2 * p[x + y + 2] + p[x + y + 3] + 2) >> 2;
|
|
78
|
-
}
|
|
79
|
-
break;
|
|
80
|
-
|
|
81
|
-
case 4: // Diagonal Down-Right
|
|
82
|
-
for (let y = 0; y < 4; y++)
|
|
83
|
-
for (let x = 0; x < 4; x++) {
|
|
84
|
-
if (x > y)
|
|
85
|
-
pred[y * 4 + x] = (p[x - y] + 2 * p[x - y + 1] + p[x - y + 2] + 2) >> 2;
|
|
86
|
-
else if (x < y)
|
|
87
|
-
pred[y * 4 + x] = (l[y - x - 1] + 2 * (x === 0 && y - 1 >= 0 ? l[y - 1] : l[y - x - 1]) + (y - x >= 2 ? l[y - x - 2] : p[0]) + 2) >> 2;
|
|
88
|
-
else // x === y
|
|
89
|
-
pred[y * 4 + x] = (p[1] + 2 * p[0] + l[0] + 2) >> 2;
|
|
90
|
-
}
|
|
91
|
-
break;
|
|
92
|
-
|
|
93
|
-
// Modes 5-8 are less common; implement with the standard filter formulas
|
|
94
|
-
case 5: // Vertical-Right
|
|
95
|
-
for (let y = 0; y < 4; y++)
|
|
96
|
-
for (let x = 0; x < 4; x++) {
|
|
97
|
-
const zVR = 2 * x - y;
|
|
98
|
-
if (zVR >= 0 && (zVR & 1) === 0)
|
|
99
|
-
pred[y * 4 + x] = (p[(zVR >> 1)] + p[(zVR >> 1) + 1] + 1) >> 1;
|
|
100
|
-
else if (zVR >= 0)
|
|
101
|
-
pred[y * 4 + x] = (p[(zVR >> 1)] + 2 * p[(zVR >> 1) + 1] + p[(zVR >> 1) + 2] + 2) >> 2;
|
|
102
|
-
else if (zVR === -1)
|
|
103
|
-
pred[y * 4 + x] = (l[0] + 2 * p[0] + p[1] + 2) >> 2;
|
|
104
|
-
else // zVR < -1
|
|
105
|
-
pred[y * 4 + x] = (l[y - 1] + 2 * l[y - 2] + l[y - 3 >= 0 ? y - 3 : 0] + 2) >> 2;
|
|
106
|
-
}
|
|
107
|
-
break;
|
|
108
|
-
|
|
109
|
-
case 6: // Horizontal-Down
|
|
110
|
-
for (let y = 0; y < 4; y++)
|
|
111
|
-
for (let x = 0; x < 4; x++) {
|
|
112
|
-
const zHD = 2 * y - x;
|
|
113
|
-
if (zHD >= 0 && (zHD & 1) === 0)
|
|
114
|
-
pred[y * 4 + x] = zHD === 0
|
|
115
|
-
? (p[0] + l[0] + 1) >> 1
|
|
116
|
-
: (l[(zHD >> 1) - 1] + l[zHD >> 1] + 1) >> 1;
|
|
117
|
-
else if (zHD >= 0)
|
|
118
|
-
pred[y * 4 + x] = zHD === 1
|
|
119
|
-
? (l[0] + 2 * p[0] + p[1] + 2) >> 2
|
|
120
|
-
: (l[(zHD >> 1) - 1] + 2 * l[zHD >> 1] + l[(zHD >> 1) + 1 < 4 ? (zHD >> 1) + 1 : 3] + 2) >> 2;
|
|
121
|
-
else if (zHD === -1)
|
|
122
|
-
pred[y * 4 + x] = (p[0] + 2 * p[1] + p[2] + 2) >> 2;
|
|
123
|
-
else
|
|
124
|
-
pred[y * 4 + x] = (p[x - 1] + 2 * p[x] + p[x + 1] + 2) >> 2;
|
|
125
|
-
}
|
|
126
|
-
break;
|
|
127
|
-
|
|
128
|
-
case 7: // Vertical-Left
|
|
129
|
-
for (let y = 0; y < 4; y++)
|
|
130
|
-
for (let x = 0; x < 4; x++) {
|
|
131
|
-
if ((y & 1) === 0)
|
|
132
|
-
pred[y * 4 + x] = (p[x + (y >> 1) + 1] + p[x + (y >> 1) + 2] + 1) >> 1;
|
|
133
|
-
else
|
|
134
|
-
pred[y * 4 + x] = (p[x + (y >> 1) + 1] + 2 * p[x + (y >> 1) + 2] + p[x + (y >> 1) + 3] + 2) >> 2;
|
|
135
|
-
}
|
|
136
|
-
break;
|
|
137
|
-
|
|
138
|
-
case 8: // Horizontal-Up
|
|
139
|
-
for (let y = 0; y < 4; y++)
|
|
140
|
-
for (let x = 0; x < 4; x++) {
|
|
141
|
-
const zHU = x + 2 * y;
|
|
142
|
-
if (zHU < 5 && (zHU & 1) === 0)
|
|
143
|
-
pred[y * 4 + x] = (l[zHU >> 1] + l[(zHU >> 1) + 1] + 1) >> 1;
|
|
144
|
-
else if (zHU < 5)
|
|
145
|
-
pred[y * 4 + x] = (l[zHU >> 1] + 2 * l[(zHU >> 1) + 1] + l[Math.min((zHU >> 1) + 2, 3)] + 2) >> 2;
|
|
146
|
-
else if (zHU === 5)
|
|
147
|
-
pred[y * 4 + x] = (l[2] + 3 * l[3] + 2) >> 2;
|
|
148
|
-
else
|
|
149
|
-
pred[y * 4 + x] = l[3];
|
|
150
|
-
}
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return pred;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// ══════════════════════════════════════════════════════════
|
|
158
|
-
// Intra 16x16 Prediction (Section 8.3.3)
|
|
159
|
-
// 4 modes for the full 16x16 luma block
|
|
160
|
-
// ══════════════════════════════════════════════════════════
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Perform Intra 16x16 prediction.
|
|
164
|
-
* @param {number} mode - Prediction mode (0-3)
|
|
165
|
-
* @param {Uint8Array} above - 16 samples above the macroblock
|
|
166
|
-
* @param {Uint8Array} left - 16 samples to the left
|
|
167
|
-
* @param {number} aboveLeft - Above-left corner sample
|
|
168
|
-
* @param {boolean} hasAbove
|
|
169
|
-
* @param {boolean} hasLeft
|
|
170
|
-
* @returns {Int32Array} 256-element predicted block (16x16 raster)
|
|
171
|
-
*/
|
|
172
|
-
export function intra16x16Predict(mode, above, left, aboveLeft, hasAbove, hasLeft) {
|
|
173
|
-
const pred = new Int32Array(256);
|
|
174
|
-
|
|
175
|
-
switch (mode) {
|
|
176
|
-
case 0: // Vertical
|
|
177
|
-
for (let y = 0; y < 16; y++)
|
|
178
|
-
for (let x = 0; x < 16; x++)
|
|
179
|
-
pred[y * 16 + x] = above[x];
|
|
180
|
-
break;
|
|
181
|
-
|
|
182
|
-
case 1: // Horizontal
|
|
183
|
-
for (let y = 0; y < 16; y++)
|
|
184
|
-
for (let x = 0; x < 16; x++)
|
|
185
|
-
pred[y * 16 + x] = left[y];
|
|
186
|
-
break;
|
|
187
|
-
|
|
188
|
-
case 2: { // DC
|
|
189
|
-
let sum = 0, count = 0;
|
|
190
|
-
if (hasAbove) { for (let i = 0; i < 16; i++) sum += above[i]; count += 16; }
|
|
191
|
-
if (hasLeft) { for (let i = 0; i < 16; i++) sum += left[i]; count += 16; }
|
|
192
|
-
const dc = count > 0 ? (sum + (count >> 1)) / count | 0 : 128;
|
|
193
|
-
pred.fill(dc);
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
case 3: { // Plane
|
|
198
|
-
let H = 0, V = 0;
|
|
199
|
-
for (let i = 0; i < 8; i++) {
|
|
200
|
-
H += (i + 1) * (above[8 + i] - above[6 - i]);
|
|
201
|
-
V += (i + 1) * (left[8 + i] - left[6 - i]);
|
|
202
|
-
}
|
|
203
|
-
const a = 16 * (above[15] + left[15]);
|
|
204
|
-
const b = (5 * H + 32) >> 6;
|
|
205
|
-
const c = (5 * V + 32) >> 6;
|
|
206
|
-
|
|
207
|
-
for (let y = 0; y < 16; y++)
|
|
208
|
-
for (let x = 0; x < 16; x++)
|
|
209
|
-
pred[y * 16 + x] = clip255((a + b * (x - 7) + c * (y - 7) + 16) >> 5);
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return pred;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// ══════════════════════════════════════════════════════════
|
|
218
|
-
// Intra Chroma Prediction (Section 8.3.4)
|
|
219
|
-
// 4 modes for each 8x8 chroma block (4:2:0)
|
|
220
|
-
// ══════════════════════════════════════════════════════════
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Perform Intra chroma prediction (8x8 for 4:2:0).
|
|
224
|
-
* @param {number} mode - 0=DC, 1=Horizontal, 2=Vertical, 3=Plane
|
|
225
|
-
* @param {Uint8Array} above - 8 samples above
|
|
226
|
-
* @param {Uint8Array} left - 8 samples to the left
|
|
227
|
-
* @param {number} aboveLeft - Corner sample
|
|
228
|
-
* @param {boolean} hasAbove
|
|
229
|
-
* @param {boolean} hasLeft
|
|
230
|
-
* @returns {Int32Array} 64-element predicted block (8x8 raster)
|
|
231
|
-
*/
|
|
232
|
-
export function intraChromaPredict(mode, above, left, aboveLeft, hasAbove, hasLeft) {
|
|
233
|
-
const pred = new Int32Array(64);
|
|
234
|
-
|
|
235
|
-
switch (mode) {
|
|
236
|
-
case 0: { // DC (per 4x4 sub-block)
|
|
237
|
-
for (let blkY = 0; blkY < 2; blkY++) {
|
|
238
|
-
for (let blkX = 0; blkX < 2; blkX++) {
|
|
239
|
-
let sum = 0, count = 0;
|
|
240
|
-
const topAvail = hasAbove;
|
|
241
|
-
const leftAvail = hasLeft;
|
|
242
|
-
|
|
243
|
-
if (topAvail) {
|
|
244
|
-
for (let i = 0; i < 4; i++) sum += above[blkX * 4 + i];
|
|
245
|
-
count += 4;
|
|
246
|
-
}
|
|
247
|
-
if (leftAvail) {
|
|
248
|
-
for (let i = 0; i < 4; i++) sum += left[blkY * 4 + i];
|
|
249
|
-
count += 4;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const dc = count > 0 ? (sum + (count >> 1)) / count | 0 : 128;
|
|
253
|
-
|
|
254
|
-
for (let y = 0; y < 4; y++)
|
|
255
|
-
for (let x = 0; x < 4; x++)
|
|
256
|
-
pred[(blkY * 4 + y) * 8 + blkX * 4 + x] = dc;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
break;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
case 1: // Horizontal
|
|
263
|
-
for (let y = 0; y < 8; y++)
|
|
264
|
-
for (let x = 0; x < 8; x++)
|
|
265
|
-
pred[y * 8 + x] = left[y];
|
|
266
|
-
break;
|
|
267
|
-
|
|
268
|
-
case 2: // Vertical
|
|
269
|
-
for (let y = 0; y < 8; y++)
|
|
270
|
-
for (let x = 0; x < 8; x++)
|
|
271
|
-
pred[y * 8 + x] = above[x];
|
|
272
|
-
break;
|
|
273
|
-
|
|
274
|
-
case 3: { // Plane
|
|
275
|
-
let H = 0, V = 0;
|
|
276
|
-
for (let i = 0; i < 4; i++) {
|
|
277
|
-
H += (i + 1) * (above[4 + i] - above[2 - i]);
|
|
278
|
-
V += (i + 1) * (left[4 + i] - left[2 - i]);
|
|
279
|
-
}
|
|
280
|
-
const a = 16 * (above[7] + left[7]);
|
|
281
|
-
const b = (17 * H + 16) >> 5;
|
|
282
|
-
const c = (17 * V + 16) >> 5;
|
|
283
|
-
|
|
284
|
-
for (let y = 0; y < 8; y++)
|
|
285
|
-
for (let x = 0; x < 8; x++)
|
|
286
|
-
pred[y * 8 + x] = clip255((a + b * (x - 3) + c * (y - 3) + 16) >> 5);
|
|
287
|
-
break;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return pred;
|
|
292
|
-
}
|