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

📄 avilib.c

📁 这是将avs视频的ES流转换成avi文件格式的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   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(const char *filename, int getIndex){   avi_t *AVI;   long i, n, rate, scale, idx_type;   unsigned char *hdrl_data;   long hdrl_len = 0;   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|_O_BINARY );   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( strncmp(data  ,"RIFF",4) !=0 ||       strncmp(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(strncmp(data,"LIST",4) == 0)      {         if( _read(AVI->fdes,data,4) != 4 )             ERR_EXIT(AVI_ERR_READ)         n -= 4;         if(strncmp(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(strncmp(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(strncmp(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 )          {            _lseek(AVI->fdes,0,SEEK_CUR);             ERR_EXIT(AVI_ERR_READ)             break;         }      }      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(strncmp(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(strncmp(hdrl_data+i,"strh",4)==0)      {         i += 8;         if(strncmp(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 (strncmp (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(strncmp(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)    {       //_lseek(AVI->fdes,0,SEEK_SET);       //AVI->video_pos = 0;       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;		unsigned long 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( strncmp(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);      if(_read(AVI->fdes,data,8)!=8) ERR_EXIT(AVI_ERR_READ)      if( strncmp(data,AVI->idx[i],4)==0 && str2ulong(data+4)==len )      {         idx_type = 1; /* Index from start of file */      }      else      {         _lseek(AVI->fdes,pos+AVI->movi_start-4,SEEK_SET);         if(_read(AVI->fdes,data,8)!=8) ERR_EXIT(AVI_ERR_READ)         if( strncmp(data,AVI->idx[i],4)==0 && str2ulong(data+4)==len )         {            idx_type = 2; /* Index from start of movi list */         }      }      /* idx_type remains 0 if neither of the two tests above succeeds */   }   if(idx_type == 0)   {      /* we must search through the file to get the index */      _lseek(AVI->fdes, AVI->movi_start, SEEK_SET);      AVI->n_idx = 0;      while(1)      {         if( _read(AVI->fdes,data,8) != 8 ) break;         n = str2ulong(data+4);         /* The movi list may contain sub-lists, ignore them */         if(strncmp(data,"LIST",4)==0)         {            _lseek(AVI->fdes,4,SEEK_CUR);            continue;         }         /* Check if we got a tag ##db, ##dc or ##wb */         if( ( (data[2]=='d' || data[2]=='D') &&               (data[3]=='b' || data[3]=='B' || data[3]=='c' || data[3]=='C') )          || ( (data[2]=='w' || data[2]=='W') &&               (data[3]=='b' || data[3]=='B') ) )         {            avi_add_index_entry(AVI,data,0,_lseek(AVI->fdes,0,SEEK_CUR)-8,n);         }         _lseek(AVI->fdes,PAD_EVEN(n),SEEK_CUR);      }      idx_type = 1;   }   /* Now generate the video index and audio index arrays */   nvi = 0;   nai = 0;   for(i=0;i<AVI->n_idx;i++)   {      if(strncmp(AVI->idx[i],AVI->video_tag,3) == 0) nvi++;      if(strncmp(AVI->idx[i],AVI->audio_tag,4) == 0) nai++;   }   AVI->video_frames = nvi;   AVI->audio_chunks = nai;   if(AVI->video_frames==0) ERR_EXIT(AVI_ERR_NO_VIDS)   AVI->video_index = (video_index_entry *) malloc(nvi*sizeof(video_index_entry));   if(AVI->video_index==0) ERR_EXIT(AVI_ERR_NO_MEM)   if(AVI->audio_chunks)   {      AVI->audio_index = (audio_index_entry *) malloc(nai*sizeof(audio_index_entry));      if(AVI->audio_index==0) ERR_EXIT(AVI_ERR_NO_MEM)   }   nvi = 0;   nai = 0;   tot = 0;   ioff = idx_type == 1 ? 8 : AVI->movi_start+4;   for(i=0;i<AVI->n_idx;i++)   {      if(strncmp(AVI->idx[i],AVI->video_tag,3) == 0)      {         AVI->video_index[nvi].pos = str2ulong(AVI->idx[i]+ 8)+ioff;         AVI->video_index[nvi].len = str2ulong(AVI->idx[i]+12);         nvi++;      }      if(strncmp(AVI->idx[i],AVI->audio_tag,4) == 0)      {         AVI->audio_index[nai].pos = str2ulong(AVI->idx[i]+ 8)+ioff;         AVI->audio_index[nai].len = str2ulong(AVI->idx[i]+12);         AVI->audio_index[nai].tot = tot;         tot += AVI->audio_index[nai].len;         nai++;      }   }   AVI->audio_bytes = tot;   /* Reposition the file */   _lseek(AVI->fdes,AVI->movi_start,SEEK_SET);   AVI->video_pos = 0;   return AVI;}long AVI_video_frames(avi_t *AVI){   return AVI->video_frames;}int  AVI_video_width(avi_t *AVI){   return AVI->width;}int  AVI_video_height(avi_t *AVI){   return AVI->height;}double AVI_video_frame_rate(avi_t *AVI){   return AVI->fps;}char* AVI_video_compressor(avi_t *AVI){   return AVI->compressor;}int AVI_audio_channels(avi_t *AVI){   return AVI->a_chans;}int AVI_audio_bits(avi_t *AVI){   return AVI->a_bits;}int AVI_audio_format(avi_t *AVI){   return AVI->a_fmt;}long AVI_audio_rate(avi_t *AVI){   return AVI->a_rate;}long AVI_audio_bytes(avi_t *AVI){   return AVI->audio_bytes;}long AVI_frame_size(avi_t *AVI, long frame){   if(AVI->mode==AVI_MODE_WRITE) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }   if(!AVI->video_index)         { AVI_errno = AVI_ERR_NO_IDX;   return -1; }   if(frame < 0 || frame >= AVI->video_frames) return 0;   return(AVI->video_index[frame].len);}int AVI_seek_start(avi_t *AVI){   if(AVI->mode==AVI_MODE_WRITE) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }   _lseek(AVI->fdes,AVI->movi_start,SEEK_SET);   AVI->video_pos = 0;   AVI->audio_posc = 0;   AVI->audio_posb = 0;   return 0;}int AVI_set_video_position(avi_t *AVI, long frame, long *frame_len){   if(AVI->mode==AVI_MODE_WRITE) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }   if(!AVI->video_index)         { AVI_errno = AVI_ERR_NO_IDX;   return -1; }   if (frame < 0 ) frame = 0;   AVI->video_pos = frame;   if (frame_len != NULL)     *frame_len = AVI->video_index[frame].len;   return 0;}      long AVI_read_frame(avi_t *AVI, char *vidbuf){   long n;   if(AVI->mode==AVI_MODE_WRITE) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }   if(!AVI->video_index)         { AVI_errno = AVI_ERR_NO_IDX;   return -1; }   if(AVI->video_pos < 0 || AVI->video_pos >= AVI->video_frames) return 0;   n = AVI->video_index[AVI->video_pos].len;   _lseek(AVI->fdes, AVI->video_index[AVI->video_pos].pos, SEEK_SET);   if (_read(AVI->fdes,vidbuf,n) != n)   {      AVI_errno = AVI_ERR_READ;      return -1;   }   AVI->video_pos++;   return n;}int AVI_set_audio_position(avi_t *AVI, long byte){   long n0, n1, n;   if(AVI->mode==AVI_MODE_WRITE) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }   if(!AVI->audio_index)         { AVI_errno = AVI_ERR_NO_IDX;   return -1; }   if(byte < 0) byte = 0;   /* Binary search in the audio chunks */   n0 = 0;   n1 = AVI->audio_chunks;   while(n0<n1-1)   {      n = (n0+n1)/2;      if(AVI->audio_index[n].tot>byte)         n1 = n;      else         n0 = n;   }   AVI->audio_posc = n0;   AVI->audio_posb = byte - AVI->audio_index[n0].tot;   return 0;}int AVI_set_audio_frame (avi_t *AVI, long frame, long *frame_len){  if (AVI->audio_posc >= AVI->audio_chunks - 1) { return -1; }  AVI->audio_posc = frame;  AVI->audio_posb = 0;  if (frame_len != NULL)    *frame_len = AVI->audio_index[frame].len;  return 0;}long AVI_read_audio(avi_t *AVI, char *audbuf, long bytes){   long nr, pos, left, todo;   if(AVI->mode==AVI_MODE_WRITE) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }   if(!AVI->audio_index)         { AVI_errno = AVI_ERR_NO_IDX;   return -1; }   nr = 0; /* total number of bytes _read */

   if(AVI->audio_posc>=AVI->audio_chunks-1) return nr;
   nr = _read(AVI->fdes,audbuf,AVI->audio_index[AVI->audio_posc].len);

   AVI->audio_posc ++;

   return nr;
   /*   while(bytes>0)   {      left = AVI->audio_index[AVI->audio_posc].len - AVI->audio_posb;      if(left==0)      {         if(AVI->audio_posc>=AVI->audio_chunks-1) return nr;         AVI->audio_posc++;         AVI->audio_posb = 0;         continue;      }      if(bytes<left)         todo = bytes;      else         todo = left;      pos = AVI->audio_index[AVI->audio_posc].pos + AVI->audio_posb;      _lseek(AVI->fdes, pos, SEEK_SET);      if (_read(AVI->fdes,audbuf+nr,todo) != todo)      {         AVI_errno = AVI_ERR_READ;         return -1;      }      bytes -= todo;      nr    += todo;      AVI->audio_posb += todo;   }
   */
      return nr;}/* AVI_read_data: Special routine for reading the next audio or video chunk                  without having an index of the file. */int AVI_read_data(avi_t *AVI, char *vidbuf, long max_vidbuf,                              char *audbuf, long max_audbuf,                              long *len){/* * Return codes: * *    1 = video data _read *    2 = audio data _read *    0 = reached EOF *   -1 = video buffer too small *   -2 = audio buffer too small */   int n;   char data[8];   if(AVI->mode==AVI_MODE_WRITE) return 0;   while(1)   {      /* Read tag and length */

	   //_lseek(AVI->fdes,-3,SEEK_CUR);      if( _read(AVI->fdes,data,4) != 4 ) return 0;      /* if we got a list tag, ignore it *//*      if(strncmp(data,"LIST",4) == 0)      {         _lseek(AVI->fdes,4,SEEK_CUR);         continue;      }*/            if(strncmp(data,AVI->video_tag,3) == 0)      {          if( _read(AVI->fdes,data,4) != 4 ) return 0;          n = PAD_EVEN(str2ulong(data));         *len = n;         AVI->video_pos++;         if(n>max_vidbuf)         {            _lseek(AVI->fdes,n,SEEK_CUR);            return -1;         }         if(_read(AVI->fdes,vidbuf,n) != n ) return 0;         return 1;      }      else if(strncmp(data,AVI->audio_tag,4) == 0)      {         if( _read(AVI->fdes,data,4) != 4 ) return 0;          n = PAD_EVEN(str2ulong(data));          *len = n;         if(n>max_audbuf)         {            _lseek(AVI->fdes,n,SEEK_CUR);            return -2;         }         _lseek(AVI->fdes,0,SEEK_CUR);         if(read(AVI->fdes,audbuf,n) != n )              return 0;         return 2;         break;      }      else         if(_lseek(AVI->fdes,-3,SEEK_CUR)<0)  return 0;   }

⌨️ 快捷键说明

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