winlin

update ts_info, parse header, adaption field and PAT

1 /** 1 /**
2 g++ -o ts_info ts_info.cpp -g -O0 -ansi 2 g++ -o ts_info ts_info.cpp -g -O0 -ansi
3 */ 3 */
  4 +#if 1
4 #include <sys/types.h> 5 #include <sys/types.h>
5 #include <sys/stat.h> 6 #include <sys/stat.h>
6 #include <fcntl.h> 7 #include <fcntl.h>
7 #include <unistd.h> 8 #include <unistd.h>
8 #include <stdio.h> 9 #include <stdio.h>
9 #include <string.h> 10 #include <string.h>
  11 +#include <assert.h>
10 12
  13 +#define trace(msg, ...) printf(msg"\n", ##__VA_ARGS__);
  14 +#define srs_freep(p) delete p; p = NULL
  15 +#define srs_freepa(p) delete[] p; p = NULL
  16 +#define srs_assert(p) assert(p)
  17 +
  18 +#endif
11 /** 19 /**
12 ISO/IEC 13818-1:2000(E) 20 ISO/IEC 13818-1:2000(E)
13 Introduction 21 Introduction
14 Intro. 1 Transport Stream 22 Intro. 1 Transport Stream
15 - The Transport Stream system layer is divided into two sub-layers, one for multiplex-wide operations  
16 - (the Transport Stream packet layer), and one for stream-specific operations (the PES packet layer).  
17 Intro. 2 Program Stream 23 Intro. 2 Program Stream
18 - The Program Stream system layer is divided into two sub-layers, one for multiplex-wide operations  
19 - (the pack layer), and one for stream-specific operations (the PES packet layer).  
20 Intro. 4 Packetized Elementary Stream 24 Intro. 4 Packetized Elementary Stream
21 SECTION 2 ¨C TECHNICAL ELEMENTS 25 SECTION 2 ¨C TECHNICAL ELEMENTS
22 2.4 Transport Stream bitstream requirements 26 2.4 Transport Stream bitstream requirements
  27 + 2.4.1 Transport Stream coding structure and parameters
  28 + 2.4.2 Transport Stream system target decoder
  29 + 2.4.3 Specification of the Transport Stream syntax and semantics
  30 + 2.4.3.1 Transport Stream
  31 + 2.4.3.2 Transport Stream packet layer
  32 + 2.4.3.3 Semantic definition of fields in Transport Stream packet layer
  33 + 2.4.3.5 Semantic definition of fields in adaptation field
  34 + 2.4.3.6 PES packet
  35 + 2.4.3.7 Semantic definition of fields in PES packet
  36 + 2.4.4 Program specific information
  37 + 2.4.4.5 Semantic definition of fields in program association section
  38 + 2.4.4.6 Conditional access Table
23 2.5 Program Stream bitstream requirements 39 2.5 Program Stream bitstream requirements
24 2.6 Program and program element descriptors 40 2.6 Program and program element descriptors
25 2.7 Restrictions on the multiplexed stream semantics 41 2.7 Restrictions on the multiplexed stream semantics
26 Annex A ¨C CRC Decoder Model 42 Annex A ¨C CRC Decoder Model
27 */ 43 */
  44 +#if 1
  45 +// Transport Stream packets are 188 bytes in length.
  46 +#define TS_PACKET_SIZE 188
28 47
29 -#define trace(msg, ...) printf(msg"\n", ##__VA_ARGS__); 48 +// Program Association Table(see Table 2-25).
  49 +#define PID_PAT 0x00
  50 +// Conditional Access Table (see Table 2-27).
  51 +#define PID_CAT 0x01
  52 +// Transport Stream Description Table
  53 +#define PID_TSDT 0x02
  54 +// null packets (see Table 2-3)
  55 +#define PID_NULL 0x01FFF
  56 +
  57 +/*adaptation_field_control*/
  58 +// No adaptation_field, payload only
  59 +#define AFC_PAYLOAD_ONLY 0x01
  60 +// Adaptation_field only, no payload
  61 +#define AFC_ADAPTION_ONLY 0x02
  62 +// Adaptation_field followed by payload
  63 +#define AFC_BOTH 0x03
  64 +#endif
  65 +
  66 +struct TSPacket
  67 +{
  68 + // 4B ts packet header.
  69 + struct Header
  70 + {
  71 + // 1B
  72 + int8_t sync_byte; //8bits
  73 + // 2B
  74 + int8_t transport_error_indicator; //1bit
  75 + int8_t payload_unit_start_indicator; //1bit
  76 + int8_t transport_priority; //1bit
  77 + u_int16_t pid; //13bits
  78 + // 1B
  79 + int8_t transport_scrambling_control; //2bits
  80 + int8_t adaption_field_control; //2bits
  81 + u_int8_t continuity_counter; //4bits
  82 +
  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;
  121 +
  122 + // variant ts packet adation field.
  123 + struct AdaptionField
  124 + {
  125 + // 1B
  126 + u_int8_t adaption_field_length; //8bits
  127 + // 1B
  128 + int8_t discontinuity_indicator; //1bit
  129 + int8_t random_access_indicator; //1bit
  130 + int8_t elementary_stream_priority_indicator; //1bit
  131 + int8_t PCR_flag; //1bit
  132 + int8_t OPCR_flag; //1bit
  133 + int8_t splicing_point_flag; //1bit
  134 + int8_t transport_private_data_flag; //1bit
  135 + int8_t adaptation_field_extension_flag; //1bit
  136 +
  137 + // if PCR_flag, 6B
  138 + int64_t program_clock_reference_base; //33bits
  139 + //6bits reserved.
  140 + int16_t program_clock_reference_extension; //9bits
  141 +
  142 + // if OPCR_flag, 6B
  143 + int64_t original_program_clock_reference_base; //33bits
  144 + //6bits reserved.
  145 + int16_t original_program_clock_reference_extension; //9bits
  146 +
  147 + // if splicing_point_flag, 1B
  148 + int8_t splice_countdown; //8bits
  149 +
  150 + // if transport_private_data_flag, 1+p[0] B
  151 + u_int8_t transport_private_data_length; //8bits
  152 + char* transport_private_data; //[transport_private_data_length]bytes
  153 +
  154 + // if adaptation_field_extension_flag, 2+x bytes
  155 + u_int8_t adaptation_field_extension_length; //8bits
  156 + int8_t ltw_flag; //1bit
  157 + int8_t piecewise_rate_flag; //1bit
  158 + int8_t seamless_splice_flag; //1bit
  159 + //5bits reserved
  160 + // if ltw_flag, 2B
  161 + int8_t ltw_valid_flag; //1bit
  162 + int16_t ltw_offset; //15bits
  163 + // if piecewise_rate_flag, 3B
  164 + //2bits reserved
  165 + int32_t piecewise_rate; //22bits
  166 + // if seamless_splice_flag, 5B
  167 + int8_t splice_type; //4bits
  168 + int8_t DTS_next_AU0; //3bits
  169 + int8_t marker_bit0; //1bit
  170 + int16_t DTS_next_AU1; //15bits
  171 + int8_t marker_bit1; //1bit
  172 + int16_t DTS_next_AU2; //15bits
  173 + int8_t marker_bit2; //1bit
  174 + // left bytes.
  175 + char* af_ext_reserved;
  176 +
  177 + // left bytes.
  178 + char* af_reserved;
  179 +
  180 + // user defined data size.
  181 + int __user_size;
  182 +
  183 + AdaptionField()
  184 + {
  185 + transport_private_data = NULL;
  186 + af_ext_reserved = NULL;
  187 + af_reserved = NULL;
  188 +
  189 + __user_size = 0;
  190 + }
  191 +
  192 + virtual ~AdaptionField()
  193 + {
  194 + srs_freepa(transport_private_data);
  195 + srs_freepa(af_ext_reserved);
  196 + srs_freepa(af_reserved);
  197 + }
  198 +
  199 + int get_size()
  200 + {
  201 + return __user_size;
  202 + }
  203 +
  204 + int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  205 + {
  206 + int ret = 0;
  207 +
  208 + adaption_field_length = *p++;
  209 + u_int8_t* pos_af = p;
  210 + __user_size = 1 + adaption_field_length;
  211 +
  212 + if (adaption_field_length <= 0) {
  213 + trace("ts+af empty af decoded.");
  214 + return ret;
  215 + }
  216 +
  217 + int8_t value = *p++;
  218 +
  219 + discontinuity_indicator = (value >> 7) & 0x01;
  220 + random_access_indicator = (value >> 6) & 0x01;
  221 + elementary_stream_priority_indicator = (value >> 5) & 0x01;
  222 + PCR_flag = (value >> 4) & 0x01;
  223 + OPCR_flag = (value >> 3) & 0x01;
  224 + splicing_point_flag = (value >> 2) & 0x01;
  225 + transport_private_data_flag = (value >> 1) & 0x01;
  226 + adaptation_field_extension_flag = (value >> 0) & 0x01;
  227 +
  228 + trace("ts+af af flags parsed, discontinuity: %d random: %d priority: %d PCR: %d OPCR: %d slicing: %d private: %d extension: %d",
  229 + discontinuity_indicator, random_access_indicator, elementary_stream_priority_indicator, PCR_flag, OPCR_flag, splicing_point_flag,
  230 + transport_private_data_flag, adaptation_field_extension_flag);
  231 +
  232 + char* pp = NULL;
  233 + if (PCR_flag) {
  234 + pp = (char*)&program_clock_reference_base;
  235 + pp[5] = *p++;
  236 + pp[4] = *p++;
  237 + pp[3] = *p++;
  238 + pp[2] = *p++;
  239 + pp[1] = *p++;
  240 + pp[0] = *p++;
  241 +
  242 + program_clock_reference_extension = program_clock_reference_base & 0x1F;
  243 + program_clock_reference_base = (program_clock_reference_base >> 9) & 0x1FFFFFFFF;
  244 + }
  245 + if (OPCR_flag) {
  246 + pp = (char*)&original_program_clock_reference_base;
  247 + pp[5] = *p++;
  248 + pp[4] = *p++;
  249 + pp[3] = *p++;
  250 + pp[2] = *p++;
  251 + pp[1] = *p++;
  252 + pp[0] = *p++;
  253 +
  254 + original_program_clock_reference_extension = original_program_clock_reference_base & 0x1F;
  255 + original_program_clock_reference_base = (original_program_clock_reference_base >> 9) & 0x1FFFFFFFF;
  256 + }
  257 + if (splicing_point_flag) {
  258 + splice_countdown = *p++;
  259 + }
  260 + if (transport_private_data_flag) {
  261 + transport_private_data_length = *p++;
  262 + transport_private_data = new char[transport_private_data_length];
  263 + for (int i = 0; i < transport_private_data_length; i++) {
  264 + transport_private_data[i] = *p++;
  265 + }
  266 + }
  267 + if (adaptation_field_extension_flag) {
  268 + adaptation_field_extension_length = *p++;
  269 + u_int8_t* pos_af_ext = p;
  270 +
  271 + ltw_flag = *p++;
  272 +
  273 + piecewise_rate_flag = (ltw_flag >> 6) & 0x01;
  274 + seamless_splice_flag = (ltw_flag >> 5) & 0x01;
  275 + ltw_flag = (ltw_flag >> 7) & 0x01;
  276 +
  277 + if (ltw_flag) {
  278 + pp = (char*)&ltw_offset;
  279 + pp[1] = *p++;
  280 + pp[0] = *p++;
  281 +
  282 + ltw_valid_flag = (ltw_offset >> 15) &0x01;
  283 + ltw_offset &= 0x7FFF;
  284 + }
  285 + if (piecewise_rate_flag) {
  286 + pp = (char*)&piecewise_rate;
  287 + pp[2] = *p++;
  288 + pp[1] = *p++;
  289 + pp[0] = *p++;
  290 +
  291 + piecewise_rate &= 0x3FFFFF;
  292 + }
  293 + if (seamless_splice_flag) {
  294 + // 1B
  295 + marker_bit0 = *p++;
  296 +
  297 + splice_type = (marker_bit0 >> 4) & 0x0F;
  298 + DTS_next_AU0 = (marker_bit0 >> 1) & 0x07;
  299 + marker_bit0 &= 0x01;
  300 +
  301 + // 2B
  302 + pp = (char*)&DTS_next_AU1;
  303 + pp[1] = *p++;
  304 + pp[0] = *p++;
  305 +
  306 + marker_bit1 = DTS_next_AU1 & 0x01;
  307 + DTS_next_AU1 = (DTS_next_AU1 >> 1) & 0x7FFF;
  308 +
  309 + // 2B
  310 + pp = (char*)&DTS_next_AU2;
  311 + pp[1] = *p++;
  312 + pp[0] = *p++;
  313 +
  314 + marker_bit2 = DTS_next_AU2 & 0x01;
  315 + DTS_next_AU2 = (DTS_next_AU2 >> 1) & 0x7FFF;
  316 + }
  317 +
  318 + // af_ext_reserved
  319 + int ext_size = adaptation_field_extension_length - (p - pos_af_ext);
  320 + if (ext_size > 0) {
  321 + af_ext_reserved = new char[ext_size];
  322 + memcpy(af_ext_reserved, p, ext_size);
  323 + p += ext_size;
  324 + }
  325 + }
  326 +
  327 + // af_reserved
  328 + int af_size = adaption_field_length - (p - pos_af);
  329 + if (af_size > 0) {
  330 + af_reserved = new char[af_size];
  331 + memcpy(af_reserved, p, af_size);
  332 + p += af_size;
  333 + }
  334 +
  335 + 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;
  371 +
  372 + Reserved()
  373 + {
  374 + size = 0;
  375 + bytes = NULL;
  376 + }
  377 +
  378 + virtual ~Reserved()
  379 + {
  380 + srs_freepa(bytes);
  381 + }
  382 +
  383 + int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  384 + {
  385 + int ret = 0;
  386 +
  387 + size = ppkt->payload.size - ppkt->payload.pointer_field_size;
  388 +
  389 + // not parsed bytes.
  390 + if (size > 0) {
  391 + bytes = new char[size];
  392 + memcpy(bytes, p, size);
  393 + p += size;
  394 + }
  395 +
  396 + 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
  438 +
  439 + PAT()
  440 + {
  441 + programs = NULL;
  442 + }
  443 +
  444 + virtual ~PAT()
  445 + {
  446 + srs_freepa(programs);
  447 + }
  448 +
  449 + int get_program(int index)
  450 + {
  451 + srs_assert(index < program_size);
  452 + return programs[index] & 0x1FFF;
  453 + }
  454 +
  455 + int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  456 + {
  457 + int ret = 0;
  458 +
  459 + table_id = *p++;
  460 +
  461 + char* pp = (char*)&section_length;
  462 + pp[1] = *p++;
  463 + pp[0] = *p++;
  464 + u_int8_t* pos = p;
  465 +
  466 + section_syntax_indicator = (section_length >> 15) & 0x01;
  467 + const0_value = (section_length >> 14) & 0x01;
  468 + section_length &= 0x0FFF;
  469 +
  470 + pp = (char*)&transport_stream_id;
  471 + pp[1] = *p++;
  472 + pp[0] = *p++;
  473 +
  474 + current_next_indicator = *p++;
  475 + version_number = (current_next_indicator >> 1) & 0x1F;
  476 + current_next_indicator &= 0x01;
  477 +
  478 + section_number = *p++;
  479 + last_section_number = *p++;
  480 +
  481 + // 4 is crc size.
  482 + int program_bytes = section_length - 4 - (p - pos);
  483 + program_size = program_bytes / 4;
  484 + if (program_size > 0) {
  485 + programs = new int32_t[program_size];
  486 + for (int i = 0; i < program_size; i++) {
  487 + pp = (char*)&programs[i];
  488 + pp[3] = *p++;
  489 + pp[2] = *p++;
  490 + pp[1] = *p++;
  491 + pp[0] = *p++;
  492 + }
  493 + }
  494 +
  495 + pp = (char*)&CRC_32;
  496 + pp[3] = *p++;
  497 + pp[2] = *p++;
  498 + pp[1] = *p++;
  499 + pp[0] = *p++;
  500 +
  501 + return ret;
  502 + }
  503 + } *pat;
  504 +
  505 + /**
  506 + * 2.4.3.6 PES packet. page 49.
  507 + */
  508 +
  509 + Payload()
  510 + {
  511 + size = 0;
  512 + pointer_field_size = 0;
  513 +
  514 + type = TypeUnknown;
  515 + reserved = NULL;
  516 + pat = NULL;
  517 + }
  518 +
  519 + virtual ~Payload()
  520 + {
  521 + srs_freep(reserved);
  522 + srs_freep(pat);
  523 + }
  524 +
  525 + int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  526 + {
  527 + int ret = 0;
  528 +
  529 + if (ppkt->header.payload_unit_start_indicator) {
  530 + pointer_field = *p++;
  531 + pointer_field_size = 1;
  532 + }
  533 +
  534 + if (ppkt->header.pid == PID_PAT) {
  535 + type = TypePAT;
  536 + pat = new PAT();
  537 + return pat->demux(ppkt, start, last, p);
  538 + }
  539 +
  540 + // not parsed bytes.
  541 + type = TypeReserved;
  542 + reserved = new Reserved();
  543 + if ((ret = reserved->demux(ppkt, start, last, p)) != 0) {
  544 + return ret;
  545 + }
  546 +
  547 + return ret;
  548 + }
  549 + }payload;
  550 +
  551 + int demux(u_int8_t* start, u_int8_t* last, u_int8_t*& p)
  552 + {
  553 + int ret = 0;
  554 +
  555 + if ((ret = header.demux(this, start, last, p)) != 0) {
  556 + return ret;
  557 + }
  558 +
  559 + if (header.adaption_field_control == AFC_ADAPTION_ONLY || header.adaption_field_control == AFC_BOTH) {
  560 + if ((ret = adaption_field.demux(this, start, last, p)) != 0) {
  561 + trace("ts+header af(adaption field) decode error. ret=%d", ret);
  562 + return ret;
  563 + }
  564 + trace("ts+header af(adaption field decoded.");
  565 + }
  566 +
  567 + // calc the user defined data size for payload.
  568 + payload.size = TS_PACKET_SIZE - header.get_size() - adaption_field.get_size();
  569 +
  570 + if (header.adaption_field_control == AFC_PAYLOAD_ONLY || header.adaption_field_control == AFC_BOTH) {
  571 + if ((ret = payload.demux(this, start, last, p)) != 0) {
  572 + trace("ts+header payload decode error. ret=%d", ret);
  573 + return ret;
  574 + }
  575 + trace("ts+header payload decoded.");
  576 + }
  577 +
  578 + trace("ts+header parsed finished. parsed: %d left: %d header: %d payload: %d(%d+%d)",
  579 + (int)(p - start), (int)(last - p), header.get_size(), payload.size, payload.pointer_field_size,
  580 + payload.size - payload.pointer_field_size);
  581 +
  582 + return finish();
  583 + }
  584 +
  585 + int finish()
  586 + {
  587 + return 0;
  588 + }
  589 +};
30 590
31 int main(int /*argc*/, char** /*argv*/) 591 int main(int /*argc*/, char** /*argv*/)
32 { 592 {
33 const char* file = "livestream-1347.ts"; 593 const char* file = "livestream-1347.ts";
  594 + //file = "nginx-rtmp-hls/livestream-1347-currupt.ts";
34 int fd = open(file, O_RDONLY); 595 int fd = open(file, O_RDONLY);
35 596
36 - trace("demuxer+read packet count offset P+0 P+1 P+2 P+x P+L2 P+L1 P+L0"); 597 + int ret = 0;
  598 + trace("demuxer+read packet count offset T+0 T+1 T+2 T+3 T+x T+L2 T+L1 T+L0");
37 for (int i = 0, offset = 0; ; i++) { 599 for (int i = 0, offset = 0; ; i++) {
38 - unsigned char PES[188];  
39 - memset(PES, 0, sizeof(PES)); 600 + u_int8_t ts_packet[TS_PACKET_SIZE];
  601 + memset(ts_packet, 0, sizeof(ts_packet));
40 602
41 - int ret = read(fd, PES, sizeof(PES));  
42 - if (ret == 0) {  
43 - trace("demuxer+read EOF, read completed, offset: %07d.", offset); 603 + int nread = read(fd, ts_packet, sizeof(ts_packet));
  604 + if (nread == 0) {
  605 + trace("demuxer+read got EOF, read completed, offset: %07d.", offset);
44 break; 606 break;
45 } 607 }
46 - trace("demuxer+read packet %04d %07d 0x%02x 0x%02x 0x%02x ... 0x%02x 0x%02x 0x%02x",  
47 - i, offset, PES[0], PES[1], PES[2], PES[185], PES[186], PES[187]); 608 + if (nread != TS_PACKET_SIZE) {
  609 + trace("demuxer+read error to read ts packet. nread=%d", nread);
  610 + break;
  611 + }
  612 + trace("demuxer+read packet %04d %07d 0x%02x 0x%02x 0x%02x 0x%02x ... 0x%02x 0x%02x 0x%02x",
  613 + i, offset, ts_packet[0], ts_packet[1], ts_packet[2], ts_packet[3],
  614 + ts_packet[TS_PACKET_SIZE - 3], ts_packet[TS_PACKET_SIZE - 2], ts_packet[TS_PACKET_SIZE - 1]);
  615 +
  616 + u_int8_t* p = ts_packet;
  617 + u_int8_t* start = ts_packet;
  618 + u_int8_t* last = ts_packet + TS_PACKET_SIZE;
48 619
  620 + TSPacket pkt;
  621 + if ((ret = pkt.demux(start, last, p)) != 0) {
  622 + trace("demuxer+read decode ts packet error. ret=%d", ret);
  623 + return ret;
  624 + }
49 625
50 - offset += ret; 626 + offset += nread;
51 } 627 }
52 628
53 close(fd); 629 close(fd);
54 - return 0; 630 + return ret;
55 } 631 }
56 632