/// <summary> /// Acquires a video codec configuration from the user /// </summary> public IDisposable AcquireVideoCodecToken(IntPtr hwnd) { if (!IsOpen) throw new InvalidOperationException("File must be opened before acquiring a codec token (or else the stream formats wouldnt be known)"); //encoder params Win32.AVICOMPRESSOPTIONS comprOptions = new Win32.AVICOMPRESSOPTIONS(); if (currVideoCodecToken != null) { comprOptions = currVideoCodecToken.comprOptions; } if (AVISaveOptions(pAviRawVideoStream, ref comprOptions, hwnd) != 0) { CodecToken ret = CodecToken.TakePossession(comprOptions); // save to config as well Global.Config.AVICodecToken = ret.Serialize(); return ret; } else return null; }
static CodecToken DeSerializeFromByteArray(byte[] data) { var m = new MemoryStream(data, false); var b = new BinaryReader(m); Win32.AVICOMPRESSOPTIONS comprOptions = new Win32.AVICOMPRESSOPTIONS(); byte[] Format; byte[] Params; try { comprOptions.fccType = b.ReadInt32(); comprOptions.fccHandler = b.ReadInt32(); comprOptions.dwKeyFrameEvery = b.ReadInt32(); comprOptions.dwQuality = b.ReadInt32(); comprOptions.dwBytesPerSecond = b.ReadInt32(); comprOptions.dwFlags = b.ReadInt32(); //comprOptions.lpFormat = b.ReadInt32(); comprOptions.cbFormat = b.ReadInt32(); //comprOptions.lpParms = b.ReadInt32(); comprOptions.cbParms = b.ReadInt32(); comprOptions.dwInterleaveEvery = b.ReadInt32(); Format = b.ReadBytes(comprOptions.cbFormat); Params = b.ReadBytes(comprOptions.cbParms); } catch (IOException) { // ran off end of array most likely return null; } finally { b.Close(); } // create unmanaged copies of Format, Params if (comprOptions.cbFormat != 0) { IntPtr lpFormat = Marshal.AllocHGlobal(comprOptions.cbFormat); Marshal.Copy(Format, 0, lpFormat, comprOptions.cbFormat); comprOptions.lpFormat = (int)lpFormat; } else comprOptions.lpFormat = (int)IntPtr.Zero; if (comprOptions.cbParms != 0) { IntPtr lpParms = Marshal.AllocHGlobal(comprOptions.cbParms); Marshal.Copy(Params, 0, lpParms, comprOptions.cbParms); comprOptions.lpParms = (int)lpParms; } else comprOptions.lpParms = (int)IntPtr.Zero; CodecToken ret = new CodecToken(); ret.marshaled = true; ret.comprOptions = comprOptions; ret.codec = Win32.decode_mmioFOURCC(comprOptions.fccHandler); return ret; }
public void Dispose() { if (allocated) { IntPtr[] infPtrs = new IntPtr[1]; IntPtr mem; // alloc unmanaged memory mem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Win32.AVICOMPRESSOPTIONS))); infPtrs[0] = mem; // copy from managed structure to unmanaged memory Marshal.StructureToPtr(comprOptions, mem, false); Win32.AVISaveOptionsFree(1, infPtrs); Marshal.FreeHGlobal(mem); codec = null; comprOptions = new Win32.AVICOMPRESSOPTIONS(); allocated = false; } if (marshaled) { IntPtr p; p = (IntPtr)comprOptions.lpFormat; if (p != IntPtr.Zero) Marshal.FreeHGlobal(p); p = (IntPtr)comprOptions.lpParms; if (p != IntPtr.Zero) Marshal.FreeHGlobal(p); codec = null; comprOptions = new Win32.AVICOMPRESSOPTIONS(); marshaled = false; } }
/// <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"); } }
/// <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; }
static CodecToken DeSerializeFromByteArray(byte[] data) { var m = new MemoryStream(data, false); var b = new BinaryReader(m); Win32.AVICOMPRESSOPTIONS comprOptions = new Win32.AVICOMPRESSOPTIONS(); byte[] Format; byte[] Parms; try { comprOptions.fccType = b.ReadInt32(); comprOptions.fccHandler = b.ReadInt32(); comprOptions.dwKeyFrameEvery = b.ReadInt32(); comprOptions.dwQuality = b.ReadInt32(); comprOptions.dwBytesPerSecond = b.ReadInt32(); comprOptions.dwFlags = b.ReadInt32(); //comprOptions.lpFormat = b.ReadInt32(); comprOptions.cbFormat = b.ReadInt32(); //comprOptions.lpParms = b.ReadInt32(); comprOptions.cbParms = b.ReadInt32(); comprOptions.dwInterleaveEvery = b.ReadInt32(); Format = b.ReadBytes(comprOptions.cbFormat); Parms = b.ReadBytes(comprOptions.cbParms); } catch (IOException) { // ran off end of array most likely return null; } finally { b.Close(); } CodecToken ret = new CodecToken(); ret.comprOptions = comprOptions; ret.Format = Format; ret.Parms = Parms; ret.codec = Win32.decode_mmioFOURCC(comprOptions.fccHandler); return ret; }