@yume-chan/media-codec 3.0.0-beta.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 +3 -0
- package/esm/av1.d.ts +470 -0
- package/esm/av1.d.ts.map +1 -0
- package/esm/av1.js +666 -0
- package/esm/av1.js.map +1 -0
- package/esm/format.d.ts +4 -0
- package/esm/format.d.ts.map +1 -0
- package/esm/format.js +44 -0
- package/esm/format.js.map +1 -0
- package/esm/h264.d.ts +47 -0
- package/esm/h264.d.ts.map +1 -0
- package/esm/h264.js +240 -0
- package/esm/h264.js.map +1 -0
- package/esm/h265.d.ts +501 -0
- package/esm/h265.d.ts.map +1 -0
- package/esm/h265.js +1095 -0
- package/esm/h265.js.map +1 -0
- package/esm/index.d.ts +6 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +6 -0
- package/esm/index.js.map +1 -0
- package/esm/nalu.d.ts +28 -0
- package/esm/nalu.d.ts.map +1 -0
- package/esm/nalu.js +250 -0
- package/esm/nalu.js.map +1 -0
- package/package.json +43 -0
- package/src/av1.ts +782 -0
- package/src/format.ts +53 -0
- package/src/h264.ts +306 -0
- package/src/h265.ts +1393 -0
- package/src/index.ts +5 -0
- package/src/nalu.ts +304 -0
- package/tsconfig.build.json +3 -0
package/src/h265.ts
ADDED
|
@@ -0,0 +1,1393 @@
|
|
|
1
|
+
// cspell: ignore golomb
|
|
2
|
+
// cspell: ignore qpprime
|
|
3
|
+
// cspell: ignore colour
|
|
4
|
+
// cspell: ignore inbld
|
|
5
|
+
// cspell: ignore Coef
|
|
6
|
+
// cspell: ignore coeffs
|
|
7
|
+
// cspell: ignore Pocs
|
|
8
|
+
// cspell: ignore overscan
|
|
9
|
+
// cspell: ignore disp
|
|
10
|
+
// cspell: ignore bitstream
|
|
11
|
+
// cspell: ignore scal
|
|
12
|
+
// cspell: ignore ivmc
|
|
13
|
+
// cspell: ignore dbbp
|
|
14
|
+
// cspell: ignore texmc
|
|
15
|
+
// cspell: ignore rbsp
|
|
16
|
+
// cspell: ignore cprms
|
|
17
|
+
// cspell: ignore nalu
|
|
18
|
+
// cspell: ignore sodb
|
|
19
|
+
// cspell: ignore luma
|
|
20
|
+
|
|
21
|
+
import { getUint32LittleEndian } from "@yume-chan/no-data-view";
|
|
22
|
+
|
|
23
|
+
import { hexDigits } from "./format.js";
|
|
24
|
+
import { NaluSodbBitReader, annexBSplitNalu } from "./nalu.js";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 6.2 Source, decoded and output picture formats
|
|
28
|
+
*/
|
|
29
|
+
export function getSubWidthC(chroma_format_idc: number) {
|
|
30
|
+
switch (chroma_format_idc) {
|
|
31
|
+
case 0:
|
|
32
|
+
case 3:
|
|
33
|
+
return 1;
|
|
34
|
+
case 1:
|
|
35
|
+
case 2:
|
|
36
|
+
return 2;
|
|
37
|
+
default:
|
|
38
|
+
throw new Error("Invalid chroma_format_idc");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 6.2 Source, decoded and output picture formats
|
|
44
|
+
*/
|
|
45
|
+
export function getSubHeightC(chroma_format_idc: number) {
|
|
46
|
+
switch (chroma_format_idc) {
|
|
47
|
+
case 0:
|
|
48
|
+
case 2:
|
|
49
|
+
case 3:
|
|
50
|
+
return 1;
|
|
51
|
+
case 1:
|
|
52
|
+
return 2;
|
|
53
|
+
default:
|
|
54
|
+
throw new Error("Invalid chroma_format_idc");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 7.3.1.1 General NAL unit syntax
|
|
60
|
+
*/
|
|
61
|
+
export function parseNaluHeader(nalu: Uint8Array) {
|
|
62
|
+
const reader = new NaluSodbBitReader(nalu);
|
|
63
|
+
if (reader.next() !== 0) {
|
|
64
|
+
throw new Error("Invalid NALU header");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const nal_unit_type = reader.read(6);
|
|
68
|
+
const nuh_layer_id = reader.read(6);
|
|
69
|
+
const nuh_temporal_id_plus1 = reader.read(3);
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
nal_unit_type,
|
|
73
|
+
nuh_layer_id,
|
|
74
|
+
nuh_temporal_id_plus1,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type NaluHeader = ReturnType<typeof parseNaluHeader>;
|
|
79
|
+
|
|
80
|
+
export interface NaluRaw extends NaluHeader {
|
|
81
|
+
data: Uint8Array;
|
|
82
|
+
rbsp: Uint8Array;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 7.3.2.1 Video parameter set RBSP syntax
|
|
87
|
+
*/
|
|
88
|
+
export function parseVideoParameterSet(nalu: Uint8Array) {
|
|
89
|
+
const reader = new NaluSodbBitReader(nalu);
|
|
90
|
+
|
|
91
|
+
const vps_video_parameter_set_id = reader.read(4);
|
|
92
|
+
const vps_base_layer_internal_flag = !!reader.next();
|
|
93
|
+
const vps_base_layer_available_flag = !!reader.next();
|
|
94
|
+
const vps_max_layers_minus1 = reader.read(6);
|
|
95
|
+
const vps_max_sub_layers_minus1 = reader.read(3);
|
|
96
|
+
const vps_temporal_id_nesting_flag = !!reader.next();
|
|
97
|
+
reader.skip(16);
|
|
98
|
+
|
|
99
|
+
const profileTierLevel = parseProfileTierLevel(
|
|
100
|
+
reader,
|
|
101
|
+
true,
|
|
102
|
+
vps_max_sub_layers_minus1,
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const vps_sub_layer_ordering_info_present_flag = !!reader.next();
|
|
106
|
+
const vps_max_dec_pic_buffering_minus1: number[] = [];
|
|
107
|
+
const vps_max_num_reorder_pics: number[] = [];
|
|
108
|
+
const vps_max_latency_increase_plus1: number[] = [];
|
|
109
|
+
for (
|
|
110
|
+
let i = vps_sub_layer_ordering_info_present_flag
|
|
111
|
+
? 0
|
|
112
|
+
: vps_max_sub_layers_minus1;
|
|
113
|
+
i <= vps_max_sub_layers_minus1;
|
|
114
|
+
i += 1
|
|
115
|
+
) {
|
|
116
|
+
vps_max_dec_pic_buffering_minus1[i] =
|
|
117
|
+
reader.decodeExponentialGolombNumber();
|
|
118
|
+
vps_max_num_reorder_pics[i] = reader.decodeExponentialGolombNumber();
|
|
119
|
+
vps_max_latency_increase_plus1[i] =
|
|
120
|
+
reader.decodeExponentialGolombNumber();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const vps_max_layer_id = reader.read(6);
|
|
124
|
+
const vps_num_layer_sets_minus1 = reader.decodeExponentialGolombNumber();
|
|
125
|
+
const layer_id_included_flag: boolean[][] = [];
|
|
126
|
+
for (let i = 1; i <= vps_num_layer_sets_minus1; i += 1) {
|
|
127
|
+
layer_id_included_flag[i] = [];
|
|
128
|
+
for (let j = 0; j <= vps_max_layer_id; j += 1) {
|
|
129
|
+
layer_id_included_flag[i]![j] = !!reader.next();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const vps_timing_info_present_flag = !!reader.next();
|
|
134
|
+
let vps_num_units_in_tick: number | undefined;
|
|
135
|
+
let vps_time_scale: number | undefined;
|
|
136
|
+
let vps_poc_proportional_to_timing_flag: boolean | undefined;
|
|
137
|
+
let vps_num_ticks_poc_diff_one_minus1: number | undefined;
|
|
138
|
+
let vps_num_hrd_parameters: number | undefined;
|
|
139
|
+
let hrd_layer_set_idx: number[] | undefined;
|
|
140
|
+
let cprms_present_flag: boolean[] | undefined;
|
|
141
|
+
let hrdParameters: HrdParameters[] | undefined;
|
|
142
|
+
if (vps_timing_info_present_flag) {
|
|
143
|
+
vps_num_units_in_tick = reader.read(32);
|
|
144
|
+
vps_time_scale = reader.read(32);
|
|
145
|
+
|
|
146
|
+
vps_poc_proportional_to_timing_flag = !!reader.next();
|
|
147
|
+
if (vps_poc_proportional_to_timing_flag) {
|
|
148
|
+
vps_num_ticks_poc_diff_one_minus1 =
|
|
149
|
+
reader.decodeExponentialGolombNumber();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
vps_num_hrd_parameters = reader.decodeExponentialGolombNumber();
|
|
153
|
+
|
|
154
|
+
hrd_layer_set_idx = [];
|
|
155
|
+
cprms_present_flag = [true];
|
|
156
|
+
hrdParameters = [];
|
|
157
|
+
for (let i = 0; i < vps_num_hrd_parameters; i += 1) {
|
|
158
|
+
hrd_layer_set_idx[i] = reader.decodeExponentialGolombNumber();
|
|
159
|
+
if (i > 0) {
|
|
160
|
+
cprms_present_flag[i] = !!reader.next();
|
|
161
|
+
}
|
|
162
|
+
hrdParameters[i] = parseHrdParameters(
|
|
163
|
+
reader,
|
|
164
|
+
cprms_present_flag[i]!,
|
|
165
|
+
vps_max_sub_layers_minus1,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const vps_extension_flag = !!reader.next();
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
vps_video_parameter_set_id,
|
|
174
|
+
vps_base_layer_internal_flag,
|
|
175
|
+
vps_base_layer_available_flag,
|
|
176
|
+
vps_max_layers_minus1,
|
|
177
|
+
vps_max_sub_layers_minus1,
|
|
178
|
+
vps_temporal_id_nesting_flag,
|
|
179
|
+
profileTierLevel,
|
|
180
|
+
vps_sub_layer_ordering_info_present_flag,
|
|
181
|
+
vps_max_dec_pic_buffering_minus1,
|
|
182
|
+
vps_max_num_reorder_pics,
|
|
183
|
+
vps_max_latency_increase_plus1,
|
|
184
|
+
vps_max_layer_id,
|
|
185
|
+
vps_num_layer_sets_minus1,
|
|
186
|
+
layer_id_included_flag,
|
|
187
|
+
vps_timing_info_present_flag,
|
|
188
|
+
vps_num_units_in_tick,
|
|
189
|
+
vps_time_scale,
|
|
190
|
+
vps_poc_proportional_to_timing_flag,
|
|
191
|
+
vps_num_ticks_poc_diff_one_minus1,
|
|
192
|
+
vps_num_hrd_parameters,
|
|
193
|
+
hrd_layer_set_idx,
|
|
194
|
+
cprms_present_flag,
|
|
195
|
+
hrdParameters,
|
|
196
|
+
vps_extension_flag,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export type SubLayerHrdParameters = ReturnType<
|
|
201
|
+
typeof parseSubLayerHrdParameters
|
|
202
|
+
>;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* 7.3.2.2.1 General sequence parameter set RBSP syntax
|
|
206
|
+
*/
|
|
207
|
+
export function parseSequenceParameterSet(nalu: Uint8Array) {
|
|
208
|
+
const reader = new NaluSodbBitReader(nalu);
|
|
209
|
+
|
|
210
|
+
const sps_video_parameter_set_id = reader.read(4);
|
|
211
|
+
const sps_max_sub_layers_minus1 = reader.read(3);
|
|
212
|
+
const sps_temporal_id_nesting_flag = !!reader.next();
|
|
213
|
+
|
|
214
|
+
const profileTierLevel = parseProfileTierLevel(
|
|
215
|
+
reader,
|
|
216
|
+
true,
|
|
217
|
+
sps_max_sub_layers_minus1,
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
const sps_seq_parameter_set_id = reader.decodeExponentialGolombNumber();
|
|
221
|
+
const chroma_format_idc = reader.decodeExponentialGolombNumber();
|
|
222
|
+
let separate_colour_plane_flag: boolean | undefined;
|
|
223
|
+
if (chroma_format_idc === 3) {
|
|
224
|
+
separate_colour_plane_flag = !!reader.next();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const pic_width_in_luma_samples = reader.decodeExponentialGolombNumber();
|
|
228
|
+
const pic_height_in_luma_samples = reader.decodeExponentialGolombNumber();
|
|
229
|
+
|
|
230
|
+
const conformance_window_flag = !!reader.next();
|
|
231
|
+
let conf_win_left_offset: number | undefined;
|
|
232
|
+
let conf_win_right_offset: number | undefined;
|
|
233
|
+
let conf_win_top_offset: number | undefined;
|
|
234
|
+
let conf_win_bottom_offset: number | undefined;
|
|
235
|
+
if (conformance_window_flag) {
|
|
236
|
+
conf_win_left_offset = reader.decodeExponentialGolombNumber();
|
|
237
|
+
conf_win_right_offset = reader.decodeExponentialGolombNumber();
|
|
238
|
+
conf_win_top_offset = reader.decodeExponentialGolombNumber();
|
|
239
|
+
conf_win_bottom_offset = reader.decodeExponentialGolombNumber();
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const bit_depth_luma_minus8 = reader.decodeExponentialGolombNumber();
|
|
243
|
+
const bit_depth_chroma_minus8 = reader.decodeExponentialGolombNumber();
|
|
244
|
+
const log2_max_pic_order_cnt_lsb_minus4 =
|
|
245
|
+
reader.decodeExponentialGolombNumber();
|
|
246
|
+
|
|
247
|
+
const sps_max_dec_pic_buffering_minus1: number[] = [];
|
|
248
|
+
const sps_max_num_reorder_pics: number[] = [];
|
|
249
|
+
const sps_max_latency_increase_plus1: number[] = [];
|
|
250
|
+
const sps_sub_layer_ordering_info_present_flag = !!reader.next();
|
|
251
|
+
for (
|
|
252
|
+
let i = sps_sub_layer_ordering_info_present_flag
|
|
253
|
+
? 0
|
|
254
|
+
: sps_max_sub_layers_minus1;
|
|
255
|
+
i <= sps_max_sub_layers_minus1;
|
|
256
|
+
i += 1
|
|
257
|
+
) {
|
|
258
|
+
sps_max_dec_pic_buffering_minus1[i] =
|
|
259
|
+
reader.decodeExponentialGolombNumber();
|
|
260
|
+
sps_max_num_reorder_pics[i] = reader.decodeExponentialGolombNumber();
|
|
261
|
+
sps_max_latency_increase_plus1[i] =
|
|
262
|
+
reader.decodeExponentialGolombNumber();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const log2_min_luma_coding_block_size_minus3 =
|
|
266
|
+
reader.decodeExponentialGolombNumber();
|
|
267
|
+
const log2_diff_max_min_luma_coding_block_size =
|
|
268
|
+
reader.decodeExponentialGolombNumber();
|
|
269
|
+
const log2_min_luma_transform_block_size_minus2 =
|
|
270
|
+
reader.decodeExponentialGolombNumber();
|
|
271
|
+
const log2_diff_max_min_luma_transform_block_size =
|
|
272
|
+
reader.decodeExponentialGolombNumber();
|
|
273
|
+
const max_transform_hierarchy_depth_inter =
|
|
274
|
+
reader.decodeExponentialGolombNumber();
|
|
275
|
+
const max_transform_hierarchy_depth_intra =
|
|
276
|
+
reader.decodeExponentialGolombNumber();
|
|
277
|
+
|
|
278
|
+
const scaling_list_enabled_flag = !!reader.next();
|
|
279
|
+
let sps_scaling_list_data_present_flag: boolean | undefined;
|
|
280
|
+
let scalingListData: number[][][] | undefined;
|
|
281
|
+
if (scaling_list_enabled_flag) {
|
|
282
|
+
sps_scaling_list_data_present_flag = !!reader.next();
|
|
283
|
+
if (sps_scaling_list_data_present_flag) {
|
|
284
|
+
scalingListData = parseScalingListData(reader);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const amp_enabled_flag = !!reader.next();
|
|
289
|
+
const sample_adaptive_offset_enabled_flag = !!reader.next();
|
|
290
|
+
const pcm_enabled_flag = !!reader.next();
|
|
291
|
+
let pcm_sample_bit_depth_luma_minus1: number | undefined;
|
|
292
|
+
let pcm_sample_bit_depth_chroma_minus1: number | undefined;
|
|
293
|
+
let log2_min_pcm_luma_coding_block_size_minus3: number | undefined;
|
|
294
|
+
let log2_diff_max_min_pcm_luma_coding_block_size: number | undefined;
|
|
295
|
+
let pcm_loop_filter_disabled_flag: boolean | undefined;
|
|
296
|
+
if (pcm_enabled_flag) {
|
|
297
|
+
pcm_sample_bit_depth_luma_minus1 = reader.read(4);
|
|
298
|
+
pcm_sample_bit_depth_chroma_minus1 = reader.read(4);
|
|
299
|
+
log2_min_pcm_luma_coding_block_size_minus3 =
|
|
300
|
+
reader.decodeExponentialGolombNumber();
|
|
301
|
+
log2_diff_max_min_pcm_luma_coding_block_size =
|
|
302
|
+
reader.decodeExponentialGolombNumber();
|
|
303
|
+
pcm_loop_filter_disabled_flag = !!reader.next();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const num_short_term_ref_pic_sets = reader.decodeExponentialGolombNumber();
|
|
307
|
+
const shortTermRefPicSets: ShortTermReferencePictureSet[] = [];
|
|
308
|
+
for (let i = 0; i < num_short_term_ref_pic_sets; i += 1) {
|
|
309
|
+
shortTermRefPicSets[i] = parseShortTermReferencePictureSet(
|
|
310
|
+
reader,
|
|
311
|
+
i,
|
|
312
|
+
num_short_term_ref_pic_sets,
|
|
313
|
+
shortTermRefPicSets,
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const long_term_ref_pics_present_flag = !!reader.next();
|
|
318
|
+
let num_long_term_ref_pics_sps: number | undefined;
|
|
319
|
+
let lt_ref_pic_poc_lsb_sps: number[] | undefined;
|
|
320
|
+
let used_by_curr_pic_lt_sps_flag: boolean[] | undefined;
|
|
321
|
+
if (long_term_ref_pics_present_flag) {
|
|
322
|
+
num_long_term_ref_pics_sps = reader.decodeExponentialGolombNumber();
|
|
323
|
+
lt_ref_pic_poc_lsb_sps = [];
|
|
324
|
+
used_by_curr_pic_lt_sps_flag = [];
|
|
325
|
+
for (let i = 0; i < num_long_term_ref_pics_sps; i += 1) {
|
|
326
|
+
lt_ref_pic_poc_lsb_sps[i] = reader.read(
|
|
327
|
+
log2_max_pic_order_cnt_lsb_minus4 + 4,
|
|
328
|
+
);
|
|
329
|
+
used_by_curr_pic_lt_sps_flag[i] = !!reader.next();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const sps_temporal_mvp_enabled_flag = !!reader.next();
|
|
334
|
+
const strong_intra_smoothing_enabled_flag = !!reader.next();
|
|
335
|
+
const vui_parameters_present_flag = !!reader.next();
|
|
336
|
+
let vuiParameters: VuiParameters | undefined;
|
|
337
|
+
if (vui_parameters_present_flag) {
|
|
338
|
+
vuiParameters = parseVuiParameters(reader, sps_max_sub_layers_minus1);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const sps_extension_present_flag = !!reader.next();
|
|
342
|
+
let sps_range_extension_flag: boolean | undefined;
|
|
343
|
+
let sps_multilayer_extension_flag: boolean | undefined;
|
|
344
|
+
let sps_3d_extension_flag: boolean | undefined;
|
|
345
|
+
let sps_scc_extension_flag: boolean | undefined;
|
|
346
|
+
let sps_extension_4bits: number | undefined;
|
|
347
|
+
if (sps_extension_present_flag) {
|
|
348
|
+
sps_range_extension_flag = !!reader.next();
|
|
349
|
+
sps_multilayer_extension_flag = !!reader.next();
|
|
350
|
+
sps_3d_extension_flag = !!reader.next();
|
|
351
|
+
sps_scc_extension_flag = !!reader.next();
|
|
352
|
+
sps_extension_4bits = reader.read(4);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (sps_range_extension_flag) {
|
|
356
|
+
throw new Error("Not implemented");
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
let spsMultilayerExtension: SpsMultilayerExtension | undefined;
|
|
360
|
+
if (sps_multilayer_extension_flag) {
|
|
361
|
+
spsMultilayerExtension = parseSpsMultilayerExtension(reader);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
let sps3dExtension: Sps3dExtension | undefined;
|
|
365
|
+
if (sps_3d_extension_flag) {
|
|
366
|
+
sps3dExtension = parseSps3dExtension(reader);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (sps_scc_extension_flag) {
|
|
370
|
+
throw new Error("Not implemented");
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
let sps_extension_data_flag: boolean[] | undefined;
|
|
374
|
+
if (sps_extension_4bits) {
|
|
375
|
+
sps_extension_data_flag = [];
|
|
376
|
+
let i = 0;
|
|
377
|
+
while (!reader.ended) {
|
|
378
|
+
sps_extension_data_flag[i] = !!reader.next();
|
|
379
|
+
i += 1;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return {
|
|
384
|
+
sps_video_parameter_set_id,
|
|
385
|
+
sps_max_sub_layers_minus1,
|
|
386
|
+
sps_temporal_id_nesting_flag,
|
|
387
|
+
profileTierLevel,
|
|
388
|
+
sps_seq_parameter_set_id,
|
|
389
|
+
chroma_format_idc,
|
|
390
|
+
separate_colour_plane_flag,
|
|
391
|
+
pic_width_in_luma_samples,
|
|
392
|
+
pic_height_in_luma_samples,
|
|
393
|
+
conformance_window_flag,
|
|
394
|
+
conf_win_left_offset,
|
|
395
|
+
conf_win_right_offset,
|
|
396
|
+
conf_win_top_offset,
|
|
397
|
+
conf_win_bottom_offset,
|
|
398
|
+
bit_depth_luma_minus8,
|
|
399
|
+
bit_depth_chroma_minus8,
|
|
400
|
+
log2_max_pic_order_cnt_lsb_minus4,
|
|
401
|
+
sps_sub_layer_ordering_info_present_flag,
|
|
402
|
+
sps_max_dec_pic_buffering_minus1,
|
|
403
|
+
sps_max_num_reorder_pics,
|
|
404
|
+
sps_max_latency_increase_plus1,
|
|
405
|
+
log2_min_luma_coding_block_size_minus3,
|
|
406
|
+
log2_diff_max_min_luma_coding_block_size,
|
|
407
|
+
log2_min_luma_transform_block_size_minus2,
|
|
408
|
+
log2_diff_max_min_luma_transform_block_size,
|
|
409
|
+
max_transform_hierarchy_depth_inter,
|
|
410
|
+
max_transform_hierarchy_depth_intra,
|
|
411
|
+
scaling_list_enabled_flag,
|
|
412
|
+
sps_scaling_list_data_present_flag,
|
|
413
|
+
scalingListData,
|
|
414
|
+
amp_enabled_flag,
|
|
415
|
+
sample_adaptive_offset_enabled_flag,
|
|
416
|
+
pcm_enabled_flag,
|
|
417
|
+
pcm_sample_bit_depth_luma_minus1,
|
|
418
|
+
pcm_sample_bit_depth_chroma_minus1,
|
|
419
|
+
log2_min_pcm_luma_coding_block_size_minus3,
|
|
420
|
+
log2_diff_max_min_pcm_luma_coding_block_size,
|
|
421
|
+
pcm_loop_filter_disabled_flag,
|
|
422
|
+
num_short_term_ref_pic_sets,
|
|
423
|
+
shortTermRefPicSets,
|
|
424
|
+
long_term_ref_pics_present_flag,
|
|
425
|
+
num_long_term_ref_pics_sps,
|
|
426
|
+
lt_ref_pic_poc_lsb_sps,
|
|
427
|
+
used_by_curr_pic_lt_sps_flag,
|
|
428
|
+
sps_temporal_mvp_enabled_flag,
|
|
429
|
+
strong_intra_smoothing_enabled_flag,
|
|
430
|
+
vui_parameters_present_flag,
|
|
431
|
+
vuiParameters,
|
|
432
|
+
sps_extension_present_flag,
|
|
433
|
+
sps_range_extension_flag,
|
|
434
|
+
sps_multilayer_extension_flag,
|
|
435
|
+
sps_3d_extension_flag,
|
|
436
|
+
sps_scc_extension_flag,
|
|
437
|
+
sps_extension_4bits,
|
|
438
|
+
spsMultilayerExtension,
|
|
439
|
+
sps3dExtension,
|
|
440
|
+
sps_extension_data_flag,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* 7.3.3 Profile, tier and level syntax
|
|
446
|
+
*
|
|
447
|
+
* Common part between general_profile_tier_level and
|
|
448
|
+
* sub_layer_profile_tier_level
|
|
449
|
+
*/
|
|
450
|
+
function parseProfileTier(reader: NaluSodbBitReader) {
|
|
451
|
+
const profile_space = reader.read(2);
|
|
452
|
+
const tier_flag = !!reader.next();
|
|
453
|
+
const profile_idc = reader.read(5);
|
|
454
|
+
|
|
455
|
+
const profileCompatibilitySet = reader.peekBytes(4);
|
|
456
|
+
const profile_compatibility_flag: boolean[] = [];
|
|
457
|
+
for (let j = 0; j < 32; j += 1) {
|
|
458
|
+
profile_compatibility_flag[j] = !!reader.next();
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const constraintSet = reader.peekBytes(6);
|
|
462
|
+
|
|
463
|
+
const progressive_source_flag = !!reader.next();
|
|
464
|
+
const interlaced_source_flag = !!reader.next();
|
|
465
|
+
const non_packed_constraint_flag = !!reader.next();
|
|
466
|
+
const frame_only_constraint_flag = !!reader.next();
|
|
467
|
+
|
|
468
|
+
let max_12bit_constraint_flag: boolean | undefined;
|
|
469
|
+
let max_10bit_constraint_flag: boolean | undefined;
|
|
470
|
+
let max_8bit_constraint_flag: boolean | undefined;
|
|
471
|
+
let max_422chroma_constraint_flag: boolean | undefined;
|
|
472
|
+
let max_420chroma_constraint_flag: boolean | undefined;
|
|
473
|
+
let max_monochrome_constraint_flag: boolean | undefined;
|
|
474
|
+
let intra_constraint_flag: boolean | undefined;
|
|
475
|
+
let one_picture_only_constraint_flag: boolean | undefined;
|
|
476
|
+
let lower_bit_rate_constraint_flag: boolean | undefined;
|
|
477
|
+
let max_14bit_constraint_flag: boolean | undefined;
|
|
478
|
+
if (
|
|
479
|
+
profile_idc === 4 ||
|
|
480
|
+
profile_compatibility_flag[4] ||
|
|
481
|
+
profile_idc === 5 ||
|
|
482
|
+
profile_compatibility_flag[5] ||
|
|
483
|
+
profile_idc === 6 ||
|
|
484
|
+
profile_compatibility_flag[6] ||
|
|
485
|
+
profile_idc === 7 ||
|
|
486
|
+
profile_compatibility_flag[7] ||
|
|
487
|
+
profile_idc === 8 ||
|
|
488
|
+
profile_compatibility_flag[8] ||
|
|
489
|
+
profile_idc === 9 ||
|
|
490
|
+
profile_compatibility_flag[9] ||
|
|
491
|
+
profile_idc === 10 ||
|
|
492
|
+
profile_compatibility_flag[10] ||
|
|
493
|
+
profile_idc === 11 ||
|
|
494
|
+
profile_compatibility_flag[11]
|
|
495
|
+
) {
|
|
496
|
+
max_12bit_constraint_flag = !!reader.next();
|
|
497
|
+
max_10bit_constraint_flag = !!reader.next();
|
|
498
|
+
max_8bit_constraint_flag = !!reader.next();
|
|
499
|
+
max_422chroma_constraint_flag = !!reader.next();
|
|
500
|
+
max_420chroma_constraint_flag = !!reader.next();
|
|
501
|
+
max_monochrome_constraint_flag = !!reader.next();
|
|
502
|
+
intra_constraint_flag = !!reader.next();
|
|
503
|
+
one_picture_only_constraint_flag = !!reader.next();
|
|
504
|
+
lower_bit_rate_constraint_flag = !!reader.next();
|
|
505
|
+
if (
|
|
506
|
+
profile_idc === 5 ||
|
|
507
|
+
profile_compatibility_flag[5] ||
|
|
508
|
+
profile_idc === 9 ||
|
|
509
|
+
profile_compatibility_flag[9] ||
|
|
510
|
+
profile_idc === 10 ||
|
|
511
|
+
profile_compatibility_flag[10] ||
|
|
512
|
+
profile_idc === 11 ||
|
|
513
|
+
profile_compatibility_flag[11]
|
|
514
|
+
) {
|
|
515
|
+
max_14bit_constraint_flag = !!reader.next();
|
|
516
|
+
reader.skip(33);
|
|
517
|
+
} else {
|
|
518
|
+
reader.skip(34);
|
|
519
|
+
}
|
|
520
|
+
} else if (profile_idc === 2 || profile_compatibility_flag[2]) {
|
|
521
|
+
reader.skip(7);
|
|
522
|
+
one_picture_only_constraint_flag = !!reader.next();
|
|
523
|
+
reader.skip(35);
|
|
524
|
+
} else {
|
|
525
|
+
reader.skip(43);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
let inbld_flag: boolean | undefined;
|
|
529
|
+
if (
|
|
530
|
+
profile_idc === 1 ||
|
|
531
|
+
profile_compatibility_flag[1] ||
|
|
532
|
+
profile_idc === 2 ||
|
|
533
|
+
profile_compatibility_flag[2] ||
|
|
534
|
+
profile_idc === 3 ||
|
|
535
|
+
profile_compatibility_flag[3] ||
|
|
536
|
+
profile_idc === 4 ||
|
|
537
|
+
profile_compatibility_flag[4] ||
|
|
538
|
+
profile_idc === 5 ||
|
|
539
|
+
profile_compatibility_flag[5] ||
|
|
540
|
+
profile_idc === 9 ||
|
|
541
|
+
profile_compatibility_flag[9] ||
|
|
542
|
+
profile_idc === 11 ||
|
|
543
|
+
profile_compatibility_flag[11]
|
|
544
|
+
) {
|
|
545
|
+
inbld_flag = !!reader.next();
|
|
546
|
+
} else {
|
|
547
|
+
reader.skip(1);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
return {
|
|
551
|
+
profile_space,
|
|
552
|
+
tier_flag,
|
|
553
|
+
profile_idc,
|
|
554
|
+
profileCompatibilitySet,
|
|
555
|
+
profile_compatibility_flag,
|
|
556
|
+
constraintSet,
|
|
557
|
+
progressive_source_flag,
|
|
558
|
+
interlaced_source_flag,
|
|
559
|
+
non_packed_constraint_flag,
|
|
560
|
+
frame_only_constraint_flag,
|
|
561
|
+
max_12bit_constraint_flag,
|
|
562
|
+
max_10bit_constraint_flag,
|
|
563
|
+
max_8bit_constraint_flag,
|
|
564
|
+
max_422chroma_constraint_flag,
|
|
565
|
+
max_420chroma_constraint_flag,
|
|
566
|
+
max_monochrome_constraint_flag,
|
|
567
|
+
intra_constraint_flag,
|
|
568
|
+
one_picture_only_constraint_flag,
|
|
569
|
+
lower_bit_rate_constraint_flag,
|
|
570
|
+
max_14bit_constraint_flag,
|
|
571
|
+
inbld_flag,
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
export type ProfileTier = ReturnType<typeof parseProfileTier>;
|
|
576
|
+
|
|
577
|
+
export interface ProfileTierLevel {
|
|
578
|
+
generalProfileTier: ProfileTier | undefined;
|
|
579
|
+
general_level_idc: number;
|
|
580
|
+
sub_layer_profile_present_flag: boolean[];
|
|
581
|
+
sub_layer_level_present_flag: boolean[];
|
|
582
|
+
subLayerProfileTier: ProfileTier[];
|
|
583
|
+
sub_layer_level_idc: number[];
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* 7.3.3 Profile, tier and level syntax
|
|
588
|
+
*/
|
|
589
|
+
function parseProfileTierLevel(
|
|
590
|
+
reader: NaluSodbBitReader,
|
|
591
|
+
profilePresentFlag: true,
|
|
592
|
+
maxNumSubLayersMinus1: number,
|
|
593
|
+
): ProfileTierLevel & { generalProfileTier: ProfileTier };
|
|
594
|
+
function parseProfileTierLevel(
|
|
595
|
+
reader: NaluSodbBitReader,
|
|
596
|
+
profilePresentFlag: false,
|
|
597
|
+
maxNumSubLayersMinus1: number,
|
|
598
|
+
): ProfileTierLevel & { generalProfileTier: undefined };
|
|
599
|
+
function parseProfileTierLevel(
|
|
600
|
+
reader: NaluSodbBitReader,
|
|
601
|
+
profilePresentFlag: boolean,
|
|
602
|
+
maxNumSubLayersMinus1: number,
|
|
603
|
+
): ProfileTierLevel;
|
|
604
|
+
function parseProfileTierLevel(
|
|
605
|
+
reader: NaluSodbBitReader,
|
|
606
|
+
profilePresentFlag: boolean,
|
|
607
|
+
maxNumSubLayersMinus1: number,
|
|
608
|
+
): ProfileTierLevel {
|
|
609
|
+
let generalProfileTier: ProfileTier | undefined;
|
|
610
|
+
if (profilePresentFlag) {
|
|
611
|
+
generalProfileTier = parseProfileTier(reader);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
const general_level_idc = reader.read(8);
|
|
615
|
+
|
|
616
|
+
const sub_layer_profile_present_flag: boolean[] = [];
|
|
617
|
+
const sub_layer_level_present_flag: boolean[] = [];
|
|
618
|
+
for (let i = 0; i < maxNumSubLayersMinus1; i += 1) {
|
|
619
|
+
sub_layer_profile_present_flag[i] = !!reader.next();
|
|
620
|
+
sub_layer_level_present_flag[i] = !!reader.next();
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
if (maxNumSubLayersMinus1 > 0) {
|
|
624
|
+
for (let i = maxNumSubLayersMinus1; i < 8; i += 1) {
|
|
625
|
+
reader.read(2);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const subLayerProfileTier: ProfileTier[] = [];
|
|
630
|
+
const sub_layer_level_idc: number[] = [];
|
|
631
|
+
for (let i = 0; i < maxNumSubLayersMinus1; i += 1) {
|
|
632
|
+
if (sub_layer_profile_present_flag[i]) {
|
|
633
|
+
subLayerProfileTier[i] = parseProfileTier(reader);
|
|
634
|
+
}
|
|
635
|
+
if (sub_layer_level_present_flag[i]) {
|
|
636
|
+
sub_layer_level_idc[i] = reader.read(8);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return {
|
|
641
|
+
generalProfileTier,
|
|
642
|
+
general_level_idc,
|
|
643
|
+
sub_layer_profile_present_flag,
|
|
644
|
+
sub_layer_level_present_flag,
|
|
645
|
+
subLayerProfileTier,
|
|
646
|
+
sub_layer_level_idc,
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* 7.3.4 Scaling list data syntax
|
|
652
|
+
*/
|
|
653
|
+
export function parseScalingListData(reader: NaluSodbBitReader) {
|
|
654
|
+
const scaling_list: number[][][] = [];
|
|
655
|
+
for (let sizeId = 0; sizeId < 4; sizeId += 1) {
|
|
656
|
+
scaling_list[sizeId] = [];
|
|
657
|
+
for (let matrixId = 0; matrixId < 6; matrixId += sizeId === 3 ? 3 : 1) {
|
|
658
|
+
const scaling_list_pred_mode_flag = !!reader.next();
|
|
659
|
+
if (!scaling_list_pred_mode_flag) {
|
|
660
|
+
reader.decodeExponentialGolombNumber();
|
|
661
|
+
} else {
|
|
662
|
+
let nextCoef = 8;
|
|
663
|
+
const coefNum = Math.min(64, 1 << (4 + (sizeId << 1)));
|
|
664
|
+
if (sizeId > 1) {
|
|
665
|
+
const scaling_list_dc_coef_minus8 =
|
|
666
|
+
reader.decodeExponentialGolombNumber();
|
|
667
|
+
nextCoef = scaling_list_dc_coef_minus8 + 8;
|
|
668
|
+
}
|
|
669
|
+
scaling_list[sizeId]![matrixId] = [];
|
|
670
|
+
for (let i = 0; i < coefNum; i += 1) {
|
|
671
|
+
const scaling_list_delta_coef =
|
|
672
|
+
reader.decodeExponentialGolombNumber();
|
|
673
|
+
nextCoef = (nextCoef + scaling_list_delta_coef + 256) % 256;
|
|
674
|
+
scaling_list[sizeId]![matrixId]![i] = nextCoef;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
return scaling_list;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
interface ShortTermReferencePictureSet {
|
|
683
|
+
stRpsIdx: number;
|
|
684
|
+
num_short_term_ref_pic_sets: number;
|
|
685
|
+
|
|
686
|
+
inter_ref_pic_set_prediction_flag: boolean;
|
|
687
|
+
delta_idx_minus1: number;
|
|
688
|
+
delta_rps_sign: boolean;
|
|
689
|
+
abs_delta_rps_minus1: number;
|
|
690
|
+
used_by_curr_pic_flag: boolean[];
|
|
691
|
+
use_delta_flag: boolean[];
|
|
692
|
+
num_negative_pics: number;
|
|
693
|
+
num_positive_pics: number;
|
|
694
|
+
delta_poc_s0_minus1: number[];
|
|
695
|
+
used_by_curr_pic_s0_flag: boolean[];
|
|
696
|
+
delta_poc_s1_minus1: number[];
|
|
697
|
+
used_by_curr_pic_s1_flag: boolean[];
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* 7.3.7 Short-term reference picture set syntax
|
|
702
|
+
*/
|
|
703
|
+
export function parseShortTermReferencePictureSet(
|
|
704
|
+
reader: NaluSodbBitReader,
|
|
705
|
+
stRpsIdx: number,
|
|
706
|
+
num_short_term_ref_pic_sets: number,
|
|
707
|
+
sets: ShortTermReferencePictureSet[],
|
|
708
|
+
): ShortTermReferencePictureSet {
|
|
709
|
+
let inter_ref_pic_set_prediction_flag = false;
|
|
710
|
+
if (stRpsIdx !== 0) {
|
|
711
|
+
inter_ref_pic_set_prediction_flag = !!reader.next();
|
|
712
|
+
}
|
|
713
|
+
let delta_idx_minus1 = 0;
|
|
714
|
+
let delta_rps_sign = false;
|
|
715
|
+
let abs_delta_rps_minus1 = 0;
|
|
716
|
+
const used_by_curr_pic_flag: boolean[] = [];
|
|
717
|
+
const use_delta_flag: boolean[] = [];
|
|
718
|
+
let num_negative_pics: number;
|
|
719
|
+
let num_positive_pics: number;
|
|
720
|
+
const delta_poc_s0_minus1: number[] = [];
|
|
721
|
+
const used_by_curr_pic_s0_flag: boolean[] = [];
|
|
722
|
+
const delta_poc_s1_minus1: number[] = [];
|
|
723
|
+
const used_by_curr_pic_s1_flag: boolean[] = [];
|
|
724
|
+
if (inter_ref_pic_set_prediction_flag) {
|
|
725
|
+
if (stRpsIdx === num_short_term_ref_pic_sets) {
|
|
726
|
+
delta_idx_minus1 = reader.decodeExponentialGolombNumber();
|
|
727
|
+
}
|
|
728
|
+
delta_rps_sign = !!reader.next();
|
|
729
|
+
abs_delta_rps_minus1 = reader.decodeExponentialGolombNumber();
|
|
730
|
+
const RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);
|
|
731
|
+
const RefRps = sets[RefRpsIdx]!;
|
|
732
|
+
const NumDeltaPocs_RefRpsIdx =
|
|
733
|
+
RefRps.num_negative_pics + RefRps.num_positive_pics;
|
|
734
|
+
for (let j = 0; j <= NumDeltaPocs_RefRpsIdx; j += 1) {
|
|
735
|
+
used_by_curr_pic_flag[j] = !!reader.next();
|
|
736
|
+
if (!used_by_curr_pic_flag[j]!) {
|
|
737
|
+
use_delta_flag[j] = !!reader.next();
|
|
738
|
+
} else {
|
|
739
|
+
use_delta_flag[j] = true;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
const DeltaRps =
|
|
744
|
+
(1 - 2 * Number(delta_rps_sign)) * (abs_delta_rps_minus1 + 1);
|
|
745
|
+
|
|
746
|
+
const RefPocS0: number[] = [];
|
|
747
|
+
const RefPocS1: number[] = [];
|
|
748
|
+
const pocS0: number[] = [];
|
|
749
|
+
const pocS1: number[] = [];
|
|
750
|
+
|
|
751
|
+
let dPoc = 0;
|
|
752
|
+
for (let i = 0; i < RefRps.num_negative_pics; i += 1) {
|
|
753
|
+
dPoc -= RefRps.delta_poc_s0_minus1[i]! + 1;
|
|
754
|
+
RefPocS0[i] = dPoc;
|
|
755
|
+
}
|
|
756
|
+
dPoc = 0;
|
|
757
|
+
for (let i = 0; i < RefRps.num_positive_pics; i += 1) {
|
|
758
|
+
dPoc += RefRps.delta_poc_s1_minus1[i]! + 1;
|
|
759
|
+
RefPocS1[i] = dPoc;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
let i = 0;
|
|
763
|
+
if (RefRps.num_positive_pics > 0) {
|
|
764
|
+
for (let j = RefRps.num_positive_pics - 1; j >= 0; j -= 1) {
|
|
765
|
+
dPoc = RefPocS1[j]! + DeltaRps;
|
|
766
|
+
if (dPoc < 0 && use_delta_flag[RefRps.num_negative_pics + j]) {
|
|
767
|
+
pocS0[i] = dPoc;
|
|
768
|
+
used_by_curr_pic_s0_flag[i] =
|
|
769
|
+
used_by_curr_pic_flag[RefRps.num_negative_pics + j]!;
|
|
770
|
+
i += 1;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
if (DeltaRps < 0 && use_delta_flag[NumDeltaPocs_RefRpsIdx]) {
|
|
775
|
+
pocS0[i] = DeltaRps;
|
|
776
|
+
used_by_curr_pic_s0_flag[i] =
|
|
777
|
+
used_by_curr_pic_flag[NumDeltaPocs_RefRpsIdx]!;
|
|
778
|
+
i += 1;
|
|
779
|
+
}
|
|
780
|
+
for (let j = 0; j < RefRps.num_negative_pics; j += 1) {
|
|
781
|
+
dPoc = RefPocS0[j]! + DeltaRps;
|
|
782
|
+
if (dPoc < 0 && use_delta_flag[j]) {
|
|
783
|
+
pocS0[i] = dPoc;
|
|
784
|
+
used_by_curr_pic_s0_flag[i] = used_by_curr_pic_flag[j]!;
|
|
785
|
+
i += 1;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
num_negative_pics = i;
|
|
790
|
+
let prev = 0;
|
|
791
|
+
for (i = 0; i < num_negative_pics; i += 1) {
|
|
792
|
+
const current = pocS0[i]!;
|
|
793
|
+
delta_poc_s0_minus1[i] = -(current - prev - 1);
|
|
794
|
+
prev = current;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
i = 0;
|
|
798
|
+
if (RefRps.num_negative_pics > 0) {
|
|
799
|
+
for (let j = RefRps.num_negative_pics - 1; j >= 0; j -= 1) {
|
|
800
|
+
dPoc = RefPocS0[j]! + DeltaRps;
|
|
801
|
+
if (dPoc > 0 && use_delta_flag[j]) {
|
|
802
|
+
pocS1[i] = dPoc;
|
|
803
|
+
used_by_curr_pic_s1_flag[i] = used_by_curr_pic_flag[j]!;
|
|
804
|
+
i += 1;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
if (DeltaRps > 0 && use_delta_flag[NumDeltaPocs_RefRpsIdx]) {
|
|
809
|
+
pocS1[i] = DeltaRps;
|
|
810
|
+
used_by_curr_pic_s1_flag[i] =
|
|
811
|
+
used_by_curr_pic_flag[NumDeltaPocs_RefRpsIdx]!;
|
|
812
|
+
i += 1;
|
|
813
|
+
}
|
|
814
|
+
for (let j = 0; j < RefRps.num_positive_pics; j += 1) {
|
|
815
|
+
dPoc = RefPocS1[j]! + DeltaRps;
|
|
816
|
+
if (dPoc > 0 && use_delta_flag[RefRps.num_negative_pics + j]) {
|
|
817
|
+
pocS1[i] = dPoc;
|
|
818
|
+
used_by_curr_pic_s1_flag[i] =
|
|
819
|
+
used_by_curr_pic_flag[RefRps.num_negative_pics + j]!;
|
|
820
|
+
i += 1;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
num_positive_pics = i;
|
|
825
|
+
prev = 0;
|
|
826
|
+
for (i = 0; i < num_positive_pics; i += 1) {
|
|
827
|
+
const current = pocS1[i]!;
|
|
828
|
+
delta_poc_s1_minus1[i] = current - prev - 1;
|
|
829
|
+
prev = current;
|
|
830
|
+
}
|
|
831
|
+
} else {
|
|
832
|
+
num_negative_pics = reader.decodeExponentialGolombNumber();
|
|
833
|
+
num_positive_pics = reader.decodeExponentialGolombNumber();
|
|
834
|
+
for (let i = 0; i < num_negative_pics; i += 1) {
|
|
835
|
+
delta_poc_s0_minus1[i] = reader.decodeExponentialGolombNumber();
|
|
836
|
+
used_by_curr_pic_s0_flag[i] = !!reader.next();
|
|
837
|
+
}
|
|
838
|
+
for (let i = 0; i < num_positive_pics; i += 1) {
|
|
839
|
+
delta_poc_s1_minus1[i] = reader.decodeExponentialGolombNumber();
|
|
840
|
+
used_by_curr_pic_s1_flag[i] = !!reader.next();
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
return {
|
|
845
|
+
stRpsIdx,
|
|
846
|
+
num_short_term_ref_pic_sets,
|
|
847
|
+
inter_ref_pic_set_prediction_flag,
|
|
848
|
+
delta_idx_minus1,
|
|
849
|
+
delta_rps_sign,
|
|
850
|
+
abs_delta_rps_minus1,
|
|
851
|
+
used_by_curr_pic_flag,
|
|
852
|
+
use_delta_flag,
|
|
853
|
+
num_negative_pics,
|
|
854
|
+
num_positive_pics,
|
|
855
|
+
delta_poc_s0_minus1,
|
|
856
|
+
used_by_curr_pic_s0_flag,
|
|
857
|
+
delta_poc_s1_minus1,
|
|
858
|
+
used_by_curr_pic_s1_flag,
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
export const AspectRatioIndicator = {
|
|
863
|
+
Unspecified: 0,
|
|
864
|
+
Square: 1,
|
|
865
|
+
["12:11"]: 2,
|
|
866
|
+
["10:11"]: 3,
|
|
867
|
+
["16:11"]: 4,
|
|
868
|
+
["40:33"]: 5,
|
|
869
|
+
["24:11"]: 6,
|
|
870
|
+
["20:11"]: 7,
|
|
871
|
+
["32:11"]: 8,
|
|
872
|
+
["80:33"]: 9,
|
|
873
|
+
["18:11"]: 10,
|
|
874
|
+
["15:11"]: 11,
|
|
875
|
+
["64:33"]: 12,
|
|
876
|
+
["160:99"]: 13,
|
|
877
|
+
["4:3"]: 15,
|
|
878
|
+
["3:2"]: 16,
|
|
879
|
+
["2:1"]: 17,
|
|
880
|
+
Extended: 255,
|
|
881
|
+
} as const;
|
|
882
|
+
|
|
883
|
+
export type AspectRatioIndicator =
|
|
884
|
+
(typeof AspectRatioIndicator)[keyof typeof AspectRatioIndicator];
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
* E.2.1 VUI parameters syntax
|
|
888
|
+
*/
|
|
889
|
+
export function parseVuiParameters(
|
|
890
|
+
reader: NaluSodbBitReader,
|
|
891
|
+
sps_max_sub_layers_minus1: number,
|
|
892
|
+
) {
|
|
893
|
+
const aspect_ratio_info_present_flag = !!reader.next();
|
|
894
|
+
let aspect_ratio_idc: AspectRatioIndicator | undefined;
|
|
895
|
+
let sar_width: number | undefined;
|
|
896
|
+
let sar_height: number | undefined;
|
|
897
|
+
if (aspect_ratio_info_present_flag) {
|
|
898
|
+
aspect_ratio_idc = reader.read(8) as AspectRatioIndicator;
|
|
899
|
+
if (aspect_ratio_idc === AspectRatioIndicator.Extended) {
|
|
900
|
+
sar_width = reader.read(16);
|
|
901
|
+
sar_height = reader.read(16);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
const overscan_info_present_flag = !!reader.next();
|
|
906
|
+
let overscan_appropriate_flag: boolean | undefined;
|
|
907
|
+
if (overscan_info_present_flag) {
|
|
908
|
+
overscan_appropriate_flag = !!reader.next();
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
const video_signal_type_present_flag = !!reader.next();
|
|
912
|
+
let video_format: number | undefined;
|
|
913
|
+
let video_full_range_flag: boolean | undefined;
|
|
914
|
+
let colour_description_present_flag: boolean | undefined;
|
|
915
|
+
let colour_primaries: number | undefined;
|
|
916
|
+
let transfer_characteristics: number | undefined;
|
|
917
|
+
let matrix_coeffs: number | undefined;
|
|
918
|
+
if (video_signal_type_present_flag) {
|
|
919
|
+
video_format = reader.read(3);
|
|
920
|
+
video_full_range_flag = !!reader.next();
|
|
921
|
+
colour_description_present_flag = !!reader.next();
|
|
922
|
+
if (colour_description_present_flag) {
|
|
923
|
+
colour_primaries = reader.read(8);
|
|
924
|
+
transfer_characteristics = reader.read(8);
|
|
925
|
+
matrix_coeffs = reader.read(8);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
const chroma_loc_info_present_flag = !!reader.next();
|
|
930
|
+
let chroma_sample_loc_type_top_field: number | undefined;
|
|
931
|
+
let chroma_sample_loc_type_bottom_field: number | undefined;
|
|
932
|
+
if (chroma_loc_info_present_flag) {
|
|
933
|
+
chroma_sample_loc_type_top_field =
|
|
934
|
+
reader.decodeExponentialGolombNumber();
|
|
935
|
+
chroma_sample_loc_type_bottom_field =
|
|
936
|
+
reader.decodeExponentialGolombNumber();
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
const neutral_chroma_indication_flag = !!reader.next();
|
|
940
|
+
const field_seq_flag = !!reader.next();
|
|
941
|
+
const frame_field_info_present_flag = !!reader.next();
|
|
942
|
+
|
|
943
|
+
const default_display_window_flag = !!reader.next();
|
|
944
|
+
let def_disp_win_left_offset: number | undefined;
|
|
945
|
+
let def_disp_win_right_offset: number | undefined;
|
|
946
|
+
let def_disp_win_top_offset: number | undefined;
|
|
947
|
+
let def_disp_win_bottom_offset: number | undefined;
|
|
948
|
+
if (default_display_window_flag) {
|
|
949
|
+
def_disp_win_left_offset = reader.decodeExponentialGolombNumber();
|
|
950
|
+
def_disp_win_right_offset = reader.decodeExponentialGolombNumber();
|
|
951
|
+
def_disp_win_top_offset = reader.decodeExponentialGolombNumber();
|
|
952
|
+
def_disp_win_bottom_offset = reader.decodeExponentialGolombNumber();
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
const vui_timing_info_present_flag = !!reader.next();
|
|
956
|
+
let vui_num_units_in_tick: number | undefined;
|
|
957
|
+
let vui_time_scale: number | undefined;
|
|
958
|
+
let vui_poc_proportional_to_timing_flag: boolean | undefined;
|
|
959
|
+
let vui_num_ticks_poc_diff_one_minus1: number | undefined;
|
|
960
|
+
let vui_hrd_parameters_present_flag: boolean | undefined;
|
|
961
|
+
let vui_hrd_parameters: HrdParameters | undefined;
|
|
962
|
+
if (vui_timing_info_present_flag) {
|
|
963
|
+
vui_num_units_in_tick = reader.read(32);
|
|
964
|
+
vui_time_scale = reader.read(32);
|
|
965
|
+
vui_poc_proportional_to_timing_flag = !!reader.next();
|
|
966
|
+
if (vui_poc_proportional_to_timing_flag) {
|
|
967
|
+
vui_num_ticks_poc_diff_one_minus1 =
|
|
968
|
+
reader.decodeExponentialGolombNumber();
|
|
969
|
+
}
|
|
970
|
+
vui_hrd_parameters_present_flag = !!reader.next();
|
|
971
|
+
if (vui_hrd_parameters_present_flag) {
|
|
972
|
+
vui_hrd_parameters = parseHrdParameters(
|
|
973
|
+
reader,
|
|
974
|
+
true,
|
|
975
|
+
sps_max_sub_layers_minus1,
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const bitstream_restriction_flag = !!reader.next();
|
|
981
|
+
let tiles_fixed_structure_flag: boolean | undefined;
|
|
982
|
+
let motion_vectors_over_pic_boundaries_flag: boolean | undefined;
|
|
983
|
+
let restricted_ref_pic_lists_flag: boolean | undefined;
|
|
984
|
+
let min_spatial_segmentation_idc: number | undefined;
|
|
985
|
+
let max_bytes_per_pic_denom: number | undefined;
|
|
986
|
+
let max_bits_per_min_cu_denom: number | undefined;
|
|
987
|
+
let log2_max_mv_length_horizontal: number | undefined;
|
|
988
|
+
let log2_max_mv_length_vertical: number | undefined;
|
|
989
|
+
if (bitstream_restriction_flag) {
|
|
990
|
+
tiles_fixed_structure_flag = !!reader.next();
|
|
991
|
+
motion_vectors_over_pic_boundaries_flag = !!reader.next();
|
|
992
|
+
restricted_ref_pic_lists_flag = !!reader.next();
|
|
993
|
+
min_spatial_segmentation_idc = reader.decodeExponentialGolombNumber();
|
|
994
|
+
max_bytes_per_pic_denom = reader.decodeExponentialGolombNumber();
|
|
995
|
+
max_bits_per_min_cu_denom = reader.decodeExponentialGolombNumber();
|
|
996
|
+
log2_max_mv_length_horizontal = reader.decodeExponentialGolombNumber();
|
|
997
|
+
log2_max_mv_length_vertical = reader.decodeExponentialGolombNumber();
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
return {
|
|
1001
|
+
aspect_ratio_info_present_flag,
|
|
1002
|
+
aspect_ratio_idc,
|
|
1003
|
+
sar_width,
|
|
1004
|
+
sar_height,
|
|
1005
|
+
|
|
1006
|
+
overscan_info_present_flag,
|
|
1007
|
+
overscan_appropriate_flag,
|
|
1008
|
+
|
|
1009
|
+
video_signal_type_present_flag,
|
|
1010
|
+
video_format,
|
|
1011
|
+
video_full_range_flag,
|
|
1012
|
+
colour_description_present_flag,
|
|
1013
|
+
colour_primaries,
|
|
1014
|
+
transfer_characteristics,
|
|
1015
|
+
matrix_coeffs,
|
|
1016
|
+
|
|
1017
|
+
chroma_loc_info_present_flag,
|
|
1018
|
+
chroma_sample_loc_type_top_field,
|
|
1019
|
+
chroma_sample_loc_type_bottom_field,
|
|
1020
|
+
|
|
1021
|
+
neutral_chroma_indication_flag,
|
|
1022
|
+
field_seq_flag,
|
|
1023
|
+
frame_field_info_present_flag,
|
|
1024
|
+
|
|
1025
|
+
default_display_window_flag,
|
|
1026
|
+
def_disp_win_left_offset,
|
|
1027
|
+
def_disp_win_right_offset,
|
|
1028
|
+
def_disp_win_top_offset,
|
|
1029
|
+
def_disp_win_bottom_offset,
|
|
1030
|
+
|
|
1031
|
+
vui_timing_info_present_flag,
|
|
1032
|
+
vui_num_units_in_tick,
|
|
1033
|
+
vui_time_scale,
|
|
1034
|
+
vui_poc_proportional_to_timing_flag,
|
|
1035
|
+
vui_num_ticks_poc_diff_one_minus1,
|
|
1036
|
+
vui_hrd_parameters_present_flag,
|
|
1037
|
+
vui_hrd_parameters,
|
|
1038
|
+
|
|
1039
|
+
bitstream_restriction_flag,
|
|
1040
|
+
tiles_fixed_structure_flag,
|
|
1041
|
+
motion_vectors_over_pic_boundaries_flag,
|
|
1042
|
+
restricted_ref_pic_lists_flag,
|
|
1043
|
+
min_spatial_segmentation_idc,
|
|
1044
|
+
max_bytes_per_pic_denom,
|
|
1045
|
+
max_bits_per_min_cu_denom,
|
|
1046
|
+
log2_max_mv_length_horizontal,
|
|
1047
|
+
log2_max_mv_length_vertical,
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
export type VuiParameters = ReturnType<typeof parseVuiParameters>;
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* E.2.2 HRD parameters syntax
|
|
1055
|
+
*/
|
|
1056
|
+
export function parseHrdParameters(
|
|
1057
|
+
reader: NaluSodbBitReader,
|
|
1058
|
+
commonInfPresentFlag: boolean,
|
|
1059
|
+
maxNumSubLayersMinus1: number,
|
|
1060
|
+
) {
|
|
1061
|
+
let nal_hrd_parameters_present_flag: boolean | undefined;
|
|
1062
|
+
let vcl_hrd_parameters_present_flag: boolean | undefined;
|
|
1063
|
+
let sub_pic_hrd_params_present_flag: boolean | undefined;
|
|
1064
|
+
let tick_divisor_minus2: number | undefined;
|
|
1065
|
+
let du_cpb_removal_delay_increment_length_minus1: number | undefined;
|
|
1066
|
+
let sub_pic_cpb_params_in_pic_timing_sei_flag: boolean | undefined;
|
|
1067
|
+
let dpb_output_delay_du_length_minus1: number | undefined;
|
|
1068
|
+
let bit_rate_scale: number | undefined;
|
|
1069
|
+
let cpb_size_scale: number | undefined;
|
|
1070
|
+
let cpb_size_du_scale: number | undefined;
|
|
1071
|
+
let initial_cpb_removal_delay_length_minus1: number | undefined;
|
|
1072
|
+
let au_cpb_removal_delay_length_minus1: number | undefined;
|
|
1073
|
+
let dpb_output_delay_length_minus1: number | undefined;
|
|
1074
|
+
if (commonInfPresentFlag) {
|
|
1075
|
+
nal_hrd_parameters_present_flag = !!reader.next();
|
|
1076
|
+
vcl_hrd_parameters_present_flag = !!reader.next();
|
|
1077
|
+
if (
|
|
1078
|
+
nal_hrd_parameters_present_flag ||
|
|
1079
|
+
vcl_hrd_parameters_present_flag
|
|
1080
|
+
) {
|
|
1081
|
+
sub_pic_hrd_params_present_flag = !!reader.next();
|
|
1082
|
+
if (sub_pic_hrd_params_present_flag) {
|
|
1083
|
+
tick_divisor_minus2 = reader.read(8);
|
|
1084
|
+
du_cpb_removal_delay_increment_length_minus1 = reader.read(5);
|
|
1085
|
+
sub_pic_cpb_params_in_pic_timing_sei_flag = !!reader.next();
|
|
1086
|
+
dpb_output_delay_du_length_minus1 = reader.read(5);
|
|
1087
|
+
}
|
|
1088
|
+
bit_rate_scale = reader.read(4);
|
|
1089
|
+
cpb_size_scale = reader.read(4);
|
|
1090
|
+
if (sub_pic_hrd_params_present_flag) {
|
|
1091
|
+
cpb_size_du_scale = reader.read(4);
|
|
1092
|
+
}
|
|
1093
|
+
initial_cpb_removal_delay_length_minus1 = reader.read(5);
|
|
1094
|
+
au_cpb_removal_delay_length_minus1 = reader.read(5);
|
|
1095
|
+
dpb_output_delay_length_minus1 = reader.read(5);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
const fixed_pic_rate_general_flag: boolean[] = [];
|
|
1100
|
+
const fixed_pic_rate_within_cvs_flag: boolean[] = [];
|
|
1101
|
+
const elemental_duration_in_tc_minus1: number[] = [];
|
|
1102
|
+
const low_delay_hrd_flag: boolean[] = [];
|
|
1103
|
+
const cpb_cnt_minus1: number[] = [];
|
|
1104
|
+
const nalHrdParameters: SubLayerHrdParameters[] = [];
|
|
1105
|
+
const vclHrdParameters: SubLayerHrdParameters[] = [];
|
|
1106
|
+
for (let i = 0; i <= maxNumSubLayersMinus1; i += 1) {
|
|
1107
|
+
fixed_pic_rate_general_flag[i] = !!reader.next();
|
|
1108
|
+
if (!fixed_pic_rate_general_flag[i]) {
|
|
1109
|
+
fixed_pic_rate_within_cvs_flag[i] = !!reader.next();
|
|
1110
|
+
}
|
|
1111
|
+
if (fixed_pic_rate_within_cvs_flag[i]) {
|
|
1112
|
+
elemental_duration_in_tc_minus1[i] =
|
|
1113
|
+
reader.decodeExponentialGolombNumber();
|
|
1114
|
+
} else {
|
|
1115
|
+
low_delay_hrd_flag[i] = !!reader.next();
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
if (!low_delay_hrd_flag[i]) {
|
|
1119
|
+
cpb_cnt_minus1[i] = reader.decodeExponentialGolombNumber();
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
if (nal_hrd_parameters_present_flag) {
|
|
1123
|
+
nalHrdParameters[i] = parseSubLayerHrdParameters(
|
|
1124
|
+
reader,
|
|
1125
|
+
i,
|
|
1126
|
+
getCpbCnt(cpb_cnt_minus1[i]!),
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
if (vcl_hrd_parameters_present_flag) {
|
|
1130
|
+
vclHrdParameters[i] = parseSubLayerHrdParameters(
|
|
1131
|
+
reader,
|
|
1132
|
+
i,
|
|
1133
|
+
getCpbCnt(cpb_cnt_minus1[i]!),
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
return {
|
|
1139
|
+
nal_hrd_parameters_present_flag,
|
|
1140
|
+
vcl_hrd_parameters_present_flag,
|
|
1141
|
+
sub_pic_hrd_params_present_flag,
|
|
1142
|
+
tick_divisor_minus2,
|
|
1143
|
+
du_cpb_removal_delay_increment_length_minus1,
|
|
1144
|
+
sub_pic_cpb_params_in_pic_timing_sei_flag,
|
|
1145
|
+
dpb_output_delay_du_length_minus1,
|
|
1146
|
+
bit_rate_scale,
|
|
1147
|
+
cpb_size_scale,
|
|
1148
|
+
cpb_size_du_scale,
|
|
1149
|
+
initial_cpb_removal_delay_length_minus1,
|
|
1150
|
+
au_cpb_removal_delay_length_minus1,
|
|
1151
|
+
dpb_output_delay_length_minus1,
|
|
1152
|
+
fixed_pic_rate_general_flag,
|
|
1153
|
+
fixed_pic_rate_within_cvs_flag,
|
|
1154
|
+
elemental_duration_in_tc_minus1,
|
|
1155
|
+
low_delay_hrd_flag,
|
|
1156
|
+
cpb_cnt_minus1,
|
|
1157
|
+
nalHrdParameters,
|
|
1158
|
+
vclHrdParameters,
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
export type HrdParameters = ReturnType<typeof parseHrdParameters>;
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* E.2.3 Sub-layer HRD parameters syntax
|
|
1166
|
+
*/
|
|
1167
|
+
export function parseSubLayerHrdParameters(
|
|
1168
|
+
reader: NaluSodbBitReader,
|
|
1169
|
+
subLayerId: number,
|
|
1170
|
+
CpbCnt: number,
|
|
1171
|
+
) {
|
|
1172
|
+
const bit_rate_value_minus1: number[] = [];
|
|
1173
|
+
const cpb_size_value_minus1: number[] = [];
|
|
1174
|
+
const cpb_size_du_value_minus1: number[] = [];
|
|
1175
|
+
const bit_rate_du_value_minus1: number[] = [];
|
|
1176
|
+
const cbr_flag: boolean[] = [];
|
|
1177
|
+
for (let i = 0; i < CpbCnt; i += 1) {
|
|
1178
|
+
bit_rate_value_minus1[i] = reader.decodeExponentialGolombNumber();
|
|
1179
|
+
cpb_size_value_minus1[i] = reader.decodeExponentialGolombNumber();
|
|
1180
|
+
if (subLayerId > 0) {
|
|
1181
|
+
cbr_flag[i] = !!reader.next();
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
return {
|
|
1185
|
+
bit_rate_value_minus1,
|
|
1186
|
+
cpb_size_value_minus1,
|
|
1187
|
+
cpb_size_du_value_minus1,
|
|
1188
|
+
bit_rate_du_value_minus1,
|
|
1189
|
+
cbr_flag,
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
/**
|
|
1194
|
+
* E.3.3 Sub-layer HRD parameters semantics
|
|
1195
|
+
*/
|
|
1196
|
+
function getCpbCnt(cpb_cnt_minus_1: number) {
|
|
1197
|
+
return cpb_cnt_minus_1 + 1;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
export function searchConfiguration(buffer: Uint8Array) {
|
|
1201
|
+
let videoParameterSet!: NaluRaw;
|
|
1202
|
+
let sequenceParameterSet!: NaluRaw;
|
|
1203
|
+
let pictureParameterSet!: NaluRaw;
|
|
1204
|
+
let count = 0;
|
|
1205
|
+
|
|
1206
|
+
for (const nalu of annexBSplitNalu(buffer)) {
|
|
1207
|
+
const header = parseNaluHeader(nalu);
|
|
1208
|
+
const raw: NaluRaw = {
|
|
1209
|
+
...header,
|
|
1210
|
+
data: nalu,
|
|
1211
|
+
rbsp: nalu.subarray(2),
|
|
1212
|
+
};
|
|
1213
|
+
switch (header.nal_unit_type) {
|
|
1214
|
+
case 32:
|
|
1215
|
+
videoParameterSet = raw;
|
|
1216
|
+
break;
|
|
1217
|
+
case 33:
|
|
1218
|
+
sequenceParameterSet = raw;
|
|
1219
|
+
break;
|
|
1220
|
+
case 34:
|
|
1221
|
+
pictureParameterSet = raw;
|
|
1222
|
+
break;
|
|
1223
|
+
default:
|
|
1224
|
+
continue;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
count += 1;
|
|
1228
|
+
if (count === 3) {
|
|
1229
|
+
return {
|
|
1230
|
+
videoParameterSet,
|
|
1231
|
+
sequenceParameterSet,
|
|
1232
|
+
pictureParameterSet,
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
throw new Error("Invalid data");
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
export function parseSpsMultilayerExtension(reader: NaluSodbBitReader) {
|
|
1241
|
+
const inter_view_mv_vert_constraint_flag = !!reader.next();
|
|
1242
|
+
return {
|
|
1243
|
+
inter_view_mv_vert_constraint_flag,
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
export type SpsMultilayerExtension = ReturnType<
|
|
1248
|
+
typeof parseSpsMultilayerExtension
|
|
1249
|
+
>;
|
|
1250
|
+
|
|
1251
|
+
export function parseSps3dExtension(reader: NaluSodbBitReader) {
|
|
1252
|
+
const iv_di_mc_enabled_flag: boolean[] = [];
|
|
1253
|
+
const iv_mv_scal_enabled_flag: boolean[] = [];
|
|
1254
|
+
|
|
1255
|
+
iv_di_mc_enabled_flag[0] = !!reader.next();
|
|
1256
|
+
iv_mv_scal_enabled_flag[0] = !!reader.next();
|
|
1257
|
+
|
|
1258
|
+
const log2_ivmc_sub_pb_size_minus3 = reader.decodeExponentialGolombNumber();
|
|
1259
|
+
const iv_res_pred_enabled_flag = !!reader.next();
|
|
1260
|
+
const depth_ref_enabled_flag = !!reader.next();
|
|
1261
|
+
const vsp_mc_enabled_flag = !!reader.next();
|
|
1262
|
+
const dbbp_enabled_flag = !!reader.next();
|
|
1263
|
+
|
|
1264
|
+
iv_di_mc_enabled_flag[1] = !!reader.next();
|
|
1265
|
+
iv_mv_scal_enabled_flag[1] = !!reader.next();
|
|
1266
|
+
|
|
1267
|
+
const tex_mc_enabled_flag = !!reader.next();
|
|
1268
|
+
const log2_texmc_sub_pb_size_minus3 =
|
|
1269
|
+
reader.decodeExponentialGolombNumber();
|
|
1270
|
+
const intra_contour_enabled_flag = !!reader.next();
|
|
1271
|
+
const intra_dc_only_wedge_enabled_flag = !!reader.next();
|
|
1272
|
+
const cqt_cu_part_pred_enabled_flag = !!reader.next();
|
|
1273
|
+
const inter_dc_only_enabled_flag = !!reader.next();
|
|
1274
|
+
const skip_intra_enabled_flag = !!reader.next();
|
|
1275
|
+
|
|
1276
|
+
return {
|
|
1277
|
+
iv_di_mc_enabled_flag,
|
|
1278
|
+
iv_mv_scal_enabled_flag,
|
|
1279
|
+
log2_ivmc_sub_pb_size_minus3,
|
|
1280
|
+
iv_res_pred_enabled_flag,
|
|
1281
|
+
depth_ref_enabled_flag,
|
|
1282
|
+
vsp_mc_enabled_flag,
|
|
1283
|
+
dbbp_enabled_flag,
|
|
1284
|
+
tex_mc_enabled_flag,
|
|
1285
|
+
log2_texmc_sub_pb_size_minus3,
|
|
1286
|
+
intra_contour_enabled_flag,
|
|
1287
|
+
intra_dc_only_wedge_enabled_flag,
|
|
1288
|
+
cqt_cu_part_pred_enabled_flag,
|
|
1289
|
+
inter_dc_only_enabled_flag,
|
|
1290
|
+
skip_intra_enabled_flag,
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
export type Sps3dExtension = ReturnType<typeof parseSps3dExtension>;
|
|
1295
|
+
|
|
1296
|
+
export interface Configuration {
|
|
1297
|
+
videoParameterSet: NaluRaw;
|
|
1298
|
+
sequenceParameterSet: NaluRaw;
|
|
1299
|
+
pictureParameterSet: NaluRaw;
|
|
1300
|
+
|
|
1301
|
+
generalProfileSpace: number;
|
|
1302
|
+
generalProfileIndex: number;
|
|
1303
|
+
generalProfileCompatibilitySet: Uint8Array;
|
|
1304
|
+
generalTierFlag: boolean;
|
|
1305
|
+
generalLevelIndex: number;
|
|
1306
|
+
generalConstraintSet: Uint8Array;
|
|
1307
|
+
|
|
1308
|
+
encodedWidth: number;
|
|
1309
|
+
encodedHeight: number;
|
|
1310
|
+
|
|
1311
|
+
cropLeft: number;
|
|
1312
|
+
cropRight: number;
|
|
1313
|
+
cropTop: number;
|
|
1314
|
+
cropBottom: number;
|
|
1315
|
+
croppedWidth: number;
|
|
1316
|
+
croppedHeight: number;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
export function parseConfiguration(data: Uint8Array): Configuration {
|
|
1320
|
+
const { videoParameterSet, sequenceParameterSet, pictureParameterSet } =
|
|
1321
|
+
searchConfiguration(data);
|
|
1322
|
+
|
|
1323
|
+
const {
|
|
1324
|
+
profileTierLevel: {
|
|
1325
|
+
generalProfileTier: {
|
|
1326
|
+
profile_space: generalProfileSpace,
|
|
1327
|
+
tier_flag: generalTierFlag,
|
|
1328
|
+
profile_idc: generalProfileIndex,
|
|
1329
|
+
profileCompatibilitySet: generalProfileCompatibilitySet,
|
|
1330
|
+
constraintSet: generalConstraintSet,
|
|
1331
|
+
},
|
|
1332
|
+
general_level_idc: generalLevelIndex,
|
|
1333
|
+
},
|
|
1334
|
+
} = parseVideoParameterSet(videoParameterSet.rbsp);
|
|
1335
|
+
|
|
1336
|
+
const {
|
|
1337
|
+
chroma_format_idc,
|
|
1338
|
+
pic_width_in_luma_samples: encodedWidth,
|
|
1339
|
+
pic_height_in_luma_samples: encodedHeight,
|
|
1340
|
+
conf_win_left_offset: cropLeft = 0,
|
|
1341
|
+
conf_win_right_offset: cropRight = 0,
|
|
1342
|
+
conf_win_top_offset: cropTop = 0,
|
|
1343
|
+
conf_win_bottom_offset: cropBottom = 0,
|
|
1344
|
+
} = parseSequenceParameterSet(sequenceParameterSet.rbsp);
|
|
1345
|
+
|
|
1346
|
+
const SubWidthC = getSubWidthC(chroma_format_idc);
|
|
1347
|
+
const SubHeightC = getSubHeightC(chroma_format_idc);
|
|
1348
|
+
|
|
1349
|
+
const croppedWidth = encodedWidth - SubWidthC * (cropLeft + cropRight);
|
|
1350
|
+
const croppedHeight = encodedHeight - SubHeightC * (cropTop + cropBottom);
|
|
1351
|
+
|
|
1352
|
+
return {
|
|
1353
|
+
videoParameterSet,
|
|
1354
|
+
sequenceParameterSet,
|
|
1355
|
+
pictureParameterSet,
|
|
1356
|
+
|
|
1357
|
+
generalProfileSpace,
|
|
1358
|
+
generalProfileIndex,
|
|
1359
|
+
generalProfileCompatibilitySet,
|
|
1360
|
+
generalTierFlag,
|
|
1361
|
+
generalLevelIndex,
|
|
1362
|
+
generalConstraintSet,
|
|
1363
|
+
|
|
1364
|
+
encodedWidth,
|
|
1365
|
+
encodedHeight,
|
|
1366
|
+
cropLeft,
|
|
1367
|
+
cropRight,
|
|
1368
|
+
cropTop,
|
|
1369
|
+
cropBottom,
|
|
1370
|
+
croppedWidth,
|
|
1371
|
+
croppedHeight,
|
|
1372
|
+
};
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
export function toCodecString(configuration: Configuration) {
|
|
1376
|
+
const {
|
|
1377
|
+
generalProfileSpace,
|
|
1378
|
+
generalProfileIndex,
|
|
1379
|
+
generalProfileCompatibilitySet,
|
|
1380
|
+
generalTierFlag,
|
|
1381
|
+
generalLevelIndex,
|
|
1382
|
+
generalConstraintSet,
|
|
1383
|
+
} = configuration;
|
|
1384
|
+
|
|
1385
|
+
return [
|
|
1386
|
+
"hev1",
|
|
1387
|
+
["", "A", "B", "C"][generalProfileSpace]! +
|
|
1388
|
+
generalProfileIndex.toString(),
|
|
1389
|
+
hexDigits(getUint32LittleEndian(generalProfileCompatibilitySet, 0)),
|
|
1390
|
+
(generalTierFlag ? "H" : "L") + generalLevelIndex.toString(),
|
|
1391
|
+
...Array.from(generalConstraintSet, hexDigits),
|
|
1392
|
+
].join(".");
|
|
1393
|
+
}
|