Example #1
0
        private void EncodePredictedFrame(Stream outStream, BitmapData inputData, BitmapData previousData, int pixelBytes)
        {
            outStream.WriteByte((byte)FrameType.Predicted);

            int xBlocksCount = DivideRoundUp(frameWidth, MCBlockSize);
            int yBlocksCount = DivideRoundUp(frameHeight, MCBlockSize);

            int identicalBlocksCount = 0;
            int translatedBlocksCount = 0;
            int fullBlocksCount = 0;

            for (int yBlock = 0; yBlock < yBlocksCount; yBlock++)
            {
                for (int xBlock = 0; xBlock < xBlocksCount; xBlock++)
                {
                    // absolute position of the block start
                    int yStart = yBlock * MCBlockSize;
                    int xStart = xBlock * MCBlockSize;

                    MotionVector motionVector;
                    bool motionVectorFound = SearchMotionVector(inputData,
                        previousData, pixelBytes, yStart, xStart, out motionVector);

                    if (motionVectorFound)
                    {
                        if ((motionVector.x == 0) && (motionVector.y == 0))
                        {
                            outStream.WriteByte((byte)MCRecordType.Identical);
                            identicalBlocksCount++;
                        }
                        else
                        {
                            // store a record type being a motion vector
                            outStream.WriteByte((byte)MCRecordType.MotionVector);
                            // store the motion vector itself
                            // TODO: store only a difference to the previous motion vector
                            // TODO: it could be possible to store only an index to the vector of
                            // possible motion vectors
                            outStream.WriteSShort(motionVector.x);
                            outStream.WriteSShort(motionVector.y);
                            translatedBlocksCount++;
                        }
                    }
                    else
                    {
                        // store a record type being a full block
                        outStream.WriteByte((byte)MCRecordType.FullBlock);
                        // store the full block contents
                        EncodeFullBlock(outStream, inputData, previousData, pixelBytes, yStart, xStart);
                        fullBlocksCount++;
                    }
                }
            }
            Log("Block counts - identical: {0}, translated: {1}, full: {2}", identicalBlocksCount, translatedBlocksCount, fullBlocksCount);
        }
Example #2
0
        public void EncodeFrame(int frameIndex, Bitmap inputFrame, Stream outStream)
        {
            if ((inputFrame == null) || (outStream == null)) return;

            int width = inputFrame.Width;
            int height = inputFrame.Height;
            if ((width != frameWidth) || (height != frameHeight)) return;

            // frame header: [ MAGIC_FRAME, frameIndex, frameType ]
            outStream.WriteUInt(MAGIC_FRAME);
            outStream.WriteSShort((short)frameIndex);

            BitmapData inputData = inputFrame.LockBits(
                new Rectangle(0, 0, width, height),
                ImageLockMode.ReadOnly, inputFrame.PixelFormat);
            BitmapData previousData = previousFrame.LockBits(
                new Rectangle(0, 0, width, height),
                ImageLockMode.ReadOnly, previousFrame.PixelFormat);

            int pixelBytes = GetBytesPerPixel(inputFrame.PixelFormat);
            if ((frameIndex % IntraFrameFrequency) == 0)
            {
                EncodeIntraFrame(outStream, inputData, pixelBytes);
            }
            else
            {
                EncodePredictedFrame(outStream, inputData, previousData, pixelBytes);
            }

            inputFrame.UnlockBits(inputData);
            previousFrame.UnlockBits(previousData);
            previousFrame.Dispose();

            previousFrame = inputFrame;
        }