1 #include
2 #include
3 #include
4 #include
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
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
90 descriptor()
91 }
92
93 elementary_stream_map_length 16 bits
94
95 for (i=0;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
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
292 reserved 8 bits
293 }
294 }
295 }
296
297 for (i=0; i
298 stuffing_byte 8 bits
299 }
300
301 for (i=0; 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
312 pes_packet_data_byte 8 bits
313 }
314 } else if (steam_id == padding_stream) {
315 for (i=0; 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
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
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, sizeof(pts));
502 memset(dts, 0x0, sizeof(dts));
503
504 memcpy(pts, data, max_pdts_len);
505 memcpy(dts, data+max_pdts_len, max_pdts_len);
506
507 getpdts(pts, &pspes.pts, pspes.ptsstr);
508 getpdts(dts, &pspes.dts, pspes.dtsstr);
509
510 break;
511
512 default:
513 break;
514 }
515 }
516
517
518 #ifdef printf_debug
519 if ((streamid>=0xc0) && (streamid<=0xdf))
520 {
521 audionum++;
522
523 printf("%s%spes, audio[%d], streamid: 0x%02x(%d), peslength: %d, pesheaderlen: %d", tab44, tab44, audionum, streamid, streamid, peslen, pspes.pesheaderlen);
524
525 if (2 == pts_dts_flag)
526 {
527 printf(", pts: %s(%lld)", pspes.ptsstr, pspes.pts);
528 }
529
530 if (3 == pts_dts_flag)
531 {
532 printf(", pts: %s(%lld), dts: %s(%lld)", pspes.ptsstr, pspes.pts, pspes.dtsstr, pspes.dts);
533 }
534
535 printf("\n");
536 }
537 else if ((streamid>=0xe0) && (streamid<=0xef))
538 {
539 videonum++;
540
541 printf("%s%spes, video[%d], streamid: 0x%02x(%d), peslength: %d, pesheaderlen: %d", tab44, tab44, videonum, streamid, streamid, peslen, pspes.pesheaderlen);
542
543 if (2 == pts_dts_flag)
544 {
545 printf(", pts: %s(%lld)", pspes.ptsstr, pspes.pts);
546 }
547
548 if (3 == pts_dts_flag)
549 {
550 printf(", pts: %s(%lld), dts: %s(%lld)", pspes.ptsstr, pspes.pts, pspes.dtsstr, pspes.dts);
551 }
552
553 printf("\n");
554 }
555 else if ((streamid==0xbd) || (streamid==0xbf))
556 {
557 privatenum++;
558
559 printf("%s%spes, private[%d], streamid: 0x%02x(%d), peslength: %d\n", tab44, tab44, privatenum, streamid, streamid, peslen);
560 }
561 else if (streamid==0xbe)
562 {
563 paddingnum++;
564
565 printf("%s%spes, padding[%d], streamid: 0x%02x(%d), peslength: %d\n", tab44, tab44, privatenum, streamid, streamid, peslen);
566 }
567 else
568 {
569 printf("%s%spes, streamid: 0x%02x(%d), peslength: %d\n", tab44, tab44, streamid, streamid, peslen);
570 }
571 #endif
572 }
573
574 int main(int argc, char *argv[])
575 {
576 int readlen = 0;
577 int pack_stuffing_length = 0;
578
579 unsigned int startcode = 0;
580
581 unsigned short pespacketlen = 0;
582 unsigned short pssystemheaderlen = 0;
583 unsigned short pssystemmapheaderlen = 0;
584
585 unsigned char pesstreamid = 0;
586
587 unsigned char scodedata[max_ps_startcode_len+1] = {0};
588 unsigned char psdata[mmin_ps_header_len-3] = {0};
589
590 unsigned char *pesdata = null;
591
592 file *fp = null;
593
594 if (2 != argc)
595 {
596 printf("usage: flvparse **.mpg\n");
597
598 return -1;
599 }
600
601 fp = fopen(argv[1], "rb");
602 if (!fp)
603 {
604 printf("open file[%s] error!\n", argv[1]);
605
606 return -1;
607 }
608
609 while (1)
610 {
611 readlen = fread(&startcode, max_ps_startcode_len, 1, fp);
612 if (1 != readlen)
613 {
614 break;
615 }
616
617 startcode = ntohl(startcode);
618
619 #ifdef printf_debug
620 if (scode_ps_header == startcode)
621 {
622 printf("+startcode: 0x%08x\n", startcode);
623 }
624 else
625 {
626 printf("%s+startcode: 0x%08x\n", tab44, startcode);
627 }
628 #endif
629
630 if ((0 != (startcode>>24 & 0xff)) && (0 != (startcode>>16 & 0xff)) && (1 != (startcode>>8 & 0xff)))
631 {
632 return -1;
633 }
634
635 switch (startcode)
636 {
637 case scode_ps_header:
638 memset(psdata, 0x0, sizeof(psdata));
639
640 readlen = fread(psdata, 1, mmin_ps_header_len-4, fp);
641 if ((mmin_ps_header_len-4) != readlen)
642 {
643 fclose(fp);
644
645 return 0;
646 }
647
648 pack_stuffing_length = psdata[mmin_ps_header_len-5] & 0x7;
649
650 fseek(fp, pack_stuffing_length, seek_cur);
651
652 break;
653
654 case scode_ps_system_header:
655 if (1 != fread(&pssystemheaderlen, 2, 1, fp))
656 {
657 fclose(fp);
658
659 return 0;
660 }
661
662 pssystemheaderlen = ntohs(pssystemheaderlen);
663
664 fseek(fp, pssystemheaderlen, seek_cur);
665
666 break;
667
668 case scode_ps_system_map_header:
669 if (1 != fread(&pssystemmapheaderlen, 2, 1, fp))
670 {
671 fclose(fp);
672
673 return 0;
674 }
675
676 pssystemmapheaderlen = ntohs(pssystemmapheaderlen);
677
678 pesdata = (unsigned char*)malloc(pssystemmapheaderlen);
679 if (pesdata)
680 {
681 memset(pesdata, 0x0, pespacketlen);
682
683 if (pssystemmapheaderlen != fread(pesdata, 1, pssystemmapheaderlen, fp))
684 {
685 fclose(fp);
686
687 return 0;
688 }
689
690 parsepssystemmapheader(pesdata);
691
692 free(pesdata);
693
694 pesdata = null;
695 }
696
697 break;
698
699 case scode_ps_end:
700 #ifdef printf_debug
701 printf("ps is end!\n");
702 #endif
703
704 return 0;
705
706 break;
707
708 /* pes pcaket */
709 default:
710 pesstreamid = startcode & 0xff;
711
712 if (1 != fread(&pespacketlen, 2, 1, fp))
713 {
714 fclose(fp);
715
716 return 0;
717 }
718
719 pespacketlen = ntohs(pespacketlen);
720
721 pesdata = (unsigned char*)malloc(pespacketlen);
722 if (pesdata)
723 {
724 memset(pesdata, 0x0, pespacketlen);
725
726 if (pespacketlen != fread(pesdata, 1, pespacketlen, fp))
727 {
728 fclose(fp);
729
730 return 0;
731 }
732
733 parsepes(pesstreamid, pesdata, pespacketlen);
734
735 free(pesdata);
736
737 pesdata = null;
738 }
739
740 break;
741 }
742 }
743
744 fclose(fp);
745
746 return 0;
747 }