Annotation of multiplexer/pes2es.c, revision 1.1

1.1     ! oskar       1: /*
        !             2:  * read packetised elementary stream
        !             3:  * Copyright (C) 1999-2004 Christian Wolff
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify
        !             6:  * it under the terms of the GNU General Public License as published by
        !             7:  * the Free Software Foundation; either version 2 of the License, or
        !             8:  * (at your option) any later version.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful,
        !            11:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            12:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            13:  * GNU General Public License for more details.
        !            14:  *
        !            15:  * You should have received a copy of the GNU General Public License
        !            16:  * along with this program; if not, write to the Free Software
        !            17:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            18:  */
        !            19: 
        !            20: #include "pes2es.h"
        !            21: #include "crc16.h"
        !            22: 
        !            23: PES_header *PES;
        !            24: 
        !            25: unsigned short CRC;
        !            26: 
        !            27: void print_PES(PES_header *PES) {  // debug output of PES-Header
        !            28:   int i;
        !            29:   printf("- PES Header -\n\
        !            30: stream_id:               0x%02X\n\
        !            31: PES_packet_length:       %i\n",
        !            32:     PES->stream_id,
        !            33:     PES->PES_packet_length);
        !            34:   if (
        !            35:     (PES->stream_id!=padding_stream_id) &&
        !            36:     (PES->stream_id!=private_stream_2_id) &&
        !            37:     (PES->stream_id!=ECM_stream_id) &&
        !            38:     (PES->stream_id!=EMM_stream_id) &&
        !            39:     (PES->stream_id!=DSMCC_stream_id) &&
        !            40:     (PES->stream_id!=ITU_E_id) &&
        !            41:     (PES->stream_id!=program_stream_directory_id)) {
        !            42:     printf("\
        !            43: PES_scrambling_control:      %i\n\
        !            44: PES_priority:                %i\n\
        !            45: data_alignment_indicator:    %i\n\
        !            46: copyright:                   %i\n\
        !            47: original_or_copy:            %i\n\
        !            48: PTS_flag:                    %i\n\
        !            49: DTS_flag:                    %i\n\
        !            50: ESCR_flag:                   %i\n\
        !            51: ES_rate_flag:                %i\n\
        !            52: DSM_trick_mode_flag:         %i\n\
        !            53: additional_copy_info_flag:   %i\n\
        !            54: PES_CRC_flag:                %i\n\
        !            55: PES_extension_flag:          %i\n\
        !            56: PES_header_data_length:      %i\n",
        !            57:       PES->PES_scrambling_control,
        !            58:       ((PES->PES_priority)?1:0),
        !            59:       ((PES->data_alignment_indicator)?1:0),
        !            60:       ((PES->copyright)?1:0),
        !            61:       ((PES->original_or_copy)?1:0),
        !            62:       ((PES->PTS_flag)?1:0),
        !            63:       ((PES->DTS_flag)?1:0),
        !            64:       ((PES->ESCR_flag)?1:0),
        !            65:       ((PES->ES_rate_flag)?1:0),
        !            66:       ((PES->DSM_trick_mode_flag)?1:0),
        !            67:       ((PES->additional_copy_info_flag)?1:0),
        !            68:       ((PES->PES_CRC_flag)?1:0),
        !            69:       ((PES->PES_extension_flag)?1:0),
        !            70:       PES->PES_header_data_length);
        !            71:     if (PES->PTS_flag) {
        !            72:       printf("\
        !            73: PTS:                         %lld\n",
        !            74:         PES->PTS);
        !            75:       if (PES->DTS_flag) {
        !            76:         printf("\
        !            77: DTS:                         %lld\n",
        !            78:           PES->DTS);
        !            79:       }
        !            80:     }
        !            81:     if (PES->ESCR_flag) {
        !            82:       printf("\
        !            83: ESCR_base:                   %lld\n\
        !            84: ESCR_extension:              %d\n",
        !            85:         PES->ESCR_base,
        !            86:         PES->ESCR_extension);
        !            87:     }
        !            88:     if (PES->ES_rate_flag) {
        !            89:       printf("\
        !            90: ES_rate:                     %i (%i bytes/sec)\n",
        !            91:         PES->ES_rate,PES->ES_rate*50);
        !            92:     }
        !            93:     if (PES->DSM_trick_mode_flag) {
        !            94:       printf("\
        !            95: trick_mode_control:          0x%02X\n",
        !            96:         PES->trick_mode_control);
        !            97:     }
        !            98:     if (PES->additional_copy_info_flag) {
        !            99:       printf("\
        !           100: additional_copy_info:        0x%02X\n",
        !           101:         PES->additional_copy_info);
        !           102:     }
        !           103:     if (PES->PES_CRC_flag) {
        !           104:       printf("\
        !           105: previous_PES_packet_CRC:     0x%04X\n",
        !           106:         PES->previous_PES_packet_CRC);
        !           107:     }
        !           108:     if (PES->PES_extension_flag) {
        !           109:       printf("\
        !           110: PES_private_data_flag        %i\n\
        !           111: pack_header_field_flag       %i\n\
        !           112: program_packet_sequence_counter_flag  %i\n\
        !           113: P_STD_buffer_flag            %i\n\
        !           114: PES_extension_flag_2         %i\n",
        !           115:         ((PES->PES_private_data_flag)?1:0),
        !           116:         ((PES->pack_header_field_flag)?1:0),
        !           117:         ((PES->program_packet_sequence_counter_flag)?1:0),
        !           118:         ((PES->P_STD_buffer_flag)?1:0),
        !           119:         ((PES->PES_extension_flag_2)?1:0));
        !           120:       if (PES->PES_private_data_flag) {
        !           121:         for (i=0; i<128; i++) {
        !           122:           printf("%02X ",PES->PES_private_data[i] & 0xFF);
        !           123:           if ((i % 24)==23) printf("\n");
        !           124:         }
        !           125:         printf("\n");
        !           126:       }
        !           127:       if (PES->pack_header_field_flag) {
        !           128:         printf("\
        !           129: pack_field_length            %i\n",
        !           130:           PES->pack_field_length);
        !           131:       }
        !           132:       if (PES->program_packet_sequence_counter_flag) {
        !           133:         printf("\
        !           134: program_packet_sequence_counter  %i\n\
        !           135: MPEG1_MPEG2_identifier       %i\n\
        !           136: original_stuff_length        %i\n",
        !           137:           PES->program_packet_sequence_counter,
        !           138:           ((PES->MPEG1_MPEG2_identifier)?1:0),
        !           139:           PES->original_stuff_length);
        !           140:       }
        !           141:       if (PES->P_STD_buffer_flag) {
        !           142:         printf("\
        !           143: P_STD_buffer_scale           %i\n\
        !           144: P_STD_buffer_size            %i\n",
        !           145:           ((PES->P_STD_buffer_scale)?1:0),
        !           146:           PES->P_STD_buffer_size);
        !           147:       }
        !           148:       if (PES->PES_extension_flag_2) {
        !           149:         printf("\
        !           150: PES_extension_field_length   %i\n",
        !           151:           PES->PES_extension_field_length);
        !           152:       }
        !           153:     }
        !           154:   }
        !           155:   printf("\n");
        !           156: }
        !           157: 
        !           158: int parse_PES(
        !           159:   FILE* inputstream,            // mpeg-2 file
        !           160:   int parse,                    // true: parse  false: skip packet
        !           161:   int verbose,                  // true: debug output
        !           162:   int pipe,                     // true: selected PES as binary  false: as Hexdump
        !           163:   int useCRC) {                 // true: ignore CRC of PSI
        !           164: 
        !           165:   #define fetchchar if((filechar=fgetc(inputstream))<0)return
        !           166: 
        !           167:   char HD[256];
        !           168:   
        !           169:   int i,k,n,filechar;
        !           170:   unsigned char ch,ch0,ch1,ch2;
        !           171:   
        !           172:   unsigned int packet_data_length;
        !           173:   
        !           174:   unsigned int compare;
        !           175:   #define sequence_end_code 0x000001B7
        !           176: 
        !           177:   // scanning for 23 zero bits and a one-bit in up to 1003 bytes
        !           178:   fetchchar 0x0101; ch0=filechar;
        !           179:   fetchchar 0x0201; ch1=filechar;
        !           180:   fetchchar 0x0301; ch2=filechar;
        !           181:   k=1000; i=0;
        !           182:   while (((ch0) || (ch1) || (ch2!=0x01)) && (k--)) {
        !           183:     if (verbose) {
        !           184:       printf("%02X ",ch0 & 0xFF);
        !           185:       if ((i++ % 24) == 23) printf("\n");
        !           186:     }
        !           187:     ch0=ch1;
        !           188:     ch1=ch2;
        !           189:     fetchchar 0x0401; ch2=filechar;
        !           190:   }
        !           191:   
        !           192:   if (k) {  // 0x000001 found
        !           193:     if ((verbose) && (k<1000)) printf("\nSkipped %i byte looking for 0x000001\n",1000-k);
        !           194:     
        !           195:     fetchchar 0x0501; PES->stream_id=filechar & 0xFF;
        !           196: 
        !           197:     //if (verbose) printf("- PES Packet with %i bytes and stream_id 0x%02X\n",PES->PES_packet_length,PES->stream_id);
        !           198: 
        !           199:     // Padding bytes, ignore
        !           200:     if (PES->stream_id==padding_stream_id) {
        !           201:       fetchchar 0x0601; ch=filechar;
        !           202:       fetchchar 0x0701; PES->PES_packet_length=((ch << 8) | (filechar & 0xFF)) & 0xFFFF;
        !           203:       if (verbose) printf("- %i Padding bytes.\n",PES->PES_packet_length);
        !           204:       for (i=0; i<PES->PES_packet_length; i++)
        !           205:         fetchchar 0x0801;
        !           206:     // Direct data, no further header
        !           207:     } else if (
        !           208:       (PES->stream_id==private_stream_2_id) || 
        !           209:       (PES->stream_id==ECM_stream_id) || 
        !           210:       (PES->stream_id==EMM_stream_id) || 
        !           211:       (PES->stream_id==DSMCC_stream_id) || 
        !           212:       (PES->stream_id==ITU_E_id) || 
        !           213:       (PES->stream_id==program_stream_directory_id)) {
        !           214:       fetchchar 0x0601; ch=filechar;
        !           215:       fetchchar 0x0701; PES->PES_packet_length=((ch << 8) | (filechar & 0xFF)) & 0xFFFF;
        !           216:       if (verbose) print_PES(PES);
        !           217:       if (verbose || !pipe) {
        !           218:         printf("- %i Packet data bytes.\n",PES->PES_packet_length);
        !           219:         for (i=0; i<PES->PES_packet_length; i++) {
        !           220:           fetchchar 0x0901;
        !           221:           printf("%02X ",filechar & 0xFF);
        !           222:           if ((i % 24)==23) printf("\n");
        !           223:         }
        !           224:         printf("\n");
        !           225:       } else if (pipe) {
        !           226:         for (i=0; i<PES->PES_packet_length; i++) {
        !           227:           fetchchar 0x0A01;
        !           228:           putchar(filechar & 0xFF);
        !           229:         }
        !           230:       }
        !           231:       
        !           232:     // PES-Header, parse for subheaders
        !           233:     } else if (PES->stream_id>=0xBC) {
        !           234:       fetchchar 0x0601; ch=filechar;
        !           235:       fetchchar 0x0701; PES->PES_packet_length=((ch << 8) | (filechar & 0xFF)) & 0xFFFF;
        !           236:       fetchchar 0x0B01;
        !           237:       if ((filechar & 0xC0) != 0x80) {
        !           238:         if (verbose) printf("- SYNTAX error (wrong marker bits)\n");
        !           239:         if (useCRC) return 0x0104;
        !           240:       }
        !           241:       PES->PES_scrambling_control=((filechar >> 4) & 0x03);
        !           242:       PES->PES_priority=filechar & 0x08;
        !           243:       PES->data_alignment_indicator=filechar & 0x04;
        !           244:       PES->copyright=filechar & 0x02;
        !           245:       PES->original_or_copy=filechar & 0x01;
        !           246:       fetchchar 0x0C01;
        !           247:       PES->PTS_flag=filechar & 0x80;
        !           248:       PES->DTS_flag=filechar & 0x40;
        !           249:       PES->ESCR_flag=filechar & 0x20;
        !           250:       PES->ES_rate_flag=filechar & 0x10;
        !           251:       PES->DSM_trick_mode_flag=filechar & 0x08;
        !           252:       PES->additional_copy_info_flag=filechar & 0x04;
        !           253:       PES->PES_CRC_flag=filechar & 0x02;
        !           254:       PES->PES_extension_flag=filechar & 0x01;
        !           255:       fetchchar 0x0D01;
        !           256:       PES->PES_header_data_length=filechar & 0xFF;
        !           257:       
        !           258:       // Read remaining header bytes
        !           259:       if (fread(&HD[0],1,PES->PES_header_data_length,inputstream)!=PES->PES_header_data_length) return 0x0E01;
        !           260:       
        !           261:       // parse subheaders
        !           262:       n=0;
        !           263:       if (PES->PTS_flag) {
        !           264:         if ((HD[n] & 0xF0) != ((PES->DTS_flag)?0x30:0x20)) {
        !           265:           if (verbose) printf("- SYNTAX error (wrong marker bits for PTS)\n");
        !           266:           if (useCRC) return 0x0204;
        !           267:         }
        !           268:         PES->PTS=(HD[n++] >> 1) & 0x07ULL;  // Bit 32-30
        !           269:         PES->PTS=(PES->PTS << 8) | (HD[n++] & 0xFFULL);  // Bit 29-22
        !           270:         PES->PTS=(PES->PTS << 7) | ((HD[n++] >> 1) & 0x7FULL);  // Bit 21-15
        !           271:         PES->PTS=(PES->PTS << 8) | (HD[n++] & 0xFFULL);  // Bit 14-7
        !           272:         PES->PTS=(PES->PTS << 7) | ((HD[n++] >> 1) & 0x7FULL);  // Bit 6-0
        !           273:         if (PES->DTS_flag) {
        !           274:           if ((HD[n] & 0xF0) != 0x10) {
        !           275:             if (verbose) printf("- SYNTAX error (wrong marker bits for DTS)\n");
        !           276:             if (useCRC) return 0x0304;
        !           277:           }
        !           278:           PES->DTS=(HD[n++] >> 1) & 0x07ULL;  // Bit 32-30
        !           279:           PES->DTS=(PES->DTS << 8) | (HD[n++] & 0xFFULL);  // Bit 29-22
        !           280:           PES->DTS=(PES->DTS << 7) | ((HD[n++] >> 1) & 0x7FULL);  // Bit 21-15
        !           281:           PES->DTS=(PES->DTS << 8) | (HD[n++] & 0xFFULL);  // Bit 14-7
        !           282:           PES->DTS=(PES->DTS << 7) | ((HD[n++] >> 1) & 0x7FULL);  // Bit 6-0
        !           283:         }
        !           284:       }
        !           285:       if (PES->ESCR_flag) {
        !           286:         PES->ESCR_base=(HD[n] >> 3) & 0x07ULL;  // Bit 32-30
        !           287:         PES->ESCR_base=(PES->ESCR_base << 2) | (HD[n++] & 0x03ULL);  // Bit 29-28
        !           288:         PES->ESCR_base=(PES->ESCR_base << 8) | (HD[n++] & 0xFFULL);  // Bit 27-20
        !           289:         PES->ESCR_base=(PES->ESCR_base << 5) | ((HD[n] >> 3) & 0x1FULL);  // Bit 19-15
        !           290:         PES->ESCR_base=(PES->ESCR_base << 2) | (HD[n++] & 0x03ULL);  // Bit 14-13
        !           291:         PES->ESCR_base=(PES->ESCR_base << 8) | (HD[n++] & 0xFFULL);  // Bit 12-5
        !           292:         PES->ESCR_base=(PES->ESCR_base << 5) | ((HD[n] >> 3) & 0x7FULL);  // Bit 4-0
        !           293:         PES->ESCR_extension=HD[n++] & 0x03; // Bit 8-7
        !           294:         PES->ESCR_extension=(PES->ESCR_extension << 7) | ((HD[n++] >> 1) & 0x7F);  // Bit 6-0
        !           295:       }
        !           296:       if (PES->ES_rate_flag) {
        !           297:         PES->ES_rate=HD[n++] & 0x7F;  // Bit 21-15
        !           298:         PES->ES_rate=(PES->ES_rate << 7) | (HD[n++] & 0xFF);  // Bit 14-7
        !           299:         PES->ES_rate=(PES->ES_rate << 8) | ((HD[n++] >> 1) & 0x7F);  // Bit 6-0
        !           300:       }
        !           301:       if (PES->DSM_trick_mode_flag) {
        !           302:         PES->trick_mode_control=HD[n++] & 0xFF;
        !           303:       }
        !           304:       if (PES->additional_copy_info_flag) {
        !           305:         PES->additional_copy_info=HD[n++] & 0x7F;
        !           306:       }
        !           307:       if (PES->PES_CRC_flag) {
        !           308:         PES->previous_PES_packet_CRC=HD[n++] & 0xFF;
        !           309:         PES->previous_PES_packet_CRC=(PES->previous_PES_packet_CRC << 8) | (HD[n++] & 0xFF);
        !           310:         if (PES->previous_PES_packet_CRC!=CRC) {
        !           311:           if (verbose) printf("- CRC error in previous block 0x%04X / 0x%04X\n",PES->previous_PES_packet_CRC,CRC);
        !           312:           //if (useCRC) return 0x0304;
        !           313:         }
        !           314:       }
        !           315:       if (PES->PES_extension_flag) {
        !           316:         PES->PES_private_data_flag=HD[n] & 0x80;
        !           317:         PES->pack_header_field_flag=HD[n] & 0x40;
        !           318:         PES->program_packet_sequence_counter_flag=HD[n] & 0x20;
        !           319:         PES->P_STD_buffer_flag=HD[n] & 0x10;
        !           320:         PES->PES_extension_flag_2=HD[n] & 0x01;
        !           321:         if (PES->PES_private_data_flag) {
        !           322:           for (i=0; i<128; i++) {
        !           323:             PES->PES_private_data[i]=HD[n++] & 0xFF;
        !           324:           }
        !           325:         }
        !           326:         if (PES->pack_header_field_flag) {
        !           327:           PES->pack_field_length=HD[n++] & 0xFF;
        !           328:           n+=PES->pack_field_length;
        !           329:           // *** TO DO *** parse pack header data
        !           330:         }
        !           331:         if (PES->program_packet_sequence_counter_flag) {
        !           332:           PES->program_packet_sequence_counter=HD[n++] & 0x7F;
        !           333:           PES->MPEG1_MPEG2_identifier=HD[n] & 0x40;
        !           334:           PES->original_stuff_length=HD[n++] & 0x3F;
        !           335:         }
        !           336:         if (PES->P_STD_buffer_flag) {
        !           337:           if ((HD[n] & 0xC0) != 0x40) {
        !           338:             if (verbose) printf("- SYNTAX error (wrong marker bits for P-STD)\n");
        !           339:             if (useCRC) return 0x0404;
        !           340:           }
        !           341:           PES->P_STD_buffer_scale=HD[n] & 0x20;
        !           342:           PES->P_STD_buffer_size=HD[n++] & 0x1F;
        !           343:           PES->P_STD_buffer_size=(PES->P_STD_buffer_size << 8) | (HD[n++] & 0xFF);
        !           344:         }
        !           345:         if (PES->PES_extension_flag_2) {
        !           346:           PES->PES_extension_field_length=HD[n++] & 0x7F;
        !           347:           n+=PES->PES_extension_field_length;
        !           348:         }
        !           349:       }
        !           350: 
        !           351:       // debug output
        !           352:       if (verbose) print_PES(PES);
        !           353:       
        !           354:       //  initialise CRC for next block
        !           355:       CRC=CRC_INIT_16;
        !           356:       
        !           357:       if (PES->PES_packet_length) {
        !           358:         // how long is the size of the remaining PES-data? (now ES-data, that is)
        !           359:         packet_data_length=PES->PES_packet_length - (3 + PES->PES_header_data_length);
        !           360:         compare=0xFFFFFFFF;
        !           361:   
        !           362:         // dump or pipe raw ES-data
        !           363:         if (verbose || !pipe) {
        !           364:           printf("- %i Packet data bytes.\n%5d - ",packet_data_length,0);
        !           365:           for (i=0; i<packet_data_length; i++) {
        !           366:             fetchchar 0x0F01;
        !           367:             CRC=update_crc_16(CRC,filechar & 0xFF);
        !           368:             compare=(compare << 8) | (filechar & 0xFF);
        !           369:             // ANSI colors, 0=black, 1=red, 2=green, 3=yellow, 4=blue, 5=magenta; 6=cyan, 7=white ESC[3<fgcol>;4<bgcol>;1<for bold>m
        !           370:             //if ((compare & 0xFFFFFF00)==0x100) printf("\033[32m%02X\033[37m ",filechar & 0xFF);
        !           371:             //else printf("%02X ",filechar & 0xFF);
        !           372:             printf("%02X%c",filechar & 0xFF,(((compare & 0x00FFFFFF)==0x00000001)?'[':(((compare & 0xFFFFFF00)==0x00000100)?']':' ')));
        !           373:             //printf("%02X ",filechar & 0xFF);
        !           374:             if ((i % 24)==23) printf("\n%5d - ",i+1);
        !           375:           }
        !           376:           printf("\n");
        !           377:         } else if (pipe) {
        !           378:           for (i=0; i<packet_data_length; i++) {
        !           379:             fetchchar 0x1001;
        !           380:             CRC=update_crc_16(CRC,filechar & 0xFF);
        !           381:             putchar(filechar & 0xFF);
        !           382:           }
        !           383:         }
        !           384:       } else if ((PES->stream_id & 0xF0) == 0xE0) {  // endless video stream
        !           385:         compare=0xFFFFFFFF;
        !           386:         // dump or pipe raw ES-data
        !           387:         if (verbose || !pipe) {
        !           388:           printf("- Unbound video stream.\n");
        !           389:           for (i=0; compare!=sequence_end_code; i++) {
        !           390:             fetchchar 0x1101;
        !           391:             CRC=update_crc_16(CRC,filechar & 0xFF);
        !           392:             compare=(compare << 8) | (filechar & 0xFF);
        !           393:             printf("%02X%c",filechar & 0xFF,(((compare & 0x00FFFFFF)==0x00000001)?'<':(((compare & 0xFFFFFF00)==0x00000100)?'>':' ')));
        !           394:             if ((i % 24)==23) printf("\n");
        !           395:           }
        !           396:           printf("\n");
        !           397:         } else if (pipe) {
        !           398:           while (compare!=sequence_end_code) {
        !           399:             fetchchar 0x1201;
        !           400:             CRC=update_crc_16(CRC,filechar & 0xFF);
        !           401:             compare=(compare << 8) | (filechar & 0xFF);
        !           402:             putchar(filechar & 0xFF);
        !           403:           }
        !           404:         }
        !           405:       } else {
        !           406:         if (verbose) printf("- ERROR: Unbound stream, but no video stream.\n");
        !           407:       }
        !           408:       if (verbose) printf("CRC: 0x%04X\n\n",CRC);
        !           409:     } else {
        !           410:       if (verbose) {
        !           411:         printf("ERROR - This is not a PES-Packet!\n  Start code value: 0x%02X (",PES->stream_id);
        !           412:         if (PES->stream_id==0x00)
        !           413:           printf("picture_start_code");
        !           414:         else if (PES->stream_id<=0xAF)
        !           415:           printf("slice_start_code");
        !           416:         else if ((PES->stream_id==0xB0) || (PES->stream_id==0xB1) || (PES->stream_id==0xB6))
        !           417:           printf("reserved");
        !           418:         else if (PES->stream_id==0xB2)
        !           419:           printf("user_data_start_code");
        !           420:         else if (PES->stream_id==0xB3)
        !           421:           printf("sequence_header_code");
        !           422:         else if (PES->stream_id==0xB4)
        !           423:           printf("sequence_error_code");
        !           424:         else if (PES->stream_id==0xB5)
        !           425:           printf("extension_start_code");
        !           426:         else if (PES->stream_id==0xB7)
        !           427:           printf("sequence_end_code");
        !           428:         else if (PES->stream_id==0xB8)
        !           429:           printf("group_start_code");
        !           430:         else if (PES->stream_id==0xB9)
        !           431:           printf("iso_11172_end_code");
        !           432:         else if (PES->stream_id==0xBA)
        !           433:           printf("pack_start_code");
        !           434:         else if (PES->stream_id==0xBB)
        !           435:           printf("system_header_start_code");
        !           436:         else 
        !           437:           printf("unidentified start code");
        !           438:         printf(")\n");
        !           439:       }
        !           440:     }
        !           441:   }
        !           442:   return 0;
        !           443: }
        !           444: 
        !           445: 
        !           446: 
        !           447: int main (int argc, char* argv[]) {
        !           448: 
        !           449:   FILE* inputstream;
        !           450:   int i,filearg,startpacket,stoppacket,err,verbose,pipe,useCRC;
        !           451:   
        !           452:   if (argc < 2) {
        !           453:     printf("\
        !           454: Usage: %s [-v] [-p] [-c] [<file> [<first packet> <last packet> | <packet>]]\n\
        !           455: -v: verbose on\n\
        !           456: -p: pipe on (only raw output)\n\
        !           457: -c: use CRC on PSI\n\
        !           458: -s <prog>/<type>: show/pipe only PES of this program and this type\n\
        !           459: ",argv[0]);
        !           460:     exit (0);
        !           461:   }
        !           462:   
        !           463:   i=1;
        !           464:   filearg=0;
        !           465:   verbose=0;
        !           466:   pipe=0;
        !           467:   startpacket=0;
        !           468:   stoppacket=0;
        !           469:   useCRC=0;
        !           470:   while (i<argc) {
        !           471:     if (argv[i][0]=='-') {  // option
        !           472:       if (argv[i][1]=='v') verbose=1;    // verbose on
        !           473:       else if (argv[i][1]=='p') pipe=1;  // pipe on
        !           474:       else if (argv[i][1]=='c') useCRC=1;  // CRC on
        !           475:     } else if (!filearg) filearg=i;
        !           476:     else if (!startpacket) startpacket=atoi(argv[i]);
        !           477:     else if (!stoppacket) stoppacket=atoi(argv[i]);
        !           478:     i++;
        !           479:   }
        !           480: 
        !           481: 
        !           482:   if (filearg) {
        !           483:     if ((inputstream=fopen(argv[filearg],"r"))==NULL) {
        !           484:       printf("Couldn't open file %s\n",argv[1]);
        !           485:       exit (0);
        !           486:     }
        !           487:   } else inputstream=stdin;
        !           488:   
        !           489:   gen_crc16_table();
        !           490: 
        !           491:   if (startpacket) {
        !           492:     if (!stoppacket) stoppacket=startpacket;
        !           493:   } else stoppacket=32767;  // argh, i have to change this...
        !           494:   
        !           495:   PES=(PES_header *)malloc(sizeof(PES_header));
        !           496:   
        !           497:   err=0;
        !           498:   for (i=0; (i<stoppacket) && (err==0); i++) {
        !           499:     if ((startpacket<=(i+1)) && verbose) printf("--- Packet %i --- %ld\n",i+1,ftell(inputstream));
        !           500:     err=parse_PES(inputstream,(startpacket<=(i+1)),verbose,pipe,useCRC);
        !           501:   }
        !           502:   if (err && verbose) printf("\nError in packet %i at %ld: 0x%04X (%s)\n",i,ftell(inputstream),err,(((err & 0xFF)==0x01)?"End of File":(((err & 0xFF)==0x02)?"Data Format Error":"Unknown Error")));
        !           503:   fclose(inputstream);
        !           504: 
        !           505:   return 0;
        !           506: }

LinuxTV legacy CVS <linuxtv.org/cvs>