@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
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* H.264 Integer Transforms and Quantization
|
|
3
|
-
*
|
|
4
|
-
* Forward and inverse 4x4/8x8 integer DCT transforms,
|
|
5
|
-
* quantization, and dequantization as specified in H.264.
|
|
6
|
-
*
|
|
7
|
-
* Reference: ITU-T H.264, Section 8.5
|
|
8
|
-
*
|
|
9
|
-
* @module codecs/h264-transform
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { levelScale4x4, quantMF4x4, scanOrder4x4 } from './h264-tables.js';
|
|
13
|
-
|
|
14
|
-
// ══════════════════════════════════════════════════════════
|
|
15
|
-
// 4x4 Inverse Integer Transform (Section 8.5.12.1)
|
|
16
|
-
// ══════════════════════════════════════════════════════════
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Inverse 4x4 integer DCT.
|
|
20
|
-
* Input: 16-element array in raster order (after dequantization).
|
|
21
|
-
* Output: 16-element residual array in raster order.
|
|
22
|
-
*/
|
|
23
|
-
export function inverseDCT4x4(coeffs) {
|
|
24
|
-
const d = new Int32Array(16);
|
|
25
|
-
const r = new Int32Array(16);
|
|
26
|
-
|
|
27
|
-
// Copy input
|
|
28
|
-
for (let i = 0; i < 16; i++) d[i] = coeffs[i];
|
|
29
|
-
|
|
30
|
-
// Horizontal pass (rows)
|
|
31
|
-
for (let i = 0; i < 4; i++) {
|
|
32
|
-
const si = i * 4;
|
|
33
|
-
const e0 = d[si + 0] + d[si + 2];
|
|
34
|
-
const e1 = d[si + 0] - d[si + 2];
|
|
35
|
-
const e2 = (d[si + 1] >> 1) - d[si + 3];
|
|
36
|
-
const e3 = d[si + 1] + (d[si + 3] >> 1);
|
|
37
|
-
|
|
38
|
-
r[si + 0] = e0 + e3;
|
|
39
|
-
r[si + 1] = e1 + e2;
|
|
40
|
-
r[si + 2] = e1 - e2;
|
|
41
|
-
r[si + 3] = e0 - e3;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Vertical pass (columns)
|
|
45
|
-
const out = new Int32Array(16);
|
|
46
|
-
for (let j = 0; j < 4; j++) {
|
|
47
|
-
const e0 = r[j] + r[8 + j];
|
|
48
|
-
const e1 = r[j] - r[8 + j];
|
|
49
|
-
const e2 = (r[4 + j] >> 1) - r[12 + j];
|
|
50
|
-
const e3 = r[4 + j] + (r[12 + j] >> 1);
|
|
51
|
-
|
|
52
|
-
out[j] = (e0 + e3 + 32) >> 6;
|
|
53
|
-
out[4 + j] = (e1 + e2 + 32) >> 6;
|
|
54
|
-
out[8 + j] = (e1 - e2 + 32) >> 6;
|
|
55
|
-
out[12 + j] = (e0 - e3 + 32) >> 6;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return out;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// ══════════════════════════════════════════════════════════
|
|
62
|
-
// 4x4 Forward Integer Transform (Section 8.5 inverse)
|
|
63
|
-
// ══════════════════════════════════════════════════════════
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Forward 4x4 integer DCT (for encoder).
|
|
67
|
-
* Input: 16-element residual array in raster order.
|
|
68
|
-
* Output: 16-element coefficient array in raster order.
|
|
69
|
-
*/
|
|
70
|
-
export function forwardDCT4x4(residual) {
|
|
71
|
-
const d = new Int32Array(16);
|
|
72
|
-
const r = new Int32Array(16);
|
|
73
|
-
|
|
74
|
-
for (let i = 0; i < 16; i++) d[i] = residual[i];
|
|
75
|
-
|
|
76
|
-
// Horizontal pass (Cf * X)
|
|
77
|
-
for (let i = 0; i < 4; i++) {
|
|
78
|
-
const si = i * 4;
|
|
79
|
-
const p0 = d[si + 0] + d[si + 3];
|
|
80
|
-
const p1 = d[si + 1] + d[si + 2];
|
|
81
|
-
const p2 = d[si + 1] - d[si + 2];
|
|
82
|
-
const p3 = d[si + 0] - d[si + 3];
|
|
83
|
-
|
|
84
|
-
r[si + 0] = p0 + p1;
|
|
85
|
-
r[si + 1] = (p3 << 1) + p2;
|
|
86
|
-
r[si + 2] = p0 - p1;
|
|
87
|
-
r[si + 3] = p3 - (p2 << 1);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Vertical pass (result * Cf^T)
|
|
91
|
-
const out = new Int32Array(16);
|
|
92
|
-
for (let j = 0; j < 4; j++) {
|
|
93
|
-
const p0 = r[j] + r[12 + j];
|
|
94
|
-
const p1 = r[4 + j] + r[8 + j];
|
|
95
|
-
const p2 = r[4 + j] - r[8 + j];
|
|
96
|
-
const p3 = r[j] - r[12 + j];
|
|
97
|
-
|
|
98
|
-
out[j] = p0 + p1;
|
|
99
|
-
out[4 + j] = (p3 << 1) + p2;
|
|
100
|
-
out[8 + j] = p0 - p1;
|
|
101
|
-
out[12 + j] = p3 - (p2 << 1);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return out;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// ══════════════════════════════════════════════════════════
|
|
108
|
-
// 4x4 Hadamard Transform (for DC coefficients of Intra16x16)
|
|
109
|
-
// ══════════════════════════════════════════════════════════
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Forward 4x4 Hadamard transform for Intra16x16 luma DC coefficients.
|
|
113
|
-
* Input: 16 DC values (one per 4x4 block in the 16x16 macroblock).
|
|
114
|
-
* Output: 16 transformed values.
|
|
115
|
-
*/
|
|
116
|
-
export function forwardHadamard4x4(dc) {
|
|
117
|
-
const t = new Int32Array(16);
|
|
118
|
-
const out = new Int32Array(16);
|
|
119
|
-
|
|
120
|
-
// Horizontal
|
|
121
|
-
for (let i = 0; i < 4; i++) {
|
|
122
|
-
const s = i * 4;
|
|
123
|
-
const p0 = dc[s] + dc[s + 3];
|
|
124
|
-
const p1 = dc[s + 1] + dc[s + 2];
|
|
125
|
-
const p2 = dc[s + 1] - dc[s + 2];
|
|
126
|
-
const p3 = dc[s] - dc[s + 3];
|
|
127
|
-
t[s] = p0 + p1;
|
|
128
|
-
t[s + 1] = p3 + p2;
|
|
129
|
-
t[s + 2] = p0 - p1;
|
|
130
|
-
t[s + 3] = p3 - p2;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Vertical
|
|
134
|
-
for (let j = 0; j < 4; j++) {
|
|
135
|
-
const p0 = t[j] + t[12 + j];
|
|
136
|
-
const p1 = t[4 + j] + t[8 + j];
|
|
137
|
-
const p2 = t[4 + j] - t[8 + j];
|
|
138
|
-
const p3 = t[j] - t[12 + j];
|
|
139
|
-
out[j] = (p0 + p1) >> 1;
|
|
140
|
-
out[4 + j] = (p3 + p2) >> 1;
|
|
141
|
-
out[8 + j] = (p0 - p1) >> 1;
|
|
142
|
-
out[12 + j] = (p3 - p2) >> 1;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return out;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Inverse 4x4 Hadamard transform for Intra16x16 luma DC.
|
|
150
|
-
*/
|
|
151
|
-
export function inverseHadamard4x4(dc) {
|
|
152
|
-
// Same as forward (Hadamard is its own inverse up to scaling)
|
|
153
|
-
const t = new Int32Array(16);
|
|
154
|
-
const out = new Int32Array(16);
|
|
155
|
-
|
|
156
|
-
for (let i = 0; i < 4; i++) {
|
|
157
|
-
const s = i * 4;
|
|
158
|
-
const p0 = dc[s] + dc[s + 3];
|
|
159
|
-
const p1 = dc[s + 1] + dc[s + 2];
|
|
160
|
-
const p2 = dc[s + 1] - dc[s + 2];
|
|
161
|
-
const p3 = dc[s] - dc[s + 3];
|
|
162
|
-
t[s] = p0 + p1;
|
|
163
|
-
t[s + 1] = p3 + p2;
|
|
164
|
-
t[s + 2] = p0 - p1;
|
|
165
|
-
t[s + 3] = p3 - p2;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
for (let j = 0; j < 4; j++) {
|
|
169
|
-
const p0 = t[j] + t[12 + j];
|
|
170
|
-
const p1 = t[4 + j] + t[8 + j];
|
|
171
|
-
const p2 = t[4 + j] - t[8 + j];
|
|
172
|
-
const p3 = t[j] - t[12 + j];
|
|
173
|
-
out[j] = p0 + p1;
|
|
174
|
-
out[4 + j] = p3 + p2;
|
|
175
|
-
out[8 + j] = p0 - p1;
|
|
176
|
-
out[12 + j] = p3 - p2;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return out;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// ══════════════════════════════════════════════════════════
|
|
183
|
-
// 2x2 Hadamard Transform (for chroma DC)
|
|
184
|
-
// ══════════════════════════════════════════════════════════
|
|
185
|
-
|
|
186
|
-
export function forwardHadamard2x2(dc) {
|
|
187
|
-
return new Int32Array([
|
|
188
|
-
dc[0] + dc[1] + dc[2] + dc[3],
|
|
189
|
-
dc[0] - dc[1] + dc[2] - dc[3],
|
|
190
|
-
dc[0] + dc[1] - dc[2] - dc[3],
|
|
191
|
-
dc[0] - dc[1] - dc[2] + dc[3],
|
|
192
|
-
]);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export function inverseHadamard2x2(dc) {
|
|
196
|
-
// Same structure, no scaling needed for 2x2
|
|
197
|
-
return forwardHadamard2x2(dc);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// ══════════════════════════════════════════════════════════
|
|
201
|
-
// Inverse Quantization (Dequantization)
|
|
202
|
-
// Section 8.5.12.1
|
|
203
|
-
// ══════════════════════════════════════════════════════════
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Dequantize a 4x4 block of transform coefficients.
|
|
207
|
-
* @param {Int32Array} coeffs - 16 coefficients in scan order
|
|
208
|
-
* @param {number} qp - Quantization parameter (0-51)
|
|
209
|
-
* @param {boolean} isIntra - Whether the macroblock is intra
|
|
210
|
-
* @returns {Int32Array} Dequantized coefficients in raster order
|
|
211
|
-
*/
|
|
212
|
-
export function dequantize4x4(coeffs, qp, isIntra) {
|
|
213
|
-
const qpMod6 = qp % 6;
|
|
214
|
-
const qpDiv6 = Math.floor(qp / 6);
|
|
215
|
-
const scale = levelScale4x4[qpMod6];
|
|
216
|
-
const out = new Int32Array(16);
|
|
217
|
-
|
|
218
|
-
for (let i = 0; i < 16; i++) {
|
|
219
|
-
const pos = scanOrder4x4[i];
|
|
220
|
-
if (qpDiv6 >= 4) {
|
|
221
|
-
out[pos] = (coeffs[i] * scale[i]) << (qpDiv6 - 4);
|
|
222
|
-
} else {
|
|
223
|
-
out[pos] = (coeffs[i] * scale[i] + (1 << (3 - qpDiv6))) >> (4 - qpDiv6);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return out;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// ══════════════════════════════════════════════════════════
|
|
231
|
-
// Forward Quantization (for encoder)
|
|
232
|
-
// ══════════════════════════════════════════════════════════
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Quantize a 4x4 block of transform coefficients.
|
|
236
|
-
* @param {Int32Array} coeffs - 16 coefficients in raster order
|
|
237
|
-
* @param {number} qp - Quantization parameter (0-51)
|
|
238
|
-
* @returns {Int32Array} Quantized coefficients in scan order
|
|
239
|
-
*/
|
|
240
|
-
export function quantize4x4(coeffs, qp) {
|
|
241
|
-
const qpMod6 = qp % 6;
|
|
242
|
-
const qpDiv6 = Math.floor(qp / 6);
|
|
243
|
-
const mf = quantMF4x4[qpMod6];
|
|
244
|
-
const qBits = 15 + qpDiv6;
|
|
245
|
-
const offset = (1 << qBits) / 3; // intra offset = 1/3
|
|
246
|
-
const out = new Int32Array(16);
|
|
247
|
-
|
|
248
|
-
for (let i = 0; i < 16; i++) {
|
|
249
|
-
const pos = scanOrder4x4[i];
|
|
250
|
-
const sign = coeffs[pos] < 0 ? -1 : 1;
|
|
251
|
-
const absVal = Math.abs(coeffs[pos]);
|
|
252
|
-
out[i] = sign * ((absVal * mf[i] + offset) >> qBits);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return out;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// ══════════════════════════════════════════════════════════
|
|
259
|
-
// Clipping utility
|
|
260
|
-
// ══════════════════════════════════════════════════════════
|
|
261
|
-
|
|
262
|
-
export function clip(val, min, max) {
|
|
263
|
-
return val < min ? min : val > max ? max : val;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
export function clip255(val) {
|
|
267
|
-
return val < 0 ? 0 : val > 255 ? 255 : val;
|
|
268
|
-
}
|