public void Open( string fileName, int width, int height )
{
// close previous file
Close( );
// check width and height
if ( ( ( width & 1 ) != 0 ) || ( ( height & 1 ) != 0 ) )
{
throw new ArgumentException( "Video file resolution must be a multiple of two." );
}
bool success = false;
try
{
lock ( sync )
{
// calculate stride
stride = width * 3;
if ( ( stride % 4 ) != 0 )
stride += ( 4 - stride % 4 );
// create new file
if ( Win32.AVIFileOpen( out file, fileName, Win32.OpenFileMode.Create | Win32.OpenFileMode.Write, IntPtr.Zero ) != 0 )
throw new System.IO.IOException( "Failed opening the specified file." );
this.width = width;
this.height = height;
// describe new stream
Win32.AVISTREAMINFO info = new Win32.AVISTREAMINFO( );
info.type = Win32.mmioFOURCC( "vids" );
info.handler = Win32.mmioFOURCC( codec );
info.scale = 1;
info.rate = rate;
info.suggestedBufferSize = stride * height;
// create stream
if ( Win32.AVIFileCreateStream( file, out stream, ref info ) != 0 )
throw new VideoException( "Failed creating stream." );
// describe compression options
Win32.AVICOMPRESSOPTIONS options = new Win32.AVICOMPRESSOPTIONS( );
options.handler = Win32.mmioFOURCC( codec );
options.quality = quality;
// uncomment if video settings dialog is required to show
// Win32.AVISaveOptions( stream, ref options );
// create compressed stream
if ( Win32.AVIMakeCompressedStream( out streamCompressed, stream, ref options, IntPtr.Zero ) != 0 )
throw new VideoException( "Failed creating compressed stream." );
// describe frame format
Win32.BITMAPINFOHEADER bitmapInfoHeader = new Win32.BITMAPINFOHEADER( );
bitmapInfoHeader.size = Marshal.SizeOf( bitmapInfoHeader.GetType( ) );
bitmapInfoHeader.width = width;
bitmapInfoHeader.height = height;
bitmapInfoHeader.planes = 1;
bitmapInfoHeader.bitCount = 24;
bitmapInfoHeader.sizeImage = 0;
bitmapInfoHeader.compression = 0; // BI_RGB
// set frame format
if ( Win32.AVIStreamSetFormat( streamCompressed, 0, ref bitmapInfoHeader, Marshal.SizeOf( bitmapInfoHeader.GetType( ) ) ) != 0 )
throw new VideoException( "Failed setting format of the compressed stream." );
// alloc unmanaged memory for frame
buffer = Marshal.AllocHGlobal( stride * height );
if ( buffer == IntPtr.Zero )
{
throw new OutOfMemoryException( "Insufficient memory for internal buffer." );
}
position = 0;
success = true;
}
}
finally
{
if ( !success )
{
Close( );
}
}
}