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

📄 avilib.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *  avilib.c * *  Copyright (C) Thomas 謘treich - June 2001 *  multiple audio track support Copyright (C) 2002 Thomas 謘treich  * *  Original code: *  Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>  * *  This file is part of transcode, a linux video stream processing tool *       *  transcode is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  transcode is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *    *  You should have received a copy of the GNU General Public License *  along with GNU Make; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include "avilib.h"//#include <time.h>#define INFO_LIST/* The following variable indicates the kind of error */long AVI_errno;#define MAX_INFO_STRLEN 64static char id_str[MAX_INFO_STRLEN];#define FRAME_RATE_SCALE 1000000#ifndef PACKAGE#define PACKAGE "my"#define VERSION "0.00"#endif#ifndef O_BINARY/* win32 wants a binary flag to open(); this sets it to null   on platforms that don't have it. */#define O_BINARY 0#endif/******************************************************************* *                                                                 * *    Utilities for writing an AVI File                            * *                                                                 * *******************************************************************/static size_t avi_read(int fd, char *buf, size_t len){   size_t n = 0;   size_t r = 0;   while (r < len) {      n = read (fd, buf + r, len - r);      if (n <= 0)	  return r;      r += n;   }   return r;}static size_t avi_write (int fd, char *buf, size_t len){   size_t n = 0;   size_t r = 0;   while (r < len) {      n = write (fd, buf + r, len - r);      if (n < 0)         return n;            r += n;   }   return r;}/* HEADERBYTES: The number of bytes to reserve for the header */#define HEADERBYTES 2048/* AVI_MAX_LEN: The maximum length of an AVI file, we stay a bit below    the 2GB limit (Remember: 2*10^9 is smaller than 2 GB) */#define AVI_MAX_LEN (UINT_MAX-(1<<20)*16-HEADERBYTES)#define PAD_EVEN(x) ( ((x)+1) & ~1 )/* Copy n into dst as a 4 byte, little endian number.   Should also work on big endian machines */static void long2str(unsigned char *dst, int n){   dst[0] = (n    )&0xff;   dst[1] = (n>> 8)&0xff;   dst[2] = (n>>16)&0xff;   dst[3] = (n>>24)&0xff;}/* Convert a string of 4 or 2 bytes to a number,   also working on big endian machines */static unsigned long str2ulong(unsigned char *str){   return ( str[0] | (str[1]<<8) | (str[2]<<16) | (str[3]<<24) );}static unsigned long str2ushort(unsigned char *str){   return ( str[0] | (str[1]<<8) );}/* Calculate audio sample size from number of bits and number of channels.   This may have to be adjusted for eg. 12 bits and stereo */static int avi_sampsize(avi_t *AVI, int j){   int s;   s = ((AVI->track[j].a_bits+7)/8)*AVI->track[j].a_chans;   //   if(s==0) s=1; /* avoid possible zero divisions */   if(s<4) s=4; /* avoid possible zero divisions */    return s;}/* Add a chunk (=tag and data) to the AVI file,   returns -1 on write error, 0 on success */static int avi_add_chunk(avi_t *AVI, unsigned char *tag, unsigned char *data, int length){   unsigned char c[8];   /* Copy tag and length int c, so that we need only 1 write system call      for these two values */   memcpy(c,tag,4);   long2str(c+4,length);   /* Output tag, length and data, restore previous position      if the write fails */   length = PAD_EVEN(length);   if( avi_write(AVI->fdes,(char *)c,8) != 8 ||       avi_write(AVI->fdes,(char *)data,length) != length )   {      lseek(AVI->fdes,AVI->pos,SEEK_SET);      AVI_errno = AVI_ERR_WRITE;      return -1;   }   /* Update file position */   AVI->pos += 8 + length;   //fprintf(stderr, "pos=%lu %s\n", AVI->pos, tag);   return 0;}static int avi_add_index_entry(avi_t *AVI, unsigned char *tag, long flags, unsigned long pos, unsigned long len){   void *ptr;   if(AVI->n_idx>=AVI->max_idx) {     ptr = realloc((void *)AVI->idx,(AVI->max_idx+4096)*16);          if(ptr == 0) {       AVI_errno = AVI_ERR_NO_MEM;       return -1;     }     AVI->max_idx += 4096;     AVI->idx = (unsigned char((*)[16]) ) ptr;   }      /* Add index entry */   //   fprintf(stderr, "INDEX %s %ld %lu %lu\n", tag, flags, pos, len);   memcpy(AVI->idx[AVI->n_idx],tag,4);   long2str(AVI->idx[AVI->n_idx]+ 4,flags);   long2str(AVI->idx[AVI->n_idx]+ 8, pos);   long2str(AVI->idx[AVI->n_idx]+12, len);      /* Update counter */   AVI->n_idx++;   if(len>AVI->max_len) AVI->max_len=len;   return 0;}/*   AVI_open_output_file: Open an AVI File and write a bunch                         of zero bytes as space for the header.   returns a pointer to avi_t on success, a zero pointer on error*/avi_t* AVI_open_output_file(char * filename){   avi_t *AVI;   int i;   int mask = 0;      unsigned char AVI_header[HEADERBYTES];   /* Allocate the avi_t struct and zero it */   AVI = (avi_t *) malloc(sizeof(avi_t));   if(AVI==0)   {      AVI_errno = AVI_ERR_NO_MEM;      return 0;   }   memset((void *)AVI,0,sizeof(avi_t));   /* Since Linux needs a long time when deleting big files,      we do not truncate the file when we open it.      Instead it is truncated when the AVI file is closed */  /* mask = umask (0);   umask (mask);*/   AVI->fdes = open(filename, O_RDWR|O_CREAT|O_BINARY, 0644 &~ mask);   if (AVI->fdes < 0)   {      AVI_errno = AVI_ERR_OPEN;      free(AVI);      return 0;   }   /* Write out HEADERBYTES bytes, the header will go here      when we are finished with writing */   for (i=0;i<HEADERBYTES;i++) AVI_header[i] = 0;   i = avi_write(AVI->fdes,(char *)AVI_header,HEADERBYTES);   if (i != HEADERBYTES)   {      close(AVI->fdes);      AVI_errno = AVI_ERR_WRITE;      free(AVI);      return 0;   }   AVI->pos  = HEADERBYTES;   AVI->mode = AVI_MODE_WRITE; /* open for writing */   //init   AVI->anum = 0;   AVI->aptr = 0;   return AVI;}void AVI_set_video(avi_t *AVI, int width, int height, double fps, char *compressor){   /* may only be called if file is open for writing */   if(AVI->mode==AVI_MODE_READ) return;   AVI->width  = width;   AVI->height = height;   AVI->fps    = fps;      if(strncmp(compressor, "RGB", 3)==0) {     memset(AVI->compressor, 0, 4);   } else {     memcpy(AVI->compressor,compressor,4);   }           AVI->compressor[4] = 0;   avi_update_header(AVI);}void AVI_set_audio(avi_t *AVI, int channels, long rate, int bits, int format, long mp3rate){   /* may only be called if file is open for writing */   if(AVI->mode==AVI_MODE_READ) return;   //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);     exit(1);   }   AVI->track[AVI->aptr].a_chans = channels;   AVI->track[AVI->aptr].a_rate  = rate;   AVI->track[AVI->aptr].a_bits  = bits;   AVI->track[AVI->aptr].a_fmt   = format;   AVI->track[AVI->aptr].mp3rate = mp3rate;   avi_update_header(AVI);}#define OUT4CC(s) \   if(nhb<=HEADERBYTES-4) memcpy(AVI_header+nhb,s,4); nhb += 4#define OUTLONG(n) \   if(nhb<=HEADERBYTES-4) long2str(AVI_header+nhb,n); nhb += 4#define OUTSHRT(n) \   if(nhb<=HEADERBYTES-2) { \      AVI_header[nhb  ] = (n   )&0xff; \      AVI_header[nhb+1] = (n>>8)&0xff; \   } \   nhb += 2//ThOe write preliminary AVI file header: 0 frames, max vid/aud sizeint avi_update_header(avi_t *AVI){   int njunk, sampsize, hasIndex, ms_per_frame, frate, flag;   int movi_len, hdrl_start, strl_start, j;   unsigned char AVI_header[HEADERBYTES];   long nhb;   //assume max size   movi_len = AVI_MAX_LEN - HEADERBYTES + 4;   //assume index will be written   hasIndex=1;   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(movi_len);    // assume max size   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(0);                  // no frames yet   OUTLONG(0);                  /* InitialFrames */   OUTLONG(AVI->anum+1);   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(0);                  // no frames yet   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) {              sampsize = avi_sampsize(AVI, j);          OUT4CC ("LIST");

⌨️ 快捷键说明

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