Click here to Skip to main content
Click here to Skip to main content

A class to easily generate AVI video with OpenGL and Video for Windows

By , 26 Oct 2002
 

Sample Image - AviGenerator.jpg

Introduction

CAviGenerator is a simple wrapper for the Video For Windows (VFW) library. In the back, it takes care of a numerous initialization for you and hides the library function calls so that the user can start generating movies in a minimal number of line of code and without having much knowledge about VFW.

The class main features are:

  • generation of AVI movies with any codec installed on your machine
  • no need of generating thousands of separate images,
  • simplicity of use

The class CAVIGenerator takes it's inspiration from MSDN example writeavi.c.

CAVIGenerator: A AVI Video wrapper

A simple class that make creation of AVI video easy.

Attributes

Each object contains general characteristics of the movie such as

  • the file name,
  • the frame rate, (fps)
  • the image description: BITMAPINFOHEADER
These members are declared as protected and are accessible by Set methods.

It contains also private members that are used to handle the "Video for Windows" AVI engine.

Constructors

CAVIGenerator();

Default constructor, default file name is "Untitled.avi", frame rate is 30 fps.

CAVIGenerator(LPCTSTR sFileName, CView* pView, DWORD dwRate);

In-place constructor with CView. See SetBitmapHeader(CView* pView).

CAVIGenerator(LPCTSTR sFileName, LPBITMAPINFOHEADER lpbih, DWORD dwRate);

In-place constructor with BITMAPINFOHEADER. See SetBitmapHeader(LPBITMAPINFOHEADER lpbih)

Setters and Getters

void SetFileName(const CString& _sFileName)

SetFileName sets the name of the output file. The filename extension should be .avi otherwize the creation of the AVI won't work. Checking of .avi extension is left to the user.

void SetRate(DWORD dwRate)

SetRate sets the frame rate (fps).

void SetBitmapHeader(CView* pView);

SetBitmapHeader fills in the information about the bitmap in m_bih using using from the view the view pView the width, height, 24 bit/color, and BRG. It makes sure that the width and height are both multiple of 4.

void SetBitmapHeader(LPBITMAPINFOHEADER lpbih);

SetBitmapHeader sets the bitmap info as in lpbih. It supposes that the user knows what he's doing.

LPBITMAPINFOHEADER GetBitmapHeader()

GetBitmapHeader returns a pointer to bitmap info header structure.

AVI creation Functions

HRESULT InitEngine();

InitEngine initializes the VFW engine and chooses a codec. This function has to be called before starting to grab frames. Some asserts are made to check that bitmap info has been properly initialized. It returns the last HRESULT. If something fails, the error message can be retreived using GetLastErrorMessage().

CAviGenerator avi;
HRESULT hr;

hr=avi.InitEngine();
if (FAILED(hr))
{
    AfxMessageBox(avi.GetLastErrorMessage());
    ...
}
HRESULT AddFrame(BYTE* bmBits);

AddFrame adds a frame to the movie. The data pointed by bmBits should be compatible with the bitmap description made by SetBitmapHeader. Typically with OpenGL, bmBits is the buffer read when using glReadPixels. As for InitEnginge, it returns the HRESULT.

void ReleaseEngine();

ReleaseEngine releases ressources allocated for movie and close the file.

Using CAVIGenerator

You have to follow these steps:

  1. Set the file name (optional), frame rate (optional) and bitmap info (required). If you want to grab an OpenGL screen, just send a pointer of the CView object to the SetBitmapHeader function. Alternative, the user can fill in the BITMAPINFOHEADER structure himself. Make sure that dimension of bitmap are a multiple of 4.
  2. Initialize the AVI engine calling InitEngine. A dialog box will popup to choose and fill in the parameters of the codec.
  3. For each frame: Do the drawing stuff, fill the image buffer with BRG ordering and send it to the AVI engine using AddFrame.
  4. Release ressources and close file by calling ReleaseEngine.

And you're are done! Here's some demo pseudo-code:

CAVIGenerator AviGen;	// generator
BYTE* bmBits;	// image buffer
HRESULT hr;

AviGen.SetRate(20);	// set 20fps
AviGen.SetBitmapHeader(GetActiveView());	// get bitmap info out of the view
hr=AviGen.InitEngine()	// start engine
if (FAILED(hr))
{
    AfxMessageBox(avi.GetLastErrorMessage());
    goto Cleaning;
}

LPBITMAPINFOHEADER lpbih=AviGen.GetBitmapInfo(); // getting bitmap info

// allocating memory for bmBits
bmBits=new BYTE[3 /* BRG*/ * lpbih->biWidth* lpbih->biHeight];	
for (int i=0;i<100;i++)	// make 100 frames
{
	// TODO pust your draw code here.	
	 /* Draw code where bmBits is filled. 
	 For example, to read OpenGL buffer, put 
	 glReadPixels(0,0,lpbih->biWidth,lpbih->biHeight, 
                       GL_BGR_EXT,GL_UNSIGNED_BYTE,bmBits); */ 

	// adding frame and continue if OK
	hr=AviGen.AddFrame(bmBits);
	if (FAILED(hr))
	{
	    AfxMessageBox(avi.GetLastErrorMessage());
	    goto Cleaning;
	}
}
	
// cleaning memory	
Cleaning:
AviGen.ReleaseEngine(); // releasing ressources
delete[] bmBits;	// release ressources

Adding CAVIGenerator to your project

  1. Add AVIGenerator.h and AVIGenerator.cpp to your project.

Non-MFC Applications

If you want to use CAviGenerator without MFC, undefine _AVIGENERATOR_MFC in AviGenerator.h. It will disable MFC function calls.

Demo project

A simple MFC SDI application that shows a cube and triangle rotating using OpenGL. When selecting the menu item Avi Generation->Generate..., you start to create a 100 frames AVI movie.

OpenGL drawing code is copy-pasted from lesson 5 of NeHe Productions.

Update History

  • 21.10.2002 Ported to non-MFC application, added HRESULT handling
  • 11.8.2001 Other bug fixed. Thanks to Dick W Augustsson.
  • 11.2.2001 Bug fixed in setting bitmap header biSizeImage field. Thanks to David.
  • 10.8.2001 Bug fixed in ~CAviGenerator and in example above (LPBITMAPINFOHEADER lpbih not initialized).
  • 10.5.2001 Bug fixed in CAVIGenerator::SetBitmapHeader(LPBITMAPINFOHEADER lpbih) function. Thanks to Lori Gardi.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Jonathan de Halleux
Engineer
United States United States
Member
Jonathan de Halleux is Civil Engineer in Applied Mathematics. He finished his PhD in 2004 in the rainy country of Belgium. After 2 years in the Common Language Runtime (i.e. .net), he is now working at Microsoft Research on Pex (http://research.microsoft.com/pex).

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberManmohan2929 Aug '12 - 4:50 
exactly what i was looking for Smile | :)
GeneralMy vote of 5memberbwrtjhp27 Jul '10 - 16:27 
This project helps me out
GeneralMy vote of 5memberNickolas10119 Jul '10 - 16:16 
It helps me a lot.
Thanks!
QuestionSET DEFAULT COMPRESS SETTINGmemberDarvox3 Dec '08 - 1:08 
Hello
 
I would like keep the pop up compress setting window, because I need use allways the same codec.
Could you teach me please?
 
PS: Very good program
 
Best Regards

GeneralThanksmemberNathan Cramp28 Sep '08 - 0:35 
This is exactly what i have been looking for. Thanks!
QuestionHow to make it work for DivX6.6.1 Codec ?memberSkywalker200824 May '07 - 6:51 
Hi,
 
It is really a cool view. But it seems not work well in generating AVI using DivX 6.6.1 Codec. The AVIStreamWrite() returned a AVIERR_BADFORMAT.
 
Do you know why and how to fix it? Thanks,
Questioncan i use avigenerator in my opengl program?memberleekeng82@hotmail.com24 Apr '06 - 21:25 
i'm doing a walk-thru program using win32 application, and i would like to play an avi video file in my openGL project as an intro. So, can i use the avigenerator source? is it just need to add those two file(.h and .cpp) into my project? others like stdafx.h and .cpp? And i already have function written for creating the window, is it mean that i don need MFC definition? and...any others lib need to be added? A lot of thanks!!
Generalwhat's the differences between AVICOMPRESSOPTIONS and COMPVARSmembersthugo13 Oct '05 - 15:53 
I searched MSDN and found that there are two kinds of structures, one is AVICOMPRESSOPTIONS and the other is COMPVARS. I used COMPVARS to compress the video files. It works fine until I choose WMV9 as the compressor. It fails on ICSeqCompressFrame(). What's wrong? Does COMPVARS not work with WMV9?
 
Thanks!
 
sthugo
GeneralWorking with Dev-C++memberbenthurston30 Sep '05 - 11:09 
Any ideas about getting this to work with Dev-C++ 4.9.9? It doesn't come with the comdef.h file and the one I downloaded to use compiles with a million errors.
GeneralTerrain engine recordingmemberNishant2724 Jul '05 - 3:28 
1.Hi there.Your program is exactly what I need for my project but i don't know how to integrate it in my project.
 
2.I have made a terrain engine in opengl where i want to record the scene when I move around in the terrain and and then stop recording once i have navigated through the terrain.
 
2. How can implement this using your code.I want to activate recording then move around the terrain and record that which I can playback.Smile | :)
GeneralRe: Terrain engine recordingmemberVertexwahn17 Apr '06 - 12:39 
strange - you have implemented a whole terain engine but you can't integrate a stupid avi recorder class into your program
Generalusing AviGenerator with GLUTmembersalva230 May '05 - 11:10 
Excuse me, I´m using the GLUT library in a cloth simulation project to generate the OPENGL window. Question is: Can I use AviGenerator to generate a AVI video from the glut window? The main problem is that I don´t have a GetActiveView() function or a CView object. Please help me.
 
Thanks and please excuse me for my poor english.
GeneralRe: using AviGenerator with GLUTsussseboeh8 Jun '05 - 4:07 
For the main problem
 
There exist an alternative function
void SetBitmapHeader(LPBITMAPINFOHEADER lpbih);
 
now, you only have to fill this attributes
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
 
It's in the header Wingdi.h declared and included with Windows.h
For more information take a look at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_1rw2.asp[^]
 
greets, Seboeh
GeneralIts real COOL!!!memberarm2arm28 Mar '05 - 23:26 
Hi!!
Thanks for such a article.
I will combine it with my PMViewerSmile | :)
http://pmviewer.sourceforge.net/pmviewer1x.html[^]
Arman.
GeneralGuidancememberChivalrous13 Apr '04 - 19:23 
Dear Sir,
 
I am a final year student of Karachi, Pakistan. I am working on a Motion Detection System, which is capable of detecting meaningful motion in an Area where human motion is prohibited. First it needs to grab each and every frame and then involves image processing on each and every frame. Application of different filters and a lot.
Please recommend me suitable platforms, language and any other thing that could help me.
 
Please guide me
Wishing for a reply.
 
Thanks a lot.
M.Adil Hayat Khan

GeneralRe: GuidancememberJonathan de Halleux15 Apr '04 - 22:27 
Motion capture has nothing to do with this article. I cannot advise on this topic.
 
Jonathan de Halleux - My Blog - www.dotnetwiki.org -
MbUnit - QuickGraph - NCollection

Generalurgent: Generating AVI in C# using VFWmemberch3ckmat321 Mar '04 - 23:54 
hi all,
 
i was trying same this in C# (generating Mpeg-4 AVI from JPEG/BMP with custom frame rate) and was also trying to use VFW.
can u or some one help me pointing to some good example for C#?
 
i'm on a project and stuck with this issue.
 
TIA

GeneralRe: urgent: Generating AVI in C# using VFWsusscadessi2 Jun '04 - 23:29 
hi,
take a look at this article, it's in vb.net but should help you:
 
http://www.xaml.net/articles/webcam-video-capture-art7-3.asp
QuestionHow to add a sound to AVI stream?memberHanney Wang15 Feb '04 - 15:32 
Thanks for the article! But the AVI stream we generated is just no sound, is there any way to add a sound (like WAV audio)?
 
Regards,
Hanney
AnswerRe: How to add a sound to AVI stream?membereatitanddie20 Sep '07 - 10:17 
Check out virtualdub (www.virtualdub.org) - - it can add a .WAV to an AVI, no problem.
Questionhow to use one copression manually?memberphilmus2522 Jan '04 - 8:30 
hi,
 
how to use one compressor without choosing them from a standard dialog box for compressors showed by call to "AVISaveOptions". I want fixe my compressor from code and generate my compressed frame for creating my AVI file, i dont now if have to use streams or not! a sample code will resolve probleme(some links if any).
 
thanks for help!
AnswerRe: how to use one copression manually?memberJonathan de Halleux25 Jan '04 - 8:24 
No clue, sorry.
 
Jonathan de Halleux.

www.dotnetwiki.org

GeneralRe: how to use one copression manually?memberBrandybuck27 Aug '04 - 3:42 
Use the
AVICOMPRESSOPTIONS opts
 
Than allocate memory
memset(&opts, 0, sizeof(opts));
 
The compress format can be set via
opts.fccHandler=mmioFOURCC('A', 'V', 'I', ' ');
or
opts.fccHandler=mmioFOURCC('d', 'i', 'v', 'x');
 
I used AVISaveOptions(...) to open the compress dialog once. After confirming with OK I saved the fccHandler in the registry as option (that can be reset easily).
 
For e.g. Indeo you can also save/preset the opts.dwQuality.
 
Best wishes
 

 

 

GeneralMSVC 6membermansour_ahmadian8 Jan '04 - 3:54 
Hello,
I can’t compile the source code on windows 2000 and MSVC 6. Should I have MSVC 7?
 
Regards

GeneralRe: MSVC 6memberJonathan de Halleux15 Mar '04 - 20:28 
No, original code was compiled with msvc6. What's the error message:?
 
Jonathan de Halleux.

www.dotnetwiki.org

GUnit

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 27 Oct 2002
Article Copyright 2001 by Jonathan de Halleux
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid