Ejemplo n.º 1
0
        /// <summary>
        /// Add new frame to the AVI file.
        /// </summary>
        ///
        /// <param name="frameImage">New frame image.</param>
        ///
        /// <remarks><para>The method adds new video frame to an opened video file. The width and heights
        /// of the frame should be the same as it was specified in <see cref="Open"/> method
        /// (see <see cref="Width"/> and <see cref="Height"/> properties).</para></remarks>
        ///
        /// <exception cref="System.IO.IOException">Thrown if no video file was open.</exception>
        /// <exception cref="ArgumentException">Bitmap size must be of the same as video size, which was specified on opening video file.</exception>
        /// <exception cref="VideoException">A error occurred while writing new video frame. See exception message.</exception>
        public void AddFrame(Bitmap frameImage)
        {
            lock (sync)
            {
                // check if AVI file was properly opened
                if (buffer == IntPtr.Zero)
                {
                    throw new IOException("AVI file should be successfully opened before writing.");
                }

                // check image dimension
                if ((frameImage.Width != width) || (frameImage.Height != height))
                {
                    throw new ArgumentException("Bitmap size must be of the same as video size, which was specified on opening video file.");
                }

                // lock bitmap data
                BitmapData imageData = frameImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

                // copy image data
                int srcStride = imageData.Stride;
                int dstStride = stride;

                int src = imageData.Scan0.ToInt32() + srcStride * (height - 1);
                int dst = buffer.ToInt32();

                for (int y = 0; y < height; y++)
                {
                    NativeMethods.memcpy(dst, src, dstStride);
                    dst += dstStride;
                    src -= srcStride;
                }

                // unlock bitmap data
                frameImage.UnlockBits(imageData);

                // write to stream
                if (NativeMethods.AVIStreamWrite(streamCompressed, position, 1, buffer, stride * height, 0, IntPtr.Zero, IntPtr.Zero) != 0)
                {
                    throw new Exception("Failed adding frame.");
                }

                position++;
            }
        }