/// <summary> /// Create new AVI file and open it for writing. /// </summary> /// /// <param name="fileName">AVI file name to create.</param> /// <param name="width">Video width.</param> /// <param name="height">Video height.</param> /// /// <remarks><para>The method opens (creates) a video files, configure video codec and prepares /// the stream for saving video frames with a help of <see cref="AddFrame"/> method.</para></remarks> /// /// <exception cref="System.IO.IOException">Failed opening the specified file.</exception> /// <exception cref="VideoException">A error occurred while creating new video file. See exception message.</exception> /// <exception cref="OutOfMemoryException">Insufficient memory for internal buffer.</exception> /// <exception cref="ArgumentException">Video file resolution must be a multiple of two.</exception> /// 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( ); } } }
/// <summary> /// Open AVI file. /// </summary> /// /// <param name="fileName">AVI file name to open.</param> /// /// <remarks><para>The method opens a video file and prepares the stream and decoder for /// reading video frames with the help of <see cref="GetNextFrame"/> method.</para> /// </remarks> /// /// <exception cref="System.IO.IOException">Failed opening the specified file.</exception> /// <exception cref="VideoException">A error occurred while opening the video file. See exception message.</exception> /// /// public void Open(string fileName) { // close previous file Close( ); bool success = false; try { lock ( sync ) { // open AVI file if (Win32.AVIFileOpen(out file, fileName, Win32.OpenFileMode.ShareDenyWrite, IntPtr.Zero) != 0) { throw new System.IO.IOException("Failed opening the specified AVI file."); } // get first video stream if (Win32.AVIFileGetStream(file, out stream, Win32.mmioFOURCC("vids"), 0) != 0) { throw new VideoException("Failed getting video stream."); } // get stream info Win32.AVISTREAMINFO info = new Win32.AVISTREAMINFO( ); Win32.AVIStreamInfo(stream, ref info, Marshal.SizeOf(info)); width = info.rectFrame.right; height = info.rectFrame.bottom; position = info.start; start = info.start; length = info.length; rate = (float)info.rate / (float)info.scale; codec = Win32.decode_mmioFOURCC(info.handler); // prepare decompressor 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.compression = 0; // BI_RGB // get frame object if ((getFrame = Win32.AVIStreamGetFrameOpen(stream, ref bitmapInfoHeader)) == IntPtr.Zero) { bitmapInfoHeader.height = -height; if ((getFrame = Win32.AVIStreamGetFrameOpen(stream, ref bitmapInfoHeader)) == IntPtr.Zero) { throw new VideoException("Failed initializing decompressor."); } } success = true; } } finally { if (!success) { Close( ); } } }