Example #1
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.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER();
			int size = Marshal.SizeOf(bih);
			Avi.AVIStreamReadFormat(aviStream, 0, ref bih, ref size);
			Avi.AVISTREAMINFO streamInfo = GetStreamInfo(aviStream);

			FrameRate = (float)streamInfo.dwRate / (float)streamInfo.dwScale;
			Width = (int)streamInfo.rcFrame.right;
			Height = (int)streamInfo.rcFrame.bottom;
			FrameSize = bih.biSizeImage;
			CountBitsPerPixel = bih.biBitCount;
			FirstFrame = Avi.AVIStreamStart(aviStream.ToInt32());
			CountFrames = Avi.AVIStreamLength(aviStream.ToInt32());
		}
Example #2
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() {
			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!"); }
		}
Example #3
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);
			}

			GetStreamInfo(StreamPointer);

			//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
			Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER();
			bih = (Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(dib), bih.GetType());

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

			//copy the image

			byte[] bitmapData;
			int address = dib + Marshal.SizeOf(bih);
			if (bih.biBitCount < 16) {
				//copy palette and pixels
				bitmapData = new byte[bih.biSizeImage + Avi.PALETTE_SIZE];
			} else {
				//copy only pixels
				bitmapData = new byte[bih.biSizeImage];
			}

			Marshal.Copy(new IntPtr(address), bitmapData, 0, bitmapData.Length);

			//copy bitmap info
			byte[] bitmapInfo = new byte[Marshal.SizeOf(bih)];
			IntPtr ptr;
			ptr = Marshal.AllocHGlobal(bitmapInfo.Length);
			Marshal.StructureToPtr(bih, ptr, false);
			address = ptr.ToInt32();
			Marshal.Copy(new IntPtr(address), bitmapInfo, 0, bitmapInfo.Length);

			Marshal.FreeHGlobal(ptr);

			//create file header
			Avi.BITMAPFILEHEADER bfh = new Avi.BITMAPFILEHEADER();
			bfh.bfType = Avi.BMP_MAGIC_COOKIE;
			bfh.bfSize = 55 + bih.biSizeImage; //size of file as written to disk
			bfh.bfReserved1 = 0;
			bfh.bfReserved2 = 0;
			bfh.bfOffBits = Marshal.SizeOf(bih) + Marshal.SizeOf(bfh);
			if (bih.biBitCount < 16) {
				//There is a palette between header and pixel data
				bfh.bfOffBits += 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;
		}
Example #4
0
		/// <summary>Apply a format to a new stream</summary>
		/// <param name="aviStream">The IAVISTREAM</param>
		/// <remarks>
		/// The format must be set before the first frame can be written,
		/// and it cannot be changed later.
		/// </remarks>
		private void SetFormat(IntPtr aviStream) {
			Avi.BITMAPINFOHEADER bi = new Avi.BITMAPINFOHEADER();
			bi.biSize = Marshal.SizeOf(bi);
			bi.biWidth = Width;
			bi.biHeight = Height;
			bi.biPlanes = 1;
			bi.biBitCount = CountBitsPerPixel;
			bi.biSizeImage = FrameSize;

			int result = Avi.AVIStreamSetFormat(aviStream, 0, ref bi, bi.biSize);
			if (result != 0) {
				throw new Exception("Error in VideoStreamSetFormat: " + result);
			}
		}