Example #1
0
        /// <summary>
        /// Consolidate the incoming rows.
        /// Returns true if the buffer has to be flushed, in which case the properties BufferOutput will be valid
        /// and can be used by the caller to raise the FrameProducedEvent.
        /// </summary>
        public bool Consolidate(byte[] buffer)
        {
            if (!enabled)
            {
                throw new InvalidOperationException();
            }

            bool flush         = false;
            int  bytesPerPixel = ImageFormatHelper.BytesPerPixel(imageDescriptor.Format);
            int  stride        = imageDescriptor.Width * bytesPerPixel;

            // Consolidate the current sub-frame.
            Buffer.BlockCopy(buffer, 0, bufferCurrent, row * imageDescriptor.Width * bytesPerPixel, imageDescriptor.Width * bytesPerPixel * consolidationHeight);
            row += consolidationHeight;

            if (waterfallEnabled && (row % waterfallFlushHeight == 0))
            {
                // Flush the current and old image to output in sliding window mode.
                // "section" is at 0 after we grabbed the first section of rows.
                int totalSections = outputHeight / waterfallFlushHeight;

                // Rows are always added to the bottom, so here we continue this pattern.
                // The current image is copied at the bottom, and the old image is copied at the top.
                // We just need to figure out which portion of each image to copy.
                int bufferCurrentSource      = 0;
                int bufferCurrentLength      = (section + 1) * waterfallFlushHeight * stride;
                int bufferCurrentDestination = (totalSections - (section + 1)) * waterfallFlushHeight * stride;
                int bufferOldSource          = bufferCurrentLength;
                int bufferOldLength          = bufferCurrentDestination;
                int bufferOldDestination     = 0;

                Buffer.BlockCopy(bufferCurrent, bufferCurrentSource, bufferOutput, bufferCurrentDestination, bufferCurrentLength);
                Buffer.BlockCopy(bufferOld, bufferOldSource, bufferOutput, bufferOldDestination, bufferOldLength);

                section = (section + 1) % totalSections;

                flush = true;
            }

            if (row >= outputHeight)
            {
                row     = 0;
                section = 0;

                if (!waterfallEnabled)
                {
                    flush = true;
                }

                // Swap buffers.
                byte[] pfBufferTemp = bufferOld;
                bufferOld     = bufferCurrent;
                bufferCurrent = bufferOld;
            }

            return(flush);
        }