📄 avilib.c
字号:
OUTLONG(0); /* Length of list in bytes, don't know yet */ strl_start = nhb; /* Store start position */ OUT4CC ("strl"); /* The audio stream header */ OUT4CC ("strh"); OUTLONG(56); /* # of bytes to follow */ OUT4CC ("auds"); // ----------- // ThOe OUTLONG(0); /* Format (Optionally) */ // ----------- OUTLONG(0); /* Flags */ OUTLONG(0); /* Reserved, MS says: wPriority, wLanguage */ OUTLONG(0); /* InitialFrames */ // ThOe /4 OUTLONG(sampsize/4); /* Scale */ OUTLONG(1000*AVI->track[j].mp3rate/8); OUTLONG(0); /* Start */ OUTLONG(4*AVI->track[j].audio_bytes/sampsize); /* Length */ OUTLONG(0); /* SuggestedBufferSize */ OUTLONG(-1); /* Quality */ // ThOe /4 OUTLONG(sampsize/4); /* 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->track[j].a_fmt); /* Format */ OUTSHRT(AVI->track[j].a_chans); /* Number of channels */ OUTLONG(AVI->track[j].a_rate); /* SamplesPerSec */ // ThOe OUTLONG(1000*AVI->track[j].mp3rate/8); //ThOe (/4) OUTSHRT(sampsize/4); /* BlockAlign */ OUTSHRT(AVI->track[j].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); //11/14/01 added id string if(njunk > strlen(id_str)+8) { sprintf(id_str, "%s-%s", PACKAGE, VERSION); memcpy(AVI_header+nhb, id_str, strlen(id_str)); } 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 || avi_write(AVI->fdes,(char *)AVI_header,HEADERBYTES)!=HEADERBYTES || lseek(AVI->fdes,AVI->pos,SEEK_SET)<0) { AVI_errno = AVI_ERR_CLOSE; return -1; } return 0;}/* Write the header of an AVI file and close it. returns 0 on success, -1 on write error.*/static int avi_close_output_file(avi_t *AVI){ int ret, njunk, sampsize, hasIndex, ms_per_frame, frate, idxerror, flag; unsigned long movi_len; int hdrl_start, strl_start, j; unsigned char AVI_header[HEADERBYTES]; long nhb;#ifdef INFO_LIST long info_len;// time_t calptr;#endif /* Calculate length of movi list */ movi_len = AVI->pos - HEADERBYTES + 4; /* Try to ouput the index entries. This may fail e.g. if no space is left on device. We will report this as an error, but we still try to write the header correctly (so that the file still may be readable in the most cases */ idxerror = 0; // fprintf(stderr, "pos=%lu, index_len=%ld \n", AVI->pos, AVI->n_idx*16); ret = avi_add_chunk(AVI, (unsigned char *)"idx1", (void*)AVI->idx, AVI->n_idx*16); hasIndex = (ret==0); //fprintf(stderr, "pos=%lu, index_len=%d\n", AVI->pos, hasIndex); if(ret) { idxerror = 1; AVI_errno = AVI_ERR_WRITE_INDEX; } /* Calculate Microseconds per frame */ if(AVI->fps < 0.001) { frate=0; ms_per_frame=0; } else { frate = (int) (FRAME_RATE_SCALE*AVI->fps + 0.5); ms_per_frame=(int) (1000000/AVI->fps + 0.5); } /* Prepare the file header */ nhb = 0; /* The RIFF header */ OUT4CC ("RIFF"); OUTLONG(AVI->pos - 8); /* # of bytes to follow */ OUT4CC ("AVI "); /* Start the header list */ OUT4CC ("LIST"); OUTLONG(0); /* Length of list in bytes, don't know yet */ hdrl_start = nhb; /* Store start position */ OUT4CC ("hdrl"); /* The main AVI header */ /* The Flags in AVI File header */#define AVIF_HASINDEX 0x00000010 /* Index at end of file */#define AVIF_MUSTUSEINDEX 0x00000020#define AVIF_ISINTERLEAVED 0x00000100#define AVIF_TRUSTCKTYPE 0x00000800 /* Use CKType to find key frames */#define AVIF_WASCAPTUREFILE 0x00010000#define AVIF_COPYRIGHTED 0x00020000 OUT4CC ("avih"); OUTLONG(56); /* # of bytes to follow */ OUTLONG(ms_per_frame); /* Microseconds per frame */ //ThOe ->0 // OUTLONG(10000000); /* MaxBytesPerSec, I hope this will never be used */ OUTLONG(0); OUTLONG(0); /* PaddingGranularity (whatever that might be) */ /* Other sources call it 'reserved' */ flag = AVIF_ISINTERLEAVED; if(hasIndex) flag |= AVIF_HASINDEX; if(hasIndex && AVI->must_use_index) flag |= AVIF_MUSTUSEINDEX; OUTLONG(flag); /* Flags */ OUTLONG(AVI->video_frames); /* TotalFrames */ OUTLONG(0); /* InitialFrames */ OUTLONG(AVI->anum+1);// if (AVI->track[0].audio_bytes)// { OUTLONG(2); } /* Streams */// else// { OUTLONG(1); } /* Streams */ OUTLONG(0); /* SuggestedBufferSize */ OUTLONG(AVI->width); /* Width */ OUTLONG(AVI->height); /* Height */ /* MS calls the following 'reserved': */ OUTLONG(0); /* TimeScale: Unit used to measure time */ OUTLONG(0); /* DataRate: Data rate of playback */ OUTLONG(0); /* StartTime: Starting time of AVI data */ OUTLONG(0); /* DataLength: Size of AVI data chunk */ /* Start the video stream list ---------------------------------- */ OUT4CC ("LIST"); OUTLONG(0); /* Length of list in bytes, don't know yet */ strl_start = nhb; /* Store start position */ OUT4CC ("strl"); /* The video stream header */ OUT4CC ("strh"); OUTLONG(56); /* # of bytes to follow */ OUT4CC ("vids"); /* Type */ OUT4CC (AVI->compressor); /* Handler */ OUTLONG(0); /* Flags */ OUTLONG(0); /* Reserved, MS says: wPriority, wLanguage */ OUTLONG(0); /* InitialFrames */ OUTLONG(FRAME_RATE_SCALE); /* Scale */ OUTLONG(frate); /* Rate: Rate/Scale == samples/second */ OUTLONG(0); /* Start */ OUTLONG(AVI->video_frames); /* Length */ OUTLONG(0); /* SuggestedBufferSize */ OUTLONG(-1); /* Quality */ OUTLONG(0); /* SampleSize */ OUTLONG(0); /* Frame */ OUTLONG(0); /* Frame */ // OUTLONG(0); /* Frame */ //OUTLONG(0); /* Frame */ /* The video stream format */ OUT4CC ("strf"); OUTLONG(40); /* # of bytes to follow */ OUTLONG(40); /* Size */ OUTLONG(AVI->width); /* Width */ OUTLONG(AVI->height); /* Height */ OUTSHRT(1); OUTSHRT(24); /* Planes, Count */ OUT4CC (AVI->compressor); /* Compression */ // ThOe (*3) OUTLONG(AVI->width*AVI->height*3); /* SizeImage (in bytes?) */ OUTLONG(0); /* XPelsPerMeter */ OUTLONG(0); /* YPelsPerMeter */ OUTLONG(0); /* ClrUsed: Number of colors used */ OUTLONG(0); /* ClrImportant: Number of colors important */ /* Finish stream list, i.e. put number of bytes in the list to proper pos */ long2str(AVI_header+strl_start-4,nhb-strl_start); /* Start the audio stream list ---------------------------------- */ for(j=0; j<AVI->anum; ++j) { //if (AVI->track[j].a_chans && AVI->track[j].audio_bytes) { sampsize = avi_sampsize(AVI, j); OUT4CC ("LIST"); OUTLONG(0); /* Length of list in bytes, don't know yet */ strl_start = nhb; /* Store start position */ OUT4CC ("strl"); /* The audio stream header */ OUT4CC ("strh"); OUTLONG(56); /* # of bytes to follow */ OUT4CC ("auds"); // ----------- // ThOe OUTLONG(0); /* Format (Optionally) */ // ----------- OUTLONG(0); /* Flags */ OUTLONG(0); /* Reserved, MS says: wPriority, wLanguage */ OUTLONG(0); /* InitialFrames */ // ThOe /4 OUTLONG(sampsize/4); /* Scale */ OUTLONG(1000*AVI->track[j].mp3rate/8); OUTLONG(0); /* Start */ OUTLONG(4*AVI->track[j].audio_bytes/sampsize); /* Length */ OUTLONG(0); /* SuggestedBufferSize */ OUTLONG(-1); /* Quality */ // ThOe /4 OUTLONG(sampsize/4); /* 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->track[j].a_fmt); /* Format */ OUTSHRT(AVI->track[j].a_chans); /* Number of channels */ OUTLONG(AVI->track[j].a_rate); /* SamplesPerSec */ // ThOe OUTLONG(1000*AVI->track[j].mp3rate/8); //ThOe (/4) OUTSHRT(sampsize/4); /* BlockAlign */ OUTSHRT(AVI->track[j].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); // add INFO list --- (0.6.0pre4)#ifdef INFO_LIST OUT4CC ("LIST"); //FIXME info_len = MAX_INFO_STRLEN + 12; OUTLONG(info_len); OUT4CC ("INFO");// OUT4CC ("INAM");// OUTLONG(MAX_INFO_STRLEN);// sprintf(id_str, "\t");// memset(AVI_header+nhb, 0, MAX_INFO_STRLEN);// memcpy(AVI_header+nhb, id_str, strlen(id_str));// nhb += MAX_INFO_STRLEN; OUT4CC ("ISFT"); OUTLONG(MAX_INFO_STRLEN); sprintf(id_str, "%s-%s", PACKAGE, VERSION); memset(AVI_header+nhb, 0, MAX_INFO_STRLEN); memcpy(AVI_header+nhb, id_str, strlen(id_str)); nhb += MAX_INFO_STRLEN;// OUT4CC ("ICMT");// OUTLONG(MAX_INFO_STRLEN);// calptr=time(NULL); // sprintf(id_str, "\t%s %s", ctime(&calptr), "");// memset(AVI_header+nhb, 0, MAX_INFO_STRLEN);// memcpy(AVI_header+nhb, id_str, 25);// nhb += MAX_INFO_STRLEN;#endif // ---------------------------- /* 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 || avi_write(AVI->fdes,(char *)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, unsigned long length, int audio, int keyframe){ int n; unsigned char astr[5]; /* 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 */ //set tag for current audio track sprintf((char *)astr, "0%1dwb", AVI->aptr+1); if(audio) n = avi_add_index_entry(AVI,astr,0x00,AVI->pos,length); else n = avi_add_index_entry(AVI,(unsigned char *) "00db",((keyframe)?0x10:0x0),AVI->pos,length); if(n) return -1; /* Output tag and data */ if(audio) n = avi_add_chunk(AVI,(unsigned char *) astr, (unsigned char *)data,length); else n = avi_add_chunk(AVI,(unsigned char *)"00db",(unsigned char *)data,length); if (n) return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -