全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3023
推到 Plurk!
推到 Facebook!

AVI example code for creating AVI files

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-01-08 17:26:57 IP:61.218.xxx.xxx 未訂閱
AVI example code for creating AVI files    資料來源: http://www.wischik.com/lu/programmer/avi_utils.html    AVI example code for creating AVI files(c) 2002 Lucian Wischik. This code is free, and anyone can do with it whatever they like (except sell it or claim ownership).    This code is concerned with creating AVI files, including video and audio. The video can be compressed using whichever filters are installed on your computer - you can make it pop up a system dialog box asking the user which filter to use, or you can remember this information to avoid the dialog box in future, or you can assume no compression and avoid the dialog box totally. As for compressing the audio, I believe that this is impossible using the AVI functions. Instead, you'll have to create an AVI with uncompressed audio, and then compress it using some external utility like Windows Movie Maker.    The code consists of seven functions, written in (classless) C++ and using Video for Windows (which is built into all versions of windows). I use this code as a unit (avi_utils.cpp, avi_utils.h) added to my own project. This web page contains examples of how to use the functions to create AVI files, the header file and the source code. You should copy the code and paste it into your own project. The code is plain Win32, and compiles cleanly under Borland C++Builder5 and Visual Studio .NET, and should work on other compilers without problems.    Borland compilers normally allow FPU exceptions. This can cause a problem, because some filters (e.g. DivX) raise FPU exceptions. Therefore, Borland users should use this code at some point before creating the AVI -- I do it at the start of WinMain. (This is not necessary for Visual C , since that disables the exceptions by default).
#include 
_control87(MCW_EM, MCW_EM); // reprogram the FPU so it doesn't raise exceptions    Examples of how to create AVIsTo create an AVI from a bunch of files. The following code creates an AVI out of five bitmaps (1.bmp, 2.bmp, ... 5.bmp) and a WAV file (wav.wav).    const char *fns[] = {"1.bmp","2.bmp","3.bmp","4.bmp","5.bmp"};
HAVI avi = CreateAvi("test.avi",1000,NULL); // 1000ms is the period between frames
for (int i=0; i
#include 
#include "avi_utils.h"    // First, we'll define the WAV file format.
#include 
typedef struct
{ char id[4];         //="fmt "
  unsigned long size; //=16
  short wFormatTag;   //=WAVE_FORMAT_PCM=1
  unsigned short wChannels;       //=1 or 2 for mono or stereo
  unsigned long dwSamplesPerSec;  //=11025 or 22050 or 44100
  unsigned long dwAvgBytesPerSec; //=wBlockAlign * dwSamplesPerSec
  unsigned short wBlockAlign;     //=wChannels * (wBitsPerSample==8?1:2)
  unsigned short wBitsPerSample;  //=8 or 16, for bits per sample
} FmtChunk;    typedef struct
{ char id[4];            //="data"
  unsigned long size;    //=datsize, size of the following array
  unsigned char data[1]; //=the raw data goes here
} DataChunk;    typedef struct
{ char id[4];         //="RIFF"
  unsigned long size; //=datsize 8 16 4
  char type[4];       //="WAVE"
  FmtChunk fmt;
  DataChunk dat;
} WavChunk;
#include         // This is the internal structure represented by the HAVI handle:
typedef struct
{ IAVIFile *pfile;    // created by CreateAvi
  WAVEFORMATEX wfx;   // as given to CreateAvi (.nChanels=0 if none was given). Used when audio stream is first created.
  int period;         // specified in CreateAvi, used when the video stream is first created
  IAVIStream *as;     // audio stream, initialised when audio stream is first created
  IAVIStream *ps, *psCompressed;  // video stream, when first created
  unsigned long nframe, nsamp;    // which frame will be added next, which sample will be added next
  bool iserr;         // if true, then no function will do anything
} TAviUtil;    HAVI CreateAvi(const char *fn, int frameperiod, const WAVEFORMATEX *wfx)
{ IAVIFile *pfile;
  AVIFileInit();
  HRESULT hr = AVIFileOpen(&pfile, fn, OF_WRITE|OF_CREATE, NULL);
  if (hr!=AVIERR_OK) {AVIFileExit(); return NULL;}
  TAviUtil *au = new TAviUtil;
  au->pfile = pfile;
  if (wfx==NULL) ZeroMemory(&au->wfx,sizeof(WAVEFORMATEX)); else CopyMemory(&au->wfx,wfx,sizeof(WAVEFORMATEX));
  au->period = frameperiod;
  au->as=0; au->ps=0; au->psCompressed=0;
  au->nframe=0; au->nsamp=0;
  au->iserr=false;
  return (HAVI)au;
}    HRESULT CloseAvi(HAVI avi)
{ if (avi==NULL) return AVIERR_BADHANDLE;
  TAviUtil *au = (TAviUtil*)avi;
  if (au->as!=0) AVIStreamRelease(au->as); au->as=0;
  if (au->psCompressed!=0) AVIStreamRelease(au->psCompressed); au->psCompressed=0;
  if (au->ps!=0) AVIStreamRelease(au->ps); au->ps=0;
  if (au->pfile!=0) AVIFileRelease(au->pfile); au->pfile=0;
  AVIFileExit();
  delete au;
  return S_OK;
}    HRESULT SetAviVideoCompression(HAVI avi, HBITMAP hbm, AVICOMPRESSOPTIONS *opts, bool ShowDialog, HWND hparent)
{ if (avi==NULL) return AVIERR_BADHANDLE;
  if (hbm==NULL) return AVIERR_BADPARAM;
  DIBSECTION dibs; int sbm = GetObject(hbm,sizeof(dibs),&dibs);
  if (sbm!=sizeof(DIBSECTION)) return AVIERR_BADPARAM;
  TAviUtil *au = (TAviUtil*)avi;
  if (au->iserr) return AVIERR_ERROR;
  if (au->psCompressed!=0) return AVIERR_COMPRESSOR;
  //
  if (au->ps==0) // create the stream, if it wasn't there before
  { AVISTREAMINFO strhdr; ZeroMemory(&strhdr,sizeof(strhdr));
    strhdr.fccType = streamtypeVIDEO;// stream type
    strhdr.fccHandler = 0; 
    strhdr.dwScale = au->period;
    strhdr.dwRate = 1000;
    strhdr.dwSuggestedBufferSize  = dibs.dsBmih.biSizeImage;
    SetRect(&strhdr.rcFrame, 0, 0, dibs.dsBmih.biWidth, dibs.dsBmih.biHeight);
    HRESULT hr=AVIFileCreateStream(au->pfile, &au->ps, &strhdr);
    if (hr!=AVIERR_OK) {au->iserr=true; return hr;}
  }
  //
  if (au->psCompressed==0) // set the compression, prompting dialog if necessary
  { AVICOMPRESSOPTIONS myopts; ZeroMemory(&myopts,sizeof(myopts));
    AVICOMPRESSOPTIONS *aopts[1];
    if (opts!=NULL) aopts[0]=opts; else aopts[0]=&myopts;
    if (ShowDialog)
    { BOOL res = (BOOL)AVISaveOptions(hparent,0,1,&au->ps,aopts);
      if (!res) {AVISaveOptionsFree(1,aopts); au->iserr=true; return AVIERR_USERABORT;}
    }
    HRESULT hr = AVIMakeCompressedStream(&au->psCompressed, au->ps, aopts[0], NULL);
    AVISaveOptionsFree(1,aopts);
    if (hr != AVIERR_OK) {au->iserr=true; return hr;}
    DIBSECTION dibs; GetObject(hbm,sizeof(dibs),&dibs);
    hr = AVIStreamSetFormat(au->psCompressed, 0, &dibs.dsBmih, dibs.dsBmih.biSize dibs.dsBmih.biClrUsed*sizeof(RGBQUAD));
    if (hr!=AVIERR_OK) {au->iserr=true; return hr;}
  }
  //
  return AVIERR_OK;
}    HRESULT AddAviFrame(HAVI avi, HBITMAP hbm)
{ if (avi==NULL) return AVIERR_BADHANDLE;
  if (hbm==NULL) return AVIERR_BADPARAM;
  DIBSECTION dibs; int sbm = GetObject(hbm,sizeof(dibs),&dibs);
  if (sbm!=sizeof(DIBSECTION)) return AVIERR_BADPARAM;
  TAviUtil *au = (TAviUtil*)avi;
  if (au->iserr) return AVIERR_ERROR;
  //
  if (au->ps==0) // create the stream, if it wasn't there before
  { AVISTREAMINFO strhdr; ZeroMemory(&strhdr,sizeof(strhdr));
    strhdr.fccType = streamtypeVIDEO;// stream type
    strhdr.fccHandler = 0; 
    strhdr.dwScale = au->period;
    strhdr.dwRate = 1000;
    strhdr.dwSuggestedBufferSize  = dibs.dsBmih.biSizeImage;
    SetRect(&strhdr.rcFrame, 0, 0, dibs.dsBmih.biWidth, dibs.dsBmih.biHeight);
    HRESULT hr=AVIFileCreateStream(au->pfile, &au->ps, &strhdr);
    if (hr!=AVIERR_OK) {au->iserr=true; return hr;}
  }
  //
  // create an empty compression, if the user hasn't set any
  if (au->psCompressed==0)
  { AVICOMPRESSOPTIONS opts; ZeroMemory(&opts,sizeof(opts));
    opts.fccHandler=mmioFOURCC('D','I','B',' '); 
    HRESULT hr = AVIMakeCompressedStream(&au->psCompressed, au->ps, &opts, NULL);
    if (hr != AVIERR_OK) {au->iserr=true; return hr;}
    hr = AVIStreamSetFormat(au->psCompressed, 0, &dibs.dsBmih, dibs.dsBmih.biSize dibs.dsBmih.biClrUsed*sizeof(RGBQUAD));
    if (hr!=AVIERR_OK) {au->iserr=true; return hr;}
  }
  //
  //Now we can add the frame
  HRESULT hr = AVIStreamWrite(au->psCompressed, au->nframe, 1, dibs.dsBm.bmBits, dibs.dsBmih.biSizeImage, AVIIF_KEYFRAME, NULL, NULL);
  if (hr!=AVIERR_OK) {au->iserr=true; return hr;}
  au->nframe  ; return S_OK;
}
      HRESULT AddAviAudio(HAVI avi, void *dat, unsigned long numbytes)
{ if (avi==NULL) return AVIERR_BADHANDLE;
  if (dat==NULL || numbytes==0) return AVIERR_BADPARAM;
  TAviUtil *au = (TAviUtil*)avi;
  if (au->iserr) return AVIERR_ERROR;
  if (au->wfx.nChannels==0) return AVIERR_BADFORMAT;
  unsigned long numsamps = numbytes*8 / au->wfx.wBitsPerSample;
  if ((numsamps*au->wfx.wBitsPerSample/8)!=numbytes) return AVIERR_BADPARAM;
  //
  if (au->as==0) // create the stream if necessary
  { AVISTREAMINFO ahdr; ZeroMemory(&ahdr,sizeof(ahdr));
    ahdr.fccType=streamtypeAUDIO;
    ahdr.dwScale=au->wfx.nBlockAlign;
    ahdr.dwRate=au->wfx.nSamplesPerSec*au->wfx.nBlockAlign; 
    ahdr.dwSampleSize=au->wfx.nBlockAlign;
    ahdr.dwQuality=(DWORD)-1;
    HRESULT hr = AVIFileCreateStream(au->pfile, &au->as, &ahdr);
    if (hr!=AVIERR_OK) {au->iserr=true; return hr;}
    hr = AVIStreamSetFormat(au->as,0,&au->wfx,sizeof(WAVEFORMATEX));
    if (hr!=AVIERR_OK) {au->iserr=true; return hr;}
  }
  //
  // now we can write the data
  HRESULT hr = AVIStreamWrite(au->as,au->nsamp,numsamps,dat,numbytes,0,NULL,NULL);
  if (hr!=AVIERR_OK) {au->iserr=true; return hr;}
  au->nsamp =numsamps; return S_OK;
}        HRESULT AddAviWav(HAVI avi, const char *src, DWORD flags)
{ if (avi==NULL) return AVIERR_BADHANDLE;
  if (flags!=SND_MEMORY && flags!=SND_FILENAME) return AVIERR_BADFLAGS;
  if (src==0) return AVIERR_BADPARAM;
  TAviUtil *au = (TAviUtil*)avi;
  if (au->iserr) return AVIERR_ERROR;
  //
  char *buf=0; WavChunk *wav = (WavChunk*)src;
  if (flags==SND_FILENAME)
  { HANDLE hf=CreateFile(src,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
    if (hf==INVALID_HANDLE_VALUE) {au->iserr=true; return AVIERR_FILEOPEN;}
    DWORD size = GetFileSize(hf,NULL);
    buf = new char[size];
    DWORD red; ReadFile(hf,buf,size,&red,NULL);
    CloseHandle(hf);
    wav = (WavChunk*)buf;
  }
  //
  // check that format doesn't clash
  bool badformat=false;
  if (au->wfx.nChannels==0)
  { au->wfx.wFormatTag=wav->fmt.wFormatTag;
    au->wfx.cbSize=0;
    au->wfx.nAvgBytesPerSec=wav->fmt.dwAvgBytesPerSec;
    au->wfx.nBlockAlign=wav->fmt.wBlockAlign;
    au->wfx.nChannels=wav->fmt.wChannels;
    au->wfx.nSamplesPerSec=wav->fmt.dwSamplesPerSec;
    au->wfx.wBitsPerSample=wav->fmt.wBitsPerSample;
  }
  else
  { if (au->wfx.wFormatTag!=wav->fmt.wFormatTag) badformat=true;
    if (au->wfx.nAvgBytesPerSec!=wav->fmt.dwAvgBytesPerSec) badformat=true;
    if (au->wfx.nBlockAlign!=wav->fmt.wBlockAlign) badformat=true;
    if (au->wfx.nChannels!=wav->fmt.wChannels) badformat=true;
    if (au->wfx.nSamplesPerSec!=wav->fmt.dwSamplesPerSec) badformat=true;
    if (au->wfx.wBitsPerSample!=wav->fmt.wBitsPerSample) badformat=true;
  }
  if (badformat) {if (buf!=0) delete[] buf; return AVIERR_BADFORMAT;}
  //
  if (au->as==0) // create the stream if necessary
  { AVISTREAMINFO ahdr; ZeroMemory(&ahdr,sizeof(ahdr));
    ahdr.fccType=streamtypeAUDIO;
    ahdr.dwScale=au->wfx.nBlockAlign;
    ahdr.dwRate=au->wfx.nSamplesPerSec*au->wfx.nBlockAlign; 
    ahdr.dwSampleSize=au->wfx.nBlockAlign;
    ahdr.dwQuality=(DWORD)-1;
    HRESULT hr = AVIFileCreateStream(au->pfile, &au->as, &ahdr);
    if (hr!=AVIERR_OK) {if (buf!=0) delete[] buf; au->iserr=true; return hr;}
    hr = AVIStreamSetFormat(au->as,0,&au->wfx,sizeof(WAVEFORMATEX));
    if (hr!=AVIERR_OK) {if (buf!=0) delete[] buf; au->iserr=true; return hr;}
  }
  //
  // now we can write the data
  unsigned long numbytes = wav->dat.size;
  unsigned long numsamps = numbytes*8 / au->wfx.wBitsPerSample;
  HRESULT hr = AVIStreamWrite(au->as,au->nsamp,numsamps,wav->dat.data,numbytes,0,NULL,NULL);
  if (buf!=0) delete[] buf;
  if (hr!=AVIERR_OK) {au->iserr=true; return hr;}
  au->nsamp =numsamps; return S_OK;
}        unsigned int FormatAviMessage(HRESULT code, char *buf,unsigned int len)
{ const char *msg="unknown avi result code";
  switch (code)
  { case S_OK: msg="Success"; break;
    case AVIERR_BADFORMAT: msg="AVIERR_BADFORMAT: corrupt file or unrecognized format"; break;
    case AVIERR_MEMORY: msg="AVIERR_MEMORY: insufficient memory"; break;
    case AVIERR_FILEREAD: msg="AVIERR_FILEREAD: disk error while reading file"; break;
    case AVIERR_FILEOPEN: msg="AVIERR_FILEOPEN: disk error while opening file"; break;
    case REGDB_E_CLASSNOTREG: msg="REGDB_E_CLASSNOTREG: file type not recognised"; break;
    case AVIERR_READONLY: msg="AVIERR_READONLY: file is read-only"; break;
    case AVIERR_NOCOMPRESSOR: msg="AVIERR_NOCOMPRESSOR: a suitable compressor could not be found"; break;
    case AVIERR_UNSUPPORTED: msg="AVIERR_UNSUPPORTED: compression is not supported for this type of data"; break;
    case AVIERR_INTERNAL: msg="AVIERR_INTERNAL: internal error"; break;
    case AVIERR_BADFLAGS: msg="AVIERR_BADFLAGS"; break;
    case AVIERR_BADPARAM: msg="AVIERR_BADPARAM"; break;
    case AVIERR_BADSIZE: msg="AVIERR_BADSIZE"; break;
    case AVIERR_BADHANDLE: msg="AVIERR_BADHANDLE"; break;
    case AVIERR_FILEWRITE: msg="AVIERR_FILEWRITE: disk error while writing file"; break;
    case AVIERR_COMPRESSOR: msg="AVIERR_COMPRESSOR"; break;
    case AVIERR_NODATA: msg="AVIERR_READONLY"; break;
    case AVIERR_BUFFERTOOSMALL: msg="AVIERR_BUFFERTOOSMALL"; break;
    case AVIERR_CANTCOMPRESS: msg="AVIERR_CANTCOMPRESS"; break;
    case AVIERR_USERABORT: msg="AVIERR_USERABORT"; break;
    case AVIERR_ERROR: msg="AVIERR_ERROR"; break;
  }
  unsigned int mlen=(unsigned int)strlen(msg);
  if (buf==0 || len==0) return mlen;
  unsigned int n=mlen; if (n 1>len) n=len-1;
  strncpy(buf,msg,n); buf[n]=0;
  return mlen;
}
KeywordsThe code on this page demonstrates the following functions and data structures: WAV file format, RIFF file, Chunk, WAVE_FORMAT_PCM, IAVIFile, PAVIFile, WAVEFORMAT, WAVEFORMATEX, IAVIStream, PAVIStream, AVIFileInit, AVIFileOpen, AVIFileExit, AVIStreamRelease, AVIStreamClose, AVIFileRelease, DIBSECTION, GetObject, device independent bitmap, AVISTREAMINFO, streamtypeVIDEO, streamtypeAUDIO, AVIFileCreateStream, AVICOMPRESSOPTIONS, AVIMakeCompressedStream, AVIStreamSetFormat, mmioFOURCC, AVIStreamWrite. 聯盟----Visita網站http://www.vista.org.tw ---[ 發問前請先找找舊文章 ]---
懶懶泥
一般會員


發表:22
回覆:41
積分:12
註冊:2003-02-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-08-28 16:22:38 IP:211.76.xxx.xxx 未訂閱
const char *fns[] = {"1.bmp","2.bmp","3.bmp","4.bmp","5.bmp"}; HAVI avi = CreateAvi("test.avi",1000,NULL); for (int i=0; i
系統時間:2024-04-24 10:35:39
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!