using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Drawing = System.Drawing; using Imaging = System.Drawing.Imaging; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content.Pipeline.Graphics; using Scurvy.Media.Avi; using Scurvy.Media.VideoModel; using System.Diagnostics; namespace Scurvy.Media.Pipeline.Video.Avi { internal sealed class AviVideoContent : IVideoContent { #region Fields private string _filename; private AviManager _aviManager; private AviVideoStream _stream; private int _frameCount; private double _frameRate; byte[] pixelBuffer; private PlaybackType _readType; private bool _usecompression; #endregion public AviVideoContent(string filename) { _filename = filename; } #region Properties public IEnumerable Frames { get { if (_aviManager == null) { _aviManager = new AviManager(_filename, true); _stream = _aviManager.GetVideoStream(); _stream.GetFrameOpen(); _frameCount = _stream.CountFrames; _frameRate = _stream.FrameRate; } PlatformSurface surface = PlatformSurface.Create(); for (int i = 0; i < _frameCount; i++) { using (Drawing.Bitmap bitmap = GetFrame(surface, i)) { Texture2DContent c = TranslateBitmap(bitmap); _size = new Vector2(); _size.Y = (float)c.Faces[0][0].Height; _size.X = (float)c.Faces[0][0].Width; yield return c; } } } } public bool UseCompression { get { return _usecompression; } set { _usecompression = value; } } private Drawing.Bitmap GetFrame(PlatformSurface surface, int i) { //Drawing.Bitmap bmp = _stream.GetBitmap(i, Imaging.PixelFormat.Format16bppRgb565); Drawing.Bitmap bmp = _stream.GetBitmap(i, surface.GdiPixelFormat); return bmp; } private Texture2DContent TranslateBitmap(System.Drawing.Bitmap bitmap) { if (this.UseCompression) { bitmap = ResizeBitmap(bitmap, 256, 256); } PlatformSurface surface = PlatformSurface.Create(); Texture2DContent c = new Texture2DContent(); BitmapContent b = surface.FromGdiBitmap(bitmap); c.Faces[0].Add(b); //debugging to determine the color byte order on 360 //Drawing.Graphics g = Drawing.Graphics.FromImage(bitmap); //g.Clear(Drawing.Color.Green); //Drawing.Rectangle rect = new System.Drawing.Rectangle(0,0,bitmap.Width, (int)(bitmap.Height/3)); //g.FillRectangle(new Drawing.SolidBrush(Drawing.Color.Red), rect); //rect.Y = (int)(bitmap.Height / 3); //g.FillRectangle(new Drawing.SolidBrush(Drawing.Color.Green), rect); //rect.Y = (int)(bitmap.Height / 3) * 2; //g.FillRectangle(new Drawing.SolidBrush(Drawing.Color.Blue), rect); //System.Diagnostics.Debugger.Launch(); GetData(bitmap, surface); //throw new Exception(); if (this.UseCompression) { //bitmap = ResizeBitmap(bitmap, 256, 256); b.SetPixelData(pixelBuffer); } else { surface.SetData(b, pixelBuffer); } if (this.UseCompression) { c.ConvertBitmapType(typeof(Dxt1BitmapContent)); } else { c.ConvertBitmapType(typeof(PixelBitmapContent)); } return c; } public Drawing.Bitmap ResizeBitmap(Drawing.Bitmap b, int nWidth, int nHeight) { Drawing.Bitmap result = new Drawing.Bitmap(nWidth, nHeight); using (Drawing.Graphics g = Drawing.Graphics.FromImage((Drawing.Image)result)) g.DrawImage(b, 0, 0, nWidth, nHeight); return result; } private void GetData(Drawing.Bitmap bmp, PlatformSurface surface) { // Lock the bitmap's bits. Drawing.Rectangle rect = new Drawing.Rectangle(0, 0, bmp.Width, bmp.Height); Imaging.BitmapData bmpData = bmp.LockBits(rect, Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat); // Get the address of the first line. IntPtr ptr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. int numBytes = bmp.Width * bmp.Height * surface.SurfaceMultiplier; if (pixelBuffer == null) { pixelBuffer = new byte[numBytes]; } // Copy the RGB values into the array. Marshal.Copy(ptr, pixelBuffer, 0, numBytes); bmp.UnlockBits(bmpData); } private Vector2 _size; public Vector2 Size { get { return _size; } } public double FrameRate { get { return _frameRate; } } public int FrameCount { get { return _frameCount; } } public PlaybackType PlayType { get { return _readType; } set { _readType = value; } } #endregion public void Dispose() { _aviManager.Close(); } } }