// Get next video frame public Bitmap GetNextFrame() { // get frame at specified position IntPtr pdib = Win32.AVIStreamGetFrame(getFrame, position); if (pdib == IntPtr.Zero) { throw new ApplicationException("Failed getting frame"); } Win32.BITMAPINFOHEADER bih; // copy BITMAPINFOHEADER from unmanaged memory bih = (Win32.BITMAPINFOHEADER)Marshal.PtrToStructure(pdib, typeof(Win32.BITMAPINFOHEADER)); // create new bitmap Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); // lock bitmap data BitmapData bmData = bmp.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // copy image data int srcStride = bmData.Stride; // width * 3; int dstStride = bmData.Stride; // check image direction if (bih.biHeight > 0) { // it`s a bottom-top image int dst = bmData.Scan0.ToInt32() + dstStride * (height - 1); int src = pdib.ToInt32() + Marshal.SizeOf(typeof(Win32.BITMAPINFOHEADER)); for (int y = 0; y < height; y++) { Win32.memcpy(dst, src, srcStride); dst -= dstStride; src += srcStride; } } else { // it`s a top bootom image int dst = bmData.Scan0.ToInt32(); int src = pdib.ToInt32() + Marshal.SizeOf(typeof(Win32.BITMAPINFOHEADER)); if (srcStride != dstStride) { // copy line by line for (int y = 0; y < height; y++) { Win32.memcpy(dst, src, srcStride); dst += dstStride; src += srcStride; } } else { // copy the whole image Win32.memcpy(dst, src, srcStride * height); } } // unlock bitmap data bmp.UnlockBits(bmData); position++; return(bmp); }