Cogs.Core
MPEG_TS.cpp
1#include "MPEG_TS.h"
2
3#include "Parser.h"
4
5#include <stdio.h>
6#include <inttypes.h>
7
8namespace Cogs::Core{
9
10 static constexpr uint32_t SYNC_BYTE = 0x47;
11
12 static constexpr bool debug_print = false;
13
14 void MPEGAdaptationField::print()
15 {
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);
25 if(PCR_flag == 1){
26 printf("program_clock_reference_base %" PRIu64 "\n", program_clock_reference_base);
27 printf("program_clock_reference_extension %u\n", program_clock_reference_extension);
28 }
29 if(OPCR_flag == 1){
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);
32 }
33 if(splicing_point_flag == 1){
34 printf("splice_countdown %u\n", splice_countdown);
35 }
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]);
41 }
42 }
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);
48 if(ltw_flag == 1){
49 printf("ltw_valid_flag %u\n", ltw_valid_flag);
50 printf("ltw_offset %u\n", ltw_offset);
51 }
52 if(piecewise_rate_flag == 1){
53 printf("piecewise_rate %u\n", piecewise_rate);
54 }
55 if(seamless_splice_flag == 1){
56 printf("Splice_type %u\n", Splice_type);
57 printf("DTS_next_AU %" PRIu64 "\n", DTS_next_AU);
58 }
59 }
60 }
61 void MPEGTransportStreamHeader::print()
62 {
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);
71 }
72 void MPEGProgramAssociationSection::print()
73 {
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);
83
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]);
88 }
89
90 printf("CRC32 %u\n", CRC32);
91 }
92 void MPEGProgramMapTable::print()
93 {
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);
105
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);
110 }
111
112 printf("CRC32 %u\n", CRC32);
113 }
114 static void program_association_table(MPEGTransportStreamData &parse, uint8_t *data, size_t /*size*/)
115 {
116 size_t bit = 0;
117 MPEGProgramAssociationSection &pas = parse.pas = {};
118 pas.table_id = parse_u(8, data, bit);
119 assert(pas.table_id == 0x00); // program_association_section
120 pas.section_syntax_indicator = parse_u(1, data, bit);
121 //assert(pas.section_syntax_indicator == 1);
122 uint32_t zero = parse_u(1, data, bit);
123 assert(zero == 0);
124 /*uint32_t reserved1 =*/ 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);
128
129 pas.transport_stream_id = parse_u(16, data, bit);
130 /*uint32_t reserved2 =*/ parse_u(2, data, bit);
131 // assert(reserved2 == 0x3);
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;
137 assert(N <= 44);
138 for(uint32_t i=0; i<N; i++){
139 pas.program_number[i] = parse_u(16, data, bit);
140 /*uint32_t reserved3 =*/ parse_u(3, data, bit);
141 pas.PID[i] = parse_u(13, data, bit);
142 }
143 pas.CRC32 = parse_u(32, data, bit);
144
145 if(debug_print) pas.print();
146 }
147 static void descriptor(uint8_t *data, size_t &bit)
148 {
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;
152
153 if(debug_print){
154 printf("descriptor_tag %u\n", descriptor_tag);
155 printf("descriptor_length %u\n", descriptor_length);
156 }
157
158 assert(descriptor_tag != 0); // Reserved
159 assert(descriptor_tag != 1); // Reserved
160 if(descriptor_tag == 2){ // video_stream_descriptor
161 assert(false);
162 }
163 if(descriptor_tag == 3){ // audio_stream_descriptor
164 assert(false);
165 }
166 if(descriptor_tag == 4){ // hierarchy_descriptor
167 assert(false);
168 }
169 if(descriptor_tag == 5){ // registration_descriptor
170 assert(false);
171 }
172 if(descriptor_tag == 6){ // // data_stream_alignment_descriptor
173 assert(false);
174 }
175 if(descriptor_tag == 7){ // target_background_grid_descriptor
176 assert(false);
177 }
178 if(descriptor_tag == 8){ // video_window_descriptor
179 assert(false);
180 }
181 if(descriptor_tag == 9){ // CA_descriptor
182 assert(false);
183 }
184 if(descriptor_tag == 10){ // ISO_639_language_descriptor
185 assert(false);
186 }
187 if(descriptor_tag == 11){ // system_clock_descriptor
188 assert(false);
189 }
190 if(descriptor_tag == 12){ // multiplex_buffer_utilization_descriptor
191 assert(false);
192 }
193 if(descriptor_tag == 13){ // copyright_descriptor
194 assert(false);
195 }
196 if(descriptor_tag == 14){ // maximum_bitrate_descriptor
197 assert(false);
198 }
199 if(descriptor_tag == 15){ // private_data_indicator_descriptor
200 assert(false);
201 }
202 if(descriptor_tag == 16){ // smoothing_buffer_descriptor
203 assert(false);
204 }
205 if(descriptor_tag == 17){ // STD_descriptor
206 assert(false);
207 }
208 if(descriptor_tag == 18){ // IBP_descriptor
209 assert(false);
210 }
211 if(descriptor_tag >= 19 && descriptor_tag <= 26){ // Defined in ISO/IEC 13818-6
212 assert(false);
213 }
214 if(descriptor_tag == 27){ // MPEG-4_video_descriptor
215 assert(false);
216 }
217 if(descriptor_tag == 28){ // MPEG-4_audio_descriptor
218 assert(false);
219 }
220 if(descriptor_tag == 29){ // IOD_descriptor
221 assert(false);
222 }
223 if(descriptor_tag == 30){ // SL_descriptor
224 assert(false);
225 }
226 if(descriptor_tag == 31){ // FMC_descriptor
227 assert(false);
228 }
229 if(descriptor_tag == 32){ // external_ES_ID_descriptor
230 assert(false);
231 }
232 if(descriptor_tag == 33){ // MuxCode_descriptor
233 assert(false);
234 }
235 if(descriptor_tag == 34){ // FmxBufferSize_descriptor
236 assert(false);
237 }
238 if(descriptor_tag == 35){ // multiplexbuffer_descriptor
239 assert(false);
240 }
241 if(descriptor_tag == 36){ // content_labeling_descriptor
242 assert(false);
243 }
244 if(descriptor_tag == 37){ // metadata_pointer_descriptor
245 assert(false);
246 }
247 if(descriptor_tag == 38){ // metadata_descriptor
248 assert(false);
249 }
250 if(descriptor_tag == 39){ // metadata_STD_descriptor
251 assert(false);
252 }
253 if(descriptor_tag == 40){ // AVC video descriptor
254 assert(false);
255 }
256 if(descriptor_tag == 41){ // IPMP_descriptor
257 assert(false);
258 }
259 if(descriptor_tag == 42){ // AVC timing and HRD descriptor
260 assert(false);
261 }
262 if(descriptor_tag == 43){ // MPEG-2_AAC_audio_descriptor
263 assert(false);
264 }
265 if(descriptor_tag == 44){ // FlexMuxTiming_descriptor
266 assert(false);
267 }
268 if(descriptor_tag >= 45 && descriptor_tag <= 63){ // ITU-T Rec.H.222.0 | ISO/IEC 13818-1 Reserved
269 assert(false);
270 }
271 if(descriptor_tag >= 64 && descriptor_tag <= 255){ // User Private
272 assert(false);
273 }
274 }
275 static void program_map_table(MPEGTransportStreamData &parse, uint8_t *data, size_t /*size*/)
276 {
277 size_t bit = 0;
278 MPEGProgramMapTable &pmt = parse.pmt = {};
279 pmt.table_id = parse_u(8, data, bit);
280 assert(pmt.table_id == 0x02);
281
282 pmt.section_syntax_indicator = parse_u(1, data, bit);
283 uint32_t zero = parse_u(1, data, bit);
284 assert(zero == 0);
285 parse_u(2, data, bit); // Reserved
286 pmt.section_length = parse_u(12, data, bit);
287 pmt.program_number = parse_u(16, data, bit);
288 parse_u(2, data, bit); // Reserved
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); // Reserved
294 pmt.PCR_PID = parse_u(13, data, bit);
295 parse_u(4, data, bit); // Reserved
296 pmt.program_info_length = parse_u(12, data, bit);
297
298 for(uint32_t i=0; bit<96+pmt.program_info_length*8; i++){
299 descriptor(data, bit);
300 }
301
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); // Reserved
306 entity.elementary_PID = parse_u(13, data, bit);
307 parse_u(4, data, bit); // Reserved
308 entity.ES_info_length = parse_u(12, data, bit);
309
310 size_t s = bit;
311 for(uint32_t j=0; bit<s+entity.ES_info_length*8; j++){
312 descriptor(data, bit);
313 }
314
315 pmt.entities.push_back(entity);
316 }
317
318 assert(bit == 24+pmt.section_length*8-32);
319 pmt.CRC32 = parse_u(32, data, bit);
320
321 if(debug_print) pmt.print();
322 }
323 static void PES_packet(MPEGTransportStreamData &parse, uint8_t *data, size_t size)
324 {
325 assert(data[0] == 0x0);
326 assert(data[1] == 0x0);
327 assert(data[2] == 0x1);
328
329 size_t bit = 8*3;
330 uint32_t stream_id = parse_u(8, data, bit);
331 uint32_t PES_packet_length = parse_u(16, data, bit);
332 size_t bit_a = bit;
333
334 if(debug_print){
335 printf("\nPES_packet\n");
336 printf("stream_id %u\n", stream_id);
337 printf("PES_packet_length %u\n", PES_packet_length);
338 }
339
340 constexpr uint32_t program_stream_map = 0xbc; // 1011 1100
341 // constexpr uint32_t private_stream_1 = 0xbd; // 1011 1101
342 constexpr uint32_t padding_stream = 0xbe; // 1011 1110
343 constexpr uint32_t private_stream_2 = 0xbf; // 1011 1111
344 // constexpr uint32_t audio_strem_mask_1 = 0xc0; // 110x xxxx // audio stream number x xxxx
345 // constexpr uint32_t audio_strem_mask_2 = 0xd0; // 110x xxxx // audio stream number x xxxx
346 constexpr uint32_t video_stream_mask = 0xe0; // 1110 xxxx // video stream number xxxx
347 constexpr uint32_t ECM_stream = 0xf0; // 1111 0000
348 constexpr uint32_t EMM_stream = 0xf1; // 1111 0001
349 constexpr uint32_t DSMCC_stream = 0xf2; // 1111 0010 // TODO Rec. ITU-T H.222.0 | ISO/IEC 13818-1 Annex A or ISO/IEC 13818-6_DSMCC_stream
350 // constexpr uint32_t = 0xf3; // 1111 0011
351 // constexpr uint32_t H222_1_Type_A = 0xf3; // 1111 0100
352 // constexpr uint32_t H222_1_Type_B = 0xf5; // 1111 0101
353 // constexpr uint32_t H222_1_Type_C = 0xf6; // 1111 0110
354 // constexpr uint32_t H222_1_Type_D = 0xf7; // 1111 0111
355 constexpr uint32_t H222_1_Type_E = 0xf8; // 1111 1000
356 // constexpr uint32_t ancillary_stream = 0xf9; // 1111 1001
357 // constexpr uint32_t = 0x; // 1111 1010
358 // constexpr uint32_t = 0x; // 1111 1011
359 // constexpr uint32_t metadata_stream = 0xfc; // 1111 1100
360 // constexpr uint32_t extended_stream_id = 0xfd; // 1111 1101
361 // constexpr uint32_t reserved_data_stream = 0xfe; // 1111 1110
362 constexpr uint32_t program_stream_directory = 0xff; // 1111 1111
363
364 // Drop Non-Video
365 if((stream_id&video_stream_mask) != video_stream_mask)
366 return;
367 uint32_t video_stream_number = stream_id&!video_stream_mask;
368 assert(video_stream_number == 0); // Only one stream currently supported (No multiplexing)
369
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);
393 size_t bit_b = bit;
394
395 if(debug_print){
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);
409 }
410
411 uint64_t PTS = 0; // 33 bits
412 //uint64_t DTS = 0; // 33 bits
413
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); // 15 bslbf
420 if(parse_u(1, data, bit) != 1) assert(false);
421 uint64_t PTS_14_0 = parse_u(15, data, bit); // 15 bslbf
422 if(parse_u(1, data, bit) != 1) assert(false);
423 PTS = (PTS_32_30<<30) | (PTS_29_15<<15) | PTS_14_0;
424 }
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); // 15 bslbf
431 if(parse_u(1, data, bit) != 1) assert(false);
432 uint64_t PTS_14_0 = parse_u(15, data, bit); // 15 bslbf
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); // 3 bslbf
437 (void)DTS_32_30; // Remove warning about unused variable
438 if(parse_u(1, data, bit) != 1) assert(false);
439 uint64_t DTS_29_15 = parse_u(15, data, bit); // 15 bslbf
440 (void)DTS_29_15; // Remove warning about unused variable
441 if(parse_u(1, data, bit) != 1) assert(false);
442 uint64_t DTS_14_0 = parse_u(15, data, bit); // 15 bslbf
443 (void)DTS_14_0; // Remove warning about unused variable
444 if(parse_u(1, data, bit) != 1) assert(false);
445 PTS = (PTS_32_30<<30) | (PTS_29_15<<15) | PTS_14_0;
446 //DTS = (DTS_32_30<<30) | (DTS_29_15<<15) | DTS_14_0;
447 }
448 // printf("Id %u (0x%x) PTS %llu (%f) DTS %llu (%f)\n", stream_id, stream_id, PTS, (PTS*300)/27000000.0, DTS, (DTS*300)/27000000.0);
449 if(ESCR_flag == 0x1){
450 assert(false);
451 }
452 if(ES_rate_flag == 0x1){
453 assert(false);
454 }
455 if(DSM_trick_mode_flag == 0x1){
456 assert(false);
457 }
458 if(additional_copy_info_flag == 0x1){
459 assert(false);
460 }
461 if(PES_CRC_flag == 0x1){
462 assert(false);
463 }
464 if(PES_extension_flag == 0x1){
465 assert(false);
466 }
467 size_t bit_c = bit;
468 assert(bit%8 == 0);
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);
473 }
474 size_t bit_d = bit;
475 uint32_t N2 = PES_packet_length - (uint32_t)((bit_d - bit_a)/8); // PES_packet_data_bytes
476 if(PES_packet_length == 0){
477 N2 = (uint32_t)(size - bit_d/8);
478 }
479 TSCallbackData cb_data = {};
480 assert(bit%8u == 0);
481 cb_data.data = &data[bit/8u];
482 cb_data.size = N2;
483 cb_data.timestamp = PTS;
484 parse.callback(cb_data);
485 }
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){
493 assert(false);
494 }
495 else if(stream_id == padding_stream){
496 assert(false);
497 }
498 }
499 static void adaptation_field(MPEGTransportStreamData &parse, uint8_t *data, size_t /*size*/, size_t &adaptation_field_bytes)
500 {
501 size_t bit = 0;
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);
516 // uint32_t Reserved =
517 parse_u(6, data, bit);
518 af.program_clock_reference_extension = parse_u(9, data, bit);
519 }
520 if(af.OPCR_flag == 1){
521 af.original_program_clock_reference_base = parse_u64(33, data, bit);
522 // uint32_t Reserved =
523 parse_u(6, data, bit);
524 af.original_program_clock_reference_extension = parse_u(9, data, bit);
525 }
526 if(af.splicing_point_flag == 1){
527 af.splice_countdown = parse_u(8, data, bit);
528 }
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);
533 }
534 }
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);
541 // uint32_t Reserved =
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);
546 }
547 if(af.piecewise_rate_flag == 1){
548 // uint32_t reserved =
549 parse_u(2, data, bit);
550 af.piecewise_rate = parse_u(22, data, bit);
551 }
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);
555 // uint32_t marker_bit0 =
556 parse_u(1, data, bit);
557 uint64_t DTS_next_AU1 = parse_u(15, data, bit);
558 // uint32_t marker_bit1 =
559 parse_u(1, data, bit);
560 uint64_t DTS_next_AU0 = parse_u(15, data, bit);
561 // uint32_t marker_bit2 =
562 parse_u(1, data, bit);
563 af.DTS_next_AU = DTS_next_AU0<<0 | DTS_next_AU1<<15 | DTS_next_AU2<<30;
564 }
565 assert(bit%8 == 0);
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++){
569 //uint32_t reserved =
570 parse_u(8, data, bit);
571 }
572 }
573 assert(bit%8 == 0);
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);
579 }
580
581 if(debug_print) af.print();
582 }
583 }
584 static void transport_packet(MPEGTransportStreamData &parse, uint8_t *data, size_t size)
585 {
586 MPEGTransportStreamHeader &header = parse.header;
587 assert(size >= 188);
588 uint32_t sb = data[0];
589 assert(sb == SYNC_BYTE);
590
591 size_t bit = 8; // Start after 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); // We don't support scrambling
598 header.adaptation_field_control = parse_u(2, data, bit);
599 assert(header.adaptation_field_control != 0); // This is usually an error
600 if(header.adaptation_field_control == 0) return; // Discard Packet
601 header.continuity_counter = parse_u(4, data, bit);
602
603 if(debug_print) header.print();
604
605 // Adaptation Field
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);
609 }
610 size_t N = 184 - adaptation_field_bytes;
611
612 // Payload
613 if(header.adaptation_field_control != 0x1 && header.adaptation_field_control != 0x3)
614 return; // No Payload
615
616 if(header.PID == 0x1FFF){ // Null packet
617 assert(header.payload_unit_start_indicator == 0);
618 return;
619 }
620 if(header.PID == 0x0000){ // Program Association Table
621 size_t pointer_padding_bytes = 0;
622 if(header.payload_unit_start_indicator){
623 size_t pbit = 0;
624 uint32_t pointer_field = parse_u(8, &data[4+adaptation_field_bytes], pbit);
625 pointer_padding_bytes = 1 + pointer_field;
626 if(debug_print)
627 printf("Pointer Field %u\n", pointer_field);
628 }
629 program_association_table(parse, &data[4+adaptation_field_bytes+pointer_padding_bytes], N-1);
630 return;
631 }
632 if(header.PID == 0x0001){
633 assert(false);// Conditional Access Table
634 return;
635 }
636 if(header.PID == 0x0002){
637 assert(false);// Transport Stream Description Table
638 return;
639 }
640 if(header.PID == 0x0003){
641 assert(false);// IPMP Control Information Table
642 return;
643 }
644 if(header.PID == 0x0004){
645 assert(false);// Adaptive streaming information
646 return;
647 }
648 if(header.PID >= 0x0005 && header.PID <= 0x000F){
649 assert(false);// Reserved
650 return;
651 }
652
653 assert(header.PID >= 0x0010 && header.PID <= 0x1FFE);
654
655 // Program Association Table Assigned (Program_map_PID)
656 // Program Association Table Assigned (network_PID)
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){
661 size_t pbit = 0;
662 uint32_t pointer_field = parse_u(8, &data[4+adaptation_field_bytes], pbit);
663 pointer_padding_bytes = 1 + pointer_field;
664 }
665 if(parse.pas.program_number[idx] == 0)
666 assert(false); // network_information_table
667 else
668 program_map_table(parse, &data[4+adaptation_field_bytes+pointer_padding_bytes], N-1);
669 return;
670 }
671
672 // Program Map Table (elementary_PID)
673 if(parse.pmt.HasPID(header.PID)){
674 PES_Sinc &sinc = parse.pes_sinc[header.PID];
675 if(debug_print){
676 printf("PES packet offset %" PRIu64 "\n", 4+adaptation_field_bytes);
677 }
678 if(header.payload_unit_start_indicator && sinc.data.size()){
679 PES_packet(parse, sinc.data.data(), sinc.data.size());
680 sinc.data.clear();
681 }
682 size_t offset = sinc.data.size();
683 sinc.data.resize(offset + N);
684 memcpy(&sinc.data[offset], &data[4+adaptation_field_bytes], N);
685 return;
686 }
687
688 // Network Information Table
689 if(parse.nit.HasPID(header.PID)){
690 return;
691 }
692
693 // DVB Tables
694 if(header.PID == 0x0011){ // TODO
695 // assert(false); // Bouquet Association Table (BAT)
696 // assert(false); // Service Description Table (SDT)
697 // printf("TODO Bouquet Association Table (DVB Table)\n");
698 return;
699 }
700 if(header.PID == 0x0012){
701 assert(false); // Event Information Table (EIT)
702 return;
703 }
704 if(header.PID == 0x0013){
705 assert(false); // Running Status Table (RST)
706 return;
707 }
708 if(header.PID == 0x0014){
709 assert(false); // Time and Date Table (TDT)
710 assert(false); // Time Offset Table (TOT)
711 return;
712 }
713 if(header.PID >= 0x0010 && header.PID <= 0x0014){
714 assert(false); // Stuffing Table (ST)
715 return;
716 }
717
718 printf("Drop packet (unknown PID %u)\n", header.PID);
719 // assert(false); // Are we missing some PID?
720 }
721 void parse_mpeg_ts(MPEGTransportStreamData &parse, uint8_t *data, size_t size)
722 {
723 size_t i=0;
724 while(i+188<=size && data[i] == SYNC_BYTE){
725 if(debug_print){
726 for(size_t j=0; j<188; j++){
727 printf("0x%x\t", data[i+j]);
728 if(j%8 == 7) printf("\n");
729 }
730 printf("\n");
731 }
732 transport_packet(parse, &data[i], size-i);
733 i += 188;
734 }
735 }
736
737}// namespace ...
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....