예제 #1
0
        /// <summary>Add an existing wave audio stream to the file</summary>
        /// <param name="waveData">The new stream's data</param>
        /// <param name="streamInfo">Header info for the new stream</param>
        /// <param name="streamFormat">The new stream' format info</param>
        /// <param name="streamLength">Length of the new stream</param>
        public void AddAudioStream(IntPtr waveData, Avi.AVISTREAMINFO streamInfo, Avi.PCMWAVEFORMAT streamFormat, int streamLength)
        {
            IntPtr aviStream;
            int    result = Avi.AVIFileCreateStream(aviFile, out aviStream, ref streamInfo);

            if (result != 0)
            {
                throw new Exception("Exception in AVIFileCreateStream: " + result.ToString());
            }

            result = Avi.AVIStreamSetFormat(aviStream, 0, ref streamFormat, Marshal.SizeOf(streamFormat));
            if (result != 0)
            {
                throw new Exception("Exception in AVIStreamSetFormat: " + result.ToString());
            }

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

            result = Avi.AVIStreamRelease(aviStream);
            if (result != 0)
            {
                throw new Exception("Exception in AVIStreamRelease: " + result.ToString());
            }
        }
예제 #2
0
        /// <summary>Initialize a VideoStream for an existing stream</summary>
        /// <param name="aviFile">The file that contains the stream</param>
        /// <param name="aviStream">An IAVISTREAM from [aviFile]</param>
        public VideoStream(int aviFile, IntPtr aviStream)
        {
            this.aviFile   = aviFile;
            this.aviStream = aviStream;
            Avi.AVISTREAMINFO streamInfo = GetStreamInfo(aviStream);

            //Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER();
            //int size = Marshal.SizeOf(bih);
            Avi.BITMAPINFO bih  = new Avi.BITMAPINFO();
            int            size = Marshal.SizeOf(bih.bmiHeader);

            Avi.AVIStreamReadFormat(aviStream, 0, ref bih, ref size);

            if (bih.bmiHeader.biBitCount < 24)
            {
                size = Marshal.SizeOf(bih.bmiHeader) + Avi.PALETTE_SIZE;
                Avi.AVIStreamReadFormat(aviStream, 0, ref bih, ref size);
                CopyPalette(bih.bmiColors);
            }

            this.frameRate         = (float)streamInfo.dwRate / (float)streamInfo.dwScale;
            this.width             = (int)streamInfo.rcFrame.right;
            this.height            = (int)streamInfo.rcFrame.bottom;
            this.frameSize         = bih.bmiHeader.biSizeImage;
            this.countBitsPerPixel = bih.bmiHeader.biBitCount;
            this.firstFrame        = Avi.AVIStreamStart(aviStream.ToInt32());
            this.countFrames       = Avi.AVIStreamLength(aviStream.ToInt32());
        }
예제 #3
0
        /// <summary>Copy a piece of video and wave sound int a new file</summary>
        /// <param name="newFileName">File name</param>
        /// <param name="startAtSecond">Start copying at second x</param>
        /// <param name="stopAtSecond">Stop copying at second y</param>
        /// <returns>AviManager for the new video</returns>
        public AviManager CopyTo(String newFileName, float startAtSecond, float stopAtSecond)
        {
            AviManager newFile = new AviManager(newFileName, false);

            try {
                //copy video stream

                VideoStream videoStream = GetVideoStream();

                int startFrameIndex = (int)(videoStream.FrameRate * startAtSecond);
                int stopFrameIndex  = (int)(videoStream.FrameRate * stopAtSecond);

                videoStream.GetFrameOpen();
                Bitmap      bmp       = videoStream.GetBitmap(startFrameIndex);
                VideoStream newStream = newFile.AddVideoStream(false, videoStream.FrameRate, bmp);
                for (int n = startFrameIndex + 1; n <= stopFrameIndex; n++)
                {
                    bmp = videoStream.GetBitmap(n);
                    newStream.AddFrame(bmp);
                }
                videoStream.GetFrameClose();

                //copy audio stream

                AudioStream waveStream = GetWaveStream();

                Avi.AVISTREAMINFO streamInfo   = new Avi.AVISTREAMINFO();
                Avi.PCMWAVEFORMAT streamFormat = new Avi.PCMWAVEFORMAT();
                int    streamLength            = 0;
                IntPtr ptrRawData = waveStream.GetStreamData(
                    ref streamInfo,
                    ref streamFormat,
                    ref streamLength);

                int startByteIndex = (int)(startAtSecond * (float)(waveStream.CountSamplesPerSecond * streamFormat.nChannels * waveStream.CountBitsPerSample) / 8);
                int stopByteIndex  = (int)(stopAtSecond * (float)(waveStream.CountSamplesPerSecond * streamFormat.nChannels * waveStream.CountBitsPerSample) / 8);

                IntPtr ptrWavePart = new IntPtr(ptrRawData.ToInt32() + startByteIndex);

                byte[] rawData = new byte[stopByteIndex - startByteIndex];
                Marshal.Copy(ptrWavePart, rawData, 0, rawData.Length);
                Marshal.FreeHGlobal(ptrRawData);

                streamInfo.dwLength = rawData.Length;
                streamInfo.dwStart  = 0;

                IntPtr unmanagedRawData = Marshal.AllocHGlobal(rawData.Length);
                Marshal.Copy(rawData, 0, unmanagedRawData, rawData.Length);
                newFile.AddAudioStream(unmanagedRawData, streamInfo, streamFormat, rawData.Length);
                Marshal.FreeHGlobal(unmanagedRawData);
            } catch (Exception ex) {
                newFile.Close();
                throw ex;
            }

            return(newFile);
        }
예제 #4
0
        /// <summary>Initialize an AudioStream for an existing stream</summary>
        /// <param name="aviFile">The file that contains the stream</param>
        /// <param name="aviStream">An IAVISTREAM from [aviFile]</param>
        public AudioStream(int aviFile, IntPtr aviStream)
        {
            this.aviFile   = aviFile;
            this.aviStream = aviStream;

            int size = Marshal.SizeOf(waveFormat);

            Avi.AVIStreamReadFormat(aviStream, 0, ref waveFormat, ref size);
            Avi.AVISTREAMINFO streamInfo = GetStreamInfo(aviStream);
        }
예제 #5
0
        /// <summary>Read the stream's header information</summary>
        /// <param name="aviStream">The IAVISTREAM to read from</param>
        /// <returns>AVISTREAMINFO</returns>
        private Avi.AVISTREAMINFO GetStreamInfo(IntPtr aviStream)
        {
            Avi.AVISTREAMINFO streamInfo = new Avi.AVISTREAMINFO();
            int result = Avi.AVIStreamInfo(aviStream, ref streamInfo, Marshal.SizeOf(streamInfo));

            if (result != 0)
            {
                throw new Exception("Exception in AVIStreamInfo: " + result.ToString());
            }
            return(streamInfo);
        }
예제 #6
0
        /// <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;
        }
예제 #7
0
        /// <summary>Prepare for decompressing frames</summary>
        /// <remarks>
        /// This method has to be called before GetBitmap and ExportBitmap.
        /// Release ressources with GetFrameClose.
        /// </remarks>
        public void GetFrameOpen()
        {
            Avi.AVISTREAMINFO streamInfo = GetStreamInfo(StreamPointer);

            //Open frames

            Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER();
            bih.biBitCount      = countBitsPerPixel;
            bih.biClrImportant  = 0;
            bih.biClrUsed       = 0;
            bih.biCompression   = 0;
            bih.biPlanes        = 1;
            bih.biSize          = Marshal.SizeOf(bih);
            bih.biXPelsPerMeter = 0;
            bih.biYPelsPerMeter = 0;

            // Corrections by M. Covington:
            // If these are pre-set, interlaced video is not handled correctly.
            // Better to give zeroes and let Windows fill them in.
            bih.biHeight = 0;            // was (Int32)streamInfo.rcFrame.bottom;
            bih.biWidth  = 0;            // was (Int32)streamInfo.rcFrame.right;

            // Corrections by M. Covington:
            // Validate the bit count, because some AVI files give a bit count
            // that is not one of the allowed values in a BitmapInfoHeader.
            // Here 0 means for Windows to figure it out from other information.
            if (bih.biBitCount > 24)
            {
                bih.biBitCount = 32;
            }
            else if (bih.biBitCount > 16)
            {
                bih.biBitCount = 24;
            }
            else if (bih.biBitCount > 8)
            {
                bih.biBitCount = 16;
            }
            else if (bih.biBitCount > 4)
            {
                bih.biBitCount = 8;
            }
            else if (bih.biBitCount > 0)
            {
                bih.biBitCount = 4;
            }

            getFrameObject = Avi.AVIStreamGetFrameOpen(StreamPointer, ref bih);

            if (getFrameObject == 0)
            {
                throw new Exception("Exception in VideoStreamGetFrameOpen!");
            }
        }
예제 #8
0
        /// <summary>Add an existing wave audio stream to the file</summary>
        /// <param name="newStream">The stream to add</param>
        /// <param name="startAtFrameIndex">
        /// The index of the video frame at which the sound is going to start.
        /// '0' inserts the sound at the beginning of the video.
        /// </param>
        public void AddAudioStream(AudioStream newStream, int startAtFrameIndex)
        {
            Avi.AVISTREAMINFO streamInfo   = new Avi.AVISTREAMINFO();
            Avi.PCMWAVEFORMAT streamFormat = new Avi.PCMWAVEFORMAT();
            int streamLength = 0;

            IntPtr rawData  = newStream.GetStreamData(ref streamInfo, ref streamFormat, ref streamLength);
            IntPtr waveData = rawData;

            if (startAtFrameIndex > 0)
            {
                //not supported
                //streamInfo.dwStart = startAtFrameIndex;

                double framesPerSecond  = GetVideoStream().FrameRate;
                double samplesPerSecond = newStream.CountSamplesPerSecond;
                double startAtSecond    = startAtFrameIndex / framesPerSecond;
                int    startAtSample    = (int)(samplesPerSecond * startAtSecond);

                waveData = InsertSilence(startAtSample - 1, waveData, streamLength, ref streamInfo);
            }

            IntPtr aviStream;
            int    result = Avi.AVIFileCreateStream(aviFile, out aviStream, ref streamInfo);

            if (result != 0)
            {
                throw new Exception("Exception in AVIFileCreateStream: " + result.ToString());
            }

            result = Avi.AVIStreamSetFormat(aviStream, 0, ref streamFormat, Marshal.SizeOf(streamFormat));
            if (result != 0)
            {
                throw new Exception("Exception in AVIStreamSetFormat: " + result.ToString());
            }

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

            result = Avi.AVIStreamRelease(aviStream);
            if (result != 0)
            {
                throw new Exception("Exception in AVIStreamRelease: " + result.ToString());
            }

            Marshal.FreeHGlobal(waveData);
        }
예제 #9
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);
        }
예제 #10
0
        /// <summary>Create a new stream</summary>
        private void CreateStreamWithoutFormat()
        {
            int    scale = 1;
            double rate  = frameRate;

            GetRateAndScale(ref rate, ref scale);

            Avi.AVISTREAMINFO strhdr = new Avi.AVISTREAMINFO();
            strhdr.fccType               = Avi.mmioStringToFOURCC("vids", 0);
            strhdr.fccHandler            = Avi.mmioStringToFOURCC("CVID", 0);
            strhdr.dwFlags               = 0;
            strhdr.dwCaps                = 0;
            strhdr.wPriority             = 0;
            strhdr.wLanguage             = 0;
            strhdr.dwScale               = (int)scale;
            strhdr.dwRate                = (int)rate; // Frames per Second
            strhdr.dwStart               = 0;
            strhdr.dwLength              = 0;
            strhdr.dwInitialFrames       = 0;
            strhdr.dwSuggestedBufferSize = frameSize; //height_ * stride_;
            strhdr.dwQuality             = -1;        //default
            strhdr.dwSampleSize          = 0;
            strhdr.rcFrame.top           = 0;
            strhdr.rcFrame.left          = 0;
            strhdr.rcFrame.bottom        = (uint)height;
            strhdr.rcFrame.right         = (uint)width;
            strhdr.dwEditCount           = 0;
            strhdr.dwFormatChangeCount   = 0;
            strhdr.szName                = new UInt16[64];

            int result = Avi.AVIFileCreateStream(aviFile, out aviStream, ref strhdr);

            if (result != 0)
            {
                throw new Exception("Exception in AVIFileCreateStream: " + result.ToString());
            }
        }
예제 #11
0
        private IntPtr InsertSilence(int countSilentSamples, IntPtr waveData, int lengthWave, ref Avi.AVISTREAMINFO streamInfo)
        {
            //initialize silence
            int lengthSilence = countSilentSamples * streamInfo.dwSampleSize;

            byte[] silence = new byte[lengthSilence];

            //initialize new sound
            int    lengthNewStream = lengthSilence + lengthWave;
            IntPtr newWaveData     = Marshal.AllocHGlobal(lengthNewStream);

            //copy silence
            Marshal.Copy(silence, 0, newWaveData, lengthSilence);

            //copy sound
            byte[] sound = new byte[lengthWave];
            Marshal.Copy(waveData, sound, 0, lengthWave);
            IntPtr startOfSound = new IntPtr(newWaveData.ToInt32() + lengthSilence);

            Marshal.Copy(sound, 0, startOfSound, lengthWave);

            Marshal.FreeHGlobal(newWaveData);

            streamInfo.dwLength = lengthNewStream;
            return(newWaveData);
        }
예제 #12
0
        /// <summary>Export a frame into a bitmap</summary>
        /// <param name="position">Position of the frame</param>
        public Bitmap GetBitmap(int position)
        {
            if (position > countFrames)
            {
                throw new Exception("Invalid frame position: " + position);
            }

            Avi.AVISTREAMINFO streamInfo = GetStreamInfo(StreamPointer);

            Avi.BITMAPINFO bih        = new Avi.BITMAPINFO();
            int            headerSize = Marshal.SizeOf(bih.bmiHeader);

            //Decompress the frame and return a pointer to the DIB
            int dib = Avi.AVIStreamGetFrame(getFrameObject, firstFrame + position);

            //Copy the bitmap header into a managed struct
            bih.bmiColors = this.palette;
            bih.bmiHeader = (Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(dib), bih.bmiHeader.GetType());

            if (bih.bmiHeader.biSizeImage < 1)
            {
                throw new Exception("Exception in VideoStreamGetFrame");
            }

            //copy the image
            int framePaletteSize = bih.bmiHeader.biClrUsed * Avi.RGBQUAD_SIZE;

            byte[] bitmapData = new byte[bih.bmiHeader.biSizeImage];
            IntPtr dibPointer = new IntPtr(dib + Marshal.SizeOf(bih.bmiHeader) + framePaletteSize);

            Marshal.Copy(dibPointer, bitmapData, 0, bih.bmiHeader.biSizeImage);

            //copy bitmap info
            byte[] bitmapInfo = new byte[Marshal.SizeOf(bih)];
            IntPtr ptr        = Marshal.AllocHGlobal(bitmapInfo.Length);

            Marshal.StructureToPtr(bih, ptr, false);
            Marshal.Copy(ptr, bitmapInfo, 0, bitmapInfo.Length);
            Marshal.FreeHGlobal(ptr);

            //create file header
            Avi.BITMAPFILEHEADER bfh = new Avi.BITMAPFILEHEADER();
            bfh.bfType      = Avi.BMP_MAGIC_COOKIE;
            bfh.bfSize      = (Int32)(55 + bih.bmiHeader.biSizeImage);        //size of file as written to disk
            bfh.bfReserved1 = 0;
            bfh.bfReserved2 = 0;
            bfh.bfOffBits   = Marshal.SizeOf(bih) + Marshal.SizeOf(bfh);
            if (bih.bmiHeader.biBitCount < 8)
            {
                //There is a palette between header and pixel data
                bfh.bfOffBits += bih.bmiHeader.biClrUsed * Avi.RGBQUAD_SIZE; //Avi.PALETTE_SIZE;
            }

            //write a bitmap stream
            BinaryWriter bw = new BinaryWriter(new MemoryStream());

            //write header
            bw.Write(bfh.bfType);
            bw.Write(bfh.bfSize);
            bw.Write(bfh.bfReserved1);
            bw.Write(bfh.bfReserved2);
            bw.Write(bfh.bfOffBits);
            //write bitmap info
            bw.Write(bitmapInfo);
            //write bitmap data
            bw.Write(bitmapData);

            Bitmap   bmp            = (Bitmap)Image.FromStream(bw.BaseStream);
            Bitmap   saveableBitmap = new Bitmap(bmp.Width, bmp.Height);
            Graphics g = Graphics.FromImage(saveableBitmap);

            g.DrawImage(bmp, 0, 0);
            g.Dispose();
            bmp.Dispose();

            bw.Close();
            return(saveableBitmap);
        }