winlin

update the ts_info parse the PMT and PES header

1 # the listen ports, split by space. 1 # the listen ports, split by space.
2 -listen 1937; 2 +listen 1935;
3 # the default chunk size is 128, max is 65536, 3 # the default chunk size is 128, max is 65536,
4 # some client does not support chunk size change, 4 # some client does not support chunk size change,
5 # however, most clients supports it and it can improve 5 # however, most clients supports it and it can improve
@@ -10,6 +10,8 @@ g++ -o ts_info ts_info.cpp -g -O0 -ansi @@ -10,6 +10,8 @@ g++ -o ts_info ts_info.cpp -g -O0 -ansi
10 #include <string.h> 10 #include <string.h>
11 #include <assert.h> 11 #include <assert.h>
12 12
  13 +#include <vector>
  14 +
13 #define trace(msg, ...) printf(msg"\n", ##__VA_ARGS__); 15 #define trace(msg, ...) printf(msg"\n", ##__VA_ARGS__);
14 #define srs_freep(p) delete p; p = NULL 16 #define srs_freep(p) delete p; p = NULL
15 #define srs_freepa(p) delete[] p; p = NULL 17 #define srs_freepa(p) delete[] p; p = NULL
@@ -63,11 +65,65 @@ Annex A ¨C CRC Decoder Model @@ -63,11 +65,65 @@ Annex A ¨C CRC Decoder Model
63 #define AFC_BOTH 0x03 65 #define AFC_BOTH 0x03
64 #endif 66 #endif
65 67
66 -struct TSPacket 68 +// Table 2-29 – Stream type assignments. page 66.
  69 +enum TSStreamType
  70 +{
  71 + /*defined by ffmpeg*/
  72 + TSStreamTypeVideoMpeg1 = 0x01,
  73 + TSStreamTypeVideoMpeg2 = 0x02,
  74 + TSStreamTypeAudioMpeg1 = 0x03,
  75 + TSStreamTypeAudioMpeg2 = 0x04,
  76 + TSStreamTypePrivateSection = 0x05,
  77 + TSStreamTypePrivateData = 0x06,
  78 + TSStreamTypeAudioAAC = 0x0f,
  79 + TSStreamTypeVideoMpeg4 = 0x10,
  80 + TSStreamTypeVideoH264 = 0x1b,
  81 + TSStreamTypeAudioAC3 = 0x81,
  82 + TSStreamTypeAudioDTS = 0x8a,
  83 +};
  84 +
  85 +/**
  86 +* the actually parsed type.
  87 +*/
  88 +enum TSPidType
67 { 89 {
68 - // 4B ts packet header.  
69 - struct Header  
70 - { 90 + TSPidTypeReserved = 0, // TSPidTypeReserved, nothing parsed, used reserved.
  91 +
  92 + TSPidTypePAT, // Program associtate table
  93 + TSPidTypePMT, // Program map table.
  94 +
  95 + TSPidTypeVideo,
  96 + TSPidTypeAudio,
  97 +};
  98 +
  99 +// forward declares.
  100 +class TSHeader;
  101 +class TSAdaptionField;
  102 +class TSPayload;
  103 +class TSPayloadReserved;
  104 +class TSPayloadPAT;
  105 +class TSPayloadPMT;
  106 +class TSPayloadPES;
  107 +class TSContext;
  108 +
  109 +// TSPacket declares.
  110 +class TSPacket
  111 +{
  112 +public:
  113 + TSHeader* header;
  114 + TSAdaptionField* adaption_field;
  115 + TSPayload* payload;
  116 +
  117 + TSPacket();
  118 + virtual ~TSPacket();
  119 + int demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
  120 + int finish();
  121 +};
  122 +
  123 +// TSHeader declares.
  124 +class TSHeader
  125 +{
  126 +public:
71 // 1B 127 // 1B
72 int8_t sync_byte; //8bits 128 int8_t sync_byte; //8bits
73 // 2B 129 // 2B
@@ -80,48 +136,16 @@ struct TSPacket @@ -80,48 +136,16 @@ struct TSPacket
80 int8_t adaption_field_control; //2bits 136 int8_t adaption_field_control; //2bits
81 u_int8_t continuity_counter; //4bits 137 u_int8_t continuity_counter; //4bits
82 138
83 - int get_size()  
84 - {  
85 - return 4;  
86 - }  
87 -  
88 - int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)  
89 - {  
90 - int ret = 0;  
91 -  
92 - // ts packet header.  
93 - sync_byte = *p++;  
94 - if (sync_byte != 0x47) {  
95 - trace("ts+sync_bytes invalid sync_bytes: %#x, expect is 0x47", sync_byte);  
96 - return -1;  
97 - }  
98 -  
99 - pid = 0;  
100 - ((char*)&pid)[1] = *p++;  
101 - ((char*)&pid)[0] = *p++;  
102 -  
103 - transport_error_indicator = (pid >> 15) & 0x01;  
104 - payload_unit_start_indicator = (pid >> 14) & 0x01;  
105 - transport_priority = (pid >> 13) & 0x01;  
106 - pid &= 0x1FFF;  
107 -  
108 - continuity_counter = *p++;  
109 -  
110 - transport_scrambling_control = (continuity_counter >> 6) & 0x03;  
111 - adaption_field_control = (continuity_counter >> 4) & 0x03;  
112 - continuity_counter &= 0x0F;  
113 -  
114 - trace("ts+header sync: %#x error: %d unit_start: %d priotiry: %d pid: %d scrambling: %d adaption: %d counter: %d",  
115 - sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid,  
116 - transport_scrambling_control, adaption_field_control, continuity_counter);  
117 -  
118 - return ret;  
119 - }  
120 - } *header; 139 + TSHeader();
  140 + virtual ~TSHeader();
  141 + int get_size();
  142 + int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
  143 +};
121 144
122 - // variant ts packet adation field.  
123 - struct AdaptionField  
124 - { 145 +// variant ts packet adation field. page 40.
  146 +class TSAdaptionField
  147 +{
  148 +public:
125 // 1B 149 // 1B
126 u_int8_t adaption_field_length; //8bits 150 u_int8_t adaption_field_length; //8bits
127 // 1B 151 // 1B
@@ -180,29 +204,288 @@ struct TSPacket @@ -180,29 +204,288 @@ struct TSPacket
180 // user defined data size. 204 // user defined data size.
181 int __user_size; 205 int __user_size;
182 206
183 - AdaptionField()  
184 - { 207 + TSAdaptionField();
  208 + virtual ~TSAdaptionField();
  209 + int get_size();
  210 + int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
  211 +};
  212 +
  213 +// variant ts packet payload.
  214 +// PES packet or PSI table.
  215 +// TSPayloadPAT: page 61.
  216 +class TSPayload
  217 +{
  218 +public:
  219 + /**
  220 + * the size of payload(payload plush the 1byte pointer_field).
  221 + */
  222 + int size;
  223 + int pointer_field_size;
  224 +
  225 + TSPidType type;
  226 +
  227 + /**
  228 + * 2.4.4.2 Semantics definition of fields in pointer syntax
  229 + */
  230 + u_int8_t pointer_field;
  231 +
  232 + TSPayloadReserved* reserved;
  233 + TSPayloadPAT* pat;
  234 + TSPayloadPMT* pmt;
  235 + TSPayloadPES* pes;
  236 +
  237 + /**
  238 + * 2.4.3.6 PES packet. page 49.
  239 + */
  240 +
  241 + TSPayload();
  242 + virtual ~TSPayload();;
  243 + void read_pointer_field(TSPacket* pkt, u_int8_t*& p);
  244 + int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
  245 +};
  246 +
  247 +
  248 +/**
  249 +* 2.4.4.3 Program association Table. page 61.
  250 +*/
  251 +class TSPayloadPAT
  252 +{
  253 +public:
  254 + // 1B
  255 + u_int8_t table_id; //8bits
  256 +
  257 + // 2B
  258 + int8_t section_syntax_indicator; //1bit
  259 + int8_t const0_value; //1bit
  260 + // 2bits reserved.
  261 + u_int16_t section_length; //12bits
  262 +
  263 + // 2B
  264 + u_int16_t transport_stream_id; //16bits
  265 +
  266 + // 1B
  267 + // 2bits reerverd.
  268 + int8_t version_number; //5bits
  269 + int8_t current_next_indicator; //1bit
  270 +
  271 + // 1B
  272 + u_int8_t section_number; //8bits
  273 +
  274 + // 1B
  275 + u_int8_t last_section_number; //8bits
  276 +
  277 + // multiple 4B program data.
  278 + // program_number 16bits
  279 + // reserved 2bits
  280 + // 13bits data: 0x1FFF
  281 + // if program_number program_map_PID 13bits
  282 + // else network_PID 13bytes.
  283 + int program_size;
  284 + int32_t* programs; //32bits
  285 +
  286 + // 4B
  287 + int32_t CRC_32; //32bits
  288 +
  289 + TSPayloadPAT();
  290 + virtual ~TSPayloadPAT();
  291 + int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
  292 +};
  293 +
  294 +class TSPMTESInfo
  295 +{
  296 +public:
  297 + // 1B
  298 + u_int8_t stream_type; //8bits
  299 +
  300 + // 2B
  301 + // 3bits reserved
  302 + int16_t elementary_PID; //13bits
  303 +
  304 + // 2B
  305 + // 4bits reserved
  306 + int16_t ES_info_length; //12bits
  307 +
  308 + char* ES_info; //[ES_info_length] bytes.
  309 +
  310 + TSPMTESInfo();
  311 + virtual ~TSPMTESInfo();
  312 +};
  313 +
  314 +
  315 +/**
  316 +* 2.4.4.8 Program Map Table. page 64.
  317 +*/
  318 +class TSPayloadPMT
  319 +{
  320 +public:
  321 + // 1B
  322 + u_int8_t table_id; //8bits
  323 +
  324 + // 2B
  325 + int8_t section_syntax_indicator; //1bit
  326 + int8_t const0_value; //1bit
  327 + // 2bits reserved.
  328 + u_int16_t section_length; //12bits
  329 +
  330 + // 2B
  331 + u_int16_t program_number; //16bits
  332 +
  333 + // 1B
  334 + // 2bits reerverd.
  335 + int8_t version_number; //5bits
  336 + int8_t current_next_indicator; //1bit
  337 +
  338 + // 1B
  339 + u_int8_t section_number; //8bits
  340 +
  341 + // 1B
  342 + u_int8_t last_section_number; //8bits
  343 +
  344 + // 2B
  345 + // 2bits reserved.
  346 + int16_t PCR_PID; //16bits
  347 +
  348 + // 2B
  349 + // 4bits reserved.
  350 + int16_t program_info_length; //12bits
  351 + char* program_info_desc; //[program_info_length]bytes
  352 +
  353 + // array of TSPMTESInfo.
  354 + std::vector<TSPMTESInfo*> ES_info;
  355 +
  356 + // 4B
  357 + int32_t CRC_32; //32bits
  358 +
  359 + TSPayloadPMT();
  360 + virtual ~TSPayloadPMT();
  361 + int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
  362 +};
  363 +
  364 +
  365 +/**
  366 +* 2.4.3.7 Semantic definition of fields in PES packet. page 49.
  367 +*/
  368 +class TSPayloadPES
  369 +{
  370 +public:
  371 + // 3B
  372 + int32_t packet_start_code_prefix; //24bits
  373 + // 1B
  374 + u_int8_t stream_id; //8bits
  375 + // 2B
  376 + u_int16_t PES_packet_length; //16bits
  377 +
  378 + TSPayloadPES();
  379 + virtual ~TSPayloadPES();
  380 + int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
  381 +};
  382 +
  383 +class TSPayloadReserved
  384 +{
  385 +public:
  386 + int size;
  387 + char* bytes;
  388 +
  389 + TSPayloadReserved();
  390 + virtual ~TSPayloadReserved();
  391 + int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
  392 +};
  393 +
  394 +struct TSPid
  395 +{
  396 + TSPidType type;
  397 + int16_t pid;
  398 +};
  399 +
  400 +// ts context
  401 +class TSContext
  402 +{
  403 +public:
  404 + /**
  405 + * consumed pids.
  406 + */
  407 + int pid_size;
  408 + TSPid* pids;
  409 +
  410 + TSContext();
  411 + virtual ~TSContext();
  412 + bool exists(int16_t pid);
  413 + TSPid* get(int16_t pid);
  414 + void push(TSPidType type, int16_t pid);
  415 +};
  416 +
  417 +TSContext::TSContext()
  418 +{
  419 + pid_size = 0;
  420 + pids = NULL;
  421 +}
  422 +
  423 +TSContext::~TSContext()
  424 +{
  425 + srs_freepa(pids);
  426 +}
  427 +
  428 +bool TSContext::exists(int16_t pid)
  429 +{
  430 + for (int i = 0; i < pid_size; i++) {
  431 + if (pid == pids[i].pid) {
  432 + return true;
  433 + }
  434 + }
  435 +
  436 + return false;
  437 +}
  438 +
  439 +TSPid* TSContext::get(int16_t pid)
  440 +{
  441 + for (int i = 0; i < pid_size; i++) {
  442 + if (pid == pids[i].pid) {
  443 + return &pids[i];
  444 + }
  445 + }
  446 +
  447 + return NULL;
  448 +}
  449 +
  450 +void TSContext::push(TSPidType type, int16_t pid)
  451 +{
  452 + if (exists(pid)) {
  453 + return;
  454 + }
  455 +
  456 + TSPid* p = new TSPid[pid_size + 1];
  457 + memcpy(p, pids, sizeof(TSPid) * pid_size);
  458 +
  459 + p[pid_size] = (TSPid){type, pid};
  460 + pid_size++;
  461 +
  462 + srs_freepa(pids);
  463 + pids = p;
  464 +}
  465 +
  466 +TSAdaptionField::TSAdaptionField()
  467 +{
185 transport_private_data = NULL; 468 transport_private_data = NULL;
186 af_ext_reserved = NULL; 469 af_ext_reserved = NULL;
187 af_reserved = NULL; 470 af_reserved = NULL;
188 471
189 __user_size = 0; 472 __user_size = 0;
190 - } 473 +}
191 474
192 - virtual ~AdaptionField()  
193 - { 475 +TSAdaptionField::~TSAdaptionField()
  476 +{
194 srs_freepa(transport_private_data); 477 srs_freepa(transport_private_data);
195 srs_freepa(af_ext_reserved); 478 srs_freepa(af_ext_reserved);
196 srs_freepa(af_reserved); 479 srs_freepa(af_reserved);
197 - } 480 +}
198 481
199 - int get_size()  
200 - { 482 +int TSAdaptionField::get_size()
  483 +{
201 return __user_size; 484 return __user_size;
202 - } 485 +}
203 486
204 - int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)  
205 - { 487 +int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  488 +{
206 int ret = 0; 489 int ret = 0;
207 490
208 adaption_field_length = *p++; 491 adaption_field_length = *p++;
@@ -333,58 +616,24 @@ struct TSPacket @@ -333,58 +616,24 @@ struct TSPacket
333 } 616 }
334 617
335 return ret; 618 return ret;
336 - }  
337 - } *adaption_field;  
338 -  
339 - // variant ts packet payload.  
340 - // PES packet or PSI table.  
341 - struct Payload  
342 - {  
343 - /**  
344 - * the size of payload(payload plush the 1byte pointer_field).  
345 - */  
346 - int size;  
347 - int pointer_field_size;  
348 -  
349 - /**  
350 - * the actually parsed type.  
351 - */  
352 - enum Type  
353 - {  
354 - TypeUnknown=-1,  
355 - TypeReserved, // TypeReserved, nothing parsed, used reserved.  
356 - TypePAT, //TypePAT, PAT parsed, in pat field.  
357 - } type;  
358 -  
359 - /**  
360 - * 2.4.4.2 Semantics definition of fields in pointer syntax  
361 - */  
362 - u_int8_t pointer_field;  
363 -  
364 - /**  
365 - * if not parsed, store data in this field.  
366 - */  
367 - struct Reserved  
368 - {  
369 - int size;  
370 - char* bytes; 619 +}
371 620
372 - Reserved()  
373 - { 621 +TSPayloadReserved::TSPayloadReserved()
  622 +{
374 size = 0; 623 size = 0;
375 bytes = NULL; 624 bytes = NULL;
376 - } 625 +}
377 626
378 - virtual ~Reserved()  
379 - { 627 +TSPayloadReserved::~TSPayloadReserved()
  628 +{
380 srs_freepa(bytes); 629 srs_freepa(bytes);
381 - } 630 +}
382 631
383 - int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)  
384 - { 632 +int TSPayloadReserved::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  633 +{
385 int ret = 0; 634 int ret = 0;
386 635
387 - size = ppkt->payload->size - ppkt->payload->pointer_field_size; 636 + size = pkt->payload->size - pkt->payload->pointer_field_size;
388 637
389 // not parsed bytes. 638 // not parsed bytes.
390 if (size > 0) { 639 if (size > 0) {
@@ -394,66 +643,20 @@ struct TSPacket @@ -394,66 +643,20 @@ struct TSPacket
394 } 643 }
395 644
396 return ret; 645 return ret;
397 - }  
398 - } *reserved;  
399 -  
400 - /**  
401 - * 2.4.4.3 Program association Table. page 61.  
402 - */  
403 - struct PAT {  
404 - // 1B  
405 - u_int8_t table_id; //8bits  
406 -  
407 - // 2B  
408 - int8_t section_syntax_indicator; //1bit  
409 - int8_t const0_value; //1bit  
410 - // 2bits reserved.  
411 - u_int16_t section_length; //12bits  
412 -  
413 - // 2B  
414 - u_int16_t transport_stream_id; //16bits  
415 -  
416 - // 1B  
417 - // 2bits reerverd.  
418 - int8_t version_number; //5bits  
419 - int8_t current_next_indicator; //1bit  
420 -  
421 - // 1B  
422 - u_int8_t section_number; //8bits  
423 -  
424 - // 1B  
425 - u_int8_t last_section_number; //8bits  
426 -  
427 - // multiple 4B program data.  
428 - // program_number 16bits  
429 - // reserved 2bits  
430 - // 13bits data: 0x1FFF  
431 - // if program_number program_map_PID 13bits  
432 - // else network_PID 13bytes.  
433 - int program_size;  
434 - int32_t* programs; //32bits  
435 -  
436 - // 4B  
437 - int32_t CRC_32; //32bits 646 +}
438 647
439 - PAT()  
440 - { 648 +TSPayloadPAT::TSPayloadPAT()
  649 +{
441 programs = NULL; 650 programs = NULL;
442 - } 651 +}
443 652
444 - virtual ~PAT()  
445 - { 653 +TSPayloadPAT::~TSPayloadPAT()
  654 +{
446 srs_freepa(programs); 655 srs_freepa(programs);
447 - }  
448 -  
449 - int get_program(int index)  
450 - {  
451 - srs_assert(index < program_size);  
452 - return programs[index] & 0x1FFF;  
453 - } 656 +}
454 657
455 - int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)  
456 - { 658 +int TSPayloadPAT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  659 +{
457 int ret = 0; 660 int ret = 0;
458 661
459 table_id = *p++; 662 table_id = *p++;
@@ -489,6 +692,9 @@ struct TSPacket @@ -489,6 +692,9 @@ struct TSPacket
489 pp[2] = *p++; 692 pp[2] = *p++;
490 pp[1] = *p++; 693 pp[1] = *p++;
491 pp[0] = *p++; 694 pp[0] = *p++;
  695 +
  696 + int16_t pid = programs[i] & 0x1FFF;
  697 + ctx->push(TSPidTypePMT, pid);
492 } 698 }
493 } 699 }
494 700
@@ -499,79 +705,251 @@ struct TSPacket @@ -499,79 +705,251 @@ struct TSPacket
499 pp[0] = *p++; 705 pp[0] = *p++;
500 706
501 return ret; 707 return ret;
  708 +}
  709 +
  710 +TSPMTESInfo::TSPMTESInfo()
  711 +{
  712 + ES_info_length = 0;
  713 + ES_info = NULL;
  714 +}
  715 +
  716 +TSPMTESInfo::~TSPMTESInfo()
  717 +{
  718 + srs_freepa(ES_info);
  719 +}
  720 +
  721 +TSPayloadPMT::TSPayloadPMT()
  722 +{
  723 + program_info_length = 0;
  724 + program_info_desc = NULL;
  725 +}
  726 +
  727 +TSPayloadPMT::~TSPayloadPMT()
  728 +{
  729 + srs_freepa(program_info_desc);
  730 +
  731 + for (std::vector<TSPMTESInfo*>::iterator it = ES_info.begin(); it != ES_info.end(); ++it) {
  732 + TSPMTESInfo* info = *it;
  733 + srs_freep(info);
502 } 734 }
503 - } *pat; 735 + ES_info.clear();
  736 +}
504 737
505 - /**  
506 - * 2.4.3.6 PES packet. page 49.  
507 - */ 738 +int TSPayloadPMT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  739 +{
  740 + int ret = 0;
  741 +
  742 + table_id = *p++;
  743 +
  744 + char* pp = (char*)&section_length;
  745 + pp[1] = *p++;
  746 + pp[0] = *p++;
  747 + u_int8_t* pos = p;
  748 +
  749 + section_syntax_indicator = (section_length >> 15) & 0x01;
  750 + const0_value = (section_length >> 14) & 0x01;
  751 + section_length &= 0x0FFF;
  752 +
  753 + pp = (char*)&program_number;
  754 + pp[1] = *p++;
  755 + pp[0] = *p++;
  756 +
  757 + current_next_indicator = *p++;
  758 + version_number = (current_next_indicator >> 1) & 0x1F;
  759 + current_next_indicator &= 0x01;
  760 +
  761 + section_number = *p++;
  762 + last_section_number = *p++;
  763 +
  764 + pp = (char*)&PCR_PID;
  765 + pp[1] = *p++;
  766 + pp[0] = *p++;
  767 +
  768 + PCR_PID &= 0x1FFF;
  769 +
  770 + pp = (char*)&program_info_length;
  771 + pp[1] = *p++;
  772 + pp[0] = *p++;
  773 +
  774 + program_info_length &= 0xFFF;
  775 +
  776 + if (program_info_length > 0) {
  777 + program_info_desc = new char[program_info_length];
  778 + memcpy(program_info_desc, p, program_info_length);
  779 + p += program_info_length;
  780 + }
  781 +
  782 + // [section_length] - 4(CRC) - 9B - [program_info_length]
  783 + int ES_bytes = section_length - 4 - 9 - program_info_length;
  784 + while (ES_bytes > 0) {
  785 + TSPMTESInfo* info = new TSPMTESInfo();
  786 +
  787 + info->stream_type = *p++;
  788 + ES_bytes--;
  789 +
  790 + pp = (char*)&info->elementary_PID;
  791 + pp[1] = *p++;
  792 + pp[0] = *p++;
  793 + ES_bytes -= 2;
  794 +
  795 + info->elementary_PID &= 0x1FFF;
  796 +
  797 + pp = (char*)&info->ES_info_length;
  798 + pp[1] = *p++;
  799 + pp[0] = *p++;
  800 + ES_bytes -= 2;
  801 +
  802 + info->ES_info_length &= 0x0FFF;
  803 +
  804 + if (info->ES_info_length > 0) {
  805 + info->ES_info = new char[info->ES_info_length];
  806 + memcpy(info->ES_info, p, info->ES_info_length);
  807 +
  808 + p += info->ES_info_length;
  809 + ES_bytes -= info->ES_info_length;
  810 + }
  811 +
  812 + ES_info.push_back(info);
  813 +
  814 + // TODO: support more video type.
  815 + if (info->stream_type == TSStreamTypeVideoH264) {
  816 + ctx->push(TSPidTypeVideo, info->elementary_PID);
  817 + }
  818 + // TODO: support more audio type.
  819 + if (info->stream_type == TSStreamTypeAudioAAC) {
  820 + ctx->push(TSPidTypeAudio, info->elementary_PID);
  821 + }
  822 + }
  823 +
  824 + pp = (char*)&CRC_32;
  825 + pp[3] = *p++;
  826 + pp[2] = *p++;
  827 + pp[1] = *p++;
  828 + pp[0] = *p++;
  829 +
  830 + return ret;
  831 +}
  832 +
  833 +TSPayloadPES::TSPayloadPES()
  834 +{
  835 +}
508 836
509 - Payload()  
510 - { 837 +TSPayloadPES::~TSPayloadPES()
  838 +{
  839 +}
  840 +
  841 +int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  842 +{
  843 + int ret = 0;
  844 +
  845 + char* pp = (char*)&packet_start_code_prefix;
  846 + pp[2] = *p++;
  847 + pp[1] = *p++;
  848 + pp[0] = *p++;
  849 +
  850 + packet_start_code_prefix &= 0xFFFFFF;
  851 +
  852 + stream_id = *p++;
  853 +
  854 + pp = (char*)&PES_packet_length;
  855 + pp[1] = *p++;
  856 + pp[0] = *p++;
  857 +
  858 + return ret;
  859 +}
  860 +
  861 +/**
  862 +* 2.4.3.6 PES packet. page 49.
  863 +*/
  864 +
  865 +TSPayload::TSPayload()
  866 +{
511 size = 0; 867 size = 0;
512 pointer_field_size = 0; 868 pointer_field_size = 0;
513 869
514 - type = TypeUnknown; 870 + type = TSPidTypeReserved;
515 reserved = NULL; 871 reserved = NULL;
516 pat = NULL; 872 pat = NULL;
517 - } 873 + pmt = NULL;
  874 + pes = NULL;
  875 +}
518 876
519 - virtual ~Payload()  
520 - { 877 +TSPayload::~TSPayload()
  878 +{
521 srs_freep(reserved); 879 srs_freep(reserved);
522 srs_freep(pat); 880 srs_freep(pat);
  881 + srs_freep(pmt);
  882 + srs_freep(pes);
  883 +}
  884 +
  885 +void TSPayload::read_pointer_field(TSPacket* pkt, u_int8_t*& p)
  886 +{
  887 + if (pkt->header->payload_unit_start_indicator) {
  888 + pointer_field = *p++;
  889 + pointer_field_size = 1;
523 } 890 }
  891 +}
524 892
525 - int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)  
526 - { 893 +int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  894 +{
527 int ret = 0; 895 int ret = 0;
528 896
529 - if (ppkt->header->payload_unit_start_indicator) {  
530 - pointer_field = *p++;  
531 - pointer_field_size = 1; 897 + if (pkt->header->pid == PID_PAT) {
  898 + read_pointer_field(pkt, p);
  899 +
  900 + type = TSPidTypePAT;
  901 + pat = new TSPayloadPAT();
  902 + return pat->demux(ctx, pkt, start, last, p);
532 } 903 }
533 904
534 - if (ppkt->header->pid == PID_PAT) {  
535 - type = TypePAT;  
536 - pat = new PAT();  
537 - return pat->demux(ppkt, start, last, p); 905 + TSPid* pid = ctx->get(pkt->header->pid);
  906 + if (pid && pid->type == TSPidTypePMT) {
  907 + read_pointer_field(pkt, p);
  908 +
  909 + type = pid->type;
  910 + pmt = new TSPayloadPMT();
  911 + return pmt->demux(ctx, pkt, start, last, p);
  912 + }
  913 + if (pid && (pid->type == TSPidTypeVideo || pid->type == TSPidTypeAudio)) {
  914 + type = pid->type;
  915 + pes = new TSPayloadPES();
  916 + return pes->demux(ctx, pkt, start, last, p);
538 } 917 }
539 918
540 // not parsed bytes. 919 // not parsed bytes.
541 - type = TypeReserved;  
542 - reserved = new Reserved();  
543 - if ((ret = reserved->demux(ppkt, start, last, p)) != 0) { 920 + type = TSPidTypeReserved;
  921 + reserved = new TSPayloadReserved();
  922 + if ((ret = reserved->demux(ctx, pkt, start, last, p)) != 0) {
544 return ret; 923 return ret;
545 } 924 }
546 925
547 return ret; 926 return ret;
548 - }  
549 - } *payload; 927 +}
550 928
551 - TSPacket()  
552 - {  
553 - header = new Header();  
554 - adaption_field = new AdaptionField();  
555 - payload = new Payload();  
556 - } 929 +TSPacket::TSPacket()
  930 +{
  931 + header = new TSHeader();
  932 + adaption_field = new TSAdaptionField();
  933 + payload = new TSPayload();
  934 +}
557 935
558 - virtual ~TSPacket()  
559 - { 936 +TSPacket::~TSPacket()
  937 +{
560 srs_freep(header); 938 srs_freep(header);
561 srs_freep(adaption_field); 939 srs_freep(adaption_field);
562 srs_freep(payload); 940 srs_freep(payload);
563 - } 941 +}
564 942
565 - int demux(u_int8_t* start, u_int8_t* last, u_int8_t*& p)  
566 - { 943 +int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  944 +{
567 int ret = 0; 945 int ret = 0;
568 946
569 - if ((ret = header->demux(this, start, last, p)) != 0) { 947 + if ((ret = header->demux(ctx, this, start, last, p)) != 0) {
570 return ret; 948 return ret;
571 } 949 }
572 950
573 if (header->adaption_field_control == AFC_ADAPTION_ONLY || header->adaption_field_control == AFC_BOTH) { 951 if (header->adaption_field_control == AFC_ADAPTION_ONLY || header->adaption_field_control == AFC_BOTH) {
574 - if ((ret = adaption_field->demux(this, start, last, p)) != 0) { 952 + if ((ret = adaption_field->demux(ctx, this, start, last, p)) != 0) {
575 trace("ts+header af(adaption field) decode error. ret=%d", ret); 953 trace("ts+header af(adaption field) decode error. ret=%d", ret);
576 return ret; 954 return ret;
577 } 955 }
@@ -582,7 +960,7 @@ struct TSPacket @@ -582,7 +960,7 @@ struct TSPacket
582 payload->size = TS_PACKET_SIZE - header->get_size() - adaption_field->get_size(); 960 payload->size = TS_PACKET_SIZE - header->get_size() - adaption_field->get_size();
583 961
584 if (header->adaption_field_control == AFC_PAYLOAD_ONLY || header->adaption_field_control == AFC_BOTH) { 962 if (header->adaption_field_control == AFC_PAYLOAD_ONLY || header->adaption_field_control == AFC_BOTH) {
585 - if ((ret = payload->demux(this, start, last, p)) != 0) { 963 + if ((ret = payload->demux(ctx, this, start, last, p)) != 0) {
586 trace("ts+header payload decode error. ret=%d", ret); 964 trace("ts+header payload decode error. ret=%d", ret);
587 return ret; 965 return ret;
588 } 966 }
@@ -594,13 +972,60 @@ struct TSPacket @@ -594,13 +972,60 @@ struct TSPacket
594 payload->size - payload->pointer_field_size); 972 payload->size - payload->pointer_field_size);
595 973
596 return finish(); 974 return finish();
597 - } 975 +}
598 976
599 - int finish()  
600 - { 977 +int TSPacket::finish()
  978 +{
601 return 0; 979 return 0;
  980 +}
  981 +
  982 +TSHeader::TSHeader()
  983 +{
  984 +}
  985 +
  986 +TSHeader::~TSHeader()
  987 +{
  988 +}
  989 +
  990 +int TSHeader::get_size()
  991 +{
  992 + return 4;
  993 +}
  994 +
  995 +int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  996 +{
  997 + int ret = 0;
  998 +
  999 + // ts packet header.
  1000 + sync_byte = *p++;
  1001 + if (sync_byte != 0x47) {
  1002 + trace("ts+sync_bytes invalid sync_bytes: %#x, expect is 0x47", sync_byte);
  1003 + return -1;
602 } 1004 }
603 -}; 1005 +
  1006 + pid = 0;
  1007 + ((char*)&pid)[1] = *p++;
  1008 + ((char*)&pid)[0] = *p++;
  1009 +
  1010 + transport_error_indicator = (pid >> 15) & 0x01;
  1011 + payload_unit_start_indicator = (pid >> 14) & 0x01;
  1012 + transport_priority = (pid >> 13) & 0x01;
  1013 + pid &= 0x1FFF;
  1014 +
  1015 + ctx->push(TSPidTypePAT, pid);
  1016 +
  1017 + continuity_counter = *p++;
  1018 +
  1019 + transport_scrambling_control = (continuity_counter >> 6) & 0x03;
  1020 + adaption_field_control = (continuity_counter >> 4) & 0x03;
  1021 + continuity_counter &= 0x0F;
  1022 +
  1023 + trace("ts+header sync: %#x error: %d unit_start: %d priotiry: %d pid: %d scrambling: %d adaption: %d counter: %d",
  1024 + sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid,
  1025 + transport_scrambling_control, adaption_field_control, continuity_counter);
  1026 +
  1027 + return ret;
  1028 +}
604 1029
605 int main(int /*argc*/, char** /*argv*/) 1030 int main(int /*argc*/, char** /*argv*/)
606 { 1031 {
@@ -610,6 +1035,8 @@ int main(int /*argc*/, char** /*argv*/) @@ -610,6 +1035,8 @@ int main(int /*argc*/, char** /*argv*/)
610 1035
611 int ret = 0; 1036 int ret = 0;
612 trace("demuxer+read packet count offset T+0 T+1 T+2 T+3 T+x T+L2 T+L1 T+L0"); 1037 trace("demuxer+read packet count offset T+0 T+1 T+2 T+3 T+x T+L2 T+L1 T+L0");
  1038 +
  1039 + TSContext ctx;
613 for (int i = 0, offset = 0; ; i++) { 1040 for (int i = 0, offset = 0; ; i++) {
614 u_int8_t ts_packet[TS_PACKET_SIZE]; 1041 u_int8_t ts_packet[TS_PACKET_SIZE];
615 memset(ts_packet, 0, sizeof(ts_packet)); 1042 memset(ts_packet, 0, sizeof(ts_packet));
@@ -632,7 +1059,7 @@ int main(int /*argc*/, char** /*argv*/) @@ -632,7 +1059,7 @@ int main(int /*argc*/, char** /*argv*/)
632 u_int8_t* last = ts_packet + TS_PACKET_SIZE; 1059 u_int8_t* last = ts_packet + TS_PACKET_SIZE;
633 1060
634 TSPacket pkt; 1061 TSPacket pkt;
635 - if ((ret = pkt.demux(start, last, p)) != 0) { 1062 + if ((ret = pkt.demux(&ctx, start, last, p)) != 0) {
636 trace("demuxer+read decode ts packet error. ret=%d", ret); 1063 trace("demuxer+read decode ts packet error. ret=%d", ret);
637 return ret; 1064 return ret;
638 } 1065 }
@@ -41,7 +41,9 @@ file @@ -41,7 +41,9 @@ file
41 ..\core\srs_core_pithy_print.hpp, 41 ..\core\srs_core_pithy_print.hpp,
42 ..\core\srs_core_pithy_print.cpp, 42 ..\core\srs_core_pithy_print.cpp,
43 ..\core\srs_core_log.hpp, 43 ..\core\srs_core_log.hpp,
44 - ..\core\srs_core_log.cpp; 44 + ..\core\srs_core_log.cpp,
  45 + research readonly separator,
  46 + ..\..\research\ts_info.cpp;
45 mainconfig 47 mainconfig
46 "" = "MAIN"; 48 "" = "MAIN";
47 49