title: compress avi video file using directshow
body: <p>I created an avi video file but it is uncompressed and its size is large. I want to compress the video file to lower the size . I found this code but as I am beginner , I am unable to set compression. can anyone point out the way ?</p>
  
  <p>This is avi class:</p>
  
  <pre><code>#define STRICT
  #define WIN32_LEAN_AND_MEAN
  #include &lt;windows.h&gt;
  #include &lt;vfw.h&gt;
      #include "avi_utils.h"
  
  
  
  // First, we'll define the WAV file format.
  #include &lt;pshpack1.h&gt;
  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 &lt;poppack.h&gt;
  
  
  
  
  // 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(&amp;pfile, fn, OF_WRITE|OF_CREATE, NULL);
      if (hr!=AVIERR_OK) {AVIFileExit(); return NULL;}
      TAviUtil *au = new TAviUtil;
      au-&gt;pfile = pfile;
      if (wfx==NULL) ZeroMemory(&amp;au-&gt;wfx,sizeof(WAVEFORMATEX)); else CopyMemory(&amp;au-&gt;wfx,wfx,sizeof(WAVEFORMATEX));
      au-&gt;period = frameperiod;
      au-&gt;as=0; au-&gt;ps=0; au-&gt;psCompressed=0;
      au-&gt;nframe=0; au-&gt;nsamp=0;
      au-&gt;iserr=false;
      return (HAVI)au;
  }
  
  HRESULT CloseAvi(HAVI avi)
  { if (avi==NULL) return AVIERR_BADHANDLE;
      TAviUtil *au = (TAviUtil*)avi;
      if (au-&gt;as!=0) AVIStreamRelease(au-&gt;as); au-&gt;as=0;
      if (au-&gt;psCompressed!=0) AVIStreamRelease(au-&gt;psCompressed); au-&gt;psCompressed=0;
      if (au-&gt;ps!=0) AVIStreamRelease(au-&gt;ps); au-&gt;ps=0;
      if (au-&gt;pfile!=0) AVIFileRelease(au-&gt;pfile); au-&gt;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),&amp;dibs);
      if (sbm!=sizeof(DIBSECTION)) return AVIERR_BADPARAM;
      TAviUtil *au = (TAviUtil*)avi;
      if (au-&gt;iserr) return AVIERR_ERROR;
      if (au-&gt;psCompressed!=0) return AVIERR_COMPRESSOR;
      //
      if (au-&gt;ps==0) // create the stream, if it wasn't there before
      { AVISTREAMINFO strhdr; ZeroMemory(&amp;strhdr,sizeof(strhdr));
      strhdr.fccType = streamtypeVIDEO;// stream type
      strhdr.fccHandler = 0; 
      strhdr.dwScale = au-&gt;period;
      strhdr.dwRate = 1000;
      strhdr.dwSuggestedBufferSize  = dibs.dsBmih.biSizeImage;
      SetRect(&amp;strhdr.rcFrame, 0, 0, dibs.dsBmih.biWidth, dibs.dsBmih.biHeight);
      HRESULT hr=AVIFileCreateStream(au-&gt;pfile, &amp;au-&gt;ps, &amp;strhdr);
      if (hr!=AVIERR_OK) {au-&gt;iserr=true; return hr;}
      }
      //
      if (au-&gt;psCompressed==0) // set the compression, prompting dialog if necessary
      { AVICOMPRESSOPTIONS myopts; ZeroMemory(&amp;myopts,sizeof(myopts));
      AVICOMPRESSOPTIONS *aopts[1];
      if (opts!=NULL) aopts[0]=opts; else aopts[0]=&amp;myopts;
      if (ShowDialog)
      { BOOL res = (BOOL)AVISaveOptions(hparent,0,1,&amp;au-&gt;ps,aopts);
          if (!res) {AVISaveOptionsFree(1,aopts); au-&gt;iserr=true; return AVIERR_USERABORT;}
      }
      HRESULT hr = AVIMakeCompressedStream(&amp;au-&gt;psCompressed, au-&gt;ps, aopts[0], NULL);
      AVISaveOptionsFree(1,aopts);
      if (hr != AVIERR_OK) {au-&gt;iserr=true; return hr;}
      DIBSECTION dibs; GetObject(hbm,sizeof(dibs),&amp;dibs);
      hr = AVIStreamSetFormat(au-&gt;psCompressed, 0, &amp;dibs.dsBmih, dibs.dsBmih.biSize+dibs.dsBmih.biClrUsed*sizeof(RGBQUAD));
      if (hr!=AVIERR_OK) {au-&gt;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),&amp;dibs);
      if (sbm!=sizeof(DIBSECTION)) return AVIERR_BADPARAM;
      TAviUtil *au = (TAviUtil*)avi;
      if (au-&gt;iserr) return AVIERR_ERROR;
      //
      if (au-&gt;ps==0) // create the stream, if it wasn't there before
      { AVISTREAMINFO strhdr; ZeroMemory(&amp;strhdr,sizeof(strhdr));
      strhdr.fccType = streamtypeVIDEO;// stream type
      strhdr.fccHandler = 0; 
      strhdr.dwScale = au-&gt;period;
      strhdr.dwRate = 1000;
      strhdr.dwSuggestedBufferSize  = dibs.dsBmih.biSizeImage;
      SetRect(&amp;strhdr.rcFrame, 0, 0, dibs.dsBmih.biWidth, dibs.dsBmih.biHeight);
      HRESULT hr=AVIFileCreateStream(au-&gt;pfile, &amp;au-&gt;ps, &amp;strhdr);
      if (hr!=AVIERR_OK) {au-&gt;iserr=true; return hr;}
      }
      //
      // create an empty compression, if the user hasn't set any
      if (au-&gt;psCompressed==0)
      { AVICOMPRESSOPTIONS opts; ZeroMemory(&amp;opts,sizeof(opts));
      opts.fccHandler=mmioFOURCC('D','I','B',' '); 
      HRESULT hr = AVIMakeCompressedStream(&amp;au-&gt;psCompressed, au-&gt;ps, &amp;opts, NULL);
      if (hr != AVIERR_OK) {au-&gt;iserr=true; return hr;}
      hr = AVIStreamSetFormat(au-&gt;psCompressed, 0, &amp;dibs.dsBmih, dibs.dsBmih.biSize+dibs.dsBmih.biClrUsed*sizeof(RGBQUAD));
      if (hr!=AVIERR_OK) {au-&gt;iserr=true; return hr;}
      }
      //
      //Now we can add the frame
      HRESULT hr = AVIStreamWrite(au-&gt;psCompressed, au-&gt;nframe, 1, dibs.dsBm.bmBits, dibs.dsBmih.biSizeImage, AVIIF_KEYFRAME, NULL, NULL);
      if (hr!=AVIERR_OK) {au-&gt;iserr=true; return hr;}
      au-&gt;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-&gt;iserr) return AVIERR_ERROR;
      if (au-&gt;wfx.nChannels==0) return AVIERR_BADFORMAT;
      unsigned long numsamps = numbytes*8 / au-&gt;wfx.wBitsPerSample;
      if ((numsamps*au-&gt;wfx.wBitsPerSample/8)!=numbytes) return AVIERR_BADPARAM;
      //
      if (au-&gt;as==0) // create the stream if necessary
      { AVISTREAMINFO ahdr; ZeroMemory(&amp;ahdr,sizeof(ahdr));
      ahdr.fccType=streamtypeAUDIO;
      ahdr.dwScale=au-&gt;wfx.nBlockAlign;
      ahdr.dwRate=au-&gt;wfx.nSamplesPerSec*au-&gt;wfx.nBlockAlign; 
      ahdr.dwSampleSize=au-&gt;wfx.nBlockAlign;
      ahdr.dwQuality=(DWORD)-1;
      HRESULT hr = AVIFileCreateStream(au-&gt;pfile, &amp;au-&gt;as, &amp;ahdr);
      if (hr!=AVIERR_OK) {au-&gt;iserr=true; return hr;}
      hr = AVIStreamSetFormat(au-&gt;as,0,&amp;au-&gt;wfx,sizeof(WAVEFORMATEX));
      if (hr!=AVIERR_OK) {au-&gt;iserr=true; return hr;}
      }
      //
      // now we can write the data
      HRESULT hr = AVIStreamWrite(au-&gt;as,au-&gt;nsamp,numsamps,dat,numbytes,0,NULL,NULL);
      if (hr!=AVIERR_OK) {au-&gt;iserr=true; return hr;}
      au-&gt;nsamp+=numsamps; return S_OK;
  }
  
  
  
  HRESULT AddAviWav(HAVI avi, const char *src, DWORD flags)
  { if (avi==NULL) return AVIERR_BADHANDLE;
      if (flags!=SND_MEMORY &amp;&amp; flags!=SND_FILENAME) return AVIERR_BADFLAGS;
      if (src==0) return AVIERR_BADPARAM;
      TAviUtil *au = (TAviUtil*)avi;
      if (au-&gt;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-&gt;iserr=true; return AVIERR_FILEOPEN;}
      DWORD size = GetFileSize(hf,NULL);
      buf = new char[size];
      DWORD red; ReadFile(hf,buf,size,&amp;red,NULL);
      CloseHandle(hf);
      wav = (WavChunk*)buf;
      }
      //
      // check that format doesn't clash
      bool badformat=false;
      if (au-&gt;wfx.nChannels==0)
      { au-&gt;wfx.wFormatTag=wav-&gt;fmt.wFormatTag;
      au-&gt;wfx.cbSize=0;
      au-&gt;wfx.nAvgBytesPerSec=wav-&gt;fmt.dwAvgBytesPerSec;
      au-&gt;wfx.nBlockAlign=wav-&gt;fmt.wBlockAlign;
      au-&gt;wfx.nChannels=wav-&gt;fmt.wChannels;
      au-&gt;wfx.nSamplesPerSec=wav-&gt;fmt.dwSamplesPerSec;
      au-&gt;wfx.wBitsPerSample=wav-&gt;fmt.wBitsPerSample;
      }
      else
      { if (au-&gt;wfx.wFormatTag!=wav-&gt;fmt.wFormatTag) badformat=true;
      if (au-&gt;wfx.nAvgBytesPerSec!=wav-&gt;fmt.dwAvgBytesPerSec) badformat=true;
      if (au-&gt;wfx.nBlockAlign!=wav-&gt;fmt.wBlockAlign) badformat=true;
      if (au-&gt;wfx.nChannels!=wav-&gt;fmt.wChannels) badformat=true;
      if (au-&gt;wfx.nSamplesPerSec!=wav-&gt;fmt.dwSamplesPerSec) badformat=true;
      if (au-&gt;wfx.wBitsPerSample!=wav-&gt;fmt.wBitsPerSample) badformat=true;
      }
      if (badformat) {if (buf!=0) delete[] buf; return AVIERR_BADFORMAT;}
      //
      if (au-&gt;as==0) // create the stream if necessary
      { AVISTREAMINFO ahdr; ZeroMemory(&amp;ahdr,sizeof(ahdr));
      ahdr.fccType=streamtypeAUDIO;
      ahdr.dwScale=au-&gt;wfx.nBlockAlign;
      ahdr.dwRate=au-&gt;wfx.nSamplesPerSec*au-&gt;wfx.nBlockAlign; 
      ahdr.dwSampleSize=au-&gt;wfx.nBlockAlign;
      ahdr.dwQuality=(DWORD)-1;
      HRESULT hr = AVIFileCreateStream(au-&gt;pfile, &amp;au-&gt;as, &amp;ahdr);
      if (hr!=AVIERR_OK) {if (buf!=0) delete[] buf; au-&gt;iserr=true; return hr;}
      hr = AVIStreamSetFormat(au-&gt;as,0,&amp;au-&gt;wfx,sizeof(WAVEFORMATEX));
      if (hr!=AVIERR_OK) {if (buf!=0) delete[] buf; au-&gt;iserr=true; return hr;}
      }
      //
      // now we can write the data
      unsigned long numbytes = wav-&gt;dat.size;
      unsigned long numsamps = numbytes*8 / au-&gt;wfx.wBitsPerSample;
      HRESULT hr = AVIStreamWrite(au-&gt;as,au-&gt;nsamp,numsamps,wav-&gt;dat.data,numbytes,0,NULL,NULL);
      if (buf!=0) delete[] buf;
      if (hr!=AVIERR_OK) {au-&gt;iserr=true; return hr;}
      au-&gt;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&gt;len) n=len-1;
      strncpy(buf,msg,n); buf[n]=0;
      return mlen;
  }
  </code></pre>
  
  <p>Here is my main:</p>
  
  <pre><code>int main ()
  {
      const char *fns[] = {"1.bmp","2.bmp","3.bmp","4.bmp","5.bmp"};
  
      HAVI avi = CreateAvi("test.avi",1000/5,NULL);
      for (int i=0; i&lt;sizeof(fns)/sizeof(fns[0]); i++)
      { 
          HBITMAP hbm=(HBITMAP)LoadImage(NULL,fns[i],IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
          AddAviFrame(avi,hbm);
          DeleteObject(hbm);
      }
      AddAviWav(avi,"wav.wav",SND_FILENAME);
      CloseAvi(avi);
  
  }
  </code></pre>
  
  <p>what should I do in main ?</p>