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

📄 avilib.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 4 页
字号:
   return 0;}int AVI_write_frame(avi_t *AVI, char *data, long bytes, int keyframe){  unsigned 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,keyframe)) 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,(unsigned char *)"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,0) ) return -1;   AVI->track[AVI->aptr].audio_bytes += bytes;   return 0;}int AVI_append_audio(avi_t *AVI, char *data, long bytes){  long i, length, pos;  unsigned char c[4];  if(AVI->mode==AVI_MODE_READ) { AVI_errno = AVI_ERR_NOT_PERM; return -1; }    // update last index entry:    --AVI->n_idx;  length = str2ulong(AVI->idx[AVI->n_idx]+12);  pos    = str2ulong(AVI->idx[AVI->n_idx]+8);  //update;  long2str(AVI->idx[AVI->n_idx]+12,length+bytes);     ++AVI->n_idx;  AVI->track[AVI->aptr].audio_bytes += bytes;  //update chunk header  lseek(AVI->fdes, pos+4, SEEK_SET);  long2str(c, length+bytes);       avi_write(AVI->fdes,(char *) c, 4);  lseek(AVI->fdes, pos+8+length, SEEK_SET);  i=PAD_EVEN(length + bytes);  bytes = i - length;  avi_write(AVI->fdes, data, bytes);  AVI->pos = pos + 8 + i;  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));}long AVI_bytes_written(avi_t *AVI){   if(AVI->mode==AVI_MODE_READ) return 0;   return (AVI->pos + 8 + 16*AVI->n_idx);}int AVI_set_audio_track(avi_t *AVI, int track){    if(track < 0 || track + 1 > AVI->anum) return(-1);  //this info is not written to file anyway  AVI->aptr=track;  return 0;}int AVI_get_audio_track(avi_t *AVI){    return(AVI->aptr);}/******************************************************************* *                                                                 * *    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 an error, we first clean up */   close(AVI->fdes);   if(AVI->idx) free(AVI->idx);   if(AVI->video_index) free(AVI->video_index);   //FIXME   //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=NULL;    /* 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;    }    avi_parse_input_file(AVI, getIndex);  AVI->aptr=0; //reset    return AVI;}avi_t *AVI_open_fd(int fd, int getIndex){  avi_t *AVI=NULL;    /* 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 */    // file alread open  AVI->fdes = fd;    avi_parse_input_file(AVI, getIndex);  AVI->aptr=0; //reset    return AVI;}int avi_parse_input_file(avi_t *AVI, int getIndex){  long i, n, rate, scale, idx_type;  unsigned char *hdrl_data;  long header_offset=0, hdrl_len=0;  long nvi, nai[AVI_MAX_TRACKS], ioff;  long tot[AVI_MAX_TRACKS];  int j;  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];    /* Read first 12 bytes and check that this is an AVI file */   if( avi_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( avi_read(AVI->fdes,data,8) != 8 ) break; /* We assume it's EOF */      n = str2ulong((unsigned char *) data+4);      n = PAD_EVEN(n);      if(strncasecmp(data,"LIST",4) == 0)      {         if( avi_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);				 	    // offset of header	    	    header_offset = lseek(AVI->fdes,0,SEEK_CUR);				             if( avi_read(AVI->fdes,(char *)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(avi_read(AVI->fdes, (char *) 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((char *) 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((char *)hdrl_data+i,"strh",4)==0)      {         i += 8;         if(strncasecmp((char *)hdrl_data+i,"vids",4) == 0 && !vids_strh_seen)         {            memcpy(AVI->compressor,hdrl_data+i+4,4);            AVI->compressor[4] = 0;	    // ThOe	    AVI->v_codech_off = header_offset + i+4;            scale = str2ulong((unsigned char *)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;	    AVI->max_len = 0;            vids_strh_seen = 1;            lasttag = 1; /* vids */         }         else if (strncasecmp ((char *) hdrl_data+i,"auds",4) ==0 && ! auds_strh_seen)         {	   //inc audio tracks	   AVI->aptr=AVI->anum;	   ++AVI->anum;	   	   if(AVI->anum > AVI_MAX_TRACKS) {	     fprintf(stderr, "error - only %d audio tracks supported\n", AVI_MAX_TRACKS);	     return(-1);	   }	   	   AVI->track[AVI->aptr].audio_bytes = str2ulong(hdrl_data+i+32)*avi_sampsize(AVI, 0);	   AVI->track[AVI->aptr].audio_strn = num_stream;	   //	   auds_strh_seen = 1;	   lasttag = 2; /* auds */	   	   // ThOe	   AVI->track[AVI->aptr].a_codech_off = header_offset + i;	            }         else            lasttag = 0;         num_stream++;      }      else if(strncasecmp((char *) 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;	    //ThOe	    AVI->v_codecf_off = header_offset + i+16;	    memcpy(AVI->compressor2, hdrl_data+i+16, 4);            AVI->compressor2[4] = 0;         }         else if(lasttag == 2)         {            AVI->track[AVI->aptr].a_fmt   = str2ushort(hdrl_data+i  );	    //ThOe	    AVI->track[AVI->aptr].a_codecf_off = header_offset + i;	                AVI->track[AVI->aptr].a_chans = str2ushort(hdrl_data+i+2);            AVI->track[AVI->aptr].a_rate  = str2ulong (hdrl_data+i+4);	    //ThOe: read mp3bitrate	    AVI->track[AVI->aptr].mp3rate = 8*str2ulong(hdrl_data+i+8)/1000;	    //:ThOe            AVI->track[AVI->aptr].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) 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->track[0].a_chans) AVI->track[0].audio_strn = 99;   for(j=0; j<AVI->anum; ++j) {     AVI->track[j].audio_tag[0] = (j+1)/10 + '0';     AVI->track[j].audio_tag[1] = (j+1)%10 + '0';     AVI->track[j].audio_tag[2] = 'w';     AVI->track[j].audio_tag[3] = 'b';   }   lseek(AVI->fdes,AVI->movi_start,SEEK_SET);   /* get index if wanted */   if(!getIndex) return(0);   /* 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((char *) AVI->idx[i],(char *) 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(avi_read(AVI->fdes,data,8)!=8) ERR_EXIT(AVI_ERR_READ)      if( strncasecmp((char *)data,(char *)AVI->idx[i],4)==0 &&       str2ulong((unsigned char *)data+4)==len )      {         idx_type = 1; /* Index from start of file */      }      else      {         lseek(AVI->fdes,pos+AVI->movi_start-4,SEEK_SET);         if(avi_read(AVI->fdes,data,8)!=8) ERR_EXIT(AVI_ERR_READ)         if( strncasecmp((char *)data,(char *)AVI->idx[i],4)==0 && str2ulong((unsigned char *)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( avi_read(AVI->fdes,data,8) != 8 ) break;         n = str2ulong((unsigned char *)data+4);         /* The movi list may contain sub-lists, ignore them */         if(strncasecmp(data,"LIST",4)==0)

⌨️ 快捷键说明

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