public static Bitmap Open(string fileName, int width, int height, PixelFormat format) { // Make sure any previous file is closed Close(); bool success = false; Bitmap theBitmap = new Bitmap(width, height, format); // Get the actual stride BitmapData bmpData = theBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, theBitmap.PixelFormat); m_Stride = bmpData.Stride; theBitmap.UnlockBits(bmpData); try { // create new file if (NM.AVIFileOpen(out m_File, fileName, NM.OpenFileMode.Create | NM.OpenFileMode.Write, IntPtr.Zero) != 0) { throw new Exception("Failed to create the file"); } m_Width = width; m_Height = height; // describe new stream NM.AVISTREAMINFO info = new NM.AVISTREAMINFO(); info.fccType = mmioFOURCC("vids"); info.fccHandler = mmioFOURCC(m_Codec); info.dwScale = 1; info.dwRate = FrameRate; info.dwSuggestedBufferSize = m_Stride * height; // create stream if (NM.AVIFileCreateStream(m_File, out m_Stream, ref info) != 0) { throw new Exception("Failed to create the stream"); } // describe compression options NM.AVICOMPRESSOPTIONS options = new NM.AVICOMPRESSOPTIONS(); options.fccHandler = mmioFOURCC(m_Codec); options.dwQuality = Quality * 100; options.dwKeyFrameEvery = KeyFrameEvery; if (options.dwKeyFrameEvery == 0) { options.dwFlags = NM.AviCompression.AVICOMPRESSF_VALID; } else { options.dwFlags = NM.AviCompression.AVICOMPRESSF_KEYFRAMES | NM.AviCompression.AVICOMPRESSF_VALID; } // Create the compressed stream if (NM.AVIMakeCompressedStream(out m_StreamCompressed, m_Stream, ref options, IntPtr.Zero) != 0) { throw new Exception("Failed to create the compressed stream"); } // Create the header for the frame format NM.BITMAPINFOHEADER bitmapInfoHeader = new NM.BITMAPINFOHEADER(); bitmapInfoHeader.biSize = Marshal.SizeOf(typeof(NM.BITMAPINFOHEADER)); bitmapInfoHeader.biWidth = width; bitmapInfoHeader.biHeight = height; bitmapInfoHeader.biPlanes = 1; bitmapInfoHeader.biBitCount = (short)Image.GetPixelFormatSize(format); bitmapInfoHeader.biSizeImage = 0; bitmapInfoHeader.biCompression = 0; // BI_RGB // Write the header if (NM.AVIStreamSetFormat(m_StreamCompressed, 0, ref bitmapInfoHeader, bitmapInfoHeader.biSize) != 0) { throw new Exception("Failed to set the compressed stream format"); } // alloc unmanaged memory for the flipped frame buffer m_FlippedFrameBuffer = Marshal.AllocHGlobal(m_Stride * height); if (m_FlippedFrameBuffer == IntPtr.Zero) { throw new Exception("Failed to allocate memory for the flipped frame buffer"); } m_CurrentFrame = 0; success = true; } finally { if (!success) { Close(); } } return(theBitmap); }