-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathapv.hexpat
More file actions
414 lines (340 loc) · 14.6 KB
/
apv.hexpat
File metadata and controls
414 lines (340 loc) · 14.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
#pragma pattern for Advanced Professional Video (*.apv)
#pragma magic [ 61 50 76 31 ] @ 0x04
#pragma endian big
import std.io;
import std.mem;
import type.guid;
/* PBU types */
enum PbuType : u8 {
FRM_PRI = 1,
FRM_NONPRI = 2,
FRM_PREVIEW = 25,
FRM_DEPTH = 26,
FRM_ALPHA = 27,
AUI = 65,
METADATA = 66,
FILLER = 67
};
fn get_0xff_ext_var(auto addr) {
u32 read = 1;
u32 var = 0;
u8 ext = std::mem::read_unsigned(addr, 1);
while (ext == 0xFF) {
var += 0xFF;
ext = std::mem::read_unsigned(addr + read, 1);
read += 1;
}
var += ext;
return var;
};
fn get_0xff_ext_var_bytes(auto addr) {
u32 read = 1;
u8 ext = std::mem::read_unsigned(addr, 1);
while (ext == 0xFF) {
ext = std::mem::read_unsigned(addr + read, 1);
read += 1;
}
return read;
};
fn get_num_comp(auto chroma_format_idc) {
u32 nc = 0;
if(chroma_format_idc == 0) nc = 1;
else if(chroma_format_idc == 4) nc = 4;
else nc = 3;
return nc;
};
struct PbuBase {
u32 read = 0;
str ptype_str = "";
/*
syntax code | type
--------------------------------------------------------------|-----
pbu_header(){ |
pbu_type | u(8)
group_id | u(16)
reserved_zero_8bits | u(8)
}
*/
u32 pbu_size; // originally, this syntax is part of AccessUnit
u8 pbu_type;
u16 group_id;
u8 reserved_zero_8bits;
read += 4;
};
/*
syntax code | type
--------------------------------------------------------------|-----
frame_info(){ |
profile_idc | u(8)
level_idc | u(8)
band_idc | u(3)
reserved_zero_5bits | u(5)
frame_width | u(24)
frame_height | u(24)
chroma_format_idc | u(4)
bit_depth_minus8 | u(4)
capture_time_distance | u(8)
reserved_zero_8bits | u(8)
}
*/
bitfield FrmInfo {
profile_idc : 8;
level_idc : 8;
band_idc : 3;
reserved_zero_5bits: 5;
frame_width: 24;
frame_height: 24;
chroma_format_idc: 4;
bit_depth_minus8: 4;
capture_time_distance: 8;
reserved_zero_8bits: 8;
};
bitfield ColorInfo {
u32 readbits = 25;
color_primaries : 8;
transfer_characteristics : 8;
matrix_coefficients : 8;
bool full_range_flag : 1;
};
fn get_num_tiles (auto tile_w_mb, auto tile_h_mb, auto w, auto h) {
u32 startMb = 0;
u32 w_mb = 0;
u32 h_mb = 0;
u32 TileCols = 0;
u32 TileRows = 0;
w_mb = (w + 15) >> 4;
h_mb = (h + 15) >> 4;
TileCols = 0;
startMb = 0;
while(startMb < w_mb){
startMb += tile_w_mb;
TileCols += 1;
}
TileRows = 0;
startMb = 0;
while(startMb < h_mb){
startMb += tile_h_mb;
TileRows += 1;
}
return (TileCols * TileRows);
};
bitfield FrmHeader {
u32 readbits = 0;
FrmInfo finfo [[name("frame_info()")]];
readbits += (12 * 8);
reserved_zero_8bits_0 : 8;
readbits += 8;
u8 NumComps = get_num_comp(finfo.chroma_format_idc) [[export]];
bool color_description_present_flag : 1;
readbits += 1;
if(color_description_present_flag) {
ColorInfo color_description;
readbits += color_description.readbits;
}
bool use_q_matrix : 1;
readbits += 1;
if(use_q_matrix) { // quantization_matrix()
qmatrix0_00 : 8; qmatrix0_01 : 8; qmatrix0_02 : 8; qmatrix0_03 : 8; qmatrix0_04 : 8; qmatrix0_05 : 8; qmatrix0_06 : 8; qmatrix0_07 : 8;
qmatrix0_08 : 8; qmatrix0_09 : 8; qmatrix0_10 : 8; qmatrix0_11 : 8; qmatrix0_12 : 8; qmatrix0_13 : 8; qmatrix0_14 : 8; qmatrix0_15 : 8;
qmatrix0_16 : 8; qmatrix0_17 : 8; qmatrix0_18 : 8; qmatrix0_19 : 8; qmatrix0_20 : 8; qmatrix0_21 : 8; qmatrix0_22 : 8; qmatrix0_23 : 8;
qmatrix0_24 : 8; qmatrix0_25 : 8; qmatrix0_26 : 8; qmatrix0_27 : 8; qmatrix0_28 : 8; qmatrix0_29 : 8; qmatrix0_30 : 8; qmatrix0_31 : 8;
qmatrix0_32 : 8; qmatrix0_33 : 8; qmatrix0_34 : 8; qmatrix0_35 : 8; qmatrix0_36 : 8; qmatrix0_37 : 8; qmatrix0_38 : 8; qmatrix0_39 : 8;
qmatrix0_40 : 8; qmatrix0_41 : 8; qmatrix0_42 : 8; qmatrix0_43 : 8; qmatrix0_44 : 8; qmatrix0_45 : 8; qmatrix0_46 : 8; qmatrix0_47 : 8;
qmatrix0_48 : 8; qmatrix0_49 : 8; qmatrix0_50 : 8; qmatrix0_51 : 8; qmatrix0_52 : 8; qmatrix0_53 : 8; qmatrix0_54 : 8; qmatrix0_55 : 8;
qmatrix0_56 : 8; qmatrix0_57 : 8; qmatrix0_58 : 8; qmatrix0_59 : 8; qmatrix0_60 : 8; qmatrix0_61 : 8; qmatrix0_62 : 8; qmatrix0_63 : 8;
if(NumComps > 1) {
qmatrix1_00 : 8; qmatrix1_01 : 8; qmatrix1_02 : 8; qmatrix1_03 : 8; qmatrix1_04 : 8; qmatrix1_05 : 8; qmatrix1_06 : 8; qmatrix1_07 : 8;
qmatrix1_08 : 8; qmatrix1_09 : 8; qmatrix1_10 : 8; qmatrix1_11 : 8; qmatrix1_12 : 8; qmatrix1_13 : 8; qmatrix1_14 : 8; qmatrix1_15 : 8;
qmatrix1_16 : 8; qmatrix1_17 : 8; qmatrix1_18 : 8; qmatrix1_19 : 8; qmatrix1_20 : 8; qmatrix1_21 : 8; qmatrix1_22 : 8; qmatrix1_23 : 8;
qmatrix1_24 : 8; qmatrix1_25 : 8; qmatrix1_26 : 8; qmatrix1_27 : 8; qmatrix1_28 : 8; qmatrix1_29 : 8; qmatrix1_30 : 8; qmatrix1_31 : 8;
qmatrix1_32 : 8; qmatrix1_33 : 8; qmatrix1_34 : 8; qmatrix1_35 : 8; qmatrix1_36 : 8; qmatrix1_37 : 8; qmatrix1_38 : 8; qmatrix1_39 : 8;
qmatrix1_40 : 8; qmatrix1_41 : 8; qmatrix1_42 : 8; qmatrix1_43 : 8; qmatrix1_44 : 8; qmatrix1_45 : 8; qmatrix1_46 : 8; qmatrix1_47 : 8;
qmatrix1_48 : 8; qmatrix1_49 : 8; qmatrix1_50 : 8; qmatrix1_51 : 8; qmatrix1_52 : 8; qmatrix1_53 : 8; qmatrix1_54 : 8; qmatrix1_55 : 8;
qmatrix1_56 : 8; qmatrix1_57 : 8; qmatrix1_58 : 8; qmatrix1_59 : 8; qmatrix1_60 : 8; qmatrix1_61 : 8; qmatrix1_62 : 8; qmatrix1_63 : 8;
}
if(NumComps > 2) {
qmatrix2_00 : 8; qmatrix2_01 : 8; qmatrix2_02 : 8; qmatrix2_03 : 8; qmatrix2_04 : 8; qmatrix2_05 : 8; qmatrix2_06 : 8; qmatrix2_07 : 8;
qmatrix2_08 : 8; qmatrix2_09 : 8; qmatrix2_10 : 8; qmatrix2_11 : 8; qmatrix2_12 : 8; qmatrix2_13 : 8; qmatrix2_14 : 8; qmatrix2_15 : 8;
qmatrix2_16 : 8; qmatrix2_17 : 8; qmatrix2_18 : 8; qmatrix2_19 : 8; qmatrix2_20 : 8; qmatrix2_21 : 8; qmatrix2_22 : 8; qmatrix2_23 : 8;
qmatrix2_24 : 8; qmatrix2_25 : 8; qmatrix2_26 : 8; qmatrix2_27 : 8; qmatrix2_28 : 8; qmatrix2_29 : 8; qmatrix2_30 : 8; qmatrix2_31 : 8;
qmatrix2_32 : 8; qmatrix2_33 : 8; qmatrix2_34 : 8; qmatrix2_35 : 8; qmatrix2_36 : 8; qmatrix2_37 : 8; qmatrix2_38 : 8; qmatrix2_39 : 8;
qmatrix2_40 : 8; qmatrix2_41 : 8; qmatrix2_42 : 8; qmatrix2_43 : 8; qmatrix2_44 : 8; qmatrix2_45 : 8; qmatrix2_46 : 8; qmatrix2_47 : 8;
qmatrix2_48 : 8; qmatrix2_49 : 8; qmatrix2_50 : 8; qmatrix2_51 : 8; qmatrix2_52 : 8; qmatrix2_53 : 8; qmatrix2_54 : 8; qmatrix2_55 : 8;
qmatrix2_56 : 8; qmatrix2_57 : 8; qmatrix2_58 : 8; qmatrix2_59 : 8; qmatrix2_60 : 8; qmatrix2_61 : 8; qmatrix2_62 : 8; qmatrix2_63 : 8;
}
if(NumComps > 3) {
qmatrix3_00 : 8; qmatrix3_01 : 8; qmatrix3_02 : 8; qmatrix3_03 : 8; qmatrix3_04 : 8; qmatrix3_05 : 8; qmatrix3_06 : 8; qmatrix3_07 : 8;
qmatrix3_08 : 8; qmatrix3_09 : 8; qmatrix3_10 : 8; qmatrix3_11 : 8; qmatrix3_12 : 8; qmatrix3_13 : 8; qmatrix3_14 : 8; qmatrix3_15 : 8;
qmatrix3_16 : 8; qmatrix3_17 : 8; qmatrix3_18 : 8; qmatrix3_19 : 8; qmatrix3_20 : 8; qmatrix3_21 : 8; qmatrix3_22 : 8; qmatrix3_23 : 8;
qmatrix3_24 : 8; qmatrix3_25 : 8; qmatrix3_26 : 8; qmatrix3_27 : 8; qmatrix3_28 : 8; qmatrix3_29 : 8; qmatrix3_30 : 8; qmatrix3_31 : 8;
qmatrix3_32 : 8; qmatrix3_33 : 8; qmatrix3_34 : 8; qmatrix3_35 : 8; qmatrix3_36 : 8; qmatrix3_37 : 8; qmatrix3_38 : 8; qmatrix3_39 : 8;
qmatrix3_40 : 8; qmatrix3_41 : 8; qmatrix3_42 : 8; qmatrix3_43 : 8; qmatrix3_44 : 8; qmatrix3_45 : 8; qmatrix3_46 : 8; qmatrix3_47 : 8;
qmatrix3_48 : 8; qmatrix3_49 : 8; qmatrix3_50 : 8; qmatrix3_51 : 8; qmatrix3_52 : 8; qmatrix3_53 : 8; qmatrix3_54 : 8; qmatrix3_55 : 8;
qmatrix3_56 : 8; qmatrix3_57 : 8; qmatrix3_58 : 8; qmatrix3_59 : 8; qmatrix3_60 : 8; qmatrix3_61 : 8; qmatrix3_62 : 8; qmatrix3_63 : 8;
}
readbits += (NumComps * 8 * 8) * 8;
}
// tile_info()
tile_width_in_mbs : 20;
tile_height_in_mbs : 20;
bool tile_size_present_in_fh_flag : 1;
readbits += 41;
u32 NumTiles = get_num_tiles(tile_width_in_mbs, tile_height_in_mbs, finfo.frame_width, finfo.frame_height) [[export]];
if(tile_size_present_in_fh_flag) {
tile_size_in_fh : 32 * NumTiles;
readbits += 32 * NumTiles;
}
reserved_zero_8bits_1 : 8;
readbits += 8;
// byte_alignment(): 'bitfield' will align to byte at the end, automatically
};
struct PbuFrm:PbuBase {
u32 frmh_bits = 0;
u32 NumComps = 0;
u32 NumTiles = 0;
if(pbu_type == PbuType::FRM_PRI) ptype_str = "Frm(Pri)";
else if(pbu_type == PbuType::FRM_NONPRI) ptype_str = "Frm(Nonpri)";
else if(pbu_type == PbuType::FRM_PREVIEW) ptype_str = "Frm(Preview)";
else if(pbu_type == PbuType::FRM_DEPTH) ptype_str = "Frm(Depth)";
else if(pbu_type == PbuType::FRM_ALPHA) ptype_str = "Frm(Alpha)";
else ptype_str = "Frm(Unknown)";
FrmHeader fh [[name("frame_header()")]];
read += (fh.readbits + 7) >> 3;
u8 frameData[pbu_size - read] [[sealed]];
};
/* Metadata payload types */
enum MetadataPayloadType : u8 {
ITU_T_T35 = 4,
MDCV = 5,
CLL = 6,
FILLER = 10,
USER_DEFINED = 170
};
struct MetadataPayload_Base {
str mtype_str = "";
u32 read = 0;
u32 payloadType = get_0xff_ext_var($) [[export]];
read += get_0xff_ext_var_bytes($);
$ += get_0xff_ext_var_bytes($); // update current reading point
u32 payloadSize = get_0xff_ext_var($) [[export]];
read += get_0xff_ext_var_bytes($);
$ += get_0xff_ext_var_bytes($); // update current reading point
u64 endOffset = $ + payloadSize;
};
struct MetadataPayload_T35:MetadataPayload_Base {
mtype_str ="ITU-T T.35";
u8 itu_t_t35_country_code;
if (itu_t_t35_country_code == 0xFF) {
u8 itu_t_t35_country_code_extension;
u8 itu_t_t35_payload[payloadSize - 2][[sealed]];
} else {
u8 itu_t_t35_payload[payloadSize - 1][[sealed]];
}
};
struct MetadataPayload_Mdcv:MetadataPayload_Base {
mtype_str ="MDCV";
u16 primary_chromaticity_x0;
u16 primary_chromaticity_y0;
u16 primary_chromaticity_x1;
u16 primary_chromaticity_y1;
u16 primary_chromaticity_x2;
u16 primary_chromaticity_y2;
u16 white_point_chromaticity_x;
u16 white_point_chromaticity_y;
u32 max_mastering_luminance;
u32 min_mastering_luminance;
};
struct MetadataPayload_Cll:MetadataPayload_Base {
mtype_str ="CLL";
u16 max_cll;
u16 max_fall;
};
struct MetadataPayload_Filler:MetadataPayload_Base {
mtype_str ="Filler";
u8 ff_byte[payloadSize] [[sealed]];
};
struct MetadataPayload_Userdefined:MetadataPayload_Base {
mtype_str ="User defined";
type::GUID uuid;
u8 user_defined_data_payload[payloadSize - 16] [[sealed]];
};
struct MetadataPayload_Undefined:MetadataPayload_Base {
mtype_str ="Undefined";
u8 payloadData[payloadSize] [[sealed]];
};
u32 metadata_payload_count = 0;
struct MetadataPayload {
u32 payloadType = get_0xff_ext_var($); // peek payloadType
match (payloadType) {
(MetadataPayloadType::ITU_T_T35) : MetadataPayload_T35 Pay [[inline]];
(MetadataPayloadType::MDCV) : MetadataPayload_Mdcv Pay [[inline]];
(MetadataPayloadType::CLL): MetadataPayload_Cll Pay [[inline]];
(MetadataPayloadType::FILLER): MetadataPayload_Filler Pay [[inline]];
(MetadataPayloadType::USER_DEFINED): MetadataPayload_Userdefined Pay [[inline]];
(_) : MetadataPayload_Undefined Pay [[inline]];
}
// check read size
if($ != Pay.endOffset) {
std::warning("Mismatch b/w Metadata payloadSize and actual read size");
}
std::print(" metadata payload[{:d}] type = {:d} ({}), size = {:d}", metadata_payload_count, Pay.payloadType, Pay.mtype_str, Pay.payloadSize);
metadata_payload_count += 1;
} [[name(std::format("Payload[{}]:{}", (metadata_payload_count - 1), Pay.mtype_str))]];
struct PbuMetadata:PbuBase {
u64 endOffset = 0;
ptype_str = "Metadata";
metadata_payload_count = 0; // reset number of metadata payload
u32 metadata_size; // syntax
endOffset = $ + metadata_size;
MetadataPayload pay[while($ < endOffset)] [[inline]];
};
struct PbuAui:PbuBase {
ptype_str = "aui";
u8 data[pbu_size - read] [[sealed]];
};
struct PbuFiller:PbuBase {
ptype_str = "filler";
u8 data[pbu_size - read] [[sealed]];
};
struct PbuUnknown:PbuBase {
std::warning(std::format("Unknown PBU type ({})!!!", pbu_type));
ptype_str = "unknown";
u8 data[pbu_size - read] [[sealed]];
};
u32 pbu_count = 0;
struct PBU {
u32 pbu_size = std::mem::read_unsigned($, 4, std::mem::Endian::Big);
u8 pbu_type = std::mem::read_unsigned($ + 4, 1, std::mem::Endian::Big);
match (pbu_type) {
(PbuType::FRM_PRI) : PbuFrm Pbu [[inline]];
(PbuType::FRM_NONPRI) : PbuFrm Pbu [[inline]];
(PbuType::FRM_PREVIEW): PbuFrm Pbu [[inline]];
(PbuType::FRM_DEPTH): PbuFrm Pbu [[inline]];
(PbuType::FRM_ALPHA): PbuFrm Pbu [[inline]];
(PbuType::AUI): PbuAui Pbu [[inline]];
(PbuType::METADATA): PbuMetadata Pbu [[inline]];
(PbuType::FILLER): PbuFiller Pbu [[inline]];
(_) : PbuUnknown Pbu [[inline]];
}
std::print(" PBU[{:d}] size = {:d}, {}", pbu_count, pbu_size, Pbu.ptype_str);
pbu_count += 1;
} [[name(std::format("PBU[{}]:{}", (pbu_count - 1), Pbu.ptype_str))]];
u32 au_count = 0;
struct AccessUnit {
u64 au_end = 0;
u32 au_size; // originally this syntax is part of RawBitstream
std::print("AU[{:d}] size = {:d}", au_count, au_size);
au_end = $ + au_size;
pbu_count = 0; // reset number of PBU
char signature[4]; // 'aPv1'
PBU pbu[while($ < au_end)] [[inline]];
};
u32 raw_count = 0;
struct RawBitstream {
AccessUnit AU [[name(std::format("AU[{}]", raw_count))]];
raw_count += 1;
} [[name(std::format("Raw[{}]", (raw_count - 1)))]];
struct ApvBitstream {
RawBitstream Raw [[inline]];
}[[inline]];
ApvBitstream APV[while(!std::mem::eof())] @ 0x0 [[inline]];