參考鏈接:1. PS流的格式和解析總結 http://www.cnblogs.com/lihaiping/p/4181607.html 2. TS科普5 PES包解析 https://blog.csdn.net/cabbage2008/article/details/49612011 PES包的解析 ...
參考鏈接:1. PS流的格式和解析總結 http://www.cnblogs.com/lihaiping/p/4181607.html
2. TS科普5 PES包解析 https://blog.csdn.net/cabbage2008/article/details/49612011
PES包的解析(本代碼主要解析了PTS和DTS, 需結合下圖和代碼中的PES包的偽代碼看):
startcode(24) + streamid(8) + pes_len(16) + {header: flag1(8) + flag2(8, pts標識在這兒) + header_len(8)} + {header_data(header_len, 若前面的flag有數據, 數據就在這兒)} + pes_data(pes_len-3-header_len)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <arpa/inet.h> 5 6 #define TAB44 " " 7 #define PRINTF_DEBUG 8 9 #define MAX_PS_STARTCODE_LEN 4 10 #define MAX_PDTS_LEN 5 11 #define MAX_ES_NUMS 6 12 #define MAX_PDTS_STRING_LEN 12 13 #define MMIN_PS_HEADER_LEN 14 14 15 16 #define SCODE_PS_END 0x000001B9 17 #define SCODE_PS_HEADER 0x000001BA 18 #define SCODE_PS_SYSTEM_HEADER 0x000001BB 19 #define SCODE_PS_SYSTEM_MAP_HEADER 0x000001BC 20 21 /********************************************************************************************************** 22 pack_header() { 23 pack_start_code 32 bits 24 '01' 2 bits 25 system_clock_reference_base[32..30] 3 bits 26 marker_bit 1 bit 27 system_clock_reference_base[29..15] 15 bits 28 marker_bit 1 bit 29 system_clock_reference_base[14..0] 15 bits 30 marker_bit 1 bit 31 system_clock_reference_extension 9 bits 32 marker_bit 1 bit 33 program_mux_rate 22 bits 34 marker_bit 1 bit 35 marker_bit 1 bit 36 reserved 5 bit 37 pack_stuffing_length 3 bits 38 39 for (i=0; i<pack_stuffing_length; i++){ 40 stuffing_byte 8 bits 41 } 42 43 if (nextbits() == system_header_start_code) { 44 system_header() 45 } 46 } 47 **********************************************************************************************************/ 48 49 50 /********************************************************************************************************** 51 system_header() { 52 system_header_start_code 32 bits 53 header_length 16 bits 54 marker_bit 1 bit 55 rate_bound 22 bits 56 marker_bit 1 bit 57 audio_bound 6 bits 58 fixed_flag 1 bit 59 CSPS_flag 1 bit 60 system_audio_lock_flag 1 bit 61 system_video_lock_flag 1 bit 62 marker_bit 1 bit 63 vedio_bound 5 bits 64 packet_rate_restriction_flag 1 bit 65 reserved_bits 7 bits 66 67 while (nextbits() == '1') { 68 stream_id 8 bits 69 '11' 2 bits 70 P-STD_buffer_bound_scale 1 bit 71 P-STD_buffer_size_bound 13 bits 72 } 73 } 74 **********************************************************************************************************/ 75 76 77 /********************************************************************************************************** 78 program_stream_map() { 79 packet_start_code_prefix 24 bits 80 map_stream_id 8 bits 81 program_stream_map_length 16 bits 82 current_next_indicator 1 bit 83 reserved 2 bits 84 program_stream_map_version 5 bits 85 reserved 7 bits 86 marker_bit 1 bit 87 program_stream_info_length 16 bits 88 89 for (i=0;i<N;i++) { 90 descriptor() 91 } 92 93 elementary_stream_map_length 16 bits 94 95 for (i=0;i<N1;i++) { 96 stream_type 8 bits 97 elementary_stream_id 8 bits 98 99 elementary_stream_info_length 16 bits 100 101 for (i=0;i<N2;i++) { 102 descriptor() 103 } 104 } 105 106 CRC_32 32 bits 107 } 108 109 ** current_next_indicator: 當前下一個指示符欄位, 1位欄位. 置'1'時表示傳送的節目流映射當前是可用的. 110 置'0'時表示傳送的節目流映射還不可用, 但它將是下一個生效的表. 111 ** program_stream_map_version: 5位欄位, 表示整個節目流映射的版本號. 一旦節目流映射的定義發生變化, 112 該欄位將遞增1, 並對32取模. 在current_next_indicator為'1'時, 該欄位應該是當前適用的節目流映射的版本號; 113 在current_next_indicator為'0'時, 該欄位應該是下一個適用的節目流映射的版本號. 114 ** stream_type: 流類型欄位, 該欄位只能標誌包含在PES分組中的基本流且取值不能為0x05. 115 1. MPEG-4視頻流: 0x10; 116 2. H.264視頻流: 0x1B; 117 3. SVAC視頻流: 0x80; 118 4. G.711音頻流: 0x90; 119 5. G.722.1音頻流: 0x92; 120 6. G.723.1音頻流: 0x93; 121 7. G.729音頻流: 0x99; 122 8. SVAC音頻流: 0x9B. 123 因為節目映射流欄位只有在關鍵幀打包的時候, 才會存在, 所以如果要判斷PS打包的流編碼類型, 就根據這個欄位來判斷. 124 ** elementary_stream_map_length: 基本流映射長度欄位. 指出在該節目流映射中的所有基本流信息的位元組長度. 125 它只包括stream_type、elementary_stream_id和elementary_stream_info_length欄位. 126 ** elementary_stream_id: 基本流標識欄位, 8位欄位, 指出該基本流所在PES分組的PES分組標題中stream_id欄位的值. 127 這個欄位的定義, 其中0x(C0~DF)指音頻, 0x(E0~EF)為視頻. 128 **********************************************************************************************************/ 129 typedef struct t_es_map 130 { 131 unsigned char streamType; 132 unsigned char esId; 133 unsigned short esInfoLen; 134 } T_ES_MAP; 135 136 typedef struct t_ps_map 137 { 138 unsigned char curNextInd:1, :2, version:5; 139 140 unsigned short psInfoLen; 141 unsigned short esStreamMapLen; 142 143 unsigned int esMapNum; 144 145 T_ES_MAP esMaps[MAX_ES_NUMS]; 146 } T_PS_MAP; 147 148 /********************************************************************************************************** 149 PES_packet() { 150 packet_start_code_prefix 24 bits 151 stream_id 8 bits 152 PES_packet_length 16 bits 153 154 if (stream_id != program_stream_map 155 && stream_id != padding_stream 156 && stream_id != private_stream_2 157 && stream_id != ECM 158 && stream_id != EMM 159 && stream_id != program_stream_directory 160 && stream_id != DSMCC_stream 161 && stream_id != ITU-T Rec.H.222.1 type E stream) { 162 '10' 2 bits 163 PES_scrambling_control 2 bits 164 PES_priority 1 bit 165 data_alignment_indicator 1 bit 166 copyright 1 bit 167 original_or_copy 1 bit 168 169 PTS_DTS_flags 2 bits 170 ESCR_flag 1 bit 171 ES_rate_flag 1 bit 172 DSM_trick_mode_flag 1 bit 173 additional_copy_info_flag 1 bit 174 PES_CRC_flag 1 bit 175 PES_extension_flag 1 bit 176 177 PES_header_data_length 8 bits 178 179 if (PTS_DTS_flags == '10') { 180 '0010' 4 bits 181 PTS[32..30] 3 bits 182 marker_bit 1 bit 183 PTS[29..15] 15 bits 184 marker_bit 1 bit 185 PTS[14..0] 15 bits 186 marker_bit 1 bit 187 } 188 189 if (PTS_DTS_flags == '11') { 190 '0011' 4 bits 191 PTS[32..30] 3 bits 192 marker_bit 1 bit 193 PTS[29..15] 15 bits 194 marker_bit 1 bit 195 PTS[14..0] 15 bits 196 marker_bit 1 bit 197 '0001' 4 bits 198 PTS[32..30] 3 bits 199 marker_bit 1 bit 200 PTS[29..15] 15 bits 201 marker_bit 1 bits 202 PTS[14..0] 15 bits 203 marker_bit 1 bit 204 } 205 206 if (ESCR_flag == '1') { 207 reserved 2 bits 208 ESCR_base[32..30] 3 bits 209 marker_bit 1 bit 210 ESCR_base[29..15] 15 bits 211 marker_bit 1 bit 212 ESCR_base[14..0] 15 bits 213 marker_bit 1 bit 214 ESCR_extension 9 bits 215 marker_bit 1 bit 216 } 217 218 if (ES_rate_flag == '1') { 219 marker_bit 1 bit 220 ES_rate 22 bits 221 marker_bit 1 bit 222 } 223 224 if (DSM_trick_mode_flag == '1') { 225 trick_mode_control 3 bits 226 227 if (trick_mode_control == fast_forward) { 228 field_id 2 bits 229 intra_slice_refresh 1 bits 230 frequency_truncation 2 bits 231 } else if (trick_mode_control == slow_motion) { 232 rep_cntrl 5 bits 233 } else if (trick_mode _control == freeze_frame) { 234 field_id 2 bits 235 reserved 3 bits 236 } else if (trick_mode _control == fast_reverse) { 237 field_id 2 bits 238 intra_slice_refresh 1 bit 239 frequency_truncation 2 bits 240 } else if (trick_mode_control == slow_reverse) { 241 rep_cntrl 5 bits 242 } else { 243 reserved 5 bits 244 } 245 } 246 247 if (additional_copy_info_flag =='1') { 248 marker_bit 1 bit 249 additional_copy_info 7 bits 250 } 251 252 if (PES_CRC_flag == ‘1’) { 253 previous_PES_packet_CRC 16 bits 254 } 255 256 if (PES_extension_flag == '1') { 257 PES_private_data_flag 1 bit 258 pack_header_field_flag 1 bit 259 program_packet_sequence_counter_flag 1 bit 260 P-STD_buffer_flag 1 bit 261 reserved 3 bits 262 PES_extension_flag_2 1 bit 263 264 if (PES_private_data_flag == '1') { 265 PES_private_data 128 bits 266 } 267 268 if (pack_header_field_flag == '1') { 269 pack_field_length 8 bits 270 pack_header() 271 } 272 273 if (program_packet_sequence_counter_flag == '1') { 274 marker_bit 1 bit 275 program_packet_sequence_counter 7 bits 276 marker-bit 1 bit 277 MPEG1_MPEG2_indentifier 1 bit 278 original_stuff_length 6 bits 279 } 280 281 if (P-STD_buffer_flag == '1') { 282 '01' 2 bits 283 P-STD_buffer_scale 1 bit 284 P-STD_buffer_size 13 bits 285 } 286 287 if (PES_extension_flag_2 == '1') { 288 marker_bit 1 bit 289 PES_extension_field_length 7 bits 290 291 for (i=0; i<PES_extension_field_length; i++) { 292 reserved 8 bits 293 } 294 } 295 } 296 297 for (i=0; i<N1; i++) { 298 stuffing_byte 8 bits 299 } 300 301 for (i=0; i<N2; i++) { 302 PES_packet_data_byte 8 bits 303 } 304 } else if (stream_id == program_stream_map 305 || stream_id == private_stream_2 306 || stream_id == ECM 307 || stream_id == EMM 308 || stream_id == program_stream_directory 309 || stream_id == DSMCC_stream 310 || stream_id == ITU-T Rec. H.222.1 type E stream ) { 311 for (i=0; i<PES_packet_length; i++) { 312 PES_packet_data_byte 8 bits 313 } 314 } else if (steam_id == padding_stream) { 315 for (i=0; i<PES_packet_length; i++) { 316 padding_byte 8 bits 317 } 318 } 319 } 320 321 ** stream_id: 322 1011 1100 program_stream_map(0xBC) 323 1011 1101 private_stream_1(0xBD) 324 1011 1110 padding_stream(0xBE) 325 1011 1111 private_stream-2(0xBF) 326 110x xxxx GB/T XXXX.3或GB/T AAAA.3音頻流編號xxxx(0xC0~0xDF) 327 1110 xxxx GB/T XXXX.2或GB/T AAAA.2視頻流編號xxxx(0xE0~0xEF) 328 1111 0000 ECM_stream(0xF0) 329 1111 0001 EMM_stream(0xF1) 330 1111 0010 GB/T XXXX.1附錄B或GB/T XXXX.6_DSMCC_stream(0xF2) 331 1111 0011 ISO/IEC_13522_stream(0xF3) 332 1111 0100 ITU-T Rec. H.222.1類型A 333 1111 0101 ITU-T Rec. H.222.1類型B 334 1111 0110 ITU-T Rec. H.222.1類型C 335 1111 0111 ITU-T Rec. H.222.1類型D 336 1111 1000 ITU-T Rec. H.222.1類型E 337 1111 1001 ancillary_stream(0xF9) 338 1111 1010…1111 1110 保留數據流 339 1111 1111 program_stream_directory(0xFF) 340 符號x表示值'0'或'1'均被允許且可產生相同的流類型. 流號碼由x的取值決定. 341 **********************************************************************************************************/ 342 typedef struct t_ps_pes 343 { 344 unsigned char streamId; 345 346 long long pts; 347 long long dts; 348 349 unsigned char ptsStr[MAX_PDTS_STRING_LEN+1]; 350 unsigned char dtsStr[MAX_PDTS_STRING_LEN+1]; 351 352 unsigned char pesHeaderLen; 353 } T_PS_PES; 354 355 static void parsePsHeader(unsigned char* const psHeaderData) 356 { 357 358 } 359 360 static void parsePsSystemHeader(unsigned char* const psSysHeaderData) 361 { 362 363 } 364 365 static void parsePsSystemMapHeader(unsigned char* const psMapHeaderData) 366 { 367 int i = 0; 368 369 T_PS_MAP psMap = {0}; 370 371 unsigned char *data = NULL; 372 373 data = psMapHeaderData; 374 375 memset(&psMap, 0, sizeof(psMap)); 376 377 psMap.curNextInd = (data[0]>>7) & 0x1; 378 psMap.version = data[0] & 0x1f; 379 380 data += 2; 381 382 psMap.psInfoLen = (data[0] << 8) | data[1]; 383 384 data += psMap.psInfoLen; 385 386 psMap.esStreamMapLen = (data[0] << 8) | data[1]; 387 388 psMap.esMapNum = psMap.esStreamMapLen / 4; 389 390 for (i=0; i<psMap.esMapNum; i++) 391 { 392 if (i == MAX_ES_NUMS) 393 { 394 printf("now just save %d es info!\n", MAX_ES_NUMS); 395 396 break; 397 } 398 399 psMap.esMaps[i].streamType = data[0]; 400 psMap.esMaps[i].esId = data[1]; 401 psMap.esMaps[i].esInfoLen = (data[2] << 8) | data[3]; 402 403 data += (4+psMap.esMaps[i].esInfoLen); 404 } 405 406 #ifdef PRINTF_DEBUG 407 int mNUm = 0; 408 409 if (psMap.esMapNum > MAX_ES_NUMS) 410 { 411 mNUm = MAX_ES_NUMS; 412 } 413 414 for (i=0; i<mNUm; i++) 415 { 416 printf("%s%sstreamNum: %d, streamType: %d, esId: %d\n", TAB44, TAB44, i, psMap.esMaps[i].streamType, psMap.esMaps[i].esId); 417 } 418 #endif 419 } 420 421 static void getPdts(unsigned char *pdtsData, long long *pdts, unsigned char *pdtsString) 422 { 423 int hour = 0; 424 int minute = 0; 425 int second = 0; 426 int msecond = 0; 427 428 long long pts = 0; 429 long long pts2Ms = 0; 430 431 unsigned char ptsStr[MAX_PDTS_STRING_LEN+1] = {0}; 432 433 /* 5個位元組轉33位的值 */ 434 pts = (((pdtsData[0]>>1) & 0x7) << 30) | (pdtsData[1] << 22) | (((pdtsData[2]>>1) & 0x7f) << 15) | (pdtsData[3] << 7) | (pdtsData[4]>>1 & 0x7f); 435 436 /* 90KHz, 1000ms/90 */ 437 pts2Ms = pts/90; 438 439 hour = pts2Ms/(60*60*1000); 440 minute = (pts2Ms - hour * (60*60*1000)) / (60*1000); 441 second = (pts2Ms - hour * (60*60*1000) - minute * (60*1000)) / 1000; 442 msecond = pts2Ms - hour * (60*60*1000) - minute * (60*1000) - second * 1000; 443 444 sprintf(ptsStr, "%02d:%02d:%02d:%03d", hour, minute, second, msecond); 445 446 ptsStr[MAX_PDTS_STRING_LEN] = '\0'; 447 448 memcpy(pdtsString, ptsStr, MAX_PDTS_STRING_LEN); 449 450 *pdts = pts; 451 } 452 453 /********************************************************************************* 454 startcode(24) + streamid(8) + pes_len(16) + {header: flag1(8) + flag2(8, pts標識在這兒) + header_len(8)} + {header_data(header_len, 若前面的flag有數據, 數據就在這兒)} + pes_data(pes_len-3-header_len) 455 **********************************************************************************/ 456 static void parsePes(const unsigned char streamId, unsigned char* const pesData, const unsigned short pesLen) 457 { 458 unsigned char pts_dts_flag; 459 460 static int audioNum = 0; 461 static int videoNum = 0; 462 static int privateNum = 0; 463 static int paddingNum = 0; 464 465 unsigned char *data = NULL; 466 467 unsigned char pts[MAX_PDTS_LEN+1] = {0}; 468 unsigned char dts[MAX_PDTS_LEN+1] = {0}; 469 470 T_PS_PES psPes = {0}; 471 472 data = pesData; 473 474 memset(&psPes, 0x0, sizeof(psPes)); 475 476 psPes.streamId = streamId; 477 478 if (((streamId>=0xC0) && (streamId<=0xDF)) || ((streamId>=0xE0) && (streamId<=0xEF))) 479 { 480 pts_dts_flag = data[1]>>6 & 0x3; 481 482 psPes.pesHeaderLen = data[2]; 483 484 data += 3; 485 486 switch (pts_dts_flag) 487 { 488 case 0: /* 00, no pts, dts */ 489 break; 490 491 case 2: /* 10, only pts*/ 492 memset(pts, 0x0, sizeof(pts)); 493 494 memcpy(pts, data, MAX_PDTS_LEN); 495 496 getPdts(pts, &psPes.pts, psPes.ptsStr); 497 498 break; 499 500 case 3: /* 11 pts & dts*/ 501 memset(pts, 0x0,