10 static constexpr uint32_t SYNC_BYTE = 0x47;
12 static constexpr bool debug_print =
false;
14 void MPEGAdaptationField::print()
16 printf(
"\nMPEGAdaptationField\n");
17 printf(
"discontinuity_indicator %u\n", discontinuity_indicator);
18 printf(
"random_access_indicator %u\n", random_access_indicator);
19 printf(
"elementary_stream_priority_indicator %u\n", elementary_stream_priority_indicator);
20 printf(
"PCR_flag %u\n", PCR_flag);
21 printf(
"OPCR_flag %u\n", OPCR_flag);
22 printf(
"splicing_point_flag %u\n", splicing_point_flag);
23 printf(
"transport_private_data_flag %u\n", transport_private_data_flag);
24 printf(
"adaptation_field_extension_flag %u\n", adaptation_field_extension_flag);
26 printf(
"program_clock_reference_base %" PRIu64
"\n", program_clock_reference_base);
27 printf(
"program_clock_reference_extension %u\n", program_clock_reference_extension);
30 printf(
"original_program_clock_reference_base %" PRIu64
"\n", original_program_clock_reference_base);
31 printf(
"original_program_clock_reference_extension %u\n", original_program_clock_reference_extension);
33 if(splicing_point_flag == 1){
34 printf(
"splice_countdown %u\n", splice_countdown);
36 if(transport_private_data_flag == 1){
37 printf(
"transport_private_data_length %u\n", transport_private_data_length);
38 printf(
"private_data_byte[] = \n");
39 for(uint32_t i=0; i<transport_private_data_length; i++){
40 printf(
"[%u] %u\n", i, private_data_byte[i]);
43 if(adaptation_field_extension_flag == 1){
44 printf(
"adaptation_field_extension_length %u\n", adaptation_field_extension_length);
45 printf(
"ltw_flag %u\n", ltw_flag);
46 printf(
"piecewise_rate_flag %u\n", piecewise_rate_flag);
47 printf(
"seamless_splice_flag %u\n", seamless_splice_flag);
49 printf(
"ltw_valid_flag %u\n", ltw_valid_flag);
50 printf(
"ltw_offset %u\n", ltw_offset);
52 if(piecewise_rate_flag == 1){
53 printf(
"piecewise_rate %u\n", piecewise_rate);
55 if(seamless_splice_flag == 1){
56 printf(
"Splice_type %u\n", Splice_type);
57 printf(
"DTS_next_AU %" PRIu64
"\n", DTS_next_AU);
61 void MPEGTransportStreamHeader::print()
63 printf(
"\nMPEGTransportStreamHeader\n");
64 printf(
"transport_error_indicator %u\n", transport_error_indicator);
65 printf(
"payload_unit_start_indicator %u\n", payload_unit_start_indicator);
66 printf(
"transport_priority %u\n", transport_priority);
67 printf(
"PID 0x%04x\n", PID);
68 printf(
"transport_scrambling_control %u\n", transport_scrambling_control);
69 printf(
"adaptation_field_control %u\n", adaptation_field_control);
70 printf(
"continuity_counter %u\n", continuity_counter);
72 void MPEGProgramAssociationSection::print()
74 printf(
"\nMPEGProgramAssociationSection\n");
75 printf(
"table_id %u\n", table_id);
76 printf(
"section_syntax_indicator %u\n", section_syntax_indicator);
77 printf(
"section_length %u\n", section_length);
78 printf(
"transport_stream_id %u\n", transport_stream_id);
79 printf(
"version_number %u\n", version_number);
80 printf(
"current_next_indicator %u\n", current_next_indicator);
81 printf(
"section_number %u\n", section_number);
82 printf(
"last_section_number %u\n", last_section_number);
84 uint32_t N = (section_length-9)/4;
85 for(uint32_t i=0; i<N; i++){
86 printf(
"program_number[%u] %u\n", i, program_number[i]);
87 printf(
"PID[%u] 0x%04x\n", i, PID[i]);
90 printf(
"CRC32 %u\n", CRC32);
92 void MPEGProgramMapTable::print()
94 printf(
"\nMPEGProgramMapTable\n");
95 printf(
"table_id %u\n", table_id);
96 printf(
"section_syntax_indicator %u\n", section_syntax_indicator);
97 printf(
"section_length %u\n", section_length);
98 printf(
"program_number %u\n", program_number);
99 printf(
"version_number %u\n", version_number);
100 printf(
"current_next_indicator %u\n", current_next_indicator);
101 printf(
"section_number %u\n", section_number);
102 printf(
"last_section_number %u\n", last_section_number);
103 printf(
"PCR_PID 0x%x\n", PCR_PID);
104 printf(
"program_info_length %u\n", program_info_length);
106 for(
auto &entity : entities){
107 printf(
"stream_type 0x%x\n", entity.stream_type);
108 printf(
"elementary_PID 0x%x\n", entity.elementary_PID);
109 printf(
"ES_info_length 0x%x\n", entity.ES_info_length);
112 printf(
"CRC32 %u\n", CRC32);
114 static void program_association_table(MPEGTransportStreamData &parse, uint8_t *data,
size_t )
117 MPEGProgramAssociationSection &pas = parse.pas = {};
118 pas.table_id = parse_u(8, data, bit);
119 assert(pas.table_id == 0x00);
120 pas.section_syntax_indicator = parse_u(1, data, bit);
122 uint32_t zero = parse_u(1, data, bit);
124 parse_u(2, data, bit);
125 pas.section_length = parse_u(12, data, bit);
126 assert(pas.section_length >= 9);
127 assert(pas.section_length <= 0x3fd);
129 pas.transport_stream_id = parse_u(16, data, bit);
130 parse_u(2, data, bit);
132 pas.version_number = parse_u(5, data, bit);
133 pas.current_next_indicator = parse_u(1, data, bit);
134 pas.section_number = parse_u(8, data, bit);
135 pas.last_section_number = parse_u(8, data, bit);
136 uint32_t N = (pas.section_length-9)/4;
138 for(uint32_t i=0; i<N; i++){
139 pas.program_number[i] = parse_u(16, data, bit);
140 parse_u(3, data, bit);
141 pas.PID[i] = parse_u(13, data, bit);
143 pas.CRC32 = parse_u(32, data, bit);
145 if(debug_print) pas.print();
147 static void descriptor(uint8_t *data,
size_t &bit)
149 uint32_t descriptor_tag = parse_u(8, data, bit);
150 uint32_t descriptor_length = parse_u(8, data, bit);
151 bit += 8*descriptor_length;
154 printf(
"descriptor_tag %u\n", descriptor_tag);
155 printf(
"descriptor_length %u\n", descriptor_length);
158 assert(descriptor_tag != 0);
159 assert(descriptor_tag != 1);
160 if(descriptor_tag == 2){
163 if(descriptor_tag == 3){
166 if(descriptor_tag == 4){
169 if(descriptor_tag == 5){
172 if(descriptor_tag == 6){
175 if(descriptor_tag == 7){
178 if(descriptor_tag == 8){
181 if(descriptor_tag == 9){
184 if(descriptor_tag == 10){
187 if(descriptor_tag == 11){
190 if(descriptor_tag == 12){
193 if(descriptor_tag == 13){
196 if(descriptor_tag == 14){
199 if(descriptor_tag == 15){
202 if(descriptor_tag == 16){
205 if(descriptor_tag == 17){
208 if(descriptor_tag == 18){
211 if(descriptor_tag >= 19 && descriptor_tag <= 26){
214 if(descriptor_tag == 27){
217 if(descriptor_tag == 28){
220 if(descriptor_tag == 29){
223 if(descriptor_tag == 30){
226 if(descriptor_tag == 31){
229 if(descriptor_tag == 32){
232 if(descriptor_tag == 33){
235 if(descriptor_tag == 34){
238 if(descriptor_tag == 35){
241 if(descriptor_tag == 36){
244 if(descriptor_tag == 37){
247 if(descriptor_tag == 38){
250 if(descriptor_tag == 39){
253 if(descriptor_tag == 40){
256 if(descriptor_tag == 41){
259 if(descriptor_tag == 42){
262 if(descriptor_tag == 43){
265 if(descriptor_tag == 44){
268 if(descriptor_tag >= 45 && descriptor_tag <= 63){
271 if(descriptor_tag >= 64 && descriptor_tag <= 255){
275 static void program_map_table(MPEGTransportStreamData &parse, uint8_t *data,
size_t )
278 MPEGProgramMapTable &pmt = parse.pmt = {};
279 pmt.table_id = parse_u(8, data, bit);
280 assert(pmt.table_id == 0x02);
282 pmt.section_syntax_indicator = parse_u(1, data, bit);
283 uint32_t zero = parse_u(1, data, bit);
285 parse_u(2, data, bit);
286 pmt.section_length = parse_u(12, data, bit);
287 pmt.program_number = parse_u(16, data, bit);
288 parse_u(2, data, bit);
289 pmt.version_number = parse_u(5, data, bit);
290 pmt.current_next_indicator = parse_u(1, data, bit);
291 pmt.section_number = parse_u(8, data, bit);
292 pmt.last_section_number = parse_u(8, data, bit);
293 parse_u(3, data, bit);
294 pmt.PCR_PID = parse_u(13, data, bit);
295 parse_u(4, data, bit);
296 pmt.program_info_length = parse_u(12, data, bit);
298 for(uint32_t i=0; bit<96+pmt.program_info_length*8; i++){
299 descriptor(data, bit);
302 for(uint32_t i=0; bit < 24+pmt.section_length*8-32; i++){
303 MPEGProgramMapEntity entity = {};
304 entity.stream_type = parse_u(8, data, bit);
305 parse_u(3, data, bit);
306 entity.elementary_PID = parse_u(13, data, bit);
307 parse_u(4, data, bit);
308 entity.ES_info_length = parse_u(12, data, bit);
311 for(uint32_t j=0; bit<s+entity.ES_info_length*8; j++){
312 descriptor(data, bit);
315 pmt.entities.push_back(entity);
318 assert(bit == 24+pmt.section_length*8-32);
319 pmt.CRC32 = parse_u(32, data, bit);
321 if(debug_print) pmt.print();
323 static void PES_packet(MPEGTransportStreamData &parse, uint8_t *data,
size_t size)
325 assert(data[0] == 0x0);
326 assert(data[1] == 0x0);
327 assert(data[2] == 0x1);
330 uint32_t stream_id = parse_u(8, data, bit);
331 uint32_t PES_packet_length = parse_u(16, data, bit);
335 printf(
"\nPES_packet\n");
336 printf(
"stream_id %u\n", stream_id);
337 printf(
"PES_packet_length %u\n", PES_packet_length);
340 constexpr uint32_t program_stream_map = 0xbc;
342 constexpr uint32_t padding_stream = 0xbe;
343 constexpr uint32_t private_stream_2 = 0xbf;
346 constexpr uint32_t video_stream_mask = 0xe0;
347 constexpr uint32_t ECM_stream = 0xf0;
348 constexpr uint32_t EMM_stream = 0xf1;
349 constexpr uint32_t DSMCC_stream = 0xf2;
355 constexpr uint32_t H222_1_Type_E = 0xf8;
362 constexpr uint32_t program_stream_directory = 0xff;
365 if((stream_id&video_stream_mask) != video_stream_mask)
367 uint32_t video_stream_number = stream_id&!video_stream_mask;
368 assert(video_stream_number == 0);
370 if(stream_id != program_stream_map &&
371 stream_id != padding_stream &&
372 stream_id != private_stream_2 &&
373 stream_id != ECM_stream &&
374 stream_id != EMM_stream &&
375 stream_id != program_stream_directory &&
376 stream_id != DSMCC_stream &&
377 stream_id != H222_1_Type_E){
378 uint32_t magic = parse_u(2, data, bit);
379 assert(magic == 0x2);
380 uint32_t PES_scrambling_control = parse_u(2, data, bit);
381 uint32_t PES_priority = parse_u(1, data, bit);
382 uint32_t data_alignment_indicator = parse_u(1, data, bit);
383 uint32_t copyright = parse_u(1, data, bit);
384 uint32_t original_or_copy = parse_u(1, data, bit);
385 uint32_t PTS_DTS_flags = parse_u(2, data, bit);
386 uint32_t ESCR_flag = parse_u(1, data, bit);
387 uint32_t ES_rate_flag = parse_u(1, data, bit);
388 uint32_t DSM_trick_mode_flag = parse_u(1, data, bit);
389 uint32_t additional_copy_info_flag = parse_u(1, data, bit);
390 uint32_t PES_CRC_flag = parse_u(1, data, bit);
391 uint32_t PES_extension_flag = parse_u(1, data, bit);
392 uint32_t PES_header_data_length = parse_u(8, data, bit);
396 printf(
"PES_scrambling_control %u\n", PES_scrambling_control);
397 printf(
"PES_priority %u\n", PES_priority);
398 printf(
"data_alignment_indicator %u\n", data_alignment_indicator);
399 printf(
"copyright %u\n", copyright);
400 printf(
"original_or_copy %u\n", original_or_copy);
401 printf(
"PTS_DTS_flags %u\n", PTS_DTS_flags);
402 printf(
"ESCR_flag %u\n", ESCR_flag);
403 printf(
"ES_rate_flag %u\n", ES_rate_flag);
404 printf(
"DSM_trick_mode_flag %u\n", DSM_trick_mode_flag);
405 printf(
"additional_copy_info_flag %u\n", additional_copy_info_flag);
406 printf(
"PES_CRC_flag %u\n", PES_CRC_flag);
407 printf(
"PES_extension_flag %u\n", PES_extension_flag);
408 printf(
"PES_header_data_length %u\n", PES_header_data_length);
414 if(PTS_DTS_flags == 0x2){
415 uint32_t magic2 = parse_u(4, data, bit);
416 assert(magic2 == 0x2);
417 uint64_t PTS_32_30 = parse_u(3, data, bit);
418 if(parse_u(1, data, bit) != 1) assert(
false);
419 uint64_t PTS_29_15 = parse_u(15, data, bit);
420 if(parse_u(1, data, bit) != 1) assert(
false);
421 uint64_t PTS_14_0 = parse_u(15, data, bit);
422 if(parse_u(1, data, bit) != 1) assert(
false);
423 PTS = (PTS_32_30<<30) | (PTS_29_15<<15) | PTS_14_0;
425 if(PTS_DTS_flags == 0x3){
426 uint32_t magic2 = parse_u(4, data, bit);
427 assert(magic2 == 0x3);
428 uint64_t PTS_32_30 = parse_u(3, data, bit);
429 if(parse_u(1, data, bit) != 1) assert(
false);
430 uint64_t PTS_29_15 = parse_u(15, data, bit);
431 if(parse_u(1, data, bit) != 1) assert(
false);
432 uint64_t PTS_14_0 = parse_u(15, data, bit);
433 if(parse_u(1, data, bit) != 1) assert(
false);
434 uint32_t magic3 = parse_u(4, data, bit);
435 assert(magic3 == 0x1);
436 uint64_t DTS_32_30 = parse_u(3, data, bit);
438 if(parse_u(1, data, bit) != 1) assert(
false);
439 uint64_t DTS_29_15 = parse_u(15, data, bit);
441 if(parse_u(1, data, bit) != 1) assert(
false);
442 uint64_t DTS_14_0 = parse_u(15, data, bit);
444 if(parse_u(1, data, bit) != 1) assert(
false);
445 PTS = (PTS_32_30<<30) | (PTS_29_15<<15) | PTS_14_0;
449 if(ESCR_flag == 0x1){
452 if(ES_rate_flag == 0x1){
455 if(DSM_trick_mode_flag == 0x1){
458 if(additional_copy_info_flag == 0x1){
461 if(PES_CRC_flag == 0x1){
464 if(PES_extension_flag == 0x1){
469 uint32_t N1 = PES_header_data_length - (uint32_t)((bit_c - bit_b)/8);
470 for(uint32_t i=0; i < N1; i++){
471 uint32_t stuffing_byte = parse_u(8, data, bit);
472 assert(stuffing_byte == 0xff);
475 uint32_t N2 = PES_packet_length - (uint32_t)((bit_d - bit_a)/8);
476 if(PES_packet_length == 0){
477 N2 = (uint32_t)(size - bit_d/8);
479 TSCallbackData cb_data = {};
481 cb_data.data = &data[bit/8u];
483 cb_data.timestamp = PTS;
484 parse.callback(cb_data);
486 else if(stream_id == program_stream_map ||
487 stream_id == private_stream_2 ||
488 stream_id == ECM_stream ||
489 stream_id == EMM_stream ||
490 stream_id == program_stream_directory ||
491 stream_id == DSMCC_stream ||
492 stream_id == H222_1_Type_E){
495 else if(stream_id == padding_stream){
499 static void adaptation_field(MPEGTransportStreamData &parse, uint8_t *data,
size_t ,
size_t &adaptation_field_bytes)
502 uint32_t adaptation_field_length = parse_u(8, data, bit);
503 adaptation_field_bytes = adaptation_field_length+1;
504 if(adaptation_field_length > 0){
505 MPEGAdaptationField &af = parse.af = {};
506 af.discontinuity_indicator = parse_u(1, data, bit);
507 af.random_access_indicator = parse_u(1, data, bit);
508 af.elementary_stream_priority_indicator = parse_u(1, data, bit);
509 af.PCR_flag = parse_u(1, data, bit);
510 af.OPCR_flag = parse_u(1, data, bit);
511 af.splicing_point_flag = parse_u(1, data, bit);
512 af.transport_private_data_flag = parse_u(1, data, bit);
513 af.adaptation_field_extension_flag = parse_u(1, data, bit);
514 if(af.PCR_flag == 1){
515 af.program_clock_reference_base = parse_u64(33, data, bit);
517 parse_u(6, data, bit);
518 af.program_clock_reference_extension = parse_u(9, data, bit);
520 if(af.OPCR_flag == 1){
521 af.original_program_clock_reference_base = parse_u64(33, data, bit);
523 parse_u(6, data, bit);
524 af.original_program_clock_reference_extension = parse_u(9, data, bit);
526 if(af.splicing_point_flag == 1){
527 af.splice_countdown = parse_u(8, data, bit);
529 if(af.transport_private_data_flag == 1){
530 af.transport_private_data_length = parse_u(8, data, bit);
531 for(uint32_t i=0; i<af.transport_private_data_length; i++){
532 af.private_data_byte[i] = parse_u(8, data, bit);
535 if(af.adaptation_field_extension_flag == 1){
536 af.adaptation_field_extension_length = parse_u(8, data, bit);
537 uint32_t offset = (uint32_t)bit;
538 af.ltw_flag = parse_u(1, data, bit);
539 af.piecewise_rate_flag = parse_u(1, data, bit);
540 af.seamless_splice_flag = parse_u(1, data, bit);
542 parse_u(5, data, bit);
543 if(af.ltw_flag == 1){
544 af.ltw_valid_flag = parse_u(1, data, bit);
545 af.ltw_offset = parse_u(15, data, bit);
547 if(af.piecewise_rate_flag == 1){
549 parse_u(2, data, bit);
550 af.piecewise_rate = parse_u(22, data, bit);
552 if(af.seamless_splice_flag == 1){
553 af.Splice_type = parse_u(4, data, bit);
554 uint64_t DTS_next_AU2 = parse_u(3, data, bit);
556 parse_u(1, data, bit);
557 uint64_t DTS_next_AU1 = parse_u(15, data, bit);
559 parse_u(1, data, bit);
560 uint64_t DTS_next_AU0 = parse_u(15, data, bit);
562 parse_u(1, data, bit);
563 af.DTS_next_AU = DTS_next_AU0<<0 | DTS_next_AU1<<15 | DTS_next_AU2<<30;
566 assert(af.adaptation_field_extension_length >= (bit-offset)/8);
567 uint32_t N = af.adaptation_field_extension_length - (uint32_t)((bit-offset)/8);
568 for(uint32_t i=0; i<N; i++){
570 parse_u(8, data, bit);
574 assert(adaptation_field_length+1 >= bit/8);
575 uint32_t N = adaptation_field_length+1 - (uint32_t)(bit/8);
576 for(uint32_t i=0; i<N; i++){
577 uint32_t stuffing_byte = parse_u(8, data, bit);
578 assert(stuffing_byte == 0xff);
581 if(debug_print) af.print();
584 static void transport_packet(MPEGTransportStreamData &parse, uint8_t *data,
size_t size)
586 MPEGTransportStreamHeader &header = parse.header;
588 uint32_t sb = data[0];
589 assert(sb == SYNC_BYTE);
592 header.transport_error_indicator = parse_b(1, data, bit);
593 header.payload_unit_start_indicator = parse_b(1, data, bit);
594 header.transport_priority = parse_b(1, data, bit);
595 header.PID = parse_u(13, data, bit);
596 header.transport_scrambling_control = parse_u(2, data, bit);
597 assert(header.transport_scrambling_control == 0);
598 header.adaptation_field_control = parse_u(2, data, bit);
599 assert(header.adaptation_field_control != 0);
600 if(header.adaptation_field_control == 0)
return;
601 header.continuity_counter = parse_u(4, data, bit);
603 if(debug_print) header.print();
606 size_t adaptation_field_bytes = 0;
607 if(header.adaptation_field_control == 0x2 || header.adaptation_field_control == 0x3){
608 adaptation_field(parse, &data[4], size-4, adaptation_field_bytes);
610 size_t N = 184 - adaptation_field_bytes;
613 if(header.adaptation_field_control != 0x1 && header.adaptation_field_control != 0x3)
616 if(header.PID == 0x1FFF){
617 assert(header.payload_unit_start_indicator == 0);
620 if(header.PID == 0x0000){
621 size_t pointer_padding_bytes = 0;
622 if(header.payload_unit_start_indicator){
624 uint32_t pointer_field = parse_u(8, &data[4+adaptation_field_bytes], pbit);
625 pointer_padding_bytes = 1 + pointer_field;
627 printf(
"Pointer Field %u\n", pointer_field);
629 program_association_table(parse, &data[4+adaptation_field_bytes+pointer_padding_bytes], N-1);
632 if(header.PID == 0x0001){
636 if(header.PID == 0x0002){
640 if(header.PID == 0x0003){
644 if(header.PID == 0x0004){
648 if(header.PID >= 0x0005 && header.PID <= 0x000F){
653 assert(header.PID >= 0x0010 && header.PID <= 0x1FFE);
657 uint32_t idx = (uint32_t)-1;
658 if(parse.pas.HasPID(header.PID, idx)){
659 size_t pointer_padding_bytes = 0;
660 if(header.payload_unit_start_indicator){
662 uint32_t pointer_field = parse_u(8, &data[4+adaptation_field_bytes], pbit);
663 pointer_padding_bytes = 1 + pointer_field;
665 if(parse.pas.program_number[idx] == 0)
668 program_map_table(parse, &data[4+adaptation_field_bytes+pointer_padding_bytes], N-1);
673 if(parse.pmt.HasPID(header.PID)){
674 PES_Sinc &sinc = parse.pes_sinc[header.PID];
676 printf(
"PES packet offset %" PRIu64
"\n", 4+adaptation_field_bytes);
678 if(header.payload_unit_start_indicator && sinc.data.size()){
679 PES_packet(parse, sinc.data.data(), sinc.data.size());
682 size_t offset = sinc.data.size();
683 sinc.data.resize(offset + N);
684 memcpy(&sinc.data[offset], &data[4+adaptation_field_bytes], N);
689 if(parse.nit.HasPID(header.PID)){
694 if(header.PID == 0x0011){
700 if(header.PID == 0x0012){
704 if(header.PID == 0x0013){
708 if(header.PID == 0x0014){
713 if(header.PID >= 0x0010 && header.PID <= 0x0014){
718 printf(
"Drop packet (unknown PID %u)\n", header.PID);
721 void parse_mpeg_ts(MPEGTransportStreamData &parse, uint8_t *data,
size_t size)
724 while(i+188<=size && data[i] == SYNC_BYTE){
726 for(
size_t j=0; j<188; j++){
727 printf(
"0x%x\t", data[i+j]);
728 if(j%8 == 7) printf(
"\n");
732 transport_packet(parse, &data[i], size-i);
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....