コード例 #1
0
ファイル: VideoCodec.cs プロジェクト: bzamecnik/grcis
        private unsafe bool SearchMotionVector(BitmapData inputData, BitmapData previousData, int pixelBytes, int yStart, int xStart, out MotionVector motionVector)
        {
            byte* inputPtr = (byte*)inputData.Scan0;
            byte* previousPtr = (byte*)previousData.Scan0;

            motionVector = MotionVector.ZERO;
            // Origin - no translation. This is most probable.
            if (TestMotionVector(inputData, previousData, pixelBytes, yStart, xStart, inputPtr, previousPtr, MotionVector.ZERO))
            {
                return true;
            }

            foreach (MotionVector favouriteVector in favouriteMotionVectors)
            {
                if (TestMotionVector(inputData, previousData, pixelBytes, yStart, xStart, inputPtr, previousPtr, favouriteVector))
                {
                    motionVector = favouriteVector;
                    return true;
                }
            }

            // check possible offsets to find an equal shifted
            // block in the previous frame
            for (int i = 0; i < mcPossibleOffsets.Length; i++)
            {
                motionVector = mcPossibleOffsets[i];
                if (TestMotionVector(inputData, previousData, pixelBytes, yStart, xStart, inputPtr, previousPtr, motionVector))
                {
                    if (!favouriteMotionVectors.Contains(motionVector))
                    {
                        favouriteMotionVectors.AddFirst(motionVector);
                        if (favouriteMotionVectors.Count > MAX_FAVOURITE_MOTION_VECTORS_SIZE)
                        {
                            favouriteMotionVectors.RemoveLast();
                        }
                    }
                    return true;
                }
            }
            return false;
        }
コード例 #2
0
ファイル: VideoCodec.cs プロジェクト: bzamecnik/grcis
 private unsafe bool TestMotionVector(BitmapData inputData, BitmapData previousData, int pixelBytes, int yStart, int xStart, byte* inputPtr, byte* previousPtr, MotionVector motionVector)
 {
     for (int y = yStart; y < yStart + MCBlockSize; y++)
     {
         byte* inputRow = inputPtr + (y * inputData.Stride);
         byte* previousRow = previousPtr + (y * previousData.Stride);
         for (int x = xStart; x < xStart + MCBlockSize; x++)
         {
             int xSource = x + motionVector.x;
             int ySource = y + motionVector.y;
             if ((x < 0) || (x >= frameWidth) ||
                 (y < 0) || (y >= frameHeight) ||
                 (xSource < 0) || (xSource >= frameWidth) ||
                 (ySource < 0) || (ySource >= frameHeight))
             {
                 return false;
             }
             // assume BGRA pixel format
             for (int band = 0; band < 3; band++)
             {
                 int inputIndex = x * pixelBytes + band;
                 int previousIndex = motionVector.y * previousData.Stride + xSource * pixelBytes + band;
                 if (inputRow[inputIndex] != previousRow[previousIndex])
                 {
                     // means: inputFrame[x, y] != previousFrame[xSource, ySource])
                     return false;
                 }
             }
         }
     }
     return true;
 }
コード例 #3
0
ファイル: VideoCodec.cs プロジェクト: bzamecnik/grcis
        private unsafe void DecodeTranslatedBlock(Stream inStream, BitmapData currentData, BitmapData previousData, int pixelBytes, int yStart, int xStart, MotionVector motionVector)
        {
            byte* currentPtr = (byte*)currentData.Scan0;
            byte* previousPtr = (byte*)previousData.Scan0;
            int debugPixelBytes = pixelBytes;
            if (VisualizeMCBlockTypes)
            {
                debugPixelBytes = GetBytesPerPixel(debugFrame.PixelFormat);
            }

            bool isIdenticalBlock = (motionVector.x == 0) && (motionVector.y == 0);

            for (int y = yStart; y < yStart + MCBlockSize; y++)
            {
                byte* currentRow = currentPtr + (y * currentData.Stride);
                byte* previousRow = previousPtr + ((y + motionVector.y) * previousData.Stride);
                byte* debugRow = (byte*)0;
                if (VisualizeMCBlockTypes)
                {
                    debugRow = (byte*)debugFrameData.Scan0 + (y * debugFrameData.Stride);
                }
                for (int x = xStart; x < xStart + MCBlockSize; x++)
                {
                    // assume BGRA input pixel format, store as RGB
                    for (int band = 2; band >= 0; band--)
                    {
                        // temporal prediction
                        int currentIndex = x * pixelBytes + band;
                        int previousIndex = currentIndex + motionVector.x * pixelBytes;
                        currentRow[currentIndex] = previousRow[previousIndex];
                    }
                    if (pixelBytes == 4)
                    {
                        currentRow[x * pixelBytes + 3] = 255; // assume full alpha
                    }
                    if (VisualizeMCBlockTypes)
                    {
                        // identical - green
                        // translated - blue
                        int index = x * debugPixelBytes;
                        debugRow[index] = (byte)((isIdenticalBlock) ? 0 : 255);
                        debugRow[index + 1] = (byte)((isIdenticalBlock) ? 255 : 0);
                        debugRow[index + 2] = 0;
                    }
                }
            }
        }