⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readfile.c

📁 MPEG2 PLAYER in linux
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * readfile.c -- * *       Procedures concerned with reading data and parsing  *       start codes from MPEG files. * *//* * Copyright (c) 1995 The Regents of the University of California. * All rights reserved. *  * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. *  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. *//* * Portions of this software Copyright (c) 1995 Brown University. * All rights reserved. *  * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement * is hereby granted, provided that the above copyright notice and the * following two paragraphs appear in all copies of this software. *  * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *  * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */#include "video.h"#include "proto.h"#include <sys/types.h>#include <signal.h>#ifndef MIPS#include <netinet/in.h>#else#include <bsd/netinet/in.h>#endif#include "util.h"#include "dither.h"#ifdef __STDC__#include <stdlib.h>#include <string.h>#endif/*   Changes to make the code reentrant:      deglobalized: totNumFrames, realTimeStart, stream id vars, Prase_done,         swap, seekValue, input, EOF_flag, ReadPacket statics, sys_layer,	 bitOffset, bitLength, bitBuffer, curVidStream   removed: [aud,sys,vid]Bytes   Additional changes:      get rid on ANSI C complaints about shifting   -lsh@cs.brown.edu (Loring Holden) *//* Silly Constants.... */#define PACK_START_CODE             ((unsigned int)0x000001ba)#define SYSTEM_HEADER_START_CODE    ((unsigned int)0x000001bb)#define PACKET_START_CODE_MASK      ((unsigned int)0xffffff00)#define PACKET_START_CODE_PREFIX    ((unsigned int)0x00000100)#define ISO_11172_END_CODE          ((unsigned int)0x000001b9)  #define PACK_HEADER_SIZE 8  #define STD_AUDIO_STREAM_ID ((unsigned char) 0xb8)#define STD_VIDEO_STREAM_ID ((unsigned char) 0xb9)#define MIN_STREAM_ID_ID    ((unsigned char) 0xbc)#define RESERVED_STREAM_ID  ((unsigned char) 0xbc)#define PRIVATE_STREAM_1_ID ((unsigned char) 0xbd)#define PADDING_STREAM_ID   ((unsigned char) 0xbe)#define PRIVATE_STREAM_2_ID ((unsigned char) 0xbf)  #define STD_SYSTEM_CLOCK_FREQ (unsigned long)90000#define MUX_RATE_SCALE_FACTOR 50#define MAX_STREAMS 8#define NOT_PACKET_ID       ((unsigned char) 0xff)#define KILL_BUFFER         ((unsigned char) 0xfe)  /* *-------------------------------------------------------------- * * get_more_data -- * *	Called by get_more_data to read in more data from *      video MPG files (non-system-layer) * * Results: *	Input buffer updated, buffer length updated. *      Returns 1 if data read, 0 if EOF, -1 if error. * * Side effects: *      None. * *-------------------------------------------------------------- */int get_more_data(vid_stream)      VidStream *vid_stream;{  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, data, result;  unsigned char byte;  unsigned int *mark;  int sys_layer= vid_stream->sys_layer;    if (sys_layer == 0) {    return pure_get_more_data(*bs_ptr,			      *max_length,			       length_ptr,			       buf_ptr,			       vid_stream);  }  if (sys_layer == -1) {    /* Time to init ourselves */    vid_stream->swap = (htonl(1) != 1);    mark = *bs_ptr;    ioBytes = fread(&data, 1, 4, vid_stream->input);    if (ioBytes != 4) {	  return 0;    }    data = ntohl(data);    if ( (data == PACK_START_CODE) || (data == SYSTEM_HEADER_START_CODE) ) {    got_sys:      /* Yow, a System Layer Stream.  Much harder to parse.  Call in the	     specialist.... */      fprintf(stderr,"This is an MPEG System Layer Stream.  ");      fprintf(stderr,"Audio is not played.\n");      vid_stream->sys_layer = 1;      result = read_sys(vid_stream,(unsigned int) data);      return result;    } else if (data ==  SEQ_START_CODE) {    got_seq:      /* No system Layer junk, just pretent we didn't peek,	     and hereafter just call pure_get_more_data */      vid_stream->sys_layer = 0;      **bs_ptr = data;      *length_ptr = 1;      result = pure_get_more_data(*bs_ptr, *max_length, 				 length_ptr, buf_ptr, vid_stream);      *buf_ptr = *bs_ptr;      return result;    } else {      int state;      fprintf(stderr, "Junk at start of stream, searching for start code\n");      state = 0;      while (TRUE) {	if ((ioBytes = fread(&byte, 1, 1, vid_stream->input)) != 1) return 0;	if (byte == 0) {	  if (state < 2) state++;	} else if ((byte == 1) && (state == 2)) {	  state++;	} else {	  state = 0;	}	if (state == 3) {	  if ((ioBytes = fread(&byte, 1, 1, vid_stream->input)) != 1) return 0;	  data = ((unsigned int) byte + 0x100);	  switch (data) {	  case SEQ_START_CODE:	    goto got_seq;	  case PACK_START_CODE:	  case SYSTEM_HEADER_START_CODE:	    goto got_sys;	  default:	    /* keep looking */	    state=0;	  }	}      }}  }  /* A system layer stream (called after the 1st time), call the specialist */  result = read_sys(vid_stream,0);  return result;}/* *------------------------------------------------------------- * * clear_data_stream * * Empties out internal buffers * *------------------------------------------------------------- */void   clear_data_stream(vid_stream)     VidStream *vid_stream;{  /* Only internal buffer is in ReadPacket */  if (vid_stream->sys_layer) {    ReadPacket(KILL_BUFFER, vid_stream);  }}/* *------------------------------------------------------------- * * SeekStream * * Goto an offset in the steam * *------------------------------------------------------------- */void  SeekStream(vid_stream)VidStream *vid_stream;{  int errno;  int code;    if (vid_stream->seekValue < 0) return; /* done seeking */#ifdef SEEK_SET  errno = fseek(vid_stream->input, vid_stream->seekValue, SEEK_SET);#else  errno = fseek(vid_stream->input, vid_stream->seekValue, 0);#endif  if (errno != 0) {    fprintf(stderr,"Error in seek (%d)\n",errno);    perror("mpeg_play");  }  vid_stream->seekValue = 0-vid_stream->seekValue;  vid_stream->totNumFrames = 0;  /* clear that buffer */  vid_stream->buffer = vid_stream->buf_start;  vid_stream->buf_length = 0;  vid_stream->bit_offset = 0;  /* Find a decent start code */ restart: NO_ZEROS:  switch(fgetc(vid_stream->input)) {  case 0:    goto ONE_ZERO;  case EOF:  goto EOF_FOUND;  default:   goto NO_ZEROS;  }   ONE_ZERO:  switch(fgetc(vid_stream->input)) {  case 0:    goto TWO_ZEROS;  case EOF:  goto EOF_FOUND;  default:   goto NO_ZEROS;  }   TWO_ZEROS:  switch(fgetc(vid_stream->input)) {  case 0x01:  goto CODE_FOUND;  case 0x00:  goto TWO_ZEROS;  case EOF:   goto EOF_FOUND;  default:    goto NO_ZEROS;  }   CODE_FOUND:  code = 0x00000100+fgetc(vid_stream->input);  if (vid_stream->sys_layer) {    clear_data_stream(vid_stream);    if (((code & PACKET_START_CODE_MASK) == PACKET_START_CODE_PREFIX) &&	((code & 0xff) >= 0xbc)) {      read_sys(vid_stream, code);      while (TRUE) {	next_start_code(vid_stream);	show_bits32(code);	if ((code == SEQ_START_CODE) ||	    (code == GOP_START_CODE)) return;	flush_bits32;       }    }  } else {    if ((code == SEQ_START_CODE) ||	(code == GOP_START_CODE)) {      *vid_stream->buffer = code;      vid_stream->buf_length = 1;      return;    }  }  goto restart; EOF_FOUND:   /* received EOF */  fprintf(stderr, "Hit EOF after seeking (offset %ld)\n",     ftell(vid_stream->input));  exit(1);}/* *-------------------------------------------------------------- * * pure_get_more_data -- *      (get_more_data from ver 2.0 with swap added) * *	Called by get_more_data to read in more data from *      video MPG files (non-system-layer) * * Results: *	Input buffer updated, buffer length updated. *      Returns 1 if data read, 0 if EOF, -1 if error. * * Side effects: *      None. * *-------------------------------------------------------------- */int pure_get_more_data(buf_start, max_length, length_ptr, buf_ptr, vid_stream)     unsigned int *buf_start;     int max_length;     int *length_ptr;     unsigned int **buf_ptr;     VidStream *vid_stream;{    int length, num_read, i;  unsigned int request;  unsigned char *buffer, *mark;  unsigned int *lmark;  BOOLEAN swap=vid_stream->swap;    if (vid_stream->EOF_flag) return 0;    length = *length_ptr;  buffer = (unsigned char *) *buf_ptr;    if (length > 0) {    memcpy((unsigned char *) buf_start, buffer, (unsigned int) (length*4));    mark = ((unsigned char *) (buf_start + length));  }  else {    mark = (unsigned char *) buf_start;    length = 0;  }    request = (max_length-length)*4;      num_read = fread(mark, 1, request, vid_stream->input);    /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */  {    int num_read_rounded;    unsigned char *index;        num_read_rounded = 4*(num_read/4);        /* this can happen only if num_read<request; i.e. end of file reached */    if ( num_read_rounded < num_read ) {  	  num_read_rounded = 4*( num_read/4+1 ); 	    /* fill in with zeros */ 	  for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 ); 	  /* advance to the next 4-byte boundary */ 	  num_read = num_read_rounded;    }  }    if (num_read < 0) {    return -1;  } else if (num_read == 0) {    *buf_ptr = buf_start;        /* Make 32 bits after end equal to 0 and 32     * bits after that equal to seq end code     * in order to prevent messy data from infinite     * recursion.     */        *(buf_start + length) = 0x0;    *(buf_start + length+1) = SEQ_END_CODE;        vid_stream->EOF_flag = 1;    return 0;  }    lmark = (unsigned int *) mark;    num_read = num_read/4;    if (swap) {    for (i = 0; i < num_read; i++) {      *lmark = htonl(*lmark);      lmark++;    }  }    *buf_ptr = buf_start;  *length_ptr = length + num_read;    return 1;}/*   Here is the specialist....   Code is adapted from our program demux....  A bunch of this needs to be #ifdef ANALYSIS'ed  define __SYSREAD_LOGGING_ON__ to get  an output file for debugging  *//* Brown - removed StreamID global variables */#ifdef ANALYSIS/* Statistics */static int gNumAudioPackets;static int gNumVideoPackets;static int gNumPaddingPackets;static int gNumReservedPackets;static int gNumPrivate_1_Packets;static int gNumPrivate_2_Packets;#endif/* *---------------------------------------------------------- * *  read_sys * *      Parse out a packet of the system layer MPEG file. * *  Results:  Returns 0 if error or EOF *            Returns 1 if more data read (could be just one int) * *  Side Effects:  ReadPacket can change *bs_ptr to be a new buffer *                 buf_ptr will remain pointing at *length_ptr (at input) *                         into the buffer *                 *length_ptr will be changed to the new size *                 *max_length can be changed if a new buffer is alloc'd * *---------------------------------------------------------- */int read_sys(vid_stream, start)     VidStream *vid_stream;     unsigned int start;       /* start is either a start code or 0 to indicate continued parsing */{  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;  unsigned int startCode;  int errorCode, PacketReply;  unsigned char packetID;  double systemClockTime;  unsigned long muxRate;  /* Statistics */#ifdef ANALYSIS  static int numPacks = 0;  static int numPackets = 0;  static int numSystemHeaders = 0;#endif  BOOLEAN match;    if (!start) {    errorCode = ReadStartCode(&startCode,vid_stream);    if (vid_stream->EOF_flag) return 0;    if (errorCode != 0) {      fprintf(stderr, "Unable to read initial pack start code\n");      return 0;    }}  else {    errorCode = 0;    startCode = start;  }    while (1) {    match=FALSE;    if (startCode == PACK_START_CODE) {#ifdef ANALYSIS      ++numPacks; #endif      match = TRUE;      errorCode = ReadPackHeader( &systemClockTime, &muxRate, vid_stream);      if (errorCode != 0) {        fprintf(stderr, "Error in reading pack header\n");        return 0;      }      errorCode = ReadStartCode( &startCode, vid_stream );      if (errorCode != 0) {        fprintf(stderr, "Error in reading start code\n");        return 0;      }    }    if (startCode == SYSTEM_HEADER_START_CODE) {#ifdef ANALYSIS      ++numSystemHeaders; #endif      match = TRUE;      errorCode = ReadSystemHeader(vid_stream);      if (errorCode != 0) {        fprintf(stderr, "Error in reading system header\n");        return 0;      }      errorCode = ReadStartCode( &startCode, vid_stream );      if (errorCode != 0) {        fprintf(stderr,"Error in reading start code after system header\n");        return 0;      }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -