正在显示
2 个修改的文件
包含
276 行增加
和
147 行删除
@@ -228,52 +228,114 @@ TS的第二个视频包数据如下: | @@ -228,52 +228,114 @@ TS的第二个视频包数据如下: | ||
228 | 228 | ||
229 | 229 | ||
230 | 230 | ||
231 | -3031个ts包是空包,解析有问题: | ||
232 | -47 41 00 38 07 50 05 09 5A A6 7E 00 00 00 01 E0 | ||
233 | -00 00 80 C0 0A 31 28 53 60 81 11 28 53 42 F9 00 | ||
234 | -00 00 01 09 F0 00 00 00 01 67 64 00 28 AC D1 C0 | ||
235 | -50 05 BB FF 00 2D 00 22 10 00 00 03 00 10 00 00 | ||
236 | -03 03 08 F1 83 11 E0 00 00 00 01 68 E9 AB 2C 8B | ||
237 | -00 00 01 65 88 84 00 42 BF 08 EE 00 02 B2 75 8D | ||
238 | -9F C4 24 E5 BD 27 87 F1 E4 09 A0 51 2D 12 FC F5 | ||
239 | -6E 31 3D C4 0E 3F 51 47 07 BD D2 8C AB 72 1C 2D | ||
240 | -D0 FA 2F 7D EF AA FB 17 C1 08 AD 36 8D F1 41 35 | ||
241 | -E0 20 AE E8 75 66 39 15 78 88 01 E8 2E 4E 8A 8B | ||
242 | -F8 04 68 BF EC 82 59 86 DE E1 66 32 37 FA 78 6D | ||
243 | -01 EF C0 2C 6B A6 E9 36 44 4B C8 37 | ||
244 | - | ||
245 | -Adaptation fields | ||
246 | - Adaptation_field_length: 7 | ||
247 | - discontinuity_indicator: False | ||
248 | - random_access_indicator: True | ||
249 | - ES_priority_indicator: False | ||
250 | - PCR_flag: True | ||
251 | - OPCR_flag: False | ||
252 | - splicing_point_flag: False | ||
253 | - transport_private_data_flag: False | ||
254 | - adaptation_field_extension_flag: False | ||
255 | - PCR: 50699466000 | ||
256 | - | ||
257 | -PES header | ||
258 | - stream_id: E0 (video stream 224) | ||
259 | - PES_packet_length: 0 (undefined) | ||
260 | - PES_scrambling: 0 | ||
261 | - PES_priority: False | ||
262 | - data_alignment: False | ||
263 | - copyright: False | ||
264 | - original_or_copy: False | ||
265 | - PTS_flag: True | ||
266 | - DTS_flag: True | ||
267 | - ESCR_flag: False | ||
268 | - ES_rate_flag: False | ||
269 | - DSM_trick_mode_flag: False | ||
270 | - additional_copy_info_flag: False | ||
271 | - PES_CRC_flag: False | ||
272 | - PES_extension_flag: False | ||
273 | - PES_header_data_length: 10 | ||
274 | - PTS: 169128000 | ||
275 | - DTS: 169124220 | ||
276 | - | ||
277 | -Video sequence | ||
278 | -Sequence header code not found in this packet | ||
279 | -AFD not found in this packet | ||
231 | +第3030个包解析有点问题,设置条件断点: | ||
232 | +condition 1 ctx->ts_packet_count == 3030 | ||
233 | +发现数据如下: | ||
234 | +(gdb) x /188xb 0x7fffffffe2f0 | ||
235 | +0x7fffffffe2f0: 0x47 0x41 0x00 0x38 0x07 0x50 0x05 0x09 | ||
236 | +0x7fffffffe2f8: 0x5a 0xa6 0x7e 0x00 0x00 0x00 0x01 0xe0 | ||
237 | +0x7fffffffe300: 0x00 0x00 0x80 0xc0 0x0a 0x31 0x28 0x53 | ||
238 | +0x7fffffffe308: 0x60 0x81 0x11 0x28 0x53 0x42 0xf9 0x00 | ||
239 | +0x7fffffffe310: 0x00 0x00 0x01 0x09 0xf0 0x00 0x00 0x00 | ||
240 | +0x7fffffffe318: 0x01 0x67 0x64 0x00 0x28 0xac 0xd1 0xc0 | ||
241 | +0x7fffffffe320: 0x50 0x05 0xbb 0xff 0x00 0x2d 0x00 0x22 | ||
242 | +0x7fffffffe328: 0x10 0x00 0x00 0x03 0x00 0x10 0x00 0x00 | ||
243 | +0x7fffffffe330: 0x03 0x03 0x08 0xf1 0x83 0x11 0xe0 0x00 | ||
244 | +0x7fffffffe338: 0x00 0x00 0x01 0x68 0xe9 0xab 0x2c 0x8b | ||
245 | +0x7fffffffe340: 0x00 0x00 0x01 0x65 0x88 0x84 0x00 0x42 | ||
246 | +0x7fffffffe348: 0xbf 0x08 0xee 0x00 0x02 0xb2 0x75 0x8d | ||
247 | +0x7fffffffe350: 0x9f 0xc4 0x24 0xe5 0xbd 0x27 0x87 0xf1 | ||
248 | +0x7fffffffe358: 0xe4 0x09 0xa0 0x51 0x2d 0x12 0xfc 0xf5 | ||
249 | +0x7fffffffe360: 0x6e 0x31 0x3d 0xc4 0x0e 0x3f 0x51 0x47 | ||
250 | +0x7fffffffe368: 0x07 0xbd 0xd2 0x8c 0xab 0x72 0x1c 0x2d | ||
251 | +0x7fffffffe370: 0xd0 0xfa 0x2f 0x7d 0xef 0xaa 0xfb 0x17 | ||
252 | +0x7fffffffe378: 0xc1 0x08 0xad 0x36 0x8d 0xf1 0x41 0x35 | ||
253 | +0x7fffffffe380: 0xe0 0x20 0xae 0xe8 0x75 0x66 0x39 0x15 | ||
254 | +0x7fffffffe388: 0x78 0x88 0x01 0xe8 0x2e 0x4e 0x8a 0x8b | ||
255 | +0x7fffffffe390: 0xf8 0x04 0x68 0xbf 0xec 0x82 0x59 0x86 | ||
256 | +0x7fffffffe398: 0xde 0xe1 0x66 0x32 0x37 0xfa 0x78 0x6d | ||
257 | +0x7fffffffe3a0: 0x01 0xef 0xc0 0x2c 0x6b 0xa6 0xe9 0x36 | ||
258 | +0x7fffffffe3a8: 0x44 0x4b 0xc8 0x37 | ||
259 | +header解析如下: | ||
260 | +(gdb) p *this | ||
261 | +$74 = {_vptr.TSHeader = 0x4080b0, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
262 | + payload_unit_start_indicator = 1 '\001', transport_priority = 0 '\000', pid = 256, | ||
263 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypeBoth, continuity_counter = 8 '\b'} | ||
264 | +(gdb) p ctx->get(pid)[0] | ||
265 | +$76 = {type = TSPidTypeVideo, stream_type = TSStreamTypeVideoH264, pid = 256, continuity_counter = 8 '\b'} | ||
266 | +(gdb) p ctx->get_msg(256)[0] | ||
267 | +$124 = {_vptr.TSMessage = 0x408290, pid = 256, type = TSPidTypeVideo, stream_type = TSStreamTypeVideoH264, | ||
268 | + continuity_counter = 8 '\b', PES_packet_length = 0, stream_id = 224 '\340', packet_start_code_prefix = 1, | ||
269 | + packet_header_size = 13, parsed_packet_size = 144, packet_data_size = 144, packet_data = 0x60b300 ""} | ||
270 | +特殊的是:PES_packet_length为0,也就是未知长度。 | ||
271 | +解析下一个包,header为: | ||
272 | +(gdb) p header[0] | ||
273 | +$123 = {_vptr.TSHeader = 0x408170, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
274 | + payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256, | ||
275 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
276 | + continuity_counter = 9 '\t'} | ||
277 | +这个包的标识是continuity_counter为上一个包的连续。这个包里面是纯粹的数据: | ||
278 | +(gdb) x /184xb 0x7fffffffe2f4 | ||
279 | +0x7fffffffe2f4: 0x9c 0xfa 0x8c 0xc9 0x02 0x36 0xc2 0x46 | ||
280 | +0x7fffffffe2fc: 0x97 0x01 0x31 0x3d 0xfa 0x83 0xc2 0x88 | ||
281 | +0x7fffffffe304: 0x6b 0xb3 0x1c 0x63 0xcf 0xc6 0xc4 0xa6 | ||
282 | +0x7fffffffe30c: 0xe2 0xa7 0xb3 0x26 0x62 0x7e 0xb4 0xf0 | ||
283 | +0x7fffffffe314: 0x17 0x13 0x4c 0xd5 0x1b 0xee 0x80 0x37 | ||
284 | +0x7fffffffe31c: 0x8f 0x6a 0xad 0x41 0x8f 0x43 0x39 0xbe | ||
285 | +0x7fffffffe324: 0x2f 0x51 0xb4 0x0a 0x54 0x62 0xab 0xdc | ||
286 | +0x7fffffffe32c: 0x11 0x92 0x92 0x85 0x18 0x92 0x29 0xd5 | ||
287 | +0x7fffffffe334: 0xb5 0xbc 0x00 0x9e 0x26 0xc3 0xa4 0x04 | ||
288 | +0x7fffffffe33c: 0xb6 0x97 0x62 0x9b 0x3b 0x3c 0x09 0x6b | ||
289 | +0x7fffffffe344: 0x68 0x15 0xe7 0xcc 0x71 0xd9 0xb5 0x02 | ||
290 | +0x7fffffffe34c: 0x19 0x8a 0x06 0x90 0x22 0xcd 0x3e 0x82 | ||
291 | +0x7fffffffe354: 0xff 0x48 0x73 0x8b 0x00 0xdc 0xe5 0xdb | ||
292 | +0x7fffffffe35c: 0x83 0x13 0x5e 0xe8 0x63 0xe9 0xb6 0xf0 | ||
293 | +0x7fffffffe364: 0xc5 0x21 0x03 0x57 0xfb 0xb2 0xe1 0x9c | ||
294 | +0x7fffffffe36c: 0x71 0x3e 0x36 0xe3 0x05 0xb7 0xf1 0x85 | ||
295 | +0x7fffffffe374: 0x88 0x0e 0x51 0x52 0xd8 0x3c 0x80 0x1a | ||
296 | +0x7fffffffe37c: 0x34 0xff 0xd9 0x5f 0x69 0xb4 0x9d 0xd7 | ||
297 | +0x7fffffffe384: 0xc2 0x21 0xa8 0x85 0xc8 0xa2 0xdd 0xb8 | ||
298 | +0x7fffffffe38c: 0xa3 0x43 0x2f 0x7e 0xc8 0xac 0x1b 0x67 | ||
299 | +0x7fffffffe394: 0x17 0x6c 0x74 0xea 0x97 0xb8 0xa4 0xcf | ||
300 | +0x7fffffffe39c: 0x43 0xf3 0x1c 0xad 0x89 0x91 0x28 0x49 | ||
301 | +0x7fffffffe3a4: 0xf2 0xe8 0x0c 0xbf 0x75 0x8a 0x1c 0xac | ||
302 | +后续还有几个包: | ||
303 | +$136 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
304 | + payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256, | ||
305 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
306 | + continuity_counter = 10 '\n'} | ||
307 | +$137 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
308 | + payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256, | ||
309 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
310 | + continuity_counter = 11 '\v'} | ||
311 | +$138 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
312 | + payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256, | ||
313 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
314 | + continuity_counter = 12 '\f'} | ||
315 | +$141 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
316 | + payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256, | ||
317 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
318 | + continuity_counter = 13 '\r'} | ||
319 | +$142 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
320 | + payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256, | ||
321 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
322 | + continuity_counter = 14 '\016'} | ||
323 | +$143 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
324 | + payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256, | ||
325 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
326 | + continuity_counter = 15 '\017'} | ||
327 | +然后,这个包变了,但是还是继续前面的包,因为是0xF溢出: | ||
328 | +$144 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
329 | + payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256, | ||
330 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
331 | + continuity_counter = 0 '\000'} | ||
332 | +$148 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
333 | + payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256, | ||
334 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
335 | + continuity_counter = 1 '\001'} | ||
336 | +如此循环,可以循环很多次。一直到这个包: | ||
337 | +$556 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000', | ||
338 | + payload_unit_start_indicator = 1 '\001', transport_priority = 0 '\000', pid = 256, | ||
339 | + transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly, | ||
340 | + continuity_counter = 4 '\004'} | ||
341 | +其中的:payload_unit_start_indicator为1。 |
@@ -13,6 +13,7 @@ g++ -o ts_info ts_info.cpp -g -O0 -ansi | @@ -13,6 +13,7 @@ g++ -o ts_info ts_info.cpp -g -O0 -ansi | ||
13 | #include <fcntl.h> | 13 | #include <fcntl.h> |
14 | #include <unistd.h> | 14 | #include <unistd.h> |
15 | #include <stdio.h> | 15 | #include <stdio.h> |
16 | +#include <stdlib.h> | ||
16 | #include <string.h> | 17 | #include <string.h> |
17 | #include <assert.h> | 18 | #include <assert.h> |
18 | 19 | ||
@@ -55,22 +56,33 @@ Annex A C CRC Decoder Model | @@ -55,22 +56,33 @@ Annex A C CRC Decoder Model | ||
55 | // Transport Stream packets are 188 bytes in length. | 56 | // Transport Stream packets are 188 bytes in length. |
56 | #define TS_PACKET_SIZE 188 | 57 | #define TS_PACKET_SIZE 188 |
57 | 58 | ||
58 | -// Program Association Table(see Table 2-25). | ||
59 | -#define PID_PAT 0x00 | ||
60 | -// Conditional Access Table (see Table 2-27). | ||
61 | -#define PID_CAT 0x01 | ||
62 | -// Transport Stream Description Table | ||
63 | -#define PID_TSDT 0x02 | ||
64 | -// null packets (see Table 2-3) | ||
65 | -#define PID_NULL 0x01FFF | 59 | +enum TSPidTable |
60 | +{ | ||
61 | + // Program Association Table(see Table 2-25). | ||
62 | + TSPidTablePAT = 0x00, | ||
63 | + // Conditional Access Table (see Table 2-27). | ||
64 | + TSPidTableCAT = 0x01, | ||
65 | + // Transport Stream Description Table | ||
66 | + TSPidTableTSDT = 0x02, | ||
67 | + // null packets (see Table 2-3) | ||
68 | + TSPidTableNULL = 0x01FFF, | ||
69 | +}; | ||
66 | 70 | ||
67 | /*adaptation_field_control*/ | 71 | /*adaptation_field_control*/ |
68 | -// No adaptation_field, payload only | ||
69 | -#define AFC_PAYLOAD_ONLY 0x01 | ||
70 | -// Adaptation_field only, no payload | ||
71 | -#define AFC_ADAPTION_ONLY 0x02 | ||
72 | -// Adaptation_field followed by payload | ||
73 | -#define AFC_BOTH 0x03 | 72 | +/** |
73 | +* Table 2-5 – Adaptation field control values, page 38. | ||
74 | +*/ | ||
75 | +enum TSAdaptionType | ||
76 | +{ | ||
77 | + // Reserved for future use by ISO/IEC | ||
78 | + TSAdaptionTypeReserved = 0x00, | ||
79 | + // No adaptation_field, payload only | ||
80 | + TSAdaptionTypePayloadOnly = 0x01, | ||
81 | + // Adaptation_field only, no payload | ||
82 | + TSAdaptionTypeAdaptionOnly = 0x02, | ||
83 | + // Adaptation_field followed by payload | ||
84 | + TSAdaptionTypeBoth = 0x03, | ||
85 | +}; | ||
74 | #endif | 86 | #endif |
75 | 87 | ||
76 | // Table 2-29 – Stream type assignments. page 66. | 88 | // Table 2-29 – Stream type assignments. page 66. |
@@ -143,10 +155,10 @@ public: | @@ -143,10 +155,10 @@ public: | ||
143 | int8_t transport_error_indicator; //1bit | 155 | int8_t transport_error_indicator; //1bit |
144 | int8_t payload_unit_start_indicator; //1bit | 156 | int8_t payload_unit_start_indicator; //1bit |
145 | int8_t transport_priority; //1bit | 157 | int8_t transport_priority; //1bit |
146 | - u_int16_t pid; //13bits | 158 | + TSPidTable pid; //13bits |
147 | // 1B | 159 | // 1B |
148 | int8_t transport_scrambling_control; //2bits | 160 | int8_t transport_scrambling_control; //2bits |
149 | - int8_t adaption_field_control; //2bits | 161 | + TSAdaptionType adaption_field_control; //2bits |
150 | u_int8_t continuity_counter; //4bits | 162 | u_int8_t continuity_counter; //4bits |
151 | 163 | ||
152 | TSHeader(); | 164 | TSHeader(); |
@@ -214,8 +226,8 @@ public: | @@ -214,8 +226,8 @@ public: | ||
214 | // left bytes. | 226 | // left bytes. |
215 | char* af_reserved; | 227 | char* af_reserved; |
216 | 228 | ||
217 | - // user defined data size. | ||
218 | - int __user_size; | 229 | + // user defined total adaption field size. |
230 | + int __field_size; | ||
219 | 231 | ||
220 | TSAdaptionField(); | 232 | TSAdaptionField(); |
221 | virtual ~TSAdaptionField(); | 233 | virtual ~TSAdaptionField(); |
@@ -510,9 +522,13 @@ public: | @@ -510,9 +522,13 @@ public: | ||
510 | */ | 522 | */ |
511 | struct TSPid | 523 | struct TSPid |
512 | { | 524 | { |
513 | - TSStreamType stream_type; | ||
514 | TSPidType type; | 525 | TSPidType type; |
515 | - int16_t pid; | 526 | + // page 66. |
527 | + TSStreamType stream_type; | ||
528 | + // page 36 | ||
529 | + TSPidTable pid; | ||
530 | + // page 36 | ||
531 | + u_int8_t continuity_counter; | ||
516 | }; | 532 | }; |
517 | 533 | ||
518 | /** | 534 | /** |
@@ -523,12 +539,14 @@ class TSMessage | @@ -523,12 +539,14 @@ class TSMessage | ||
523 | public: | 539 | public: |
524 | // 2.4.3.2 Transport Stream packet layer. page 36 | 540 | // 2.4.3.2 Transport Stream packet layer. page 36 |
525 | // the pid of PES packet. | 541 | // the pid of PES packet. |
526 | - int16_t pid; | 542 | + TSPidTable pid; |
527 | 543 | ||
528 | // the type of pid. | 544 | // the type of pid. |
529 | TSPidType type; | 545 | TSPidType type; |
530 | // the type of stream, codec type. | 546 | // the type of stream, codec type. |
531 | TSStreamType stream_type; | 547 | TSStreamType stream_type; |
548 | + // page 36 | ||
549 | + u_int8_t continuity_counter; | ||
532 | 550 | ||
533 | // 2.4.3.7 Semantic definition of fields in PES packet. page 49 | 551 | // 2.4.3.7 Semantic definition of fields in PES packet. page 49 |
534 | // PES packet header size plus data size. | 552 | // PES packet header size plus data size. |
@@ -569,15 +587,15 @@ public: | @@ -569,15 +587,15 @@ public: | ||
569 | int pid_size; | 587 | int pid_size; |
570 | TSPid* pids; | 588 | TSPid* pids; |
571 | int64_t ts_packet_count; | 589 | int64_t ts_packet_count; |
572 | - std::map<int16_t, TSMessage*> msgs; | 590 | + std::map<TSPidTable, TSMessage*> msgs; |
573 | 591 | ||
574 | TSContext(); | 592 | TSContext(); |
575 | virtual ~TSContext(); | 593 | virtual ~TSContext(); |
576 | - bool exists(int16_t pid); | ||
577 | - TSPid* get(int16_t pid); | ||
578 | - void push(TSStreamType stream_type, TSPidType type, int16_t pid); | 594 | + bool exists(TSPidTable pid); |
595 | + TSPid* get(TSPidTable pid); | ||
596 | + void push(TSPidTable pid, TSStreamType stream_type, TSPidType type, u_int8_t continuity_counter); | ||
579 | 597 | ||
580 | - TSMessage* get_msg(int16_t pid); | 598 | + TSMessage* get_msg(TSPidTable pid); |
581 | void detach(TSMessage* msg); | 599 | void detach(TSMessage* msg); |
582 | }; | 600 | }; |
583 | 601 | ||
@@ -592,7 +610,7 @@ TSContext::~TSContext() | @@ -592,7 +610,7 @@ TSContext::~TSContext() | ||
592 | { | 610 | { |
593 | srs_freepa(pids); | 611 | srs_freepa(pids); |
594 | 612 | ||
595 | - std::map<int16_t, TSMessage*>::iterator it; | 613 | + std::map<TSPidTable, TSMessage*>::iterator it; |
596 | for (it = msgs.begin(); it != msgs.end(); ++it) { | 614 | for (it = msgs.begin(); it != msgs.end(); ++it) { |
597 | TSMessage* msg = it->second; | 615 | TSMessage* msg = it->second; |
598 | srs_freep(msg); | 616 | srs_freep(msg); |
@@ -600,7 +618,7 @@ TSContext::~TSContext() | @@ -600,7 +618,7 @@ TSContext::~TSContext() | ||
600 | msgs.clear(); | 618 | msgs.clear(); |
601 | } | 619 | } |
602 | 620 | ||
603 | -bool TSContext::exists(int16_t pid) | 621 | +bool TSContext::exists(TSPidTable pid) |
604 | { | 622 | { |
605 | for (int i = 0; i < pid_size; i++) { | 623 | for (int i = 0; i < pid_size; i++) { |
606 | if (pid == pids[i].pid) { | 624 | if (pid == pids[i].pid) { |
@@ -611,7 +629,7 @@ bool TSContext::exists(int16_t pid) | @@ -611,7 +629,7 @@ bool TSContext::exists(int16_t pid) | ||
611 | return false; | 629 | return false; |
612 | } | 630 | } |
613 | 631 | ||
614 | -TSPid* TSContext::get(int16_t pid) | 632 | +TSPid* TSContext::get(TSPidTable pid) |
615 | { | 633 | { |
616 | for (int i = 0; i < pid_size; i++) { | 634 | for (int i = 0; i < pid_size; i++) { |
617 | if (pid == pids[i].pid) { | 635 | if (pid == pids[i].pid) { |
@@ -622,23 +640,25 @@ TSPid* TSContext::get(int16_t pid) | @@ -622,23 +640,25 @@ TSPid* TSContext::get(int16_t pid) | ||
622 | return NULL; | 640 | return NULL; |
623 | } | 641 | } |
624 | 642 | ||
625 | -void TSContext::push(TSStreamType stream_type, TSPidType type, int16_t pid) | 643 | +void TSContext::push(TSPidTable pid, TSStreamType stream_type, TSPidType type, u_int8_t continuity_counter) |
626 | { | 644 | { |
627 | - if (exists(pid)) { | ||
628 | - return; | 645 | + TSPid* p = get(pid); |
646 | + | ||
647 | + if (!p) { | ||
648 | + p = new TSPid[pid_size + 1]; | ||
649 | + memcpy(p, pids, sizeof(TSPid) * pid_size); | ||
650 | + | ||
651 | + p[pid_size] = (TSPid){type, stream_type, pid, continuity_counter}; | ||
652 | + pid_size++; | ||
653 | + | ||
654 | + srs_freepa(pids); | ||
655 | + pids = p; | ||
629 | } | 656 | } |
630 | 657 | ||
631 | - TSPid* p = new TSPid[pid_size + 1]; | ||
632 | - memcpy(p, pids, sizeof(TSPid) * pid_size); | ||
633 | - | ||
634 | - p[pid_size] = (TSPid){stream_type, type, pid}; | ||
635 | - pid_size++; | ||
636 | - | ||
637 | - srs_freepa(pids); | ||
638 | - pids = p; | 658 | + p->continuity_counter = continuity_counter; |
639 | } | 659 | } |
640 | 660 | ||
641 | -TSMessage* TSContext::get_msg(int16_t pid) | 661 | +TSMessage* TSContext::get_msg(TSPidTable pid) |
642 | { | 662 | { |
643 | if (msgs[pid] == NULL) { | 663 | if (msgs[pid] == NULL) { |
644 | TSMessage* msg = new TSMessage(); | 664 | TSMessage* msg = new TSMessage(); |
@@ -656,7 +676,7 @@ void TSContext::detach(TSMessage* msg) | @@ -656,7 +676,7 @@ void TSContext::detach(TSMessage* msg) | ||
656 | 676 | ||
657 | TSMessage::TSMessage() | 677 | TSMessage::TSMessage() |
658 | { | 678 | { |
659 | - pid = 0; | 679 | + pid = TSPidTablePAT; |
660 | type = TSPidTypeReserved; | 680 | type = TSPidTypeReserved; |
661 | stream_type = TSStreamTypeReserved; | 681 | stream_type = TSStreamTypeReserved; |
662 | stream_id = 0; | 682 | stream_id = 0; |
@@ -675,11 +695,21 @@ TSMessage::~TSMessage() | @@ -675,11 +695,21 @@ TSMessage::~TSMessage() | ||
675 | 695 | ||
676 | void TSMessage::append(u_int8_t*& p, int size) | 696 | void TSMessage::append(u_int8_t*& p, int size) |
677 | { | 697 | { |
678 | - if (size > 0) { | ||
679 | - memcpy(packet_data + parsed_packet_size, p, size); | ||
680 | - p += size; | ||
681 | - parsed_packet_size += size; | 698 | + if (size <= 0) { |
699 | + return; | ||
682 | } | 700 | } |
701 | + | ||
702 | + // for PES_packet_length is 0, the size is varient. | ||
703 | + if (packet_data_size - parsed_packet_size < size) { | ||
704 | + int realloc_size = size - (packet_data_size - parsed_packet_size); | ||
705 | + packet_data = (char*)realloc(packet_data, packet_data_size + realloc_size); | ||
706 | + | ||
707 | + packet_data_size += realloc_size; | ||
708 | + } | ||
709 | + | ||
710 | + memcpy(packet_data + parsed_packet_size, p, size); | ||
711 | + p += size; | ||
712 | + parsed_packet_size += size; | ||
683 | } | 713 | } |
684 | 714 | ||
685 | void TSMessage::detach(TSContext* ctx, TSMessage*& pmsg) | 715 | void TSMessage::detach(TSContext* ctx, TSMessage*& pmsg) |
@@ -729,7 +759,7 @@ TSAdaptionField::TSAdaptionField() | @@ -729,7 +759,7 @@ TSAdaptionField::TSAdaptionField() | ||
729 | marker_bit2 = 0; | 759 | marker_bit2 = 0; |
730 | af_ext_reserved = NULL; | 760 | af_ext_reserved = NULL; |
731 | af_reserved = NULL; | 761 | af_reserved = NULL; |
732 | - __user_size = 0; | 762 | + __field_size = 0; |
733 | } | 763 | } |
734 | 764 | ||
735 | TSAdaptionField::~TSAdaptionField() | 765 | TSAdaptionField::~TSAdaptionField() |
@@ -741,7 +771,7 @@ TSAdaptionField::~TSAdaptionField() | @@ -741,7 +771,7 @@ TSAdaptionField::~TSAdaptionField() | ||
741 | 771 | ||
742 | int TSAdaptionField::get_size() | 772 | int TSAdaptionField::get_size() |
743 | { | 773 | { |
744 | - return __user_size; | 774 | + return __field_size; |
745 | } | 775 | } |
746 | 776 | ||
747 | int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg) | 777 | int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg) |
@@ -750,7 +780,7 @@ int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int | @@ -750,7 +780,7 @@ int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int | ||
750 | 780 | ||
751 | adaption_field_length = *p++; | 781 | adaption_field_length = *p++; |
752 | u_int8_t* pos_af = p; | 782 | u_int8_t* pos_af = p; |
753 | - __user_size = 1 + adaption_field_length; | 783 | + __field_size = 1 + adaption_field_length; |
754 | 784 | ||
755 | if (adaption_field_length <= 0) { | 785 | if (adaption_field_length <= 0) { |
756 | trace("ts+af empty af decoded."); | 786 | trace("ts+af empty af decoded."); |
@@ -965,7 +995,7 @@ int TSPayloadPAT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | @@ -965,7 +995,7 @@ int TSPayloadPAT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | ||
965 | pp[0] = *p++; | 995 | pp[0] = *p++; |
966 | 996 | ||
967 | int16_t pid = programs[i] & 0x1FFF; | 997 | int16_t pid = programs[i] & 0x1FFF; |
968 | - ctx->push(TSStreamTypeReserved, TSPidTypePMT, pid); | 998 | + ctx->push((TSPidTable)pid, TSStreamTypeReserved, TSPidTypePMT, pkt->header->continuity_counter); |
969 | } | 999 | } |
970 | } | 1000 | } |
971 | 1001 | ||
@@ -1102,12 +1132,12 @@ int TSPayloadPMT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | @@ -1102,12 +1132,12 @@ int TSPayloadPMT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | ||
1102 | 1132 | ||
1103 | if (info->stream_type == TSStreamTypeVideoH264) { | 1133 | if (info->stream_type == TSStreamTypeVideoH264) { |
1104 | // TODO: support more video type. | 1134 | // TODO: support more video type. |
1105 | - ctx->push((TSStreamType)info->stream_type, TSPidTypeVideo, info->elementary_PID); | 1135 | + ctx->push((TSPidTable)info->elementary_PID, (TSStreamType)info->stream_type, TSPidTypeVideo, pkt->header->continuity_counter); |
1106 | trace("ts+pmt add pid: %d, type: H264 video", info->elementary_PID); | 1136 | trace("ts+pmt add pid: %d, type: H264 video", info->elementary_PID); |
1107 | } else if (info->stream_type == TSStreamTypeAudioAAC) { | 1137 | } else if (info->stream_type == TSStreamTypeAudioAAC) { |
1108 | // TODO: support more audio type. | 1138 | // TODO: support more audio type. |
1109 | // see aac: 6.2 Audio Data Transport Stream, ADTS | 1139 | // see aac: 6.2 Audio Data Transport Stream, ADTS |
1110 | - ctx->push((TSStreamType)info->stream_type, TSPidTypeAudio, info->elementary_PID); | 1140 | + ctx->push((TSPidTable)info->elementary_PID, (TSStreamType)info->stream_type, TSPidTypeAudio, pkt->header->continuity_counter); |
1111 | trace("ts+pmt add pid: %d, type: AAC audio", info->elementary_PID); | 1141 | trace("ts+pmt add pid: %d, type: AAC audio", info->elementary_PID); |
1112 | } else { | 1142 | } else { |
1113 | trace("ts+pmt ignore the stream type: %d", info->stream_type); | 1143 | trace("ts+pmt ignore the stream type: %d", info->stream_type); |
@@ -1215,23 +1245,16 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | @@ -1215,23 +1245,16 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | ||
1215 | { | 1245 | { |
1216 | int ret = 0; | 1246 | int ret = 0; |
1217 | 1247 | ||
1218 | - if (!pkt->header->payload_unit_start_indicator) { | ||
1219 | - TSMessage* msg = ctx->get_msg(pkt->header->pid); | ||
1220 | - if (msg->packet_start_code_prefix != 0x01) { | ||
1221 | - trace("ts+pes decode continous packet error, msg is empty."); | ||
1222 | - return -1; | ||
1223 | - } | ||
1224 | - msg->append(p, last - p); | ||
1225 | - msg->detach(ctx, pmsg); | ||
1226 | - return ret; | ||
1227 | - } | ||
1228 | - | ||
1229 | char* pp = (char*)&packet_start_code_prefix; | 1248 | char* pp = (char*)&packet_start_code_prefix; |
1230 | pp[2] = *p++; | 1249 | pp[2] = *p++; |
1231 | pp[1] = *p++; | 1250 | pp[1] = *p++; |
1232 | pp[0] = *p++; | 1251 | pp[0] = *p++; |
1233 | 1252 | ||
1234 | packet_start_code_prefix &= 0xFFFFFF; | 1253 | packet_start_code_prefix &= 0xFFFFFF; |
1254 | + if (packet_start_code_prefix != 0x01) { | ||
1255 | + trace("ts+pes decode unit start packet error, msg is empty."); | ||
1256 | + return -1; | ||
1257 | + } | ||
1235 | 1258 | ||
1236 | stream_id = *p++; | 1259 | stream_id = *p++; |
1237 | 1260 | ||
@@ -1413,6 +1436,7 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | @@ -1413,6 +1436,7 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | ||
1413 | 1436 | ||
1414 | msg->type = pid->type; | 1437 | msg->type = pid->type; |
1415 | msg->stream_type = pid->stream_type; | 1438 | msg->stream_type = pid->stream_type; |
1439 | + msg->continuity_counter = pid->continuity_counter; | ||
1416 | msg->stream_id = stream_id; | 1440 | msg->stream_id = stream_id; |
1417 | msg->packet_start_code_prefix = packet_start_code_prefix; | 1441 | msg->packet_start_code_prefix = packet_start_code_prefix; |
1418 | 1442 | ||
@@ -1426,6 +1450,9 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | @@ -1426,6 +1450,9 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | ||
1426 | msg->PES_packet_length = PES_packet_length; | 1450 | msg->PES_packet_length = PES_packet_length; |
1427 | msg->packet_header_size = p - pos_packet; | 1451 | msg->packet_header_size = p - pos_packet; |
1428 | msg->packet_data_size = PES_packet_length - msg->packet_header_size; | 1452 | msg->packet_data_size = PES_packet_length - msg->packet_header_size; |
1453 | + if (PES_packet_length == 0) { | ||
1454 | + msg->packet_data_size = last - p - msg->packet_header_size; | ||
1455 | + } | ||
1429 | 1456 | ||
1430 | if (msg->packet_data_size > 0) { | 1457 | if (msg->packet_data_size > 0) { |
1431 | msg->packet_data = new char[msg->packet_data_size]; | 1458 | msg->packet_data = new char[msg->packet_data_size]; |
@@ -1433,12 +1460,16 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | @@ -1433,12 +1460,16 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | ||
1433 | 1460 | ||
1434 | // PES_packet_data_byte | 1461 | // PES_packet_data_byte |
1435 | int size = srs_min(msg->packet_data_size, last - p); | 1462 | int size = srs_min(msg->packet_data_size, last - p); |
1436 | - msg->append(p, size); | 1463 | + if (size > 0) { |
1464 | + msg->append(p, size); | ||
1465 | + } | ||
1437 | 1466 | ||
1438 | - msg->detach(ctx, pmsg); | 1467 | + if (PES_packet_length > 0) { |
1468 | + msg->detach(ctx, pmsg); | ||
1469 | + } | ||
1439 | 1470 | ||
1440 | - trace("ts+pes stream_id: %d size: %d pts: %"PRId64" dts: %"PRId64" packet_size: %d parsed_size: %d", | ||
1441 | - stream_id, PES_packet_length, pts, dts, msg->packet_data_size, msg->parsed_packet_size); | 1471 | + trace("ts+pes stream_id: %d size: %d pts: %"PRId64" dts: %"PRId64" total: %d header: %d packet_size: %d parsed_size: %d", |
1472 | + stream_id, PES_packet_length, pts, dts, msg->PES_packet_length, msg->packet_header_size, msg->packet_data_size, msg->parsed_packet_size); | ||
1442 | } else if (stream_id == PES_program_stream_map | 1473 | } else if (stream_id == PES_program_stream_map |
1443 | || stream_id == PES_private_stream_2 | 1474 | || stream_id == PES_private_stream_2 |
1444 | || stream_id == PES_ECM_stream | 1475 | || stream_id == PES_ECM_stream |
@@ -1496,7 +1527,7 @@ int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* l | @@ -1496,7 +1527,7 @@ int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* l | ||
1496 | { | 1527 | { |
1497 | int ret = 0; | 1528 | int ret = 0; |
1498 | 1529 | ||
1499 | - if (pkt->header->pid == PID_PAT) { | 1530 | + if (pkt->header->pid == TSPidTablePAT) { |
1500 | read_pointer_field(pkt, p); | 1531 | read_pointer_field(pkt, p); |
1501 | 1532 | ||
1502 | type = TSPidTypePAT; | 1533 | type = TSPidTypePAT; |
@@ -1550,7 +1581,7 @@ int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& | @@ -1550,7 +1581,7 @@ int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& | ||
1550 | return ret; | 1581 | return ret; |
1551 | } | 1582 | } |
1552 | 1583 | ||
1553 | - if (header->adaption_field_control == AFC_ADAPTION_ONLY || header->adaption_field_control == AFC_BOTH) { | 1584 | + if (header->adaption_field_control == TSAdaptionTypeAdaptionOnly || header->adaption_field_control == TSAdaptionTypeBoth) { |
1554 | if ((ret = adaption_field->demux(ctx, this, start, last, p, pmsg)) != 0) { | 1585 | if ((ret = adaption_field->demux(ctx, this, start, last, p, pmsg)) != 0) { |
1555 | trace("ts+header af(adaption field) decode error. ret=%d", ret); | 1586 | trace("ts+header af(adaption field) decode error. ret=%d", ret); |
1556 | return ret; | 1587 | return ret; |
@@ -1561,7 +1592,36 @@ int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& | @@ -1561,7 +1592,36 @@ int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& | ||
1561 | // calc the user defined data size for payload. | 1592 | // calc the user defined data size for payload. |
1562 | payload->size = TS_PACKET_SIZE - header->get_size() - adaption_field->get_size(); | 1593 | payload->size = TS_PACKET_SIZE - header->get_size() - adaption_field->get_size(); |
1563 | 1594 | ||
1564 | - if (header->adaption_field_control == AFC_PAYLOAD_ONLY || header->adaption_field_control == AFC_BOTH) { | 1595 | + if (header->adaption_field_control == TSAdaptionTypePayloadOnly || header->adaption_field_control == TSAdaptionTypeBoth) { |
1596 | + TSMessage* msg = ctx->get_msg(header->pid); | ||
1597 | + | ||
1598 | + // flush previous PES_packet_length(0) packets. | ||
1599 | + if (msg->packet_start_code_prefix == 0x01 | ||
1600 | + && header->payload_unit_start_indicator == 1 | ||
1601 | + && msg->PES_packet_length == 0 | ||
1602 | + ) { | ||
1603 | + msg->detach(ctx, pmsg); | ||
1604 | + // reparse current message | ||
1605 | + p = start; | ||
1606 | + return ret; | ||
1607 | + } | ||
1608 | + | ||
1609 | + // parse continous packet. | ||
1610 | + if (!header->payload_unit_start_indicator) { | ||
1611 | + if (msg->packet_start_code_prefix != 0x01) { | ||
1612 | + trace("ts+pes decode continous packet error, msg is empty."); | ||
1613 | + return -1; | ||
1614 | + } | ||
1615 | + msg->append(p, last - p); | ||
1616 | + | ||
1617 | + // for PES_packet_length is 0, donot attach it. | ||
1618 | + if (msg->PES_packet_length > 0) { | ||
1619 | + msg->detach(ctx, pmsg); | ||
1620 | + } | ||
1621 | + return ret; | ||
1622 | + } | ||
1623 | + | ||
1624 | + // parse new packet. | ||
1565 | if ((ret = payload->demux(ctx, this, start, last, p, pmsg)) != 0) { | 1625 | if ((ret = payload->demux(ctx, this, start, last, p, pmsg)) != 0) { |
1566 | trace("ts+header payload decode error. ret=%d", ret); | 1626 | trace("ts+header payload decode error. ret=%d", ret); |
1567 | return ret; | 1627 | return ret; |
@@ -1588,9 +1648,9 @@ TSHeader::TSHeader() | @@ -1588,9 +1648,9 @@ TSHeader::TSHeader() | ||
1588 | transport_error_indicator = 0; | 1648 | transport_error_indicator = 0; |
1589 | payload_unit_start_indicator = 0; | 1649 | payload_unit_start_indicator = 0; |
1590 | transport_priority = 0; | 1650 | transport_priority = 0; |
1591 | - pid = 0; | 1651 | + pid = TSPidTablePAT; |
1592 | transport_scrambling_control = 0; | 1652 | transport_scrambling_control = 0; |
1593 | - adaption_field_control = 0; | 1653 | + adaption_field_control = TSAdaptionTypeReserved; |
1594 | continuity_counter = 0; | 1654 | continuity_counter = 0; |
1595 | } | 1655 | } |
1596 | 1656 | ||
@@ -1614,23 +1674,27 @@ int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* la | @@ -1614,23 +1674,27 @@ int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* la | ||
1614 | return -1; | 1674 | return -1; |
1615 | } | 1675 | } |
1616 | 1676 | ||
1617 | - pid = 0; | ||
1618 | - ((char*)&pid)[1] = *p++; | ||
1619 | - ((char*)&pid)[0] = *p++; | 1677 | + int16_t _pid = 0; |
1678 | + char* pp = (char*)&_pid; | ||
1679 | + pp[1] = *p++; | ||
1680 | + pp[0] = *p++; | ||
1620 | 1681 | ||
1621 | - transport_error_indicator = (pid >> 15) & 0x01; | ||
1622 | - payload_unit_start_indicator = (pid >> 14) & 0x01; | ||
1623 | - transport_priority = (pid >> 13) & 0x01; | ||
1624 | - pid &= 0x1FFF; | 1682 | + transport_error_indicator = (_pid >> 15) & 0x01; |
1683 | + payload_unit_start_indicator = (_pid >> 14) & 0x01; | ||
1684 | + transport_priority = (_pid >> 13) & 0x01; | ||
1685 | + _pid &= 0x1FFF; | ||
1625 | 1686 | ||
1626 | - ctx->push(TSStreamTypeReserved, TSPidTypePAT, pid); | 1687 | + pid = (TSPidTable)_pid; |
1627 | 1688 | ||
1628 | continuity_counter = *p++; | 1689 | continuity_counter = *p++; |
1629 | 1690 | ||
1630 | transport_scrambling_control = (continuity_counter >> 6) & 0x03; | 1691 | transport_scrambling_control = (continuity_counter >> 6) & 0x03; |
1631 | - adaption_field_control = (continuity_counter >> 4) & 0x03; | 1692 | + int8_t _adaption_field_control = (continuity_counter >> 4) & 0x03; |
1693 | + adaption_field_control = (TSAdaptionType)_adaption_field_control; | ||
1632 | continuity_counter &= 0x0F; | 1694 | continuity_counter &= 0x0F; |
1633 | 1695 | ||
1696 | + ctx->push(pid, TSStreamTypeReserved, TSPidTypePAT, continuity_counter); | ||
1697 | + | ||
1634 | trace("ts+header sync: %#x error: %d unit_start: %d priotiry: %d pid: %d scrambling: %d adaption: %d counter: %d", | 1698 | trace("ts+header sync: %#x error: %d unit_start: %d priotiry: %d pid: %d scrambling: %d adaption: %d counter: %d", |
1635 | sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid, | 1699 | sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid, |
1636 | transport_scrambling_control, adaption_field_control, continuity_counter); | 1700 | transport_scrambling_control, adaption_field_control, continuity_counter); |
@@ -1934,24 +1998,27 @@ int main(int /*argc*/, char** /*argv*/) | @@ -1934,24 +1998,27 @@ int main(int /*argc*/, char** /*argv*/) | ||
1934 | u_int8_t* start = ts_packet; | 1998 | u_int8_t* start = ts_packet; |
1935 | u_int8_t* last = ts_packet + TS_PACKET_SIZE; | 1999 | u_int8_t* last = ts_packet + TS_PACKET_SIZE; |
1936 | 2000 | ||
1937 | - TSPacket pkt; | ||
1938 | - TSMessage* msg = NULL; | ||
1939 | - if ((ret = pkt.demux(&ctx, start, last, p, msg)) != 0) { | ||
1940 | - trace("demuxer+read decode ts packet error. ret=%d", ret); | ||
1941 | - return ret; | ||
1942 | - } | ||
1943 | - | ||
1944 | - offset += nread; | ||
1945 | - if (!msg) { | ||
1946 | - continue; | ||
1947 | - } | ||
1948 | - | ||
1949 | - if ((ret = consume(msg)) != 0) { | ||
1950 | - trace("demuxer+consume parse and consume message failed. ret=%d", ret); | ||
1951 | - break; | 2001 | + // maybe need to parse multiple times for the PES_packet_length(0) packets. |
2002 | + while (p == start) { | ||
2003 | + TSPacket pkt; | ||
2004 | + TSMessage* msg = NULL; | ||
2005 | + if ((ret = pkt.demux(&ctx, start, last, p, msg)) != 0) { | ||
2006 | + trace("demuxer+read decode ts packet error. ret=%d", ret); | ||
2007 | + return ret; | ||
2008 | + } | ||
2009 | + | ||
2010 | + offset += nread; | ||
2011 | + if (!msg) { | ||
2012 | + continue; | ||
2013 | + } | ||
2014 | + | ||
2015 | + if ((ret = consume(msg)) != 0) { | ||
2016 | + trace("demuxer+consume parse and consume message failed. ret=%d", ret); | ||
2017 | + break; | ||
2018 | + } | ||
2019 | + | ||
2020 | + srs_freep(msg); | ||
1952 | } | 2021 | } |
1953 | - | ||
1954 | - srs_freep(msg); | ||
1955 | } | 2022 | } |
1956 | 2023 | ||
1957 | close(fd); | 2024 | close(fd); |
-
请 注册 或 登录 后发表评论