/// <summary>Initialize a new VideoStream and add the first frame</summary>
 /// <param name="aviFile">The file that contains the stream</param>
 /// <param name="writeCompressed">true: create a compressed stream before adding frames</param>
 /// <param name="frameRate">Frames per second</param>
 /// <param name="firstFrame">Image to write into the stream as the first frame</param>
 public VideoStream(int aviFile, Avi.AVICOMPRESSOPTIONS compressOptions, double frameRate, Bitmap firstFrame)
 {
     Initialize(aviFile, true, frameRate, firstFrame);
     CreateStream(compressOptions);
     AddFrame(firstFrame);
 }
 /// <summary>Create a new stream</summary>
 private void CreateStream(Avi.AVICOMPRESSOPTIONS options)
 {
     CreateStreamWithoutFormat();
     CreateCompressedStream(options);
 }
        /// <summary>Create a compressed stream from an uncompressed stream</summary>
        private void CreateCompressedStream(Avi.AVICOMPRESSOPTIONS options)
        {
            int result = Avi.AVIMakeCompressedStream(out compressedStream, aviStream, ref options, 0);
            if (result != 0) {
                throw new Exception("Exception in AVIMakeCompressedStream: " + result.ToString());
            }

            this.compressOptions = options;

            SetFormat(compressedStream);
        }
 /// <summary>Copy all properties from one VideoStream to another one</summary>
 /// <remarks>Used by EditableVideoStream</remarks>
 /// <param name="frameSize"></param><param name="frameRate"></param>
 /// <param name="width"></param><param name="height"></param>
 /// <param name="countBitsPerPixel"></param>
 /// <param name="countFrames"></param><param name="compressOptions"></param>
 internal VideoStream(int frameSize, double frameRate, int width, int height, Int16 countBitsPerPixel, int countFrames, Avi.AVICOMPRESSOPTIONS compressOptions, bool writeCompressed)
 {
     this.frameSize = frameSize;
     this.frameRate = frameRate;
     this.width = width;
     this.height = height;
     this.countBitsPerPixel = countBitsPerPixel;
     this.countFrames = countFrames;
     this.compressOptions = compressOptions;
     this.writeCompressed = writeCompressed;
     this.firstFrame = 0;
 }
        /// <summary>Returns all data needed to copy the stream</summary>
        /// <remarks>Do not forget to call Marshal.FreeHGlobal and release the raw data pointer</remarks>
        /// <param name="streamInfo">Receives the header information</param>
        /// <param name="format">Receives the format</param>
        /// <param name="streamLength">Receives the length of the stream</param>
        /// <returns>Pointer to the wave data</returns>
        public IntPtr GetStreamData(ref Avi.AVISTREAMINFO streamInfo, ref Avi.PCMWAVEFORMAT format, ref int streamLength)
        {
            streamInfo = GetStreamInfo();

            format = GetFormat();
            //length in bytes = length in samples * length of a sample
            streamLength = Avi.AVIStreamLength(aviStream.ToInt32()) * streamInfo.dwSampleSize;
            IntPtr waveData = Marshal.AllocHGlobal(streamLength);

            int result = Avi.AVIStreamRead(aviStream, 0, streamLength, waveData, streamLength, 0, 0);
            if(result != 0){
                throw new Exception("Exception in AVIStreamRead: "+result.ToString());
            }

            return waveData;
        }
        /// <summary>Change the AviStreamInfo values and update the frame rate</summary>
        /// <param name="info"></param>
        public void SetInfo(Avi.AVISTREAMINFO info)
        {
            int result = Avi.EditStreamSetInfo(editableStream, ref info, Marshal.SizeOf(info));
            if (result != 0) {
                throw new Exception("Exception in SetInfo: " + result.ToString());
            }

            frameRate = info.dwRate / info.dwScale;
        }