public AVICOMPRESSOPTIONS ToStruct(){ AVICOMPRESSOPTIONS returnVar = new AVICOMPRESSOPTIONS(); returnVar.fccType = this.fccType; returnVar.fccHandler = this.fccHandler; returnVar.dwKeyFrameEvery = this.dwKeyFrameEvery; returnVar.dwQuality = this.dwQuality; returnVar.dwBytesPerSecond = this.dwBytesPerSecond; returnVar.dwFlags = this.dwFlags; returnVar.lpFormat = this.lpFormat; returnVar.cbFormat = this.cbFormat; returnVar.lpParms = this.lpParms; returnVar.cbParms = this.cbParms; returnVar.dwInterleaveEvery = this.dwInterleaveEvery; return returnVar; }
public static extern int AVIMakeCompressedStream( out IntPtr ppsCompressed, IntPtr aviStream, ref AVICOMPRESSOPTIONS ao, int dummy);
unsafe private void SetOptions() { AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS(); opts.fccType = fccType_; opts.fccHandler = 0;//fccHandler_; opts.dwKeyFrameEvery = 0; opts.dwQuality = 0; // 0 .. 10000 opts.dwFlags = 0; // AVICOMRPESSF_KEYFRAMES = 4 opts.dwBytesPerSecond = 0; opts.lpFormat = new IntPtr(0); opts.cbFormat = 0; opts.lpParms = new IntPtr(0); opts.cbParms = 0; opts.dwInterleaveEvery = 0; AVICOMPRESSOPTIONS* p = &opts; AVICOMPRESSOPTIONS** pp = &p; IntPtr x = ps_; IntPtr* ptr_ps = &x; AVISaveOptions(0,0,1,ptr_ps,pp); // TODO: AVISaveOptionsFree(...) int hr = AVIMakeCompressedStream(out psCompressed_, ps_, ref opts, 0); if (hr != 0) { throw new AviException("AVIMakeCompressedStream"); } BITMAPINFOHEADER bi = new BITMAPINFOHEADER(); bi.biSize = 40; bi.biWidth = (Int32) width_; bi.biHeight = (Int32) height_; bi.biPlanes = 1; bi.biBitCount = 24; bi.biCompression = 0; // 0 = BI_RGB bi.biSizeImage = stride_*height_; bi.biXPelsPerMeter= 0; bi.biYPelsPerMeter= 0; bi.biClrUsed = 0; bi.biClrImportant = 0; hr = AVIStreamSetFormat(psCompressed_, 0, ref bi, 40); if (hr != 0) { throw new AviException("AVIStreamSetFormat",hr); } }
unsafe private static extern int AVISaveOptions(int hwnd, UInt32 flags, int nStreams, IntPtr* ptr_ptr_avi, AVICOMPRESSOPTIONS** ao);
private unsafe bool SetOptions() { int hr; AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS(); AVICOMPRESSOPTIONS *pOpts = &opts; /* opts.fccType = mmioFOURCC('v','i','d','s'); opts.fccHandler = 0;//cvid? iv50? opts.dwQuality = 0; // 0 .. 10000 opts.dwFlags = 0; // AVICOMRPESSF_KEYFRAMES = 4 */ hr = AVISaveOptions( Engine.MainWindow.Handle, 3, 1, ref m_pStream, &pOpts ); if (hr != 1) return false; // TODO: AVISaveOptionsFree(...) hr = AVIMakeCompressedStream( out m_pCompStream, m_pStream, ref opts, 0 ); if (hr != 0) return false; BITMAPINFOHEADER bi = new BITMAPINFOHEADER(); bi.biSize = 40; bi.biWidth = m_Width; bi.biHeight = m_Height; bi.biPlanes = 1; bi.biBitCount = 24; bi.biCompression = 0; // 0 = BI_RGB bi.biSizeImage = (uint)(m_Width*m_Height*(bi.biBitCount/8)); hr = AVIStreamSetFormat( m_pCompStream, 0, ref bi, 40 ); return hr == 0; }
private static unsafe extern int AVISaveOptions( IntPtr hwnd, uint flags, int nStreams, ref IntPtr pStream, AVICOMPRESSOPTIONS** aco);
private static extern int AVIMakeCompressedStream(out IntPtr ppsCompressed, IntPtr ppsSource, ref AVICOMPRESSOPTIONS lpOptions, int pclsidHandler);
public static extern int AVIMakeCompressedStream(out IntPtr ppsCompressed, IntPtr aviStream, ref AVICOMPRESSOPTIONS options, int clsidHandler);
private static extern int AVIMakeCompressedStream(out IntPtr ppsCompressed, IntPtr aviStream, ref AVICOMPRESSOPTIONS ao, int dummy);
/// <summary>Initialize the AviFile.</summary> /// <param name="path">The path to the output file.</param> /// <param name="frameRate">The frame rate for the video.</param> /// <param name="width">The width of the video.</param> /// <param name="height">The height of the video.</param> /// <param name="quality">Video quality 0 to 10000.</param> public AviWriter(string path, int frameRate, int width, int height, uint quality = 10000) { #region Validation if (path == null) { throw new ArgumentNullException(nameof(path)); } if (frameRate <= 0) { throw new ArgumentOutOfRangeException(nameof(frameRate), frameRate, "The frame rate must be at least 1 frame per second."); } if (width <= 0) { throw new ArgumentOutOfRangeException(nameof(width), width, "The width must be at least 1."); } if (height <= 0) { throw new ArgumentOutOfRangeException(nameof(height), height, "The height must be at least 1."); } #endregion //Store parameters. _width = width; _height = height; _disposed = false; //Get the stride information by creating a new bitmap and querying it using (var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb)) { var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); _stride = (uint)bmpData.Stride; bmp.UnlockBits(bmpData); } try { //Initialize the AVI library. AVIFileInit(); //Open the output AVI file. var rv = AVIFileOpen(out _aviFile, path, AVI_OPEN_MODE_CREATEWRITE, IntPtr.Zero); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } //Create a new stream in the avi file. var aviStreamInfo = new AVISTREAMINFOW { fccType = GetFourCc("vids"), fccHandler = GetFourCc("CVID"), // 808810089, //IV50 dwScale = 1, dwRate = (uint)frameRate, dwSuggestedBufferSize = (uint)(_height * _stride), dwQuality = quality, //-1 default 0xffffffff, 0 to 10.000 rcFrame = new Native.Rect { Bottom = _height, Right = _width } }; rv = AVIFileCreateStream(_aviFile, out _aviStream, ref aviStreamInfo); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } //Set compress options. var options = new AVICOMPRESSOPTIONS { fccType = GetFourCc("vids"), lpParms = IntPtr.Zero, lpFormat = IntPtr.Zero }; var mem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(AVICOMPRESSOPTIONS))); Marshal.StructureToPtr(options, mem, false); var streams = new[] { _aviStream }; var infPtrs = new[] { mem }; var ok = AVISaveOptions(IntPtr.Zero, ICMF_CHOOSE_KEYFRAME | ICMF_CHOOSE_DATARATE, 1, streams, infPtrs); if (ok) { options = (AVICOMPRESSOPTIONS)Marshal.PtrToStructure(mem, typeof(AVICOMPRESSOPTIONS)); } Marshal.FreeHGlobal(mem); if (!ok) { throw new Exception("User cancelled the operation."); } rv = AVIMakeCompressedStream(out _compStream, _aviStream, ref options, 0); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } //Configure the compressed stream. var streamFormat = new BITMAPINFOHEADER { biSize = 40, biWidth = _width, biHeight = _height, biPlanes = 1, biBitCount = 24, biSizeImage = (uint)(_stride * _height) }; rv = AVIStreamSetFormat(_compStream, 0, ref streamFormat, 40); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } } catch { // Clean up Dispose(false); try { if (File.Exists(path)) { File.Delete(path); } } catch { } throw; } }
/// <summary> /// To struct /// </summary> public AVICOMPRESSOPTIONS ToStruct() { var returnVar = new AVICOMPRESSOPTIONS(); returnVar.fccType = fccType; returnVar.fccHandler = fccHandler; returnVar.dwKeyFrameEvery = dwKeyFrameEvery; /// <summary> /// Dw quality /// </summary> returnVar.dwQuality = dwQuality; returnVar.dwBytesPerSecond = dwBytesPerSecond; /// <summary> /// Dw flags /// </summary> returnVar.dwFlags = dwFlags; returnVar.lpFormat = lpFormat; returnVar.cbFormat = cbFormat; returnVar.lpParms = lpParms; returnVar.cbParms = cbParms; returnVar.dwInterleaveEvery = dwInterleaveEvery; return returnVar; }
unsafe private void SetOptions() { var opts = new AVICOMPRESSOPTIONS(); opts.fccType = 0; //fccType_; opts.fccHandler = 0;//fccHandler_; opts.dwKeyFrameEvery = 0; opts.dwQuality = 0; // 0 .. 10000 opts.dwFlags = 0; // AVICOMRPESSF_KEYFRAMES = 4 opts.dwBytesPerSecond = 0; opts.lpFormat =new IntPtr(0); opts.cbFormat = 0; opts.lpParms = new IntPtr(0); opts.cbParms = 0; opts.dwInterleaveEvery = 0; var p = &opts; var pp = &p; var x = ps_; var ptr_ps = &x; //AVISaveOptions(0, 0, 1, ptr_ps, pp); // TODO: AVISaveOptionsFree(...) var hr = AVIMakeCompressedStream(out psCompressed_, ps_, ref opts, 0); if (hr != 0) { throw new AviException("AVIMakeCompressedStream"); } var bi = new BITMAPINFOHEADER { biSize = 40, biWidth = (int) width_, biHeight = -(int) height_, // In RGB is inverted: https://msdn.microsoft.com/en-us/library/windows/desktop/dd318229(v=vs.85).aspx biPlanes = 1, biBitCount = 24, biCompression = 0, biSizeImage = stride_*height_, biXPelsPerMeter = 0, biYPelsPerMeter = 0, biClrUsed = 0, biClrImportant = 0 }; // 0 = BI_RGB hr = AVIStreamSetFormat(psCompressed_, 0, ref bi, 40); if (hr != 0) { throw new AviException("AVIStreamSetFormat", hr); } }
/// <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() { // close previous file Close(); this.width = Options.CaptureArea.Width; this.height = Options.CaptureArea.Height; // 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 (NativeMethods.AVIFileOpen(out file, Options.OutputPath, OpenFileMode.Create | OpenFileMode.Write, IntPtr.Zero) != 0) { throw new IOException("Failed opening the specified file."); } this.rate = Options.ScreenRecordFPS; // describe new stream AVISTREAMINFO info = new AVISTREAMINFO(); info.type = NativeMethods.mmioFOURCC("vids"); info.handler = NativeMethods.mmioFOURCC("DIB "); info.scale = 1; info.rate = rate; info.suggestedBufferSize = stride * height; // create stream if (NativeMethods.AVIFileCreateStream(file, out stream, ref info) != 0) { throw new Exception("Failed creating stream."); } if (Options.AVI.CompressOptions.handler == 0) { // describe compression options Options.AVI.CompressOptions.handler = NativeMethods.mmioFOURCC("DIB "); } if (Options.ShowAVIOptionsDialog) { AVICOMPRESSOPTIONS options = new AVICOMPRESSOPTIONS(); options.handler = Options.AVI.CompressOptions.handler; options.quality = Options.AVI.CompressOptions.quality; options.flags = 8; // AVICOMPRESSF_VALID int result = NativeMethods.AVISaveOptions(stream, ref options, Options.ParentWindow); if (result == 1) { Options.AVI.CompressOptions = options; } } // create compressed stream if (NativeMethods.AVIMakeCompressedStream(out streamCompressed, stream, ref Options.AVI.CompressOptions, IntPtr.Zero) != 0) { throw new Exception("Failed creating compressed stream."); } // describe frame format BITMAPINFOHEADER bitmapInfoHeader = new BITMAPINFOHEADER(width, height, 24); // set frame format if (NativeMethods.AVIStreamSetFormat(streamCompressed, 0, ref bitmapInfoHeader, Marshal.SizeOf(bitmapInfoHeader.GetType())) != 0) { throw new Exception("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(); } } }
public static extern int AVIMakeCompressedStream(out IntPtr compressedStream, IntPtr sourceStream, ref AVICOMPRESSOPTIONS options, IntPtr clsidHandler);