经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
ps文件解析(纯c解析代码)
来源:cnblogs  作者:leaffei  时间:2019/3/8 9:04:20  对本文有异议

参考链接: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. 1 #include <stdio.h>
  2. 2 #include <stdlib.h>
  3. 3 #include <string.h>
  4. 4 #include <arpa/inet.h>
  5. 5
  6. 6 #define TAB44 " "
  7. 7 #define PRINTF_DEBUG
  8. 8
  9. 9 #define MAX_PS_STARTCODE_LEN 4
  10. 10 #define MAX_PDTS_LEN 5
  11. 11 #define MAX_ES_NUMS 6
  12. 12 #define MAX_PDTS_STRING_LEN 12
  13. 13 #define MMIN_PS_HEADER_LEN 14
  14. 14
  15. 15
  16. 16 #define SCODE_PS_END 0x000001B9
  17. 17 #define SCODE_PS_HEADER 0x000001BA
  18. 18 #define SCODE_PS_SYSTEM_HEADER 0x000001BB
  19. 19 #define SCODE_PS_SYSTEM_MAP_HEADER 0x000001BC
  20. 20
  21. 21 /**********************************************************************************************************
  22. 22 pack_header() {
  23. 23 pack_start_code 32 bits
  24. 24 '01' 2 bits
  25. 25 system_clock_reference_base[32..30] 3 bits
  26. 26 marker_bit 1 bit
  27. 27 system_clock_reference_base[29..15] 15 bits
  28. 28 marker_bit 1 bit
  29. 29 system_clock_reference_base[14..0] 15 bits
  30. 30 marker_bit 1 bit
  31. 31 system_clock_reference_extension 9 bits
  32. 32 marker_bit 1 bit
  33. 33 program_mux_rate 22 bits
  34. 34 marker_bit 1 bit
  35. 35 marker_bit 1 bit
  36. 36 reserved 5 bit
  37. 37 pack_stuffing_length 3 bits
  38. 38
  39. 39 for (i=0; i<pack_stuffing_length; i++){
  40. 40 stuffing_byte 8 bits
  41. 41 }
  42. 42
  43. 43 if (nextbits() == system_header_start_code) {
  44. 44 system_header()
  45. 45 }
  46. 46 }
  47. 47 **********************************************************************************************************/
  48. 48
  49. 49
  50. 50 /**********************************************************************************************************
  51. 51 system_header() {
  52. 52 system_header_start_code 32 bits
  53. 53 header_length 16 bits
  54. 54 marker_bit 1 bit
  55. 55 rate_bound 22 bits
  56. 56 marker_bit 1 bit
  57. 57 audio_bound 6 bits
  58. 58 fixed_flag 1 bit
  59. 59 CSPS_flag 1 bit
  60. 60 system_audio_lock_flag 1 bit
  61. 61 system_video_lock_flag 1 bit
  62. 62 marker_bit 1 bit
  63. 63 vedio_bound 5 bits
  64. 64 packet_rate_restriction_flag 1 bit
  65. 65 reserved_bits 7 bits
  66. 66
  67. 67 while (nextbits() == '1') {
  68. 68 stream_id 8 bits
  69. 69 '11' 2 bits
  70. 70 P-STD_buffer_bound_scale 1 bit
  71. 71 P-STD_buffer_size_bound 13 bits
  72. 72 }
  73. 73 }
  74. 74 **********************************************************************************************************/
  75. 75
  76. 76
  77. 77 /**********************************************************************************************************
  78. 78 program_stream_map() {
  79. 79 packet_start_code_prefix 24 bits
  80. 80 map_stream_id 8 bits
  81. 81 program_stream_map_length 16 bits
  82. 82 current_next_indicator 1 bit
  83. 83 reserved 2 bits
  84. 84 program_stream_map_version 5 bits
  85. 85 reserved 7 bits
  86. 86 marker_bit 1 bit
  87. 87 program_stream_info_length 16 bits
  88. 88
  89. 89 for (i=0;i<N;i++) {
  90. 90 descriptor()
  91. 91 }
  92. 92
  93. 93 elementary_stream_map_length 16 bits
  94. 94
  95. 95 for (i=0;i<N1;i++) {
  96. 96 stream_type 8 bits
  97. 97 elementary_stream_id 8 bits
  98. 98
  99. 99 elementary_stream_info_length 16 bits
  100. 100
  101. 101 for (i=0;i<N2;i++) {
  102. 102 descriptor()
  103. 103 }
  104. 104 }
  105. 105
  106. 106 CRC_32 32 bits
  107. 107 }
  108. 108
  109. 109 ** current_next_indicator: 当前下一个指示符字段, 1位字段. 置'1'时表示传送的节目流映射当前是可用的.
  110. 110 置'0'时表示传送的节目流映射还不可用, 但它将是下一个生效的表.
  111. 111 ** program_stream_map_version: 5位字段, 表示整个节目流映射的版本号. 一旦节目流映射的定义发生变化,
  112. 112 该字段将递增1, 并对32取模. 在current_next_indicator为'1'时, 该字段应该是当前适用的节目流映射的版本号;
  113. 113 在current_next_indicator为'0'时, 该字段应该是下一个适用的节目流映射的版本号.
  114. 114 ** stream_type: 流类型字段, 该字段只能标志包含在PES分组中的基本流且取值不能为0x05.
  115. 115 1. MPEG-4视频流: 0x10;
  116. 116 2. H.264视频流: 0x1B;
  117. 117 3. SVAC视频流: 0x80;
  118. 118 4. G.711音频流: 0x90;
  119. 119 5. G.722.1音频流: 0x92;
  120. 120 6. G.723.1音频流: 0x93;
  121. 121 7. G.729音频流: 0x99;
  122. 122 8. SVAC音频流: 0x9B.
  123. 123 因为节目映射流字段只有在关键帧打包的时候, 才会存在, 所以如果要判断PS打包的流编码类型, 就根据这个字段来判断.
  124. 124 ** elementary_stream_map_length: 基本流映射长度字段. 指出在该节目流映射中的所有基本流信息的字节长度.
  125. 125 它只包括stream_type、elementary_stream_id和elementary_stream_info_length字段.
  126. 126 ** elementary_stream_id: 基本流标识字段, 8位字段, 指出该基本流所在PES分组的PES分组标题中stream_id字段的值.
  127. 127 这个字段的定义, 其中0x(C0~DF)指音频, 0x(E0~EF)为视频.
  128. 128 **********************************************************************************************************/
  129. 129 typedef struct t_es_map
  130. 130 {
  131. 131 unsigned char streamType;
  132. 132 unsigned char esId;
  133. 133 unsigned short esInfoLen;
  134. 134 } T_ES_MAP;
  135. 135
  136. 136 typedef struct t_ps_map
  137. 137 {
  138. 138 unsigned char curNextInd:1, :2, version:5;
  139. 139
  140. 140 unsigned short psInfoLen;
  141. 141 unsigned short esStreamMapLen;
  142. 142
  143. 143 unsigned int esMapNum;
  144. 144
  145. 145 T_ES_MAP esMaps[MAX_ES_NUMS];
  146. 146 } T_PS_MAP;
  147. 147
  148. 148 /**********************************************************************************************************
  149. 149 PES_packet() {
  150. 150 packet_start_code_prefix 24 bits
  151. 151 stream_id 8 bits
  152. 152 PES_packet_length 16 bits
  153. 153
  154. 154 if (stream_id != program_stream_map
  155. 155 && stream_id != padding_stream
  156. 156 && stream_id != private_stream_2
  157. 157 && stream_id != ECM
  158. 158 && stream_id != EMM
  159. 159 && stream_id != program_stream_directory
  160. 160 && stream_id != DSMCC_stream
  161. 161 && stream_id != ITU-T Rec.H.222.1 type E stream) {
  162. 162 '10' 2 bits
  163. 163 PES_scrambling_control 2 bits
  164. 164 PES_priority 1 bit
  165. 165 data_alignment_indicator 1 bit
  166. 166 copyright 1 bit
  167. 167 original_or_copy 1 bit
  168. 168
  169. 169 PTS_DTS_flags 2 bits
  170. 170 ESCR_flag 1 bit
  171. 171 ES_rate_flag 1 bit
  172. 172 DSM_trick_mode_flag 1 bit
  173. 173 additional_copy_info_flag 1 bit
  174. 174 PES_CRC_flag 1 bit
  175. 175 PES_extension_flag 1 bit
  176. 176
  177. 177 PES_header_data_length 8 bits
  178. 178
  179. 179 if (PTS_DTS_flags == '10') {
  180. 180 '0010' 4 bits
  181. 181 PTS[32..30] 3 bits
  182. 182 marker_bit 1 bit
  183. 183 PTS[29..15] 15 bits
  184. 184 marker_bit 1 bit
  185. 185 PTS[14..0] 15 bits
  186. 186 marker_bit 1 bit
  187. 187 }
  188. 188
  189. 189 if (PTS_DTS_flags == '11') {
  190. 190 '0011' 4 bits
  191. 191 PTS[32..30] 3 bits
  192. 192 marker_bit 1 bit
  193. 193 PTS[29..15] 15 bits
  194. 194 marker_bit 1 bit
  195. 195 PTS[14..0] 15 bits
  196. 196 marker_bit 1 bit
  197. 197 '0001' 4 bits
  198. 198 PTS[32..30] 3 bits
  199. 199 marker_bit 1 bit
  200. 200 PTS[29..15] 15 bits
  201. 201 marker_bit 1 bits
  202. 202 PTS[14..0] 15 bits
  203. 203 marker_bit 1 bit
  204. 204 }
  205. 205
  206. 206 if (ESCR_flag == '1') {
  207. 207 reserved 2 bits
  208. 208 ESCR_base[32..30] 3 bits
  209. 209 marker_bit 1 bit
  210. 210 ESCR_base[29..15] 15 bits
  211. 211 marker_bit 1 bit
  212. 212 ESCR_base[14..0] 15 bits
  213. 213 marker_bit 1 bit
  214. 214 ESCR_extension 9 bits
  215. 215 marker_bit 1 bit
  216. 216 }
  217. 217
  218. 218 if (ES_rate_flag == '1') {
  219. 219 marker_bit 1 bit
  220. 220 ES_rate 22 bits
  221. 221 marker_bit 1 bit
  222. 222 }
  223. 223
  224. 224 if (DSM_trick_mode_flag == '1') {
  225. 225 trick_mode_control 3 bits
  226. 226
  227. 227 if (trick_mode_control == fast_forward) {
  228. 228 field_id 2 bits
  229. 229 intra_slice_refresh 1 bits
  230. 230 frequency_truncation 2 bits
  231. 231 } else if (trick_mode_control == slow_motion) {
  232. 232 rep_cntrl 5 bits
  233. 233 } else if (trick_mode _control == freeze_frame) {
  234. 234 field_id 2 bits
  235. 235 reserved 3 bits
  236. 236 } else if (trick_mode _control == fast_reverse) {
  237. 237 field_id 2 bits
  238. 238 intra_slice_refresh 1 bit
  239. 239 frequency_truncation 2 bits
  240. 240 } else if (trick_mode_control == slow_reverse) {
  241. 241 rep_cntrl 5 bits
  242. 242 } else {
  243. 243 reserved 5 bits
  244. 244 }
  245. 245 }
  246. 246
  247. 247 if (additional_copy_info_flag =='1') {
  248. 248 marker_bit 1 bit
  249. 249 additional_copy_info 7 bits
  250. 250 }
  251. 251
  252. 252 if (PES_CRC_flag == ‘1’) {
  253. 253 previous_PES_packet_CRC 16 bits
  254. 254 }
  255. 255
  256. 256 if (PES_extension_flag == '1') {
  257. 257 PES_private_data_flag 1 bit
  258. 258 pack_header_field_flag 1 bit
  259. 259 program_packet_sequence_counter_flag 1 bit
  260. 260 P-STD_buffer_flag 1 bit
  261. 261 reserved 3 bits
  262. 262 PES_extension_flag_2 1 bit
  263. 263
  264. 264 if (PES_private_data_flag == '1') {
  265. 265 PES_private_data 128 bits
  266. 266 }
  267. 267
  268. 268 if (pack_header_field_flag == '1') {
  269. 269 pack_field_length 8 bits
  270. 270 pack_header()
  271. 271 }
  272. 272
  273. 273 if (program_packet_sequence_counter_flag == '1') {
  274. 274 marker_bit 1 bit
  275. 275 program_packet_sequence_counter 7 bits
  276. 276 marker-bit 1 bit
  277. 277 MPEG1_MPEG2_indentifier 1 bit
  278. 278 original_stuff_length 6 bits
  279. 279 }
  280. 280
  281. 281 if (P-STD_buffer_flag == '1') {
  282. 282 '01' 2 bits
  283. 283 P-STD_buffer_scale 1 bit
  284. 284 P-STD_buffer_size 13 bits
  285. 285 }
  286. 286
  287. 287 if (PES_extension_flag_2 == '1') {
  288. 288 marker_bit 1 bit
  289. 289 PES_extension_field_length 7 bits
  290. 290
  291. 291 for (i=0; i<PES_extension_field_length; i++) {
  292. 292 reserved 8 bits
  293. 293 }
  294. 294 }
  295. 295 }
  296. 296
  297. 297 for (i=0; i<N1; i++) {
  298. 298 stuffing_byte 8 bits
  299. 299 }
  300. 300
  301. 301 for (i=0; i<N2; i++) {
  302. 302 PES_packet_data_byte 8 bits
  303. 303 }
  304. 304 } else if (stream_id == program_stream_map
  305. 305 || stream_id == private_stream_2
  306. 306 || stream_id == ECM
  307. 307 || stream_id == EMM
  308. 308 || stream_id == program_stream_directory
  309. 309 || stream_id == DSMCC_stream
  310. 310 || stream_id == ITU-T Rec. H.222.1 type E stream ) {
  311. 311 for (i=0; i<PES_packet_length; i++) {
  312. 312 PES_packet_data_byte 8 bits
  313. 313 }
  314. 314 } else if (steam_id == padding_stream) {
  315. 315 for (i=0; i<PES_packet_length; i++) {
  316. 316 padding_byte 8 bits
  317. 317 }
  318. 318 }
  319. 319 }
  320. 320
  321. 321 ** stream_id:
  322. 322 1011 1100 program_stream_map(0xBC)
  323. 323 1011 1101 private_stream_1(0xBD)
  324. 324 1011 1110 padding_stream(0xBE)
  325. 325 1011 1111 private_stream-2(0xBF)
  326. 326 110x xxxx GB/T XXXX.3或GB/T AAAA.3音频流编号xxxx(0xC0~0xDF)
  327. 327 1110 xxxx GB/T XXXX.2或GB/T AAAA.2视频流编号xxxx(0xE0~0xEF)
  328. 328 1111 0000 ECM_stream(0xF0)
  329. 329 1111 0001 EMM_stream(0xF1)
  330. 330 1111 0010 GB/T XXXX.1附录B或GB/T XXXX.6_DSMCC_stream(0xF2)
  331. 331 1111 0011 ISO/IEC_13522_stream(0xF3)
  332. 332 1111 0100 ITU-T Rec. H.222.1类型A
  333. 333 1111 0101 ITU-T Rec. H.222.1类型B
  334. 334 1111 0110 ITU-T Rec. H.222.1类型C
  335. 335 1111 0111 ITU-T Rec. H.222.1类型D
  336. 336 1111 1000 ITU-T Rec. H.222.1类型E
  337. 337 1111 1001 ancillary_stream(0xF9)
  338. 338 1111 1010…1111 1110 保留数据流
  339. 339 1111 1111 program_stream_directory(0xFF)
  340. 340 符号x表示值'0'或'1'均被允许且可产生相同的流类型. 流号码由x的取值决定.
  341. 341 **********************************************************************************************************/
  342. 342 typedef struct t_ps_pes
  343. 343 {
  344. 344 unsigned char streamId;
  345. 345
  346. 346 long long pts;
  347. 347 long long dts;
  348. 348
  349. 349 unsigned char ptsStr[MAX_PDTS_STRING_LEN+1];
  350. 350 unsigned char dtsStr[MAX_PDTS_STRING_LEN+1];
  351. 351
  352. 352 unsigned char pesHeaderLen;
  353. 353 } T_PS_PES;
  354. 354
  355. 355 static void parsePsHeader(unsigned char* const psHeaderData)
  356. 356 {
  357. 357
  358. 358 }
  359. 359
  360. 360 static void parsePsSystemHeader(unsigned char* const psSysHeaderData)
  361. 361 {
  362. 362
  363. 363 }
  364. 364
  365. 365 static void parsePsSystemMapHeader(unsigned char* const psMapHeaderData)
  366. 366 {
  367. 367 int i = 0;
  368. 368
  369. 369 T_PS_MAP psMap = {0};
  370. 370
  371. 371 unsigned char *data = NULL;
  372. 372
  373. 373 data = psMapHeaderData;
  374. 374
  375. 375 memset(&psMap, 0, sizeof(psMap));
  376. 376
  377. 377 psMap.curNextInd = (data[0]>>7) & 0x1;
  378. 378 psMap.version = data[0] & 0x1f;
  379. 379
  380. 380 data += 2;
  381. 381
  382. 382 psMap.psInfoLen = (data[0] << 8) | data[1];
  383. 383
  384. 384 data += psMap.psInfoLen;
  385. 385
  386. 386 psMap.esStreamMapLen = (data[0] << 8) | data[1];
  387. 387
  388. 388 psMap.esMapNum = psMap.esStreamMapLen / 4;
  389. 389
  390. 390 for (i=0; i<psMap.esMapNum; i++)
  391. 391 {
  392. 392 if (i == MAX_ES_NUMS)
  393. 393 {
  394. 394 printf("now just save %d es info!\n", MAX_ES_NUMS);
  395. 395
  396. 396 break;
  397. 397 }
  398. 398
  399. 399 psMap.esMaps[i].streamType = data[0];
  400. 400 psMap.esMaps[i].esId = data[1];
  401. 401 psMap.esMaps[i].esInfoLen = (data[2] << 8) | data[3];
  402. 402
  403. 403 data += (4+psMap.esMaps[i].esInfoLen);
  404. 404 }
  405. 405
  406. 406 #ifdef PRINTF_DEBUG
  407. 407 int mNUm = 0;
  408. 408
  409. 409 if (psMap.esMapNum > MAX_ES_NUMS)
  410. 410 {
  411. 411 mNUm = MAX_ES_NUMS;
  412. 412 }
  413. 413
  414. 414 for (i=0; i<mNUm; i++)
  415. 415 {
  416. 416 printf("%s%sstreamNum: %d, streamType: %d, esId: %d\n", TAB44, TAB44, i, psMap.esMaps[i].streamType, psMap.esMaps[i].esId);
  417. 417 }
  418. 418 #endif
  419. 419 }
  420. 420
  421. 421 static void getPdts(unsigned char *pdtsData, long long *pdts, unsigned char *pdtsString)
  422. 422 {
  423. 423 int hour = 0;
  424. 424 int minute = 0;
  425. 425 int second = 0;
  426. 426 int msecond = 0;
  427. 427
  428. 428 long long pts = 0;
  429. 429 long long pts2Ms = 0;
  430. 430
  431. 431 unsigned char ptsStr[MAX_PDTS_STRING_LEN+1] = {0};
  432. 432
  433. 433 /* 5个字节转33位的值 */
  434. 434 pts = (((pdtsData[0]>>1) & 0x7) << 30) | (pdtsData[1] << 22) | (((pdtsData[2]>>1) & 0x7f) << 15) | (pdtsData[3] << 7) | (pdtsData[4]>>1 & 0x7f);
  435. 435
  436. 436 /* 90KHz, 1000ms/90 */
  437. 437 pts2Ms = pts/90;
  438. 438
  439. 439 hour = pts2Ms/(60*60*1000);
  440. 440 minute = (pts2Ms - hour * (60*60*1000)) / (60*1000);
  441. 441 second = (pts2Ms - hour * (60*60*1000) - minute * (60*1000)) / 1000;
  442. 442 msecond = pts2Ms - hour * (60*60*1000) - minute * (60*1000) - second * 1000;
  443. 443
  444. 444 sprintf(ptsStr, "%02d:%02d:%02d:%03d", hour, minute, second, msecond);
  445. 445
  446. 446 ptsStr[MAX_PDTS_STRING_LEN] = '\0';
  447. 447
  448. 448 memcpy(pdtsString, ptsStr, MAX_PDTS_STRING_LEN);
  449. 449
  450. 450 *pdts = pts;
  451. 451 }
  452. 452
  453. 453 /*********************************************************************************
  454. 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. 455 **********************************************************************************/
  456. 456 static void parsePes(const unsigned char streamId, unsigned char* const pesData, const unsigned short pesLen)
  457. 457 {
  458. 458 unsigned char pts_dts_flag;
  459. 459
  460. 460 static int audioNum = 0;
  461. 461 static int videoNum = 0;
  462. 462 static int privateNum = 0;
  463. 463 static int paddingNum = 0;
  464. 464
  465. 465 unsigned char *data = NULL;
  466. 466
  467. 467 unsigned char pts[MAX_PDTS_LEN+1] = {0};
  468. 468 unsigned char dts[MAX_PDTS_LEN+1] = {0};
  469. 469
  470. 470 T_PS_PES psPes = {0};
  471. 471
  472. 472 data = pesData;
  473. 473
  474. 474 memset(&psPes, 0x0, sizeof(psPes));
  475. 475
  476. 476 psPes.streamId = streamId;
  477. 477
  478. 478 if (((streamId>=0xC0) && (streamId<=0xDF)) || ((streamId>=0xE0) && (streamId<=0xEF)))
  479. 479 {
  480. 480 pts_dts_flag = data[1]>>6 & 0x3;
  481. 481
  482. 482 psPes.pesHeaderLen = data[2];
  483. 483
  484. 484 data += 3;
  485. 485
  486. 486 switch (pts_dts_flag)
  487. 487 {
  488. 488 case 0: /* 00, no pts, dts */
  489. 489 break;
  490. 490
  491. 491 case 2: /* 10, only pts*/
  492. 492 memset(pts, 0x0, sizeof(pts));
  493. 493
  494. 494 memcpy(pts, data, MAX_PDTS_LEN);
  495. 495
  496. 496 getPdts(pts, &psPes.pts, psPes.ptsStr);
  497. 497
  498. 498 break;
  499. 499
  500. 500 case 3: /* 11 pts & dts*/
  501. 501 memset(pts, 0x0, sizeof(pts));
  502. 502 memset(dts, 0x0, sizeof(dts));
  503. 503
  504. 504 memcpy(pts, data, MAX_PDTS_LEN);
  505. 505 memcpy(dts, data+MAX_PDTS_LEN, MAX_PDTS_LEN);
  506. 506
  507. 507 getPdts(pts, &psPes.pts, psPes.ptsStr);
  508. 508 getPdts(dts, &psPes.dts, psPes.dtsStr);
  509. 509
  510. 510 break;
  511. 511
  512. 512 default:
  513. 513 break;
  514. 514 }
  515. 515 }
  516. 516
  517. 517
  518. 518 #ifdef PRINTF_DEBUG
  519. 519 if ((streamId>=0xC0) && (streamId<=0xDF))
  520. 520 {
  521. 521 audioNum++;
  522. 522
  523. 523 printf("%s%spes, Audio[%d], streamId: 0x%02X(%d), pesLength: %d, pesHeaderLen: %d", TAB44, TAB44, audioNum, streamId, streamId, pesLen, psPes.pesHeaderLen);
  524. 524
  525. 525 if (2 == pts_dts_flag)
  526. 526 {
  527. 527 printf(", pts: %s(%lld)", psPes.ptsStr, psPes.pts);
  528. 528 }
  529. 529
  530. 530 if (3 == pts_dts_flag)
  531. 531 {
  532. 532 printf(", pts: %s(%lld), dts: %s(%lld)", psPes.ptsStr, psPes.pts, psPes.dtsStr, psPes.dts);
  533. 533 }
  534. 534
  535. 535 printf("\n");
  536. 536 }
  537. 537 else if ((streamId>=0xE0) && (streamId<=0xEF))
  538. 538 {
  539. 539 videoNum++;
  540. 540
  541. 541 printf("%s%spes, Video[%d], streamId: 0x%02X(%d), pesLength: %d, pesHeaderLen: %d", TAB44, TAB44, videoNum, streamId, streamId, pesLen, psPes.pesHeaderLen);
  542. 542
  543. 543 if (2 == pts_dts_flag)
  544. 544 {
  545. 545 printf(", pts: %s(%lld)", psPes.ptsStr, psPes.pts);
  546. 546 }
  547. 547
  548. 548 if (3 == pts_dts_flag)
  549. 549 {
  550. 550 printf(", pts: %s(%lld), dts: %s(%lld)", psPes.ptsStr, psPes.pts, psPes.dtsStr, psPes.dts);
  551. 551 }
  552. 552
  553. 553 printf("\n");
  554. 554 }
  555. 555 else if ((streamId==0xBD) || (streamId==0xBF))
  556. 556 {
  557. 557 privateNum++;
  558. 558
  559. 559 printf("%s%spes, private[%d], streamId: 0x%02X(%d), pesLength: %d\n", TAB44, TAB44, privateNum, streamId, streamId, pesLen);
  560. 560 }
  561. 561 else if (streamId==0xBE)
  562. 562 {
  563. 563 paddingNum++;
  564. 564
  565. 565 printf("%s%spes, padding[%d], streamId: 0x%02X(%d), pesLength: %d\n", TAB44, TAB44, privateNum, streamId, streamId, pesLen);
  566. 566 }
  567. 567 else
  568. 568 {
  569. 569 printf("%s%spes, streamId: 0x%02X(%d), pesLength: %d\n", TAB44, TAB44, streamId, streamId, pesLen);
  570. 570 }
  571. 571 #endif
  572. 572 }
  573. 573
  574. 574 int main(int argc, char *argv[])
  575. 575 {
  576. 576 int readLen = 0;
  577. 577 int pack_stuffing_length = 0;
  578. 578
  579. 579 unsigned int startCode = 0;
  580. 580
  581. 581 unsigned short pesPacketLen = 0;
  582. 582 unsigned short psSystemHeaderLen = 0;
  583. 583 unsigned short psSystemMapHeaderLen = 0;
  584. 584
  585. 585 unsigned char pesStreamId = 0;
  586. 586
  587. 587 unsigned char sCodeData[MAX_PS_STARTCODE_LEN+1] = {0};
  588. 588 unsigned char psData[MMIN_PS_HEADER_LEN-3] = {0};
  589. 589
  590. 590 unsigned char *pesData = NULL;
  591. 591
  592. 592 FILE *fp = NULL;
  593. 593
  594. 594 if (2 != argc)
  595. 595 {
  596. 596 printf("Usage: flvparse **.mpg\n");
  597. 597
  598. 598 return -1;
  599. 599 }
  600. 600
  601. 601 fp = fopen(argv[1], "rb");
  602. 602 if (!fp)
  603. 603 {
  604. 604 printf("open file[%s] error!\n", argv[1]);
  605. 605
  606. 606 return -1;
  607. 607 }
  608. 608
  609. 609 while (1)
  610. 610 {
  611. 611 readLen = fread(&startCode, MAX_PS_STARTCODE_LEN, 1, fp);
  612. 612 if (1 != readLen)
  613. 613 {
  614. 614 break;
  615. 615 }
  616. 616
  617. 617 startCode = ntohl(startCode);
  618. 618
  619. 619 #ifdef PRINTF_DEBUG
  620. 620 if (SCODE_PS_HEADER == startCode)
  621. 621 {
  622. 622 printf("+startCode: 0x%08X\n", startCode);
  623. 623 }
  624. 624 else
  625. 625 {
  626. 626 printf("%s+startCode: 0x%08X\n", TAB44, startCode);
  627. 627 }
  628. 628 #endif
  629. 629
  630. 630 if ((0 != (startCode>>24 & 0xff)) && (0 != (startCode>>16 & 0xff)) && (1 != (startCode>>8 & 0xff)))
  631. 631 {
  632. 632 return -1;
  633. 633 }
  634. 634
  635. 635 switch (startCode)
  636. 636 {
  637. 637 case SCODE_PS_HEADER:
  638. 638 memset(psData, 0x0, sizeof(psData));
  639. 639
  640. 640 readLen = fread(psData, 1, MMIN_PS_HEADER_LEN-4, fp);
  641. 641 if ((MMIN_PS_HEADER_LEN-4) != readLen)
  642. 642 {
  643. 643 fclose(fp);
  644. 644
  645. 645 return 0;
  646. 646 }
  647. 647
  648. 648 pack_stuffing_length = psData[MMIN_PS_HEADER_LEN-5] & 0x7;
  649. 649
  650. 650 fseek(fp, pack_stuffing_length, SEEK_CUR);
  651. 651
  652. 652 break;
  653. 653
  654. 654 case SCODE_PS_SYSTEM_HEADER:
  655. 655 if (1 != fread(&psSystemHeaderLen, 2, 1, fp))
  656. 656 {
  657. 657 fclose(fp);
  658. 658
  659. 659 return 0;
  660. 660 }
  661. 661
  662. 662 psSystemHeaderLen = ntohs(psSystemHeaderLen);
  663. 663
  664. 664 fseek(fp, psSystemHeaderLen, SEEK_CUR);
  665. 665
  666. 666 break;
  667. 667
  668. 668 case SCODE_PS_SYSTEM_MAP_HEADER:
  669. 669 if (1 != fread(&psSystemMapHeaderLen, 2, 1, fp))
  670. 670 {
  671. 671 fclose(fp);
  672. 672
  673. 673 return 0;
  674. 674 }
  675. 675
  676. 676 psSystemMapHeaderLen = ntohs(psSystemMapHeaderLen);
  677. 677
  678. 678 pesData = (unsigned char*)malloc(psSystemMapHeaderLen);
  679. 679 if (pesData)
  680. 680 {
  681. 681 memset(pesData, 0x0, pesPacketLen);
  682. 682
  683. 683 if (psSystemMapHeaderLen != fread(pesData, 1, psSystemMapHeaderLen, fp))
  684. 684 {
  685. 685 fclose(fp);
  686. 686
  687. 687 return 0;
  688. 688 }
  689. 689
  690. 690 parsePsSystemMapHeader(pesData);
  691. 691
  692. 692 free(pesData);
  693. 693
  694. 694 pesData = NULL;
  695. 695 }
  696. 696
  697. 697 break;
  698. 698
  699. 699 case SCODE_PS_END:
  700. 700 #ifdef PRINTF_DEBUG
  701. 701 printf("ps is end!\n");
  702. 702 #endif
  703. 703
  704. 704 return 0;
  705. 705
  706. 706 break;
  707. 707
  708. 708 /* pes pcaket */
  709. 709 default:
  710. 710 pesStreamId = startCode & 0xff;
  711. 711
  712. 712 if (1 != fread(&pesPacketLen, 2, 1, fp))
  713. 713 {
  714. 714 fclose(fp);
  715. 715
  716. 716 return 0;
  717. 717 }
  718. 718
  719. 719 pesPacketLen = ntohs(pesPacketLen);
  720. 720
  721. 721 pesData = (unsigned char*)malloc(pesPacketLen);
  722. 722 if (pesData)
  723. 723 {
  724. 724 memset(pesData, 0x0, pesPacketLen);
  725. 725
  726. 726 if (pesPacketLen != fread(pesData, 1, pesPacketLen, fp))
  727. 727 {
  728. 728 fclose(fp);
  729. 729
  730. 730 return 0;
  731. 731 }
  732. 732
  733. 733 parsePes(pesStreamId, pesData, pesPacketLen);
  734. 734
  735. 735 free(pesData);
  736. 736
  737. 737 pesData = NULL;
  738. 738 }
  739. 739
  740. 740 break;
  741. 741 }
  742. 742 }
  743. 743
  744. 744 fclose(fp);
  745. 745
  746. 746 return 0;
  747. 747 }
View Code

 

原文链接:http://www.cnblogs.com/leaffei/p/10487540.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号