示例#1
0
        private void WritePendingFrame(bool forceKeyFrame)
        {
            if (!framePending)
            {
                return;
            }
            framePending = false;

            bool keyFrame = forceKeyFrame || frameCount % keyFramePeriodInFrames == 0;

            FlvWriter.FlvVideoFrameFlags frameFlags = FlvWriter.FlvVideoFrameFlags.Codec_ScreenVideo
                                                      | (keyFrame ? FlvWriter.FlvVideoFrameFlags.Type_KeyFrame : FlvWriter.FlvVideoFrameFlags.Type_InterFrame);

            flvWriter.WriteFlvVideoFrame(frameFlags,
                                         (int)(frameCount * 1000.0 / framesPerSecond),
                                         reserveBytesPerFrame,
                                         delegate(byte[] buffer, ref int bufferOffset)
            {
                // write frame header
                buffer[bufferOffset++] = (byte)(((nominalBlockWidth / 16 - 1) << 4) | (width >> 8));
                buffer[bufferOffset++] = (byte)width;
                buffer[bufferOffset++] = (byte)(((nominalBlockHeight / 16 - 1) << 4) | (height >> 8));
                buffer[bufferOffset++] = (byte)height;

                // proceed from bottom-left to top-right row by row
                for (int blockYOrigin = height; blockYOrigin >= 0; blockYOrigin -= nominalBlockHeight)
                {
                    int blockHeight = Math.Min(blockYOrigin, nominalBlockHeight);

                    for (int blockXOrigin = 0; blockXOrigin < width; blockXOrigin += nominalBlockWidth)
                    {
                        int blockWidth = Math.Min(width - blockXOrigin, nominalBlockWidth);

                        bool diff             = false;
                        int blockBufferOffset = 0;
                        int frameOffset       = blockYOrigin * width + blockXOrigin;
                        for (int y = 0; y < blockHeight; y++)
                        {
                            frameOffset -= width;

                            for (int x = 0; x < blockWidth; x++)
                            {
                                int color = currentFramePixels[frameOffset];

                                blockBuffer[blockBufferOffset++] = (byte)color;         // B
                                blockBuffer[blockBufferOffset++] = (byte)(color >> 8);  // G
                                blockBuffer[blockBufferOffset++] = (byte)(color >> 16); // R

                                if (previousFramePixels[frameOffset++] != color)
                                {
                                    diff = true;
                                }
                            }

                            frameOffset -= blockWidth;
                        }

                        if (keyFrame || diff)
                        {
                            deflater.Reset();
                            deflater.SetInput(blockBuffer, 0, blockBufferOffset);
                            deflater.Finish();

                            int blockLength = deflater.Deflate(buffer, bufferOffset + 2, buffer.Length - bufferOffset - 2);
                            Debug.Assert(deflater.IsFinished, "Deflater should be finished.");

                            buffer[bufferOffset++] = (byte)(blockLength >> 8);
                            buffer[bufferOffset++] = (byte)blockLength;
                            bufferOffset          += blockLength;
                        }
                        else
                        {
                            buffer[bufferOffset++] = 0;
                            buffer[bufferOffset++] = 0;
                        }
                    }
                }
            });

            frameCount += 1;
        }