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:
- 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.
- Initialize the AVI engine calling
InitEngine
. A dialog box will
popup to choose and fill in the parameters of the codec.
- For each frame: Do the drawing stuff, fill the image buffer with BRG ordering and send it to the AVI engine using
AddFrame
.
- Release ressources and close file by calling
ReleaseEngine
.
And you're are done! Here's some demo pseudo-code:
CAVIGenerator AviGen;
BYTE* bmBits;
HRESULT hr;
AviGen.SetRate(20);
AviGen.SetBitmapHeader(GetActiveView());
hr=AviGen.InitEngine()
if (FAILED(hr))
{
AfxMessageBox(avi.GetLastErrorMessage());
goto Cleaning;
}
LPBITMAPINFOHEADER lpbih=AviGen.GetBitmapInfo();
bmBits=new BYTE[3 * lpbih->biWidth* lpbih->biHeight];
for (int i=0;i<100;i++)
{
hr=AviGen.AddFrame(bmBits);
if (FAILED(hr))
{
AfxMessageBox(avi.GetLastErrorMessage());
goto Cleaning;
}
}
Cleaning:
AviGen.ReleaseEngine();
delete[] bmBits;
Adding CAVIGenerator to your project
- 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.