/// <summary> /// Acquires a video codec configuration from the user /// </summary> public IDisposable AcquireVideoCodecToken(IntPtr hwnd, CodecToken lastCodecToken) { if (!IsOpen) { throw new InvalidOperationException("File must be opened before acquiring a codec token (or else the stream formats wouldnt be known)"); } if (lastCodecToken != null) { currVideoCodecToken = lastCodecToken; } //encoder params Win32.AVICOMPRESSOPTIONS comprOptions = new Win32.AVICOMPRESSOPTIONS(); if (currVideoCodecToken != null) { currVideoCodecToken.AllocateToAVICOMPRESSOPTIONS(ref comprOptions); } bool result = AVISaveOptions(pAviRawVideoStream, ref comprOptions, hwnd) != 0; CodecToken ret = CodecToken.CreateFromAVICOMPRESSOPTIONS(ref comprOptions); //so, AVISaveOptions may have changed some of the pointers //if it changed the pointers, did it it free the old ones? we don't know //let's assume it frees them. if we're wrong, we leak. if we assume otherwise and we're wrong, we may crash. //so that means any pointers that come in here are either //1. ones we allocated a minute ago //2. ones VFW allocated //guess what? doesn't matter. We'll free them all ourselves. CodecToken.DeallocateAVICOMPRESSOPTIONS(ref comprOptions); if (result) { // save to config and return it Global.Config.AVICodecToken = ret.Serialize(); return(ret); } else { return(null); } }
/// <summary> /// begin recording /// </summary> public void OpenStreams() { if (currVideoCodecToken == null) { throw new InvalidOperationException("set a video codec token before opening the streams!"); } // open compressed video stream Win32.AVICOMPRESSOPTIONS opts = new Win32.AVICOMPRESSOPTIONS(); currVideoCodecToken.AllocateToAVICOMPRESSOPTIONS(ref opts); bool failed = Win32.FAILED(Win32.AVIMakeCompressedStream(out pAviCompressedVideoStream, pAviRawVideoStream, ref opts, IntPtr.Zero)); CodecToken.DeallocateAVICOMPRESSOPTIONS(ref opts); if (failed) { CloseStreams(); throw new InvalidOperationException("Failed making compressed video stream"); } // set the compressed video stream input format Win32.BITMAPINFOHEADER bmih = new Win32.BITMAPINFOHEADER(); if (bit32) { parameters.PopulateBITMAPINFOHEADER32(ref bmih); } else { parameters.PopulateBITMAPINFOHEADER24(ref bmih); } if (Win32.FAILED(Win32.AVIStreamSetFormat(pAviCompressedVideoStream, 0, ref bmih, Marshal.SizeOf(bmih)))) { bit32 = true; // we'll try again CloseStreams(); throw new InvalidOperationException("Failed setting compressed video stream input format"); } // set audio stream input format Win32.WAVEFORMATEX wfex = new Win32.WAVEFORMATEX(); parameters.PopulateWAVEFORMATEX(ref wfex); if (Win32.FAILED(Win32.AVIStreamSetFormat(pAviRawAudioStream, 0, ref wfex, Marshal.SizeOf(wfex)))) { CloseStreams(); throw new InvalidOperationException("Failed setting raw audio stream input format"); } }