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

📄 avilib.c

📁 Simple SunPlus SP54 codec converter and a more playable mode MJPG. untar the archive go to the r
💻 C
📖 第 1 页 / 共 3 页
字号:
   OUT4CC ("\0\0\0\0");   OUTLONG(0);             /* Flags */   OUTLONG(0);             /* Reserved, MS says: wPriority, wLanguage */   OUTLONG(0);             /* InitialFrames */   OUTLONG(sampsize);      /* Scale */   OUTLONG(sampsize*AVI->a_rate); /* Rate: Rate/Scale == samples/second */   OUTLONG(0);             /* Start */   OUTLONG(AVI->audio_bytes/sampsize);   /* Length */   OUTLONG(0);             /* SuggestedBufferSize */   OUTLONG(-1);            /* Quality */   OUTLONG(sampsize);      /* SampleSize */   OUTLONG(0);             /* Frame */   OUTLONG(0);             /* Frame */   OUTLONG(0);             /* Frame */   OUTLONG(0);             /* Frame */   /* The audio stream format */   OUT4CC ("strf");   OUTLONG(16);                   /* # of bytes to follow */   OUTSHRT(AVI->a_fmt);           /* Format */   OUTSHRT(AVI->a_chans);         /* Number of channels */   OUTLONG(AVI->a_rate);          /* SamplesPerSec */   OUTLONG(sampsize*AVI->a_rate); /* AvgBytesPerSec */   OUTSHRT(sampsize);             /* BlockAlign */   OUTSHRT(AVI->a_bits);          /* BitsPerSample */   /* Finish stream list, i.e. put number of bytes in the list to proper pos */   long2str(AVI_header+strl_start-4,nhb-strl_start);   }   /* Finish header list */   long2str(AVI_header+hdrl_start-4,nhb-hdrl_start);   /* Calculate the needed amount of junk bytes, output junk */   njunk = HEADERBYTES - nhb - 8 - 12;   /* Safety first: if njunk <= 0, somebody has played with      HEADERBYTES without knowing what (s)he did.      This is a fatal error */   if(njunk<=0)   {      fprintf(stderr,"AVI_close_output_file: # of header bytes too small\n");      exit(1);   }   OUT4CC ("JUNK");   OUTLONG(njunk);   memset(AVI_header+nhb,0,njunk);   nhb += njunk;   /* Start the movi list */   OUT4CC ("LIST");   OUTLONG(movi_len); /* Length of list in bytes */   OUT4CC ("movi");   /* Output the header, truncate the file to the number of bytes      actually written, report an error if someting goes wrong */   if ( lseek(AVI->fdes,0,SEEK_SET)<0 ||        write(AVI->fdes,AVI_header,HEADERBYTES)!=HEADERBYTES ||        ftruncate(AVI->fdes,AVI->pos)<0 )   {      AVI_errno = AVI_ERR_CLOSE;      return -1;   }   if(idxerror) return -1;   return 0;}/*   AVI_write_data:   Add video or audio data to the file;   Return values:    0    No error;   -1    Error, AVI_errno is set appropriatly;*/static int avi_write_data(avi_t *AVI, char *data, long length, int audio){   int n;   /* Check for maximum file length */   if ( (AVI->pos + 8 + length + 8 + (AVI->n_idx+1)*16) > AVI_MAX_LEN )   {      AVI_errno = AVI_ERR_SIZELIM;      return -1;   }   /* Add index entry */   if(audio)      n = avi_add_index_entry(AVI,"01wb",0x00,AVI->pos,length);   else      n = avi_add_index_entry(AVI,"00db",0x10,AVI->pos,length);   if(n) return -1;   /* Output tag and data */   if(audio)      n = avi_add_chunk(AVI,"01wb",data,length);   else      n = avi_add_chunk(AVI,"00db",data,length);   if (n) return -1;   return 0;}int AVI_write_frame(avi_t *AVI, char *data, long bytes){   long pos;   if(AVI->mode==AVI_MODE_READ) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }   pos = AVI->pos;   if( avi_write_data(AVI,data,bytes,0) ) return -1;   AVI->last_pos = pos;   AVI->last_len = bytes;   AVI->video_frames++;   return 0;}int AVI_dup_frame(avi_t *AVI){   if(AVI->mode==AVI_MODE_READ) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }   if(AVI->last_pos==0) return 0; /* No previous real frame */   if(avi_add_index_entry(AVI,"00db",0x10,AVI->last_pos,AVI->last_len)) return -1;   AVI->video_frames++;   AVI->must_use_index = 1;   return 0;}int AVI_write_audio(avi_t *AVI, char *data, long bytes){   if(AVI->mode==AVI_MODE_READ) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }   if( avi_write_data(AVI,data,bytes,1) ) return -1;   AVI->audio_bytes += bytes;   return 0;}long AVI_bytes_remain(avi_t *AVI){   if(AVI->mode==AVI_MODE_READ) return 0;   return ( AVI_MAX_LEN - (AVI->pos + 8 + 16*AVI->n_idx));}/******************************************************************* *                                                                 * *    Utilities for reading video and audio from an AVI File       * *                                                                 * *******************************************************************/int AVI_close(avi_t *AVI){   int ret;   /* If the file was open for writing, the header and index still have      to be written */   if(AVI->mode == AVI_MODE_WRITE)      ret = avi_close_output_file(AVI);   else      ret = 0;   /* Even if there happened a error, we first clean up */   close(AVI->fdes);   if(AVI->idx) free(AVI->idx);   if(AVI->video_index) free(AVI->video_index);   if(AVI->audio_index) free(AVI->audio_index);   free(AVI);   return ret;}#define ERR_EXIT(x) \{ \   AVI_close(AVI); \   AVI_errno = x; \   return 0; \}avi_t *AVI_open_input_file(char *filename, int getIndex){   avi_t *AVI;   long i, n, rate, scale, idx_type;   unsigned char *hdrl_data;   long hdrl_len;   long nvi, nai, ioff;   long tot;   int lasttag = 0;   int vids_strh_seen = 0;   int vids_strf_seen = 0;   int auds_strh_seen = 0;   int auds_strf_seen = 0;   int num_stream = 0;   char data[256];   /* Create avi_t structure */   AVI = (avi_t *) malloc(sizeof(avi_t));   if(AVI==NULL)   {      AVI_errno = AVI_ERR_NO_MEM;      return 0;   }   memset((void *)AVI,0,sizeof(avi_t));   AVI->mode = AVI_MODE_READ; /* open for reading */   /* Open the file */   AVI->fdes = open(filename,O_RDONLY);   if(AVI->fdes < 0)   {      AVI_errno = AVI_ERR_OPEN;      free(AVI);      return 0;   }   /* Read first 12 bytes and check that this is an AVI file */   if( read(AVI->fdes,data,12) != 12 ) ERR_EXIT(AVI_ERR_READ)   if( strncasecmp(data  ,"RIFF",4) !=0 ||       strncasecmp(data+8,"AVI ",4) !=0 ) ERR_EXIT(AVI_ERR_NO_AVI)   /* Go through the AVI file and extract the header list,      the start position of the 'movi' list and an optionally      present idx1 tag */   hdrl_data = 0;   while(1)   {      if( read(AVI->fdes,data,8) != 8 ) break; /* We assume it's EOF */      n = str2ulong(data+4);      n = PAD_EVEN(n);      if(strncasecmp(data,"LIST",4) == 0)      {         if( read(AVI->fdes,data,4) != 4 ) ERR_EXIT(AVI_ERR_READ)         n -= 4;         if(strncasecmp(data,"hdrl",4) == 0)         {            hdrl_len = n;            hdrl_data = (unsigned char *) malloc(n);            if(hdrl_data==0) ERR_EXIT(AVI_ERR_NO_MEM)            if( read(AVI->fdes,hdrl_data,n) != n ) ERR_EXIT(AVI_ERR_READ)         }         else if(strncasecmp(data,"movi",4) == 0)         {            AVI->movi_start = lseek(AVI->fdes,0,SEEK_CUR);            lseek(AVI->fdes,n,SEEK_CUR);         }         else            lseek(AVI->fdes,n,SEEK_CUR);      }      else if(strncasecmp(data,"idx1",4) == 0)      {         /* n must be a multiple of 16, but the reading does not            break if this is not the case */         AVI->n_idx = AVI->max_idx = n/16;         AVI->idx = (unsigned  char((*)[16]) ) malloc(n);         if(AVI->idx==0) ERR_EXIT(AVI_ERR_NO_MEM)         if( read(AVI->fdes,AVI->idx,n) != n ) ERR_EXIT(AVI_ERR_READ)      }      else         lseek(AVI->fdes,n,SEEK_CUR);   }   if(!hdrl_data      ) ERR_EXIT(AVI_ERR_NO_HDRL)   if(!AVI->movi_start) ERR_EXIT(AVI_ERR_NO_MOVI)   /* Interpret the header list */   for(i=0;i<hdrl_len;)   {      /* List tags are completly ignored */      if(strncasecmp(hdrl_data+i,"LIST",4)==0) { i+= 12; continue; }      n = str2ulong(hdrl_data+i+4);      n = PAD_EVEN(n);      /* Interpret the tag and its args */      if(strncasecmp(hdrl_data+i,"strh",4)==0)      {         i += 8;         if(strncasecmp(hdrl_data+i,"vids",4) == 0 && !vids_strh_seen)         {            memcpy(AVI->compressor,hdrl_data+i+4,4);            AVI->compressor[4] = 0;            scale = str2ulong(hdrl_data+i+20);            rate  = str2ulong(hdrl_data+i+24);            if(scale!=0) AVI->fps = (double)rate/(double)scale;            AVI->video_frames = str2ulong(hdrl_data+i+32);            AVI->video_strn = num_stream;            vids_strh_seen = 1;            lasttag = 1; /* vids */         }         else if (strncasecmp (hdrl_data+i,"auds",4) ==0 && ! auds_strh_seen)         {            AVI->audio_bytes = str2ulong(hdrl_data+i+32)*avi_sampsize(AVI);            AVI->audio_strn = num_stream;            auds_strh_seen = 1;            lasttag = 2; /* auds */         }         else            lasttag = 0;         num_stream++;      }      else if(strncasecmp(hdrl_data+i,"strf",4)==0)      {         i += 8;         if(lasttag == 1)         {            AVI->width  = str2ulong(hdrl_data+i+4);            AVI->height = str2ulong(hdrl_data+i+8);            vids_strf_seen = 1;         }         else if(lasttag == 2)         {            AVI->a_fmt   = str2ushort(hdrl_data+i  );            AVI->a_chans = str2ushort(hdrl_data+i+2);            AVI->a_rate  = str2ulong (hdrl_data+i+4);            AVI->a_bits  = str2ushort(hdrl_data+i+14);            auds_strf_seen = 1;         }         lasttag = 0;      }      else      {         i += 8;         lasttag = 0;      }      i += n;   }   free(hdrl_data);   if(!vids_strh_seen || !vids_strf_seen || AVI->video_frames==0) ERR_EXIT(AVI_ERR_NO_VIDS)   AVI->video_tag[0] = AVI->video_strn/10 + '0';   AVI->video_tag[1] = AVI->video_strn%10 + '0';   AVI->video_tag[2] = 'd';   AVI->video_tag[3] = 'b';   /* Audio tag is set to "99wb" if no audio present */   if(!AVI->a_chans) AVI->audio_strn = 99;   AVI->audio_tag[0] = AVI->audio_strn/10 + '0';   AVI->audio_tag[1] = AVI->audio_strn%10 + '0';   AVI->audio_tag[2] = 'w';   AVI->audio_tag[3] = 'b';   lseek(AVI->fdes,AVI->movi_start,SEEK_SET);   /* get index if wanted */   if(!getIndex) return AVI;   /* if the file has an idx1, check if this is relative      to the start of the file or to the start of the movi list */   idx_type = 0;   if(AVI->idx)   {      long pos, len;      /* Search the first videoframe in the idx1 and look where         it is in the file */      for(i=0;i<AVI->n_idx;i++)         if( strncasecmp(AVI->idx[i],AVI->video_tag,3)==0 ) break;      if(i>=AVI->n_idx) ERR_EXIT(AVI_ERR_NO_VIDS)      pos = str2ulong(AVI->idx[i]+ 8);      len = str2ulong(AVI->idx[i]+12);      lseek(AVI->fdes,pos,SEEK_SET);

⌨️ 快捷键说明

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