view parse_es.c @ 5:6c8fb6b35c26

added Andreas Ackermann
author arpi_esp
date Sun, 25 Feb 2001 22:22:41 +0000
parents 3b5f5d1c5041
children ae91bfef2a94
line wrap: on
line source

//=================== VIDEO PARSER =========================

#define MAX_VIDEO_PACKET_SIZE (224*1024+4)
#define VIDEOBUFFER_SIZE 0x100000

//static unsigned char videobuffer[MAX_VIDEO_PACKET_SIZE];
static unsigned char* videobuffer=NULL;
static int videobuf_len=0;

static unsigned char videobuf_code[4];
static int videobuf_code_len=0;

// sync video stream, and returns next packet code
int sync_video_packet(demux_stream_t *ds){
  int skipped=0;
  // we need enough bytes in the buffer:
  while(videobuf_code_len<4){
#if 0
    int c;
    c=demux_getc(ds);if(c<0){ return 0;} // EOF
    videobuf_code[videobuf_code_len++]=c;
#else
    videobuf_code[videobuf_code_len++]=demux_getc(ds);
#endif
  }
  // sync packet:
  while(1){
    int c;
    if(videobuf_code[0]==0 &&
       videobuf_code[1]==0 &&
       videobuf_code[2]==1) break; // synced
    // shift buffer, drop first byte
    ++skipped;
    videobuf_code[0]=videobuf_code[1];
    videobuf_code[1]=videobuf_code[2];
    videobuf_code[2]=videobuf_code[3];
    c=demux_getc(ds);if(c<0){ return 0;} // EOF
    videobuf_code[3]=c;
  }
  if(verbose>=2) if(skipped) printf("videobuf: %d bytes skipped\n",skipped);
  return 0x100|videobuf_code[3];
}

// return: packet length
int read_video_packet(demux_stream_t *ds){
int packet_start;
  
  // SYNC STREAM
//  if(!sync_video_packet(ds)) return 0; // cannot sync (EOF)

  // COPY STARTCODE:
  packet_start=videobuf_len;
  videobuffer[videobuf_len+0]=videobuf_code[0];
  videobuffer[videobuf_len+1]=videobuf_code[1];
  videobuffer[videobuf_len+2]=videobuf_code[2];
  videobuffer[videobuf_len+3]=videobuf_code[3];
  videobuf_len+=4;
  
  // READ PACKET:
  { unsigned int head=-1;
    while(videobuf_len<VIDEOBUFFER_SIZE){
      int c=demux_getc(ds);
      if(c<0) break; // EOF
      videobuffer[videobuf_len++]=c;
#if 1
      head<<=8;
      if(head==0x100) break; // synced
      head|=c;
#else
      if(videobuffer[videobuf_len-4]==0 &&
         videobuffer[videobuf_len-3]==0 &&
         videobuffer[videobuf_len-2]==1) break; // synced
#endif
    }
  }
  
  if(ds->eof){
    videobuf_code_len=0; // EOF, no next code
    return videobuf_len-packet_start;
  }
  
  videobuf_len-=4;

  if(verbose>=2) printf("videobuf: packet 0x1%02X  len=%d\n",videobuffer[3],videobuf_len);

  // Save next packet code:
  videobuf_code[0]=videobuffer[videobuf_len];
  videobuf_code[1]=videobuffer[videobuf_len+1];
  videobuf_code[2]=videobuffer[videobuf_len+2];
  videobuf_code[3]=videobuffer[videobuf_len+3];
  videobuf_code_len=4;

  return videobuf_len-packet_start;
}

// return: next packet code
int skip_video_packet(demux_stream_t *ds){

  // SYNC STREAM
//  if(!sync_video_packet(ds)) return 0; // cannot sync (EOF)
  
  videobuf_code_len=0; // force resync
  
  // SYNC AGAIN:
  return sync_video_packet(ds);
}