2 using System.Collections.Generic;
\r
5 using System.Threading.Tasks;
\r
6 using System.Runtime.InteropServices;
\r
8 using DirectShowLib.DES;
\r
13 public class CAviDS : IDisposable
\r
19 return (uint)nHeight;
\r
27 return (uint)nWidth;
\r
34 double mediaLength; // in second
\r
35 VideoInfoHeader videoInfo;
\r
38 public int GetDuration()
\r
40 return (int)(1000 * mediaLength);
\r
44 public CAviDS(string filename)
\r
46 // DirectShow による AVI 再生
\r
47 mediaDet = (IMediaDet)new MediaDet();
\r
48 AMMediaType mediaType = null;
\r
49 bufferPtr = IntPtr.Zero;
\r
54 Guid type = Guid.Empty;
\r
56 mediaType = new AMMediaType();
\r
58 // Set media filename
\r
59 mediaDet.put_Filename(filename);
\r
61 // Get the number of streams in that media
\r
62 mediaDet.get_OutputStreams(out nStreams);
\r
63 for (int nIndexStream = 0; nIndexStream < nStreams; ++nIndexStream)
\r
65 mediaDet.put_CurrentStream(nIndexStream);
\r
66 mediaDet.get_StreamType(out type);
\r
67 if (type == MediaType.Video)
\r
69 // This stream is video
\r
74 if (type == MediaType.Video)
\r
76 // Get video info ( width, height, media length (in second)
\r
77 mediaDet.get_StreamMediaType(mediaType);
\r
78 videoInfo = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader));
\r
79 DsUtils.FreeAMMediaType(mediaType);
\r
82 nWidth = videoInfo.BmiHeader.Width;
\r
83 nHeight = videoInfo.BmiHeader.Height;
\r
84 mediaDet.get_StreamLength(out mediaLength);
\r
86 // あらかじめテクスチャ用のメモリを確保
\r
88 mediaDet.GetBitmapBits(1, out bufferSize, IntPtr.Zero, nWidth, nHeight);
\r
89 bufferPtr = Marshal.AllocHGlobal(bufferSize);
\r
94 if (mediaType != null)
\r
96 // free unmanaged resource if the exception is occured while obtaining videoinfo
\r
97 DsUtils.FreeAMMediaType(mediaType);
\r
99 throw new ArgumentException(String.Format("ファイルを正常に開けませんでした。\"{0}\", DirectShow による例外メッセージ: {1}", filename, e.Message));
\r
103 public unsafe void tGetBitmap(SlimDX.Direct3D9.Device device, CTexture ctex, int timeInMs)
\r
106 mediaDet.GetBitmapBits(timeInMs / 1000f, out bufferSize, IntPtr.Zero, nWidth, nHeight);
\r
108 mediaDet.GetBitmapBits(timeInMs / 1000f, out bufferSize, bufferPtr, nWidth, nHeight);
\r
109 byte* sourcePtr = (byte*)bufferPtr.ToPointer() + Marshal.SizeOf(videoInfo.BmiHeader);
\r
110 int nBmpLineByte = (nWidth * 3) + ((4 - ((nWidth * 3) % 4)) % 4);
\r
112 DataRectangle rectangle3 = ctex.texture.LockRectangle(0, SlimDX.Direct3D9.LockFlags.None);
\r
113 rectangle3.Data.Seek(0, System.IO.SeekOrigin.Begin);
\r
114 uint* outPtr = (uint*)rectangle3.Data.DataPointer.ToPointer();
\r
115 for (int i = 0; i < nHeight; ++i)
\r
117 for (int j = 0; j < nWidth; ++j)
\r
119 byte B = *((sourcePtr + (((nHeight - i) - 1) * nBmpLineByte)) + (j * 3) + 0);
\r
120 byte G = *((sourcePtr + (((nHeight - i) - 1) * nBmpLineByte)) + (j * 3) + 1);
\r
121 byte R = *((sourcePtr + (((nHeight - i) - 1) * nBmpLineByte)) + (j * 3) + 2);
\r
122 *(outPtr + (i * nWidth + j)) = ((uint)R << 16) | ((uint)G << 8) | B;
\r
125 ctex.texture.UnlockRectangle(0);
\r
128 #region [ Dispose-Finalize パターン実装 ]
\r
129 //-----------------
\r
130 public void Dispose()
\r
132 if (!this.bDisposed)
\r
134 if (bufferPtr != IntPtr.Zero)
\r
136 Marshal.FreeHGlobal(bufferPtr);
\r
137 bufferPtr = IntPtr.Zero;
\r
139 GC.SuppressFinalize(this); // 2011.8.19 from: 忘れてた。
\r
140 this.bDisposed = true;
\r
148 //-----------------
\r
151 private bool bDisposed = false;
\r