OSDN Git Service

#34198 CAviDS.cs が delete されてしまったため add
authorchnmr0 <chnmr0@16f42ceb-6dc6-49c8-ba94-f2d53467949d>
Thu, 5 Nov 2015 14:09:53 +0000 (14:09 +0000)
committerchnmr0 <chnmr0@16f42ceb-6dc6-49c8-ba94-f2d53467949d>
Thu, 5 Nov 2015 14:09:53 +0000 (14:09 +0000)
git-svn-id: http://svn.osdn.jp/svnroot/dtxmania/trunk@870 16f42ceb-6dc6-49c8-ba94-f2d53467949d

FDK17プロジェクト/コード/04.グラフィック/CAviDS.cs [new file with mode: 0644]

diff --git a/FDK17プロジェクト/コード/04.グラフィック/CAviDS.cs b/FDK17プロジェクト/コード/04.グラフィック/CAviDS.cs
new file mode 100644 (file)
index 0000000..497ee9f
--- /dev/null
@@ -0,0 +1,191 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.Threading.Tasks;\r
+using System.Runtime.InteropServices;\r
+using DirectShowLib;\r
+using DirectShowLib.DES;\r
+using SlimDX;\r
+\r
+namespace FDK\r
+{\r
+       public class CAviDS : IDisposable\r
+       {\r
+               public uint nフレーム高さ\r
+               {\r
+                       get\r
+                       {\r
+                               return (uint)nHeight;\r
+                       }\r
+               }\r
+\r
+               public uint nフレーム幅\r
+               {\r
+                       get\r
+                       {\r
+                               return (uint)nWidth;\r
+                       }\r
+               }\r
+\r
+               int nWidth;\r
+               int nHeight;\r
+               long mediaLength; // [ms]\r
+               VideoInfoHeader videoInfo;\r
+               const int timeOutMs = 1000;\r
+\r
+               public int GetDuration()\r
+               {\r
+                       return (int)(mediaLength / 10000);\r
+               }\r
+\r
+               IGraphBuilder builder;\r
+               ISampleGrabber grabber;\r
+               IMediaControl control;\r
+               IMediaSeeking seeker;\r
+               FilterState state;\r
+               AMMediaType mediaType;\r
+\r
+               public CAviDS(string filename, double playSpeed)\r
+               {\r
+                       int hr = 0x0;\r
+\r
+                       builder = (IGraphBuilder)new FilterGraphNoThread();\r
+\r
+                       #region [Sample Grabber]\r
+                       {\r
+                               grabber = new SampleGrabber() as ISampleGrabber;\r
+                               mediaType = new AMMediaType();\r
+                               mediaType.majorType = MediaType.Video;\r
+                               mediaType.subType = MediaSubType.RGB24;\r
+                               mediaType.formatType = FormatType.VideoInfo;\r
+                               hr = grabber.SetMediaType(mediaType);\r
+                               DsError.ThrowExceptionForHR(hr);\r
+                               hr = builder.AddFilter((IBaseFilter)grabber, "Sample Grabber");\r
+                               DsError.ThrowExceptionForHR(hr);\r
+                       }\r
+                       #endregion\r
+\r
+                       hr = builder.RenderFile(filename, "");\r
+                       DsError.ThrowExceptionForHR(hr);\r
+\r
+                       // Null レンダラに接続しないとウィンドウが表示される。\r
+                       // また、レンダリングを行わないため処理速度を向上できる。\r
+                       CDirectShow.tビデオレンダラをグラフから除去してNullレンダラに接続する(builder);\r
+\r
+                       #region [Video Info]\r
+                       {\r
+                               hr = grabber.GetConnectedMediaType(mediaType);\r
+                               DsError.ThrowExceptionForHR(hr);\r
+\r
+                               videoInfo = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader));\r
+                               nWidth = videoInfo.BmiHeader.Width;\r
+                               nHeight = videoInfo.BmiHeader.Height;\r
+                       }\r
+                       #endregion\r
+\r
+                       #region[ Seeker ]\r
+                       {\r
+                               seeker = builder as IMediaSeeking;\r
+                               hr = seeker.GetDuration(out mediaLength);\r
+                               DsError.ThrowExceptionForHR(hr);\r
+                               hr = seeker.SetRate(playSpeed / 20);\r
+                               DsError.ThrowExceptionForHR(hr);\r
+                       }\r
+                       #endregion\r
+\r
+                       #region [Control]\r
+                       {\r
+                               control = builder as IMediaControl;\r
+                       }\r
+                       #endregion\r
+\r
+                       hr = grabber.SetBufferSamples(true);\r
+                       DsError.ThrowExceptionForHR(hr);\r
+               }\r
+\r
+               public void Seek(int timeInMs)\r
+               {\r
+                       int hr = seeker.SetPositions(new DsLong(timeInMs * 10000), AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning);\r
+                       DsError.ThrowExceptionForHR(hr);\r
+                       hr = control.GetState(timeOutMs, out state); // state is Running\r
+                       DsError.ThrowExceptionForHR(hr);\r
+               }\r
+\r
+               public void Run()\r
+               {\r
+                       int hr = control.Run();\r
+                       DsError.ThrowExceptionForHR(hr);\r
+                       hr = control.GetState(timeOutMs, out state);\r
+                       DsError.ThrowExceptionForHR(hr);\r
+               }\r
+\r
+               public unsafe void tGetBitmap(SlimDX.Direct3D9.Device device, CTexture ctex, int timeMs)\r
+               {\r
+                       IntPtr bufferPtr = IntPtr.Zero;\r
+                       try\r
+                       {\r
+                               int bufferSize = 0;\r
+                               grabber.GetCurrentBuffer(ref bufferSize, IntPtr.Zero);\r
+\r
+                               bufferPtr = Marshal.AllocHGlobal(bufferSize);\r
+                               grabber.GetCurrentBuffer(ref bufferSize, bufferPtr);\r
+\r
+                               byte* sourcePtr = (byte*)bufferPtr.ToPointer();\r
+                               int stride = (nWidth * 3) + ((4 - ((nWidth * 3) % 4)) % 4); // BMP 1行ごとのバイト数 (4の倍数になるように調整)\r
+\r
+                               DataRectangle rectangle3 = ctex.texture.LockRectangle(0, SlimDX.Direct3D9.LockFlags.None);\r
+                               rectangle3.Data.Seek(0, System.IO.SeekOrigin.Begin);\r
+                               uint* outPtr = (uint*)rectangle3.Data.DataPointer.ToPointer();\r
+                               for (int i = 0; i < nHeight; ++i)\r
+                               {\r
+                                       for (int j = 0; j < nWidth; ++j)\r
+                                       {\r
+                                               // 上下反転しつつコピー\r
+                                               byte B = *((sourcePtr + (((nHeight - i) - 1) * stride)) + (j * 3) + 0);\r
+                                               byte G = *((sourcePtr + (((nHeight - i) - 1) * stride)) + (j * 3) + 1);\r
+                                               byte R = *((sourcePtr + (((nHeight - i) - 1) * stride)) + (j * 3) + 2);\r
+                                               *(outPtr + (i * nWidth + j)) = ((uint)R << 16) | ((uint)G << 8) | B;\r
+                                       }\r
+                               }\r
+                               ctex.texture.UnlockRectangle(0);\r
+                       }\r
+                       finally\r
+                       {\r
+                               if (bufferPtr != IntPtr.Zero)\r
+                               {\r
+                                       Marshal.FreeHGlobal(bufferPtr);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               #region [ Dispose-Finalize パターン実装 ]\r
+               public void Dispose()\r
+               {\r
+                       if (!this.bDisposed)\r
+                       {\r
+                               if (null != builder)\r
+                               {\r
+                                       Marshal.ReleaseComObject(builder);\r
+                                       builder = null;\r
+                               }\r
+                               if (null != mediaType)\r
+                               {\r
+                                       DsUtils.FreeAMMediaType(mediaType);\r
+                                       mediaType = null;\r
+                               }\r
+\r
+                               GC.SuppressFinalize(this);\r
+                               this.bDisposed = true;\r
+                       }\r
+               }\r
+\r
+               ~CAviDS()\r
+               {\r
+                       this.Dispose();\r
+               }\r
+               #endregion\r
+\r
+               private bool bDisposed = false;\r
+       }\r
+}\r