private byte[] CompressIframe(Bitmap bitmap) { YCbCr[,] yCbCrs = ColorChannel.ReadYCbCrs(bitmap); YCbCrSubSample yCbCrSubSamples = JPEG.SubSample(yCbCrs); //DCT subquantized // for each channel, run a sperate thread for DCT, quantized, zigzag sampling, and RLE var tasks = new Task[3]; sbyte[,] yQuantized = null, cbQuantized = null, crQuantized = null; tasks[0] = Task.Factory.StartNew(() => { yQuantized = DCTSubQuantized(yCbCrSubSamples.Y, LuminanceQuantizationTable); }); tasks[1] = Task.Factory.StartNew(() => { cbQuantized = DCTSubQuantized(yCbCrSubSamples.Cb, ChrominanceQuantizationTable); }); tasks[2] = Task.Factory.StartNew(() => { crQuantized = DCTSubQuantized(yCbCrSubSamples.Cr, ChrominanceQuantizationTable); }); Task.WaitAll(tasks); // upquantized IDCT, store as frame memory int yHeight = yCbCrSubSamples.Y.GetLength(0), yWidth = yCbCrSubSamples.Y.GetLength(1), cHeight = yCbCrSubSamples.Cb.GetLength(0), cWidth = yCbCrSubSamples.Cb.GetLength(1); tasks[0] = Task.Factory.StartNew(() => { frameMemory.Y = UpQuantizedIDCT(yHeight, yWidth, yQuantized, LuminanceQuantizationTable); }); tasks[1] = Task.Factory.StartNew(() => { frameMemory.Cb = UpQuantizedIDCT(cHeight, cWidth, cbQuantized, ChrominanceQuantizationTable); }); tasks[2] = Task.Factory.StartNew(() => { frameMemory.Cr = UpQuantizedIDCT(cHeight, cWidth, crQuantized, ChrominanceQuantizationTable); }); // zigzag RLE sbyte[] yStream = ZigZagTransform(yQuantized); sbyte[] cbStream = ZigZagTransform(cbQuantized); sbyte[] crStream = ZigZagTransform(crQuantized); // concatennate byte stream var data = new sbyte[yStream.Length + cbStream.Length + crStream.Length]; yStream.CopyTo(data, 0); cbStream.CopyTo(data, yStream.Length); crStream.CopyTo(data, yStream.Length + cbStream.Length); Task.WaitAll(tasks); return(RunLengthEncode(data)); }
private byte[] CompressPframe(Bitmap bitmap) { YCbCr[,] yCbCrs = ColorChannel.ReadYCbCrs(bitmap); YCbCrSubSample yCbCrSubSamples = JPEG.SubSample(yCbCrs); // motion vecotr estimate var mv = new MotionVector(15); EstimateResult vecotrDiffs = mv.Estimate(frameMemory, yCbCrSubSamples); // dct subquantized differences var tasks = new Task[3]; sbyte[,] yQuantized = null, cbQuantized = null, crQuantized = null; tasks[0] = Task.Factory.StartNew(() => { yQuantized = DCTSubQuantized(vecotrDiffs.YDiffs, LuminanceQuantizationTable); }); tasks[1] = Task.Factory.StartNew(() => { cbQuantized = DCTSubQuantized(vecotrDiffs.CbDiffs, ChrominanceQuantizationTable); }); tasks[2] = Task.Factory.StartNew(() => { crQuantized = DCTSubQuantized(vecotrDiffs.CrDiffs, ChrominanceQuantizationTable); }); Task.WaitAll(tasks); //upquantized IDCT, add to frame memory int yHeight = yCbCrSubSamples.Y.GetLength(0), yWidth = yCbCrSubSamples.Y.GetLength(1), cHeight = yCbCrSubSamples.Cb.GetLength(0), cWidth = yCbCrSubSamples.Cb.GetLength(1); tasks[0] = Task.Factory.StartNew(() => { yCbCrSubSamples.Y = UpQuantizedIDCT(yHeight, yWidth, yQuantized, LuminanceQuantizationTable); }); tasks[1] = Task.Factory.StartNew(() => { yCbCrSubSamples.Cb = UpQuantizedIDCT(cHeight, cWidth, cbQuantized, ChrominanceQuantizationTable); }); tasks[2] = Task.Factory.StartNew(() => { yCbCrSubSamples.Cr = UpQuantizedIDCT(cHeight, cWidth, crQuantized, ChrominanceQuantizationTable); }); // zigzag RLE differences sbyte[] yStream = ZigZagTransform(yQuantized); sbyte[] cbStream = ZigZagTransform(cbQuantized); sbyte[] crStream = ZigZagTransform(crQuantized); // concatennate byte stream var data = new sbyte[vecotrDiffs.Vectors.Length * 2 + yStream.Length + cbStream.Length + crStream.Length]; for (int i = 0, j = 0; i < vecotrDiffs.Vectors.Length; ++i) { data[j++] = (sbyte)(vecotrDiffs.Vectors[i].x); data[j++] = (sbyte)(vecotrDiffs.Vectors[i].y); } yStream.CopyTo(data, vecotrDiffs.Vectors.Length * 2); cbStream.CopyTo(data, yStream.Length + vecotrDiffs.Vectors.Length * 2); crStream.CopyTo(data, yStream.Length + cbStream.Length + vecotrDiffs.Vectors.Length * 2); Task.WaitAll(tasks); AddDifferencesToMemoryFrame(yCbCrSubSamples, vecotrDiffs.Vectors); // update frame memory return(RunLengthEncode(data)); }