📄 avilib.c
字号:
if(read(AVI->fdes,data,8)!=8) ERR_EXIT(AVI_ERR_READ) if( strncasecmp(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( strncasecmp(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(strncasecmp(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(strncasecmp(AVI->idx[i],AVI->video_tag,3) == 0) nvi++; if(strncasecmp(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(strncasecmp(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(strncasecmp(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_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; return 0;}int AVI_set_video_position(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 = 0; AVI->video_pos = frame; 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;}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 */ 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 */ if( read(AVI->fdes,data,8) != 8 ) return 0; /* if we got a list tag, ignore it */ if(strncasecmp(data,"LIST",4) == 0) { lseek(AVI->fdes,4,SEEK_CUR); continue; } n = PAD_EVEN(str2ulong(data+4)); if(strncasecmp(data,AVI->video_tag,3) == 0) { *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(strncasecmp(data,AVI->audio_tag,4) == 0) { *len = n; if(n>max_audbuf) { lseek(AVI->fdes,n,SEEK_CUR); return -2; } if(read(AVI->fdes,audbuf,n) != n ) return 0; return 2; break; } else if(lseek(AVI->fdes,n,SEEK_CUR)<0) return 0; }}/* AVI_print_error: Print most recent error (similar to perror) */char *(avi_errors[]) ={ /* 0 */ "avilib - No Error", /* 1 */ "avilib - AVI file size limit reached", /* 2 */ "avilib - Error opening AVI file", /* 3 */ "avilib - Error reading from AVI file", /* 4 */ "avilib - Error writing to AVI file", /* 5 */ "avilib - Error writing index (file may still be useable)", /* 6 */ "avilib - Error closing AVI file", /* 7 */ "avilib - Operation (read/write) not permitted", /* 8 */ "avilib - Out of memory (malloc failed)", /* 9 */ "avilib - Not an AVI file", /* 10 */ "avilib - AVI file has no header list (corrupted?)", /* 11 */ "avilib - AVI file has no MOVI list (corrupted?)", /* 12 */ "avilib - AVI file has no video data", /* 13 */ "avilib - operation needs an index", /* 14 */ "avilib - Unkown Error"};static int num_avi_errors = sizeof(avi_errors)/sizeof(char*);static char error_string[4096];void AVI_print_error(char *str){ int aerrno; aerrno = (AVI_errno>=0 && AVI_errno<num_avi_errors) ? AVI_errno : num_avi_errors-1; fprintf(stderr,"%s: %s\n",str,avi_errors[aerrno]); /* for the following errors, perror should report a more detailed reason: */ if(AVI_errno == AVI_ERR_OPEN || AVI_errno == AVI_ERR_READ || AVI_errno == AVI_ERR_WRITE || AVI_errno == AVI_ERR_WRITE_INDEX || AVI_errno == AVI_ERR_CLOSE ) { perror("REASON"); }}char *AVI_strerror(){ int aerrno; aerrno = (AVI_errno>=0 && AVI_errno<num_avi_errors) ? AVI_errno : num_avi_errors-1; if(AVI_errno == AVI_ERR_OPEN || AVI_errno == AVI_ERR_READ || AVI_errno == AVI_ERR_WRITE || AVI_errno == AVI_ERR_WRITE_INDEX || AVI_errno == AVI_ERR_CLOSE ) { sprintf(error_string,"%s - %s",avi_errors[aerrno],strerror(errno)); return error_string; } else { return avi_errors[aerrno]; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -