private unsafe byte[] EncodePrediction(Bitmap Frame) { //We'll just look if there are blocks that are 100% the same first BitmapData d = Frame.LockBits(new Rectangle(0, 0, Frame.Width, Frame.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); BitmapData prev = PastFrames[1].LockBits(new Rectangle(0, 0, Frame.Width, Frame.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); for (int y = 0; y < Height; y += 16) { for (int x = 0; x < Width; x += 16) { MacroBlocks[y / 16][x / 16] = new MacroBlock(d, x, y); bool same = true; for (int y2 = 0; y2 < 16; y2++) { ulong* pA = (ulong*)(((byte*)d.Scan0) + (y + y2) * d.Stride + x * 4); ulong* pB = (ulong*)(((byte*)prev.Scan0) + (y + y2) * prev.Stride + x * 4); for (int x2 = 0; x2 < 16; x2+=2) { ulong color = *pA++; ulong color2 = *pB++; if (color != color2) { same = false; break; } } if (!same) break; } if (same) MacroBlocks[y / 16][x / 16].Predict = true; else { Analyzer.ConfigureBlockY(this, MacroBlocks[y / 16][x / 16]); int blocktype2 = Analyzer.AnalyzeBlockUV(this, MacroBlocks[y / 16][x / 16]); MacroBlocks[y / 16][x / 16].UVPredictionMode = blocktype2; MacroBlocks[y / 16][x / 16].UVUseComplex8x8[0] = true; MacroBlocks[y / 16][x / 16].UVUseComplex8x8[1] = true; MacroBlocks[y / 16][x / 16].SetupDCTs(this); } } } Frame.UnlockBits(d); PastFrames[1].UnlockBits(prev); BitWriter b = new BitWriter(); b.WriteBits(0, 1);//Interframe b.WriteVarIntSigned(0); for (int y = 0; y < Height; y += 16) { for (int x = 0; x < Width; x += 16) { MacroBlock curblock = MacroBlocks[y / 16][x / 16]; if (curblock.Predict) { b.WriteBits(1, 1); b.WriteVarIntUnsigned(0); } else { b.WriteBits(0xE >> 1, 5); EncodeBlockIntra(curblock, b); } } } b.WriteBits(0, 16); b.Flush(); byte[] result = b.ToArray(); return result; }