private int EncodeFrame(IntPtr sourcePtr, IntPtr destinationPtr, uint destinationSize, out bool isKeyFrame) { var outInfo = outBitmapInfo; outInfo.ImageSize = destinationSize; var inInfo = inBitmapInfo; var flags = framesFromLastKey >= keyFrameRate ? VfwApi.ICCOMPRESS_KEYFRAME : 0; var result = VfwApi.ICCompress(compressorHandle, flags, ref outInfo, destinationPtr, ref inInfo, sourcePtr, out _, out var outFlags, frameIndex, 0, quality, IntPtr.Zero, IntPtr.Zero); CheckICResult(result); frameIndex++; isKeyFrame = (outFlags & VfwApi.AVIIF_KEYFRAME) == VfwApi.AVIIF_KEYFRAME; if (isKeyFrame) { framesFromLastKey = 1; } else { framesFromLastKey++; } return((int)outInfo.ImageSize); }
/// <summary>Encodes a frame.</summary> /// <seealso cref="IVideoEncoder.EncodeFrame"/> public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame) { // TODO: Introduce Width and Height in IVideoRecorder and add Requires to EncodeFrame contract Contract.Assert(srcOffset + 4 * width * height <= source.Length); BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, height, width * 4); var sourceHandle = GCHandle.Alloc(sourceBuffer, GCHandleType.Pinned); var encodedHandle = GCHandle.Alloc(destination, GCHandleType.Pinned); try { var outInfo = outBitmapInfo; outInfo.ImageSize = (uint)destination.Length; var inInfo = inBitmapInfo; int outFlags; int chunkID; var flags = framesFromLastKey >= keyFrameRate ? VfwApi.ICCOMPRESS_KEYFRAME : 0; var result = VfwApi.ICCompress(compressorHandle, flags, ref outInfo, encodedHandle.AddrOfPinnedObject(), ref inInfo, sourceHandle.AddrOfPinnedObject(), out chunkID, out outFlags, frameIndex, 0, quality, IntPtr.Zero, IntPtr.Zero); CheckICResult(result); frameIndex++; isKeyFrame = (outFlags & VfwApi.AVIIF_KEYFRAME) == VfwApi.AVIIF_KEYFRAME; if (isKeyFrame) { framesFromLastKey = 1; } else { framesFromLastKey++; } return((int)outInfo.ImageSize); } finally { sourceHandle.Free(); encodedHandle.Free(); } }