📄 readfile.c
字号:
packetID = startCode & 0xff; while (((startCode & PACKET_START_CODE_MASK) == PACKET_START_CODE_PREFIX) && (packetID >= 0xbc)) {#ifdef ANALYSIS ++numPackets; #endif match = TRUE; packetID = startCode & 0xff; PacketReply = ReadPacket(packetID, vid_stream); switch (PacketReply) { case 2: return 1; case 1: return 0; default: /* do nothing */ break; } errorCode = ReadStartCode( &startCode, vid_stream ); if (errorCode != 0) { fprintf(stderr,"Error in start code after packet\n"); return 0; } if (startCode == PACK_START_CODE || startCode == ISO_11172_END_CODE) { break; } } if (startCode == ISO_11172_END_CODE) { match = TRUE; if (vid_stream->Parse_done) { return 1; }#ifdef ANALYSIS fprintf(stderr, "Successful parse of MPEG system level\n"); fprintf(stderr, "%d system headers, %d packs, %d packets\n", numSystemHeaders, numPacks, numPackets); fprintf(stderr, "%d audio packets, %d video packets, %d padding packets\n", gNumAudioPackets, gNumVideoPackets, gNumPaddingPackets); fprintf(stderr, "%d reserved packets, %d/%d private type 1/2 packets\n", gNumReservedPackets, gNumPrivate_1_Packets, gNumPrivate_2_Packets);#endif ReadPacket(NOT_PACKET_ID, vid_stream); vid_stream->Parse_done = TRUE; return 1; } if (errorCode != 0) return 1; if (! match) { fprintf(stderr,"\nNo match found for start code %08x in system layer, skipping\n",startCode); startCode = find_start_code(vid_stream->input); if (startCode == EOF) { vid_stream->EOF_flag = 1; return 0; } } }}/* *----------------------------------------------------------- * * ReadStartCode * * Parses a start code out of the stream * * Results/Side Effects: Sets *startCode to the code, returns * 1 on error, 0 on success * *----------------------------------------------------------- */int ReadStartCode(startCode, vid_stream) unsigned int *startCode; VidStream *vid_stream;{ int numRead; numRead = fread((unsigned char *)startCode, 1, 4, vid_stream->input); *startCode = htonl(*startCode); if (numRead < 4) { vid_stream->EOF_flag = 1; return 1; } if ((*startCode&0xfffffe00) != 0) { fprintf(stderr,"Problem with system layer parse, skipping to start code\n"); *startCode = find_start_code(vid_stream->input); if (*startCode == EOF) { vid_stream->EOF_flag = TRUE; return 0; } } return 0;}/* *----------------------------------------------------------- * * find_start_code * * Parses a start code out of the stream by tossing bytes until it gets one * * Results/Side Effects: Parses bytes of the stream, returns code * Returns EOF in case of end of file * *----------------------------------------------------------- */int find_start_code(input) FILE *input;{ NO_ZEROS: switch(fgetc(input)) { case 0: goto ONE_ZERO; case EOF: goto EOF_FOUND; default: goto NO_ZEROS; } ONE_ZERO: switch(fgetc(input)) { case 0: goto TWO_ZEROS; case EOF: goto EOF_FOUND; default: goto NO_ZEROS; } TWO_ZEROS: switch(fgetc(input)) { case 0x01: goto CODE_FOUND; case 0x00: goto TWO_ZEROS; case EOF: goto EOF_FOUND; default: goto NO_ZEROS; } CODE_FOUND: return 0x00000100+fgetc(input); EOF_FOUND: /* received EOF */ return EOF;}/* *----------------------------------------------------------------- * * ReadPackHeader * * Parses out the PACK header * * Returns: 1 on error, 0 on success * *------------------------------------------------------------------- */int ReadPackHeader(systemClockTime,muxRate, vid_stream) double *systemClockTime; unsigned long *muxRate; VidStream *vid_stream;{ int numRead; unsigned char inputBuffer[PACK_HEADER_SIZE]; unsigned long systemClockRef; unsigned char systemClockRefHiBit; int errorCode; numRead = fread(inputBuffer, 1, PACK_HEADER_SIZE, vid_stream->input); if (numRead < PACK_HEADER_SIZE) { vid_stream->EOF_flag = 1; return 1; } ReadTimeStamp(inputBuffer, &systemClockRefHiBit, &systemClockRef); errorCode = MakeFloatClockTime(systemClockRefHiBit, systemClockRef, systemClockTime); ReadRate(&inputBuffer[5], muxRate); *muxRate *= MUX_RATE_SCALE_FACTOR; return 0;}/* *------------------------------------------------------------------ * * ReadSystemHeader * * Parse out the system header, setup out stream IDs for parsing packets * * Results: Returns 1 on error, 0 on success. * Sets gAudioStreamID and gVideoStreamID * *------------------------------------------------------------------ */int ReadSystemHeader(vid_stream) VidStream *vid_stream;{ unsigned char *inputBuffer = NULL; int numRead; int pos; unsigned short headerSize; unsigned char streamID; numRead = fread((char *)&headerSize, 1, 2, vid_stream->input); headerSize = ntohs(headerSize); if (numRead != 2) { vid_stream->EOF_flag = 1; return 1; } inputBuffer = (unsigned char *) malloc((unsigned int) headerSize+1); if (inputBuffer == NULL) { return 1; } inputBuffer[headerSize]=0; numRead = fread(inputBuffer, 1, headerSize, vid_stream->input); /* Brown - get rid of Ansi C complaints */ if (numRead < (int) headerSize) { vid_stream->EOF_flag = 1; return 1; } pos = 6; while ((inputBuffer[pos] & 0x80) == 0x80) { streamID = inputBuffer[pos]; switch (streamID) { case STD_VIDEO_STREAM_ID: break; case STD_AUDIO_STREAM_ID: break; case RESERVED_STREAM_ID: break; case PADDING_STREAM_ID: break; case PRIVATE_STREAM_1_ID: break; case PRIVATE_STREAM_2_ID: break; default: if (streamID < MIN_STREAM_ID_ID) { return 1; } switch (streamID >> 4) { case 0xc: case 0xd: vid_stream->gAudioStreamID = streamID; break; case 0xe: if ((vid_stream->gVideoStreamID != 0) && (vid_stream->gVideoStreamID!=streamID)) { break; } vid_stream->gVideoStreamID = streamID; break; case 0xf:/*Brown - deglobalized gReservedStreamID */ vid_stream->gReservedStreamID = streamID; break; } break; } pos += 3; } if (inputBuffer != NULL) free(inputBuffer); return 0;}/* *----------------------------------------------------------------- * * ReadPacket * * Reads a single packet out of the stream, and puts it in the * buffer if it is video. * * Results: * Changes the value of *length_ptr to be the new length (plus old) * If the buffer is too small, can change *bs_ptr, *max_length, and * buf_ptr to be correct for a newly allocated buffer. * * State: * The buffer is in ints, but the packets can be an arbitrary number * of bytes, so leftover bytes are kept in the VidStream variable and * are added on the next call. * *----------------------------------------------------------------- */ #ifdef __STDC__int ReadPacket(unsigned char packetID, VidStream *vid_stream)#elseint ReadPacket(packetID, vid_stream) unsigned char packetID; VidStream *vid_stream;#endif /* Returns: 0 - no error, but not video packet we want 1 - error 2 - got video packet into buffer */{ unsigned int **bs_ptr=&vid_stream->buf_start; int *max_length = &vid_stream->max_buf_length; int *length_ptr=&vid_stream->buf_length; unsigned int **buf_ptr=&vid_stream->buffer; int ioBytes; unsigned char nextByte; unsigned short packetLength; unsigned char *packetBuffer = NULL; int pos; int numStuffBytes = 0; unsigned int packetDataLength; int byte_length; unsigned char scratch[10]; /* Leftovers from previous video packets */ if (packetID == NOT_PACKET_ID) { /* Gross hack to handle unread bytes before end of stream */ if (vid_stream->num_left != 0) { /* Sigh, deal with previous leftovers */ *(*buf_ptr+*length_ptr) = vid_stream->leftover_bytes; *(*buf_ptr+*length_ptr+1) = ISO_11172_END_CODE; *length_ptr += 2; } else { *(*buf_ptr+*length_ptr) = ISO_11172_END_CODE; *length_ptr += 1; } return 1; } else if (packetID==KILL_BUFFER) { vid_stream->num_left=0; vid_stream->leftover_bytes=0; return 0; } ioBytes = fread(&packetLength, 1, 2, vid_stream->input); packetLength = htons(packetLength); if (ioBytes < 2) { return 1; } if (packetID == vid_stream->gAudioStreamID) {#ifdef ANALYSIS ++gNumAudioPackets;#endif } else if (packetID == vid_stream->gVideoStreamID) {#ifdef ANALYSIS ++gNumVideoPackets;#endif } else { switch (packetID) { case PADDING_STREAM_ID:#ifdef ANALYSIS ++gNumPaddingPackets;#endif break; case RESERVED_STREAM_ID:#ifdef ANALYSIS ++gNumReservedPackets;#endif break; case PRIVATE_STREAM_1_ID:#ifdef ANALYSIS ++gNumPrivate_1_Packets;#endif break; case PRIVATE_STREAM_2_ID:#ifdef ANALYSIS ++gNumPrivate_2_Packets;#endif break; default: fprintf(stderr, "\nUnknown packet type encountered. P'bly audio? (%x) at %d\n", packetID,(int) ftell(vid_stream->input)); } if (packetID != vid_stream->gVideoStreamID) {/* changed by jim */ fseek(vid_stream->input, packetLength, 1); return 0; } } fread(&nextByte,1,1,vid_stream->input); pos = 0; while (nextByte & 0x80) { ++numStuffBytes; ++pos; fread(&nextByte,1,1,vid_stream->input); } if ((nextByte >> 6) == 0x01) { pos += 2; fread(&nextByte,1,1,vid_stream->input); fread(&nextByte,1,1,vid_stream->input); } if ((nextByte >> 4) == 0x02) { scratch[0] = nextByte; /* jim */ fread(&scratch[1],1,4,vid_stream->input); /* jim */ fread(&nextByte,1,1,vid_stream->input); pos += 5; } else if ((nextByte >> 4) == 0x03) { scratch[0] = nextByte; /* jim */ fread(&scratch[1],1,9,vid_stream->input); /* jim */ fread(&nextByte,1,1,vid_stream->input); pos += 10; } else { fread(&nextByte,1,1,vid_stream->input); pos += 1; } /* Read all the headers, now make room for packet */ if (*bs_ptr + *max_length < *buf_ptr+ packetLength/4 + *length_ptr) { /* Brown - get rid of Ansi C complaints */ if (*max_length - *length_ptr < (int) packetLength/4) { /* Buffer too small for a packet (plus whats there), * time to enlarge it! */ unsigned int *old = *bs_ptr; *max_length = *length_ptr + packetLength/2; *bs_ptr=(unsigned int *)malloc(*max_length*4); if (*bs_ptr == NULL) { return 1; } memcpy((unsigned char *)*bs_ptr, *buf_ptr, (unsigned int) *length_ptr*4); free(old); *buf_ptr = *bs_ptr; } else { memcpy((unsigned char *)*bs_ptr, *buf_ptr, (unsigned int) *length_ptr*4); *buf_ptr = *bs_ptr; }} byte_length = *length_ptr*4; if (vid_stream->num_left != 0) { /* Sigh, deal with previous leftovers */ byte_length += vid_stream->num_left; *(*buf_ptr+*length_ptr) = vid_stream->leftover_bytes; } packetBuffer=((unsigned char *)*buf_ptr)+byte_length; packetDataLength = packetLength - pos; *packetBuffer++ = nextByte;/* Brown - deglobalize gVideoStreamID */ if (packetID == vid_stream->gVideoStreamID) { ioBytes = fread(packetBuffer, 1, packetDataLength-1, vid_stream->input); if (ioBytes != packetDataLength-1) { vid_stream->EOF_flag = 1; return 1; } if (1 != ntohl(1)) { unsigned int *mark = *buf_ptr+*length_ptr; int i; for (i=0; i < ((packetDataLength+ vid_stream->num_left)&0xfffffffc); i+=4) { *mark=ntohl(*mark); mark++; } } byte_length = byte_length + packetDataLength; vid_stream->num_left = byte_length % 4; *length_ptr = byte_length / 4; vid_stream->leftover_bytes = *(*buf_ptr + *length_ptr); return 2; } else if (packetID == vid_stream->gAudioStreamID) { packetBuffer = (unsigned char *)(*buf_ptr + *length_ptr + 1); fread(packetBuffer, 1, packetDataLength - 1, vid_stream->input); } else /* Donno what it is, just nuke it */ { /* This code should be unreachable */ packetBuffer = (unsigned char *)(*buf_ptr + *length_ptr + 1); fread(packetBuffer, 1, packetDataLength - 1, vid_stream->input); } return 0; }/* * The remaining procedures are formatting utility procedures. */void ReadTimeStamp(inputBuffer,hiBit,low4Bytes) unsigned char *inputBuffer, *hiBit; unsigned long *low4Bytes;{ *hiBit = ((unsigned long)inputBuffer[0] >> 3) & 0x01; *low4Bytes = (((unsigned long)inputBuffer[0] >> 1) & 0x03) << 30; *low4Bytes |= (unsigned long)inputBuffer[1] << 22; *low4Bytes |= ((unsigned long)inputBuffer[2] >> 1) << 15; *low4Bytes |= (unsigned long)inputBuffer[3] << 7; *low4Bytes |= ((unsigned long)inputBuffer[4]) >> 1; }void ReadSTD(inputBuffer,stdBufferScale,stdBufferSize) unsigned char *inputBuffer;unsigned char *stdBufferScale;unsigned long *stdBufferSize;{ /* Brown - get rid of ANSI C complaints */ *stdBufferScale = ((int)(inputBuffer[0] & 0x20) >> 5); *stdBufferSize = ((unsigned long)inputBuffer[0] & 0x1f) << 8; *stdBufferSize |= (unsigned long)inputBuffer[1];}void ReadRate(inputBuffer,rate) unsigned char *inputBuffer; unsigned long *rate;{ *rate = (inputBuffer[0] & 0x7f) << 15; *rate |= inputBuffer[1] << 7; /* Brown - get rid of ANSI C complaints */ *rate |= (int) (inputBuffer[2] & 0xfe) >> 1;}#define FLOAT_0x10000 (double)((unsigned long)1 << 16)#ifdef __STDC__int MakeFloatClockTime(unsigned char hiBit, unsigned long low4Bytes, double * floatClockTime)#elseint MakeFloatClockTime(hiBit,low4Bytes,floatClockTime) unsigned char hiBit; unsigned long low4Bytes; double *floatClockTime;#endif{ if (hiBit != 0 && hiBit != 1) { *floatClockTime = 0.0; return 1; } *floatClockTime = (double)hiBit*FLOAT_0x10000*FLOAT_0x10000 + (double)low4Bytes; *floatClockTime /= (double)STD_SYSTEM_CLOCK_FREQ; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -