private void SetupVideo(DisplayFormat videoFormat, VideoCompressor compressor, int fps) { int colorDepth = Bitmap.GetPixelFormatSize(videoFormat.PixelFormat); int width = videoFormat.Width; int height = videoFormat.Height; // Calculate pitch int bytesPerPixel = colorDepth / 8; int pitch = width * bytesPerPixel; int pitch_factor = 4; if (pitch % pitch_factor != 0) { pitch = pitch + pitch_factor - pitch % pitch_factor; } // Create AVI Stream Avi32Interop.AVISTREAMINFO asf = new Avi32Interop.AVISTREAMINFO(); asf.dwRate = fps; asf.dwSuggestedBufferSize = pitch * height * bytesPerPixel; asf.dwScale = 1; asf.fccType = Avi32Interop.streamtypeVIDEO; asf.szName = null; asf.rcFrame = new Avi32Interop.RECT(0, 0, width, height); int hr = Avi32Interop.AVIFileCreateStream(this.pAviFile, out this.pVideoStream, ref asf); if (hr != 0) { throw new AviException("AVIFileCreateStream", hr); } // Set stream format Avi32Interop.BITMAPINFOHEADER bih = new Avi32Interop.BITMAPINFOHEADER(); bih.biBitCount = (ushort)colorDepth; bih.biCompression = 0; // BI_RGB bih.biHeight = videoFormat.Height; bih.biPlanes = 1; bih.biSize = (uint)Marshal.SizeOf(bih); bih.biSizeImage = (uint)(pitch * height * (colorDepth / 8)); bih.biWidth = videoFormat.Width; if (compressor != null && !compressor.Equals(VideoCompressor.None)) { // Setup compressor this.SetupVideoCompressor(compressor); hr = Avi32Interop.AVIStreamSetFormat(this.pAviCompressedStream, 0, ref bih, Marshal.SizeOf(bih)); } else { hr = Avi32Interop.AVIStreamSetFormat(this.pVideoStream, 0, ref bih, Marshal.SizeOf(bih)); } if (hr != 0) { throw new AviException("AVIStreamSetFormat", hr); } }
private void SetupVideoCompressor(VideoCompressor compressor) { Avi32Interop.AVICOMPRESSOPTIONS compressorOptions = new Avi32Interop.AVICOMPRESSOPTIONS(); uint fccHandler = compressor.FccHandler; compressorOptions.fccType = Avi32Interop.ICTYPE_VIDEO; compressorOptions.fccHandler = fccHandler; compressorOptions.dwQuality = (uint)compressor.Quality; // Open compressor IntPtr hic = Avi32Interop.ICOpen(Avi32Interop.ICTYPE_VIDEO, fccHandler, Avi32Interop.ICMODE_QUERY); if (hic == IntPtr.Zero) { int errorCode = Marshal.GetLastWin32Error(); throw new AviException(errorCode, string.Format("ICOpen failed, error code = 0x{0:X8}.", errorCode)); } // Get number of bytes required for params uint cbParams = (uint)Avi32Interop.ICGetState(hic, IntPtr.Zero, 0); IntPtr pParams = Marshal.AllocHGlobal((int)cbParams); try { // Get params int retval = Avi32Interop.ICGetState(hic, pParams, cbParams); compressorOptions.cbParms = cbParams; // If the Xvid Video Codec is selected, hack params to hide status window! if (string.Equals(compressor.FccHandlerString, xvidCodec)) { ModifyXvidParams(pParams, (int)cbParams); } compressorOptions.lpParms = pParams; compressorOptions.dwFlags = Avi32Interop.AVICOMPRESSF_VALID; // Close compressor Avi32Interop.ICClose(hic); // Make compressed stream int hr = Avi32Interop.AVIMakeCompressedStream(out this.pAviCompressedStream, this.pVideoStream, ref compressorOptions, 0); if (hr != 0) { throw new AviException(hr, string.Format("AVIMakeCompressedStream failed, error code = 0x{0:X8}.", hr)); } } finally { if (pParams != IntPtr.Zero) { Marshal.FreeHGlobal(pParams); } } }
public static VideoCompressor Create(string fccHandler) { if (string.IsNullOrEmpty(fccHandler)) { throw new ArgumentNullException("fccHandler"); } if (fccHandler.Length != 4) { throw new ArgumentException("fccHandler"); } uint ffcHandler = Avi32Interop.mmioFOURCC(fccHandler[0], fccHandler[1], fccHandler[2], fccHandler[3]); VideoCompressor compressor = new VideoCompressor(ffcHandler); return(compressor); }
public void Open(string fileName, DisplayFormat videoFormat, int fps, VideoCompressor compressor, SoundFormat audioFormat, AcmEncoder audioEncoder) { if (this.opened) { throw new InvalidOperationException(); } if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullException("fileName"); } this.video = videoFormat != null; this.audio = audioFormat != null; if (!this.audio && !this.video) { // There is nothing to do! throw new InvalidOperationException(); } // Open AVI File int hr = Avi32Interop.AVIFileOpen(out this.pAviFile, fileName, Avi32Interop.OF_CREATE, IntPtr.Zero); if (hr != 0) { throw new AviException("AVIFileOpen", hr); } try { if (this.video) { this.SetupVideo(videoFormat, compressor, fps); } if (this.audio) { this.SetupAudio(audioFormat, audioEncoder); } this.opened = true; } finally { if (!this.opened) { this.Close(); } } }
private void SetupAudio(SoundFormat audioFormat, AcmEncoder audioEncoder) { IntPtr pwfx = audioFormat.ToPtr(); try { Avi32Interop.AVISTREAMINFO asi = new Avi32Interop.AVISTREAMINFO(); asi.fccType = Avi32Interop.streamtypeAUDIO; asi.dwScale = audioFormat.BlockAlign; asi.dwRate = audioFormat.AverageBytesPerSecond; asi.dwStart = 0; asi.dwLength = -1; asi.dwInitialFrames = 0; asi.dwSuggestedBufferSize = 0; asi.dwQuality = -1; asi.dwSampleSize = audioFormat.BlockAlign; int hr = Avi32Interop.AVIFileCreateStream(this.pAviFile, out this.pAudioStream, ref asi); if (hr != 0) { throw new AviException("AVIStreamSetFormat", hr); } hr = Avi32Interop.AVIStreamSetFormat(this.pAudioStream, 0, pwfx, audioFormat.ToalSize); if (hr != 0) { throw new AviException("AVIStreamSetFormat", hr); } if (audioEncoder != null) { audioEncoder.Open(); } this.audioFormat = audioFormat; this.audioEncoder = audioEncoder; } finally { Marshal.FreeHGlobal(pwfx); } }
public static int ICGetDefaultQuality(IntPtr hic, ref uint pQuality) { return(Avi32Interop.ICSendMessage(hic, Avi32Interop.ICM_GETDEFAULTQUALITY, ref pQuality, (UIntPtr)(sizeof(uint)))); }
public static int ICGetState(IntPtr hic, IntPtr pv, uint cb) { return(Avi32Interop.ICSendMessage(hic, Avi32Interop.ICM_GETSTATE, (UIntPtr)(ulong)pv, (UIntPtr)((ulong)cb))); }
public static int ICAbout(IntPtr hic, IntPtr hWnd) { return(Avi32Interop.ICSendMessage(hic, Avi32Interop.ICM_ABOUT, (UIntPtr)(ulong)hWnd, UIntPtr.Zero)); }
public static int ICConfigure(IntPtr hic, IntPtr hWnd) { return(Avi32Interop.ICSendMessage(hic, Avi32Interop.ICM_CONFIGURE, (UIntPtr)(ulong)hWnd, UIntPtr.Zero)); }
public static int ICCompressQuery(IntPtr hic, ref Avi32Interop.BITMAPINFOHEADER lpbiInput, IntPtr lpbiOutput) { return(Avi32Interop.ICSendMessage(hic, Avi32Interop.ICM_COMPRESS_QUERY, ref lpbiInput, (UIntPtr)((ulong)lpbiOutput))); }
public static int ICCompressQuery(IntPtr hic, ref Avi32Interop.BITMAPINFOHEADER lpbiInput, IntPtr lpbiOutput) { return Avi32Interop.ICSendMessage(hic, Avi32Interop.ICM_COMPRESS_QUERY, ref lpbiInput, (UIntPtr)((ulong)lpbiOutput)); }