Esempio n. 1
0
        /// <summary>
        /// カメラ制御とビデオ品質制御
        /// </summary>
        public static void Sample14()
        {
            string __FUNCTION__ = MethodBase.GetCurrentMethod().Name;

            Console.WriteLine(__FUNCTION__);

            IGraphBuilder         graph         = null;
            ICaptureGraphBuilder2 builder       = null;
            IBaseFilter           videoSource   = null;
            IBaseFilter           videoGrabber  = null;
            IBaseFilter           videoRenderer = null;
            var videoGrabberCB = new CxSampleGrabberCB();

            try
            {
                #region グラフビルダーの生成:
                {
                    // 必須:
                    graph = (IGraphBuilder)Axi.CoCreateInstance(GUID.CLSID_FilterGraph);
                    if (graph == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }

                    // 任意: 当例に於いては必須ではありませんが、後述のフィルタ接続を簡潔に記述できます.
                    builder = (ICaptureGraphBuilder2)Axi.CoCreateInstance(GUID.CLSID_CaptureGraphBuilder2);
                    if (builder == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }
                    builder.SetFiltergraph(graph);
                }
                #endregion

                #region  像入力用: ソースフィルタを生成します.
                {
                    videoSource = Axi.CreateFilter(GUID.CLSID_VideoInputDeviceCategory, null, 0);
                    if (videoSource == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoSource.");
                    }
                    graph.AddFilter(videoSource, "VideoSource");

                    // フレームサイズを設定します.
                    // ※注) この操作は、ピンを接続する前に行う必要があります.
                    IPin pin = Axi.FindPin(videoSource, 0, PIN_DIRECTION.PINDIR_OUTPUT);
                    Axi.SetFormatSize(pin, 640, 480);
                }
                #endregion

                #region  像捕獲用: サンプルグラバーを生成します.
                {
                    videoGrabber = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_SampleGrabber);
                    if (videoGrabber == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoGrabber.");
                    }
                    graph.AddFilter(videoGrabber, "videoGrabber");

                    // サンプルグラバフィルタの入力形式設定.
                    // SetMediaType で必要なメディア タイプを指定します。
                    //   http://msdn.microsoft.com/ja-jp/library/cc369546.aspx
                    // ※AM_MEDIA_TYPE 構造体のメンバをすべて設定する必要はない。
                    // ※デフォルトでは、サンプル グラバに優先メディア タイプはない。
                    // ※サンプル グラバを正しいフィルタに確実に接続するには、フィルタ グラフを作成する前にこのメソッドを呼び出す。
                    // majortype: http://msdn.microsoft.com/ja-jp/library/cc370108.aspx
                    // subtype  : http://msdn.microsoft.com/ja-jp/library/cc371040.aspx
                    {
                        var grabber = (ISampleGrabber)videoGrabber;

                        var mt = new AM_MEDIA_TYPE();
                        mt.majortype  = new Guid(GUID.MEDIATYPE_Video);
                        mt.subtype    = new Guid(GUID.MEDIASUBTYPE_RGB24);
                        mt.formattype = new Guid(GUID.FORMAT_VideoInfo);
                        grabber.SetMediaType(mt);
                        grabber.SetBufferSamples(false);                                        // サンプルコピー 無効.
                        grabber.SetOneShot(false);                                              // One Shot 無効.
                        //grabber.SetCallback(videoGrabberCB, 0);	// 0:SampleCB メソッドを呼び出すよう指示する.
                        grabber.SetCallback(videoGrabberCB, 1);                                 // 1:BufferCB メソッドを呼び出すよう指示する.
                    }
                }
                #endregion

                #region  像出力用: レンダラーを生成します.
                {
                    videoRenderer = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_NullRenderer);
                    if (videoRenderer == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoRenderer.");
                    }
                    graph.AddFilter(videoRenderer, "videoRenderer");
                }
                #endregion

                #region フィルタの接続:
                if (builder != null)
                {
                    unsafe
                    {
                        var mediatype = new Guid(GUID.MEDIATYPE_Video);
                        var hr        = (HRESULT)builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype), videoSource, videoGrabber, videoRenderer);
                        if (hr < HRESULT.S_OK)
                        {
                            throw new CxDSException(hr);
                        }
                    }
                }
                else
                {
                    // ピンの取得.
                    IPin videoSourceOutput  = Axi.FindPin(videoSource, 0, PIN_DIRECTION.PINDIR_OUTPUT);
                    IPin videoGrabberInput  = Axi.FindPin(videoGrabber, 0, PIN_DIRECTION.PINDIR_INPUT);
                    IPin videoGrabberOutput = Axi.FindPin(videoGrabber, 0, PIN_DIRECTION.PINDIR_OUTPUT);
                    IPin videoRendererInput = Axi.FindPin(videoRenderer, 0, PIN_DIRECTION.PINDIR_INPUT);

                    // ピンの接続.
                    graph.Connect(videoSourceOutput, videoGrabberInput);
                    graph.Connect(videoGrabberOutput, videoRendererInput);
                }
                #endregion

                // ------------------------------

                #region カメラ制御:
                Console.WriteLine("");
                Console.WriteLine("CameraControlProperty");
                {
                    #region 取得:
                    var watch = new Stopwatch();
                    watch.Start();
                    var ranges  = new Dictionary <CameraControlProperty, TxPropertyRange>();
                    var control = Axi.GetInterface <IAMCameraControl>(graph);
                    foreach (CameraControlProperty prop in Enum.GetValues(typeof(CameraControlProperty)))
                    {
                        HRESULT hr;
                        var     range = TxPropertyRange.Reset();

                        try
                        {
                            // レンジの取得.
                            hr = (HRESULT)control.GetRange(
                                prop,
                                ref range.Min,
                                ref range.Max,
                                ref range.SteppingDelta,
                                ref range.DefaultValue,
                                ref range.CapsFlag
                                );
                            if (hr < HRESULT.S_OK)
                            {
                                continue;
                            }

                            // 現在値の取得.
                            hr = (HRESULT)control.Get(
                                prop,
                                ref range.Value,
                                ref range.Flag
                                );
                            if (hr < HRESULT.S_OK)
                            {
                                continue;
                            }

                            range.IsSupported = true;
                        }
                        catch (System.Exception)
                        {
                        }
                        finally
                        {
                            ranges[prop] = range;
                        }
                    }
                    Console.WriteLine("Completed. {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                    #endregion

                    #region 視覚的な確認の為の出力:
                    Console.WriteLine("--- {0,-22}: {1,5}, {2,5}, {3,6}, {4,4}, {5,5} ~ {6,5}",
                                      "Name", "Value", "Def", "Flag", "Step", "Lower", "Upper");

                    foreach (var item in ranges)
                    {
                        var name  = item.Key.ToString();
                        var range = item.Value;
                        if (range.IsSupported)
                        {
                            Console.WriteLine("[O] {0,-22}: {1,5}, {2,5}, 0x{3:X4}, {4,4}, {5,5} ~ {6,5}",
                                              name,
                                              range.Value,
                                              range.DefaultValue,
                                              range.CapsFlag,
                                              range.SteppingDelta,
                                              range.Min,
                                              range.Max
                                              );
                        }
                        else
                        {
                            Console.WriteLine("[-] {0,-22}:", name);
                        }
                    }
                    #endregion
                }
                #endregion

                #region ビデオ品質制御:
                Console.WriteLine("");
                Console.WriteLine("VideoProcAmpProperty");
                {
                    #region 取得:
                    var watch = new Stopwatch();
                    watch.Start();
                    var ranges  = new Dictionary <VideoProcAmpProperty, TxPropertyRange>();
                    var control = Axi.GetInterface <IAMVideoProcAmp>(graph);
                    foreach (VideoProcAmpProperty prop in Enum.GetValues(typeof(VideoProcAmpProperty)))
                    {
                        HRESULT hr;
                        var     range = TxPropertyRange.Reset();

                        try
                        {
                            // レンジ.
                            hr = (HRESULT)control.GetRange(
                                prop,
                                ref range.Min,
                                ref range.Max,
                                ref range.SteppingDelta,
                                ref range.DefaultValue,
                                ref range.CapsFlag
                                );
                            if (hr >= HRESULT.S_OK)
                            {
                                // 現在値.
                                hr = (HRESULT)control.Get(
                                    prop,
                                    ref range.Value,
                                    ref range.Flag
                                    );
                                if (hr >= HRESULT.S_OK)
                                {
                                    range.IsSupported = true;
                                }
                            }
                        }
                        catch (System.Exception)
                        {
                        }

                        ranges[prop] = range;
                    }
                    Console.WriteLine("Completed. {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                    #endregion

                    #region 視覚的な確認の為の出力:
                    Console.WriteLine("--- {0,-22}: {1,5}, {2,5}, {3,6}, {4,4}, {5,5} ~ {6,5}",
                                      "Name", "Value", "Def", "Flag", "Step", "Lower", "Upper");

                    foreach (var item in ranges)
                    {
                        var name  = item.Key.ToString();
                        var range = item.Value;
                        if (range.IsSupported)
                        {
                            Console.WriteLine("[O] {0,-22}: {1,5}, {2,5}, 0x{3:X4}, {4,4}, {5,5} ~ {6,5}",
                                              name,
                                              range.Value,
                                              range.DefaultValue,
                                              range.CapsFlag,
                                              range.SteppingDelta,
                                              range.Min,
                                              range.Max
                                              );
                        }
                        else
                        {
                            Console.WriteLine("[-] {0,-22}:", name);
                        }
                    }
                    #endregion
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("{0}", ex.StackTrace);
            }
            finally
            {
                #region 解放:
                if (videoSource != null)
                {
                    Marshal.ReleaseComObject(videoSource);
                }
                videoSource = null;

                if (videoGrabber != null)
                {
                    Marshal.ReleaseComObject(videoGrabber);
                }
                videoGrabber = null;

                if (videoRenderer != null)
                {
                    Marshal.ReleaseComObject(videoRenderer);
                }
                videoRenderer = null;

                if (builder != null)
                {
                    Marshal.ReleaseComObject(builder);
                }
                builder = null;

                if (graph != null)
                {
                    Marshal.ReleaseComObject(graph);
                }
                graph = null;
                #endregion
            }
        }
Esempio n. 2
0
        /// <summary>
        /// WMV 形式のファイルを読み込む処理
        /// </summary>
        /// <remarks>
        ///		RenderStream (NULL, MEDIATYPE_Video, source, videoGrabber, renderner)<br/>
        ///		RenderStream (NULL, MEDIATYPE_Audio, source, audioGrabber, renderner)<br/>
        ///		<pre>
        ///		 source          grabber          mux        renderner
        ///		+--------+     +---------+     +-------+     +-------+
        ///		|  audio 0 ----0  audio  0 --- 1       0 --- 0       |
        ///		|        |     +---------+     |       |     +-------+
        ///		|        |                     |       |
        ///		|        |     +---------+     |       |
        ///		|  video 1 --- 0  video  0 --- 0       |
        ///		+--------+     +---------+     |       |
        ///		                               2       |
        ///		                               +-------+
        ///		</pre>
        /// </remarks>
        public static void Sample31()
        {
            string __FUNCTION__ = MethodBase.GetCurrentMethod().Name;

            Console.WriteLine(__FUNCTION__);

            IGraphBuilder         graph         = null;
            ICaptureGraphBuilder2 builder       = null;
            IBaseFilter           videoSource   = null;
            IBaseFilter           videoGrabber  = null;
            IBaseFilter           audioGrabber  = null;
            IBaseFilter           videoRenderer = null;
            IBaseFilter           audioRenderer = null;
            var    videoGrabberCB = new CxSampleGrabberCB();
            var    audioGrabberCB = new CxSampleGrabberCB();
            string src_filename   = Path.Combine(TestFiles, "stopwatch_320x240.wmv");

            try
            {
                #region グラフビルダーの生成:
                {
                    graph = (IGraphBuilder)Axi.CoCreateInstance(GUID.CLSID_FilterGraph);
                    if (graph == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }

                    builder = (ICaptureGraphBuilder2)Axi.CoCreateInstance(GUID.CLSID_CaptureGraphBuilder2);
                    if (builder == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }
                    builder.SetFiltergraph(graph);
                }
                #endregion

                #region  像入力用: ソースフィルタを生成します.
                {
#if true
                    graph.AddSourceFilter(src_filename, "VideoSource", ref videoSource);
                    if (videoSource == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoSource.");
                    }
#else
                    videoSource = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_WMAsfReader);
                    if (videoSource == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoSource.");
                    }
                    graph.AddFilter(videoSource, "VideoSource");

                    // Configure the file source filter.
                    var pConfig = (IFileSourceFilter)videoSource;
                    {
                        HRESULT hr = (HRESULT)pConfig.Load(src_filename, IntPtr.Zero);
                        if (hr < HRESULT.S_OK)
                        {
                            throw new System.IO.IOException("Failed to set the src_filename.");
                        }
                    }
#endif
                }
                #endregion

                #region  像捕獲用: サンプルグラバーを生成します.
                {
                    videoGrabber = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_SampleGrabber);
                    if (videoGrabber == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoGrabber.");
                    }
                    graph.AddFilter(videoGrabber, "videoGrabber");

                    // サンプルグラバフィルタの入力形式設定.
                    // SetMediaType で必要なメディア タイプを指定します。
                    //   http://msdn.microsoft.com/ja-jp/library/cc369546.aspx
                    // ※AM_MEDIA_TYPE 構造体のメンバをすべて設定する必要はない。
                    // ※デフォルトでは、サンプル グラバに優先メディア タイプはない。
                    // ※サンプル グラバを正しいフィルタに確実に接続するには、フィルタ グラフを作成する前にこのメソッドを呼び出す。
                    // majortype: http://msdn.microsoft.com/ja-jp/library/cc370108.aspx
                    // subtype  : http://msdn.microsoft.com/ja-jp/library/cc371040.aspx
                    {
                        var grabber = (ISampleGrabber)videoGrabber;

                        var mt = new AM_MEDIA_TYPE();
                        mt.majortype  = new Guid(GUID.MEDIATYPE_Video);
                        mt.subtype    = new Guid(GUID.MEDIASUBTYPE_RGB24);
                        mt.formattype = new Guid(GUID.FORMAT_VideoInfo);
                        grabber.SetMediaType(mt);
                        grabber.SetBufferSamples(false);                                        // サンプルコピー 無効.
                        grabber.SetOneShot(false);                                              // One Shot 無効.
                        //grabber.SetCallback(videoGrabberCB, 0);	// 0:SampleCB メソッドを呼び出すよう指示する.
                        grabber.SetCallback(videoGrabberCB, 1);                                 // 1:BufferCB メソッドを呼び出すよう指示する.
                    }
                }
                #endregion

                #region 音声捕獲用: サンプルグラバーを生成します.
                {
                    audioGrabber = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_SampleGrabber);
                    if (audioGrabber == null)
                    {
                        throw new System.IO.IOException("Failed to create a audioGrabber.");
                    }
                    graph.AddFilter(audioGrabber, "audioGrabber");

                    // サンプルグラバフィルタの入力形式設定.
                    // SetMediaType で必要なメディア タイプを指定します。
                    //   http://msdn.microsoft.com/ja-jp/library/cc369546.aspx
                    // ※AM_MEDIA_TYPE 構造体のメンバをすべて設定する必要はない。
                    // ※デフォルトでは、サンプル グラバに優先メディア タイプはない。
                    // ※サンプル グラバを正しいフィルタに確実に接続するには、フィルタ グラフを作成する前にこのメソッドを呼び出す。
                    // majortype: http://msdn.microsoft.com/ja-jp/library/cc370108.aspx
                    // subtype  : http://msdn.microsoft.com/ja-jp/library/cc371040.aspx
                    {
                        var grabber = (ISampleGrabber)audioGrabber;

                        var mt = new AM_MEDIA_TYPE();
                        mt.majortype  = new Guid(GUID.MEDIATYPE_Audio);
                        mt.subtype    = new Guid(GUID.MEDIASUBTYPE_PCM);
                        mt.formattype = new Guid(GUID.FORMAT_WaveFormatEx);
                        grabber.SetMediaType(mt);
                        grabber.SetBufferSamples(false);                                        // サンプルコピー 無効.
                        grabber.SetOneShot(false);                                              // One Shot 無効.
                        //grabber.SetCallback(audioGrabberCB, 0);	// 0:SampleCB メソッドを呼び出すよう指示する.
                        grabber.SetCallback(audioGrabberCB, 1);                                 // 1:BufferCB メソッドを呼び出すよう指示する.
                    }
                }
                #endregion

                #region  像出力用: レンダラーを生成します.
                {
                    videoRenderer = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_NullRenderer);
                    if (videoRenderer == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoRenderer.");
                    }
                    graph.AddFilter(videoRenderer, "videoRenderer");
                }
                #endregion

                #region 音声出力用: レンダラーを生成します.
                {
                    audioRenderer = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_NullRenderer);
                    if (audioRenderer == null)
                    {
                        throw new System.IO.IOException("Failed to create a audioRenderer.");
                    }
                    graph.AddFilter(audioRenderer, "audioRenderer");
                }
                #endregion

                #region フィルタの接続:
                unsafe
                {
                    HRESULT hr;

                    // フィルタの接続: (映像入力)
                    var mediatype_video = new Guid(GUID.MEDIATYPE_Video);
                    hr = (HRESULT)builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_video), videoSource, videoGrabber, videoRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // フィルタの接続: (音声入力)
                    var mediatype_audio = new Guid(GUID.MEDIATYPE_Audio);
                    hr = (HRESULT)builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_audio), videoSource, audioGrabber, audioRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }
                }
                #endregion

                #region DEBUG: GraphEdit ファイルを保存します.

                /*
                 * 現在のフィルタ構成を指定されたファイル(GRF 拡張子)に保存します。
                 * 保存されたファイルは graphedt.exe (Windws SDK 同梱) で確認できます。
                 */
                try
                {
                    Axi.SaveGraphFile(graph, Path.GetFullPath(__FUNCTION__ + ".GRF"));
                }
                catch (System.Exception ex)
                {
                    Console.WriteLine(ex.StackTrace);
                }
                #endregion

                // ------------------------------

                #region 取り込み処理:
                {
                    var mediaControl = (IMediaControl)graph;
                    var mediaEvent   = (IMediaEvent)graph;
                    var mediaSeeking = (IMediaSeeking)graph;

                    // 映像サイズの取得.
                    var vih    = Axi.GetVideoInfo((ISampleGrabber)videoGrabber);
                    var images = new List <Bitmap>();

                    var watch = new Stopwatch();
                    watch.Start();

                    // 取り込み処理.
                    videoGrabberCB.Notify += delegate(object _sender, CxSampleGrabberEventArgs _e)
                    {
                        Console.WriteLine("{0}: SampleTime={1:F6}", images.Count, _e.SampleTime);
                        images.Add(_e.ToImage(vih));
                    };

                    // 再生.
                    Console.WriteLine("Run ...");
                    {
                        HRESULT hr;
                        int     state;
                        hr = (HRESULT)mediaControl.Run();
                        hr = (HRESULT)mediaControl.GetState(1000, out state);
                    }
                    Console.WriteLine("Running ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);

                    // 再生が完了するまで待機する.
                    {
                        HRESULT hr;
                        int     code;
                        hr = (HRESULT)mediaEvent.WaitForCompletion(-1, out code);
                        hr = (HRESULT)mediaControl.Stop();
                    }

                    // 確認用:
                    Console.WriteLine("Save ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                    {
                        string subdir = Path.Combine(Results, __FUNCTION__);
                        if (Directory.Exists(subdir) == false)
                        {
                            Directory.CreateDirectory(subdir);
                        }

                        for (int i = 0; i < images.Count; i++)
                        {
                            var filename = string.Format("image{0}.png", i);
                            images[i].Save(Path.Combine(subdir, filename));
                        }
                    }

                    Console.WriteLine("Completed. {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("{0}", ex.StackTrace);
            }
            finally
            {
                #region 解放:
                if (videoSource != null)
                {
                    Marshal.ReleaseComObject(videoSource);
                }
                videoSource = null;

                if (videoGrabber != null)
                {
                    Marshal.ReleaseComObject(videoGrabber);
                }
                videoGrabber = null;

                if (audioGrabber != null)
                {
                    Marshal.ReleaseComObject(audioGrabber);
                }
                audioGrabber = null;

                if (videoRenderer != null)
                {
                    Marshal.ReleaseComObject(videoRenderer);
                }
                videoRenderer = null;

                if (audioRenderer != null)
                {
                    Marshal.ReleaseComObject(audioRenderer);
                }
                audioRenderer = null;

                if (builder != null)
                {
                    Marshal.ReleaseComObject(builder);
                }
                builder = null;

                if (graph != null)
                {
                    Marshal.ReleaseComObject(graph);
                }
                graph = null;
                #endregion
            }
        }
Esempio n. 3
0
        /// <summary>
        /// プレイヤーの接続
        /// </summary>
        /// <param name="filename"></param>
        private void Player_Connect(string filename)
        {
            #region グラフビルダーの生成:
            {
                Graph = (IGraphBuilder)Axi.CoCreateInstance(GUID.CLSID_FilterGraph);
                if (Graph == null)
                {
                    throw new System.IO.IOException("Failed to create a GraphBuilder.");
                }

                Builder = (ICaptureGraphBuilder2)Axi.CoCreateInstance(GUID.CLSID_CaptureGraphBuilder2);
                if (Builder == null)
                {
                    throw new System.IO.IOException("Failed to create a GraphBuilder.");
                }
                Builder.SetFiltergraph(Graph);
            }
            #endregion

            #region  像入力用: ソースフィルタを生成します.
            {
                Graph.AddSourceFilter(filename, "VideoSource", ref VideoSource);
                if (VideoSource == null)
                {
                    throw new System.IO.IOException("Failed to create a VideoSource.");
                }
            }
            #endregion

            #region  像捕獲用: サンプルグラバーを生成します.
            {
                VideoGrabber = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_SampleGrabber);
                if (VideoGrabber == null)
                {
                    throw new System.IO.IOException("Failed to create a VideoGrabber.");
                }
                Graph.AddFilter(VideoGrabber, "VideoGrabber");

                // サンプルグラバフィルタの入力形式設定.
                // SetMediaType で必要なメディア タイプを指定します。
                //   http://msdn.microsoft.com/ja-jp/library/cc369546.aspx
                // ※AM_MEDIA_TYPE 構造体のメンバをすべて設定する必要はない。
                // ※デフォルトでは、サンプル グラバに優先メディア タイプはない。
                // ※サンプル グラバを正しいフィルタに確実に接続するには、フィルタ グラフを作成する前にこのメソッドを呼び出す。
                // majortype: http://msdn.microsoft.com/ja-jp/library/cc370108.aspx
                // subtype  : http://msdn.microsoft.com/ja-jp/library/cc371040.aspx
                {
                    var grabber = (ISampleGrabber)VideoGrabber;

                    var mt = new AM_MEDIA_TYPE();
                    mt.majortype  = new Guid(GUID.MEDIATYPE_Video);
                    mt.subtype    = new Guid(GUID.MEDIASUBTYPE_RGB24);
                    mt.formattype = new Guid(GUID.FORMAT_VideoInfo);
                    grabber.SetMediaType(mt);
                    grabber.SetBufferSamples(false);                                    // サンプルコピー 無効.
                    grabber.SetOneShot(false);                                          // One Shot 無効.
                    //grabber.SetCallback(VideoGrabberCB, 0);	// 0:SampleCB メソッドを呼び出すよう指示する.
                    grabber.SetCallback(VideoGrabberCB, 1);                             // 1:BufferCB メソッドを呼び出すよう指示する.
                }
            }
            #endregion

            #region 音声捕獲用: サンプルグラバーを生成します.
            {
                AudioGrabber = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_SampleGrabber);
                if (AudioGrabber == null)
                {
                    throw new System.IO.IOException("Failed to create a AudioGrabber.");
                }
                Graph.AddFilter(AudioGrabber, "AudioGrabber");

                // サンプルグラバフィルタの入力形式設定.
                // SetMediaType で必要なメディア タイプを指定します。
                //   http://msdn.microsoft.com/ja-jp/library/cc369546.aspx
                // ※AM_MEDIA_TYPE 構造体のメンバをすべて設定する必要はない。
                // ※デフォルトでは、サンプル グラバに優先メディア タイプはない。
                // ※サンプル グラバを正しいフィルタに確実に接続するには、フィルタ グラフを作成する前にこのメソッドを呼び出す。
                // majortype: http://msdn.microsoft.com/ja-jp/library/cc370108.aspx
                // subtype  : http://msdn.microsoft.com/ja-jp/library/cc371040.aspx
                {
                    var grabber = (ISampleGrabber)AudioGrabber;

                    var mt = new AM_MEDIA_TYPE();
                    mt.majortype  = new Guid(GUID.MEDIATYPE_Audio);
                    mt.subtype    = new Guid(GUID.MEDIASUBTYPE_PCM);
                    mt.formattype = new Guid(GUID.FORMAT_WaveFormatEx);
                    grabber.SetMediaType(mt);
                    grabber.SetBufferSamples(false);                                    // サンプルコピー 無効.
                    grabber.SetOneShot(false);                                          // One Shot 無効.
                    //grabber.SetCallback(AudioGrabberCB, 0);	// 0:SampleCB メソッドを呼び出すよう指示する.
                    grabber.SetCallback(AudioGrabberCB, 1);                             // 1:BufferCB メソッドを呼び出すよう指示する.
                }
            }
            #endregion

            #region  像出力用: レンダラーを生成します.
            {
                VideoRenderer = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_NullRenderer);
                if (VideoRenderer == null)
                {
                    throw new System.IO.IOException("Failed to create a VideoRenderer.");
                }
                Graph.AddFilter(VideoRenderer, "VideoRenderer");
            }
            #endregion

            #region 音声出力用: レンダラーを生成します.
            {
                AudioRenderer = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_NullRenderer);
                if (AudioRenderer == null)
                {
                    throw new System.IO.IOException("Failed to create a AudioRenderer.");
                }
                Graph.AddFilter(AudioRenderer, "AudioRenderer");
            }
            #endregion

            #region フィルタの接続:
            if (filename.EndsWith(".avi", StringComparison.InvariantCultureIgnoreCase))
            {
                #region AVI 形式ファイル用の初期化:
                unsafe
                {
                    HRESULT hr;

                    // AVI 分離器の追加:
                    Splitter = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_AviSplitter);
                    if (Splitter == null)
                    {
                        throw new System.IO.IOException("Failed to create a Splitter.");
                    }
                    Graph.AddFilter(Splitter, "Splitter");

                    // フィルタの接続: (AVI 分離器)
                    hr = (HRESULT)Builder.RenderStream(IntPtr.Zero, IntPtr.Zero, VideoSource, null, Splitter);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // フィルタの接続: (映像入力)
                    var mediatype_video = new Guid(GUID.MEDIATYPE_Video);
                    hr = (HRESULT)Builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_video), Splitter, VideoGrabber, VideoRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // フィルタの接続: (音声入力) ※ Audioless も有る.
                    try
                    {
                        var mediatype_audio = new Guid(GUID.MEDIATYPE_Audio);
                        hr = (HRESULT)Builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_audio), Splitter, AudioGrabber, AudioRenderer);
                    }
                    catch (System.Exception ex)
                    {
                        Debug.WriteLine(ex.StackTrace);
                    }
                }
                #endregion
            }
            else if (
                filename.EndsWith(".asf", StringComparison.InvariantCultureIgnoreCase) ||
                filename.EndsWith(".wmv", StringComparison.InvariantCultureIgnoreCase))
            {
                #region WMV 形式ファイル用の初期化:
                unsafe
                {
                    HRESULT hr;

                    // フィルタの接続: (映像入力)
                    var mediatype_video = new Guid(GUID.MEDIATYPE_Video);
                    hr = (HRESULT)Builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_video), VideoSource, VideoGrabber, VideoRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // フィルタの接続: (音声入力)
                    var mediatype_audio = new Guid(GUID.MEDIATYPE_Audio);
                    hr = (HRESULT)Builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_audio), VideoSource, AudioGrabber, AudioRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }
                }
                #endregion
            }
            #endregion

            // 同期用: サンプルグラバーのイベント登録:
            VideoGrabberCB.Enable  = true;
            VideoGrabberCB.Notify += VideoGrabberCB_Notify;
            VideoInfoHeader        = Axi.GetVideoInfo((ISampleGrabber)VideoGrabber);
        }
Esempio n. 4
0
        /// <summary>
        /// AVI 形式のファイルを読み込み、WMV 形式のファイルに保存する処理
        /// </summary>
        /// <remarks>
        ///		RenderStream (NULL, NULL, source, null, splitter)<br/>
        ///		RenderStream (NULL, MEDIATYPE_Video, splitter, grabber, renderner)<br/>
        ///		RenderStream (NULL, MEDIATYPE_Audio, splitter, null, renderner)<br/>
        ///		<pre>
        ///		 source        splitter        grabber       renderner
        ///		+-------+     +--------+     +---------+     +-------+
        ///		|       0 --- 0  video 0 --- 0  video  0 --- 1       |
        ///		|       |     |        |     +---------+     |       |
        ///		|       |     |        |                     |       |
        ///		|       |     |        |     +---------+     |       |
        ///		|       |     |  audio 1 --- 0  audio  0 --- 0       |
        ///		+-------+     +--------+     +---------+     +-------+
        ///		</pre>
        ///		※ 本例では grabber は省略しています。<br/>
        /// </remarks>
        public static void Sample22()
        {
            string __FUNCTION__ = MethodBase.GetCurrentMethod().Name;

            Console.WriteLine(__FUNCTION__);

            IGraphBuilder         graph         = null;
            ICaptureGraphBuilder2 builder       = null;
            IBaseFilter           videoSource   = null;
            IBaseFilter           aviSplitter   = null;
            IBaseFilter           videoGrabber  = null;
            IBaseFilter           videoRenderer = null;
            IFileSinkFilter       fileSink      = null;
            var    videoGrabberCB = new CxSampleGrabberCB();
            string src_filename   = Path.Combine(TestFiles, "stopwatch_320x240.avi");
            string dst_filename   = Path.Combine(Results, __FUNCTION__ + ".wmv");

            try
            {
                #region グラフビルダーの生成:
                {
                    graph = (IGraphBuilder)Axi.CoCreateInstance(GUID.CLSID_FilterGraph);
                    if (graph == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }

                    builder = (ICaptureGraphBuilder2)Axi.CoCreateInstance(GUID.CLSID_CaptureGraphBuilder2);
                    if (builder == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }
                    builder.SetFiltergraph(graph);
                }
                #endregion

                #region  像入力用: ソースフィルタを生成します.
                {
                    graph.AddSourceFilter(src_filename, "VideoSource", ref videoSource);
                    if (videoSource == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoSource.");
                    }

                    aviSplitter = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_AviSplitter);
                    if (aviSplitter == null)
                    {
                        throw new System.IO.IOException("Failed to create a aviSplitter.");
                    }
                    graph.AddFilter(aviSplitter, "aviSplitter");
                }
                #endregion

                #region  像捕獲用: サンプルグラバーを生成します.
                {
                    videoGrabber = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_SampleGrabber);
                    if (videoGrabber == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoGrabber.");
                    }
                    graph.AddFilter(videoGrabber, "videoGrabber");

                    // サンプルグラバフィルタの入力形式設定.
                    // SetMediaType で必要なメディア タイプを指定します。
                    //   http://msdn.microsoft.com/ja-jp/library/cc369546.aspx
                    // ※AM_MEDIA_TYPE 構造体のメンバをすべて設定する必要はない。
                    // ※デフォルトでは、サンプル グラバに優先メディア タイプはない。
                    // ※サンプル グラバを正しいフィルタに確実に接続するには、フィルタ グラフを作成する前にこのメソッドを呼び出す。
                    // majortype: http://msdn.microsoft.com/ja-jp/library/cc370108.aspx
                    // subtype  : http://msdn.microsoft.com/ja-jp/library/cc371040.aspx
                    {
                        var grabber = (ISampleGrabber)videoGrabber;

                        var mt = new AM_MEDIA_TYPE();
                        mt.majortype  = new Guid(GUID.MEDIATYPE_Video);
                        mt.subtype    = new Guid(GUID.MEDIASUBTYPE_RGB24);
                        mt.formattype = new Guid(GUID.FORMAT_VideoInfo);
                        grabber.SetMediaType(mt);
                        grabber.SetBufferSamples(false);                                        // サンプルコピー 無効.
                        grabber.SetOneShot(false);                                              // One Shot 無効.
                        //grabber.SetCallback(videoGrabberCB, 0);	// 0:SampleCB メソッドを呼び出すよう指示する.
                        grabber.SetCallback(videoGrabberCB, 1);                                 // 1:BufferCB メソッドを呼び出すよう指示する.
                    }
                }
                #endregion

                #region  像出力用: 保存する動画ファイル名を設定します.
                unsafe
                {
                    HRESULT hr;

                    // 動画ファイルを保存する設定:
                    var filetype = new Guid(GUID.MEDIASUBTYPE_Asf);
                    hr = (HRESULT)builder.SetOutputFileName(new IntPtr(&filetype), dst_filename, ref videoRenderer, ref fileSink);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    /*
                     * Capturing Video to a Windows Media File
                     * https://msdn.microsoft.com/en-us/library/windows/desktop/dd318630(v=vs.85).aspx
                     */
                    var config = (IConfigAsfWriter)videoRenderer;

                    // WMProfile
                    {
                        // WMProfile_V80_256Video が取得されます.
                        Guid currentProfileGuid;
                        hr = (HRESULT)config.GetCurrentProfileGuid(out currentProfileGuid);
                        if (hr < HRESULT.S_OK)
                        {
                            throw new CxDSException(hr);
                        }

                        // WMProfile_V80_BESTVBRVideo に書き替えます.
                        Guid newProfileGuid = new Guid(GUID.WMProfile_V80_BESTVBRVideo);
                        hr = (HRESULT)config.ConfigureFilterUsingProfileGuid(newProfileGuid);
                        if (hr < HRESULT.S_OK)
                        {
                            throw new CxDSException(hr);
                        }
                    }
                }
                #endregion

                #region フィルタの接続:
                unsafe
                {
                    HRESULT hr;

                    // フィルタの接続: (AVI 分離器)
                    hr = (HRESULT)builder.RenderStream(IntPtr.Zero, IntPtr.Zero, videoSource, null, aviSplitter);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // フィルタの接続: (映像入力)
                    var mediatype_video = new Guid(GUID.MEDIATYPE_Video);
                    hr = (HRESULT)builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_video), aviSplitter, videoGrabber, videoRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // フィルタの接続: (音声入力)
                    var mediatype_audio = new Guid(GUID.MEDIATYPE_Audio);
                    hr = (HRESULT)builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_audio), aviSplitter, null, videoRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }
                }
                #endregion

                #region  像出力用: 保存する動画ファイルのフレームサイズを設定します.
                unsafe
                {
                    /*
                     * Capturing Video to a Windows Media File
                     * https://msdn.microsoft.com/en-us/library/windows/desktop/dd318630(v=vs.85).aspx
                     */
                    var config = (IConfigAsfWriter)videoRenderer;

                    // フレームサイズの取得:
                    var vih       = Axi.GetVideoInfo((ISampleGrabber)videoGrabber);
                    var frameSize = new Size(vih.bmiHeader.biWidth, vih.bmiHeader.biHeight);

                    // フレームサイズの変更:
                    Axi.SetVideoFrameSize(config, frameSize);
                }
                #endregion

                #region DEBUG: GraphEdit ファイルを保存します.

                /*
                 * 現在のフィルタ構成を指定されたファイル(GRF 拡張子)に保存します。
                 * 保存されたファイルは graphedt.exe (Windws SDK 同梱) で確認できます。
                 */
                try
                {
                    Axi.SaveGraphFile(graph, Path.GetFullPath(__FUNCTION__ + ".GRF"));
                }
                catch (System.Exception ex)
                {
                    Console.WriteLine(ex.StackTrace);
                }
                #endregion

                // ------------------------------

                #region 取り込み処理:
                {
                    var mediaControl = (IMediaControl)graph;
                    var mediaEvent   = (IMediaEvent)graph;
                    var mediaSeeking = (IMediaSeeking)graph;

                    var watch = new Stopwatch();
                    watch.Start();

                    // 再生.
                    Console.WriteLine("Run ...");
                    {
                        HRESULT hr;
                        int     state;
                        hr = (HRESULT)mediaControl.Run();
                        hr = (HRESULT)mediaControl.GetState(1000, out state);
                    }
                    Console.WriteLine("Running ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);

                    // 再生が完了するまで待機する.
                    {
                        HRESULT hr;
                        int     code;
                        hr = (HRESULT)mediaEvent.WaitForCompletion(-1, out code);
                        hr = (HRESULT)mediaControl.Stop();
                    }

                    Console.WriteLine("Completed. {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("{0}", ex.StackTrace);
            }
            finally
            {
                #region 解放:
                if (videoSource != null)
                {
                    Marshal.ReleaseComObject(videoSource);
                }
                videoSource = null;

                if (aviSplitter != null)
                {
                    Marshal.ReleaseComObject(aviSplitter);
                }
                aviSplitter = null;

                if (videoRenderer != null)
                {
                    Marshal.ReleaseComObject(videoRenderer);
                }
                videoRenderer = null;

                if (fileSink != null)
                {
                    Marshal.ReleaseComObject(fileSink);
                }
                fileSink = null;

                if (builder != null)
                {
                    Marshal.ReleaseComObject(builder);
                }
                builder = null;

                if (graph != null)
                {
                    Marshal.ReleaseComObject(graph);
                }
                graph = null;
                #endregion
            }
        }
Esempio n. 5
0
        /// <summary>
        /// カメラから画像を取り込み、動画ファイル(wmv)へ保存する処理
        /// </summary>
        /// <remarks>
        ///		WMV 形式で保存する場合は映像と音声の両方が必要です。<br/>
        ///		<br/>
        ///		RenderStream (NULL, MEDIATYPE_Audio, audio, null, renderner)<br/>
        ///		RenderStream (NULL, MEDIATYPE_Video, video, grabber, renderner)<br/>
        ///		<pre>
        ///		 audio                       renderer
        ///		+-------+                   +-------+
        ///		|       0 ----------------- 0       |
        ///		+-------+                   |       |
        ///		 video         grabber      |       |
        ///		+-------+     +-------+     |       |
        ///		|       0 --- 0       0 --- 1       |
        ///		|       1     |       |     +-------+
        ///		+-------+     +-------+
        ///		</pre>
        ///		※ 本例では grabber は省略しています。<br/>
        /// </remarks>
        public static void Sample13()
        {
            string __FUNCTION__ = MethodBase.GetCurrentMethod().Name;

            Console.WriteLine(__FUNCTION__);

            IGraphBuilder         graph         = null;
            ICaptureGraphBuilder2 builder       = null;
            IBaseFilter           videoSource   = null;
            IBaseFilter           audioSource   = null;
            IBaseFilter           videoRenderer = null;
            IFileSinkFilter       fileSink      = null;
            string filename  = Path.Combine(Results, __FUNCTION__ + ".wmv");
            var    frameSize = new Size(640, 480);

            try
            {
                #region グラフビルダーの生成:
                {
                    graph = (IGraphBuilder)Axi.CoCreateInstance(GUID.CLSID_FilterGraph);
                    if (graph == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }

                    builder = (ICaptureGraphBuilder2)Axi.CoCreateInstance(GUID.CLSID_CaptureGraphBuilder2);
                    if (builder == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }
                    builder.SetFiltergraph(graph);
                }
                #endregion

                #region  像入力用: ソースフィルタを生成します.
                {
                    videoSource = Axi.CreateFilter(GUID.CLSID_VideoInputDeviceCategory, null, 0);
                    if (videoSource == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoSource.");
                    }
                    graph.AddFilter(videoSource, "VideoSource");

                    // フレームサイズを設定します.
                    // ※注) この操作は、ピンを接続する前に行う必要があります.
                    IPin pin = Axi.FindPin(videoSource, 0, PIN_DIRECTION.PINDIR_OUTPUT);
                    Axi.SetFormatSize(pin, frameSize.Width, frameSize.Height);
                }
                #endregion

                #region 音声入力用: ソースフィルタを生成します.
                {
                    audioSource = Axi.CreateFilter(GUID.CLSID_AudioInputDeviceCategory, null, 0);
                    if (audioSource == null)
                    {
                        throw new System.IO.IOException("Failed to create a audioSource.");
                    }
                    graph.AddFilter(audioSource, "audioSource");
                }
                #endregion

                #region  像出力用: 保存する動画ファイル名を設定します.
                unsafe
                {
                    // 動画ファイルを保存する設定:
                    var     filetype = new Guid(GUID.MEDIASUBTYPE_Asf);
                    HRESULT hr       = (HRESULT)builder.SetOutputFileName(new IntPtr(&filetype), filename, ref videoRenderer, ref fileSink);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    /*
                     * Capturing Video to a Windows Media File
                     * https://msdn.microsoft.com/en-us/library/windows/desktop/dd318630(v=vs.85).aspx
                     */
                    var config = (IConfigAsfWriter)videoRenderer;

                    // WMProfile
                    {
                        // WMProfile_V80_256Video が取得されます.
                        Guid currentProfileGuid;
                        hr = (HRESULT)config.GetCurrentProfileGuid(out currentProfileGuid);
                        if (hr < HRESULT.S_OK)
                        {
                            throw new CxDSException(hr);
                        }

                        // WMProfile_V80_BESTVBRVideo に書き替えます.
                        Guid newProfileGuid = new Guid(GUID.WMProfile_V80_BESTVBRVideo);
                        hr = (HRESULT)config.ConfigureFilterUsingProfileGuid(newProfileGuid);
                        if (hr < HRESULT.S_OK)
                        {
                            throw new CxDSException(hr);
                        }
                    }
                }
                #endregion

                #region フィルタの接続:
                unsafe
                {
                    HRESULT hr;

                    // フィルタの接続: (映像入力)
                    var mediatype_video = new Guid(GUID.MEDIATYPE_Video);
                    hr = (HRESULT)builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_video), videoSource, null, videoRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // フィルタの接続: (音声入力)
                    var mediatype_audio = new Guid(GUID.MEDIATYPE_Audio);
                    hr = (HRESULT)builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype_audio), audioSource, null, videoRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }
                }
                #endregion

                #region  像出力用: 保存する動画ファイルのフレームサイズを設定します.
                unsafe
                {
                    /*
                     * Capturing Video to a Windows Media File
                     * https://msdn.microsoft.com/en-us/library/windows/desktop/dd318630(v=vs.85).aspx
                     */
                    var config = (IConfigAsfWriter)videoRenderer;

                    // フレームサイズの変更:
                    Axi.SetVideoFrameSize(config, frameSize);
                }
                #endregion

                // ------------------------------

                #region 取り込み処理:
                {
                    var mediaControl = (IMediaControl)graph;
                    var mediaEvent   = (IMediaEvent)graph;

                    var watch = new Stopwatch();
                    watch.Start();

                    // 露光開始.
                    Console.WriteLine("Run ...");
                    {
                        HRESULT hr;
                        int     state;
                        hr = (HRESULT)mediaControl.Run();
                        hr = (HRESULT)mediaControl.GetState(1000, out state);
                    }
                    Console.WriteLine("Running ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);

                    // 取り込み待機.
                    while (watch.ElapsedMilliseconds < 5000)
                    {
                        System.Threading.Thread.Sleep(1);
                    }

                    // 露光停止.
                    Console.WriteLine("Stop ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                    {
                        HRESULT hr;
                        int     state;
                        hr = (HRESULT)mediaControl.Stop();
                        hr = (HRESULT)mediaControl.GetState(1000, out state);
                    }

                    Console.WriteLine("Completed. {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("{0}", ex.StackTrace);
            }
            finally
            {
                #region 解放:
                if (videoSource != null)
                {
                    Marshal.ReleaseComObject(videoSource);
                }
                videoSource = null;

                if (videoRenderer != null)
                {
                    Marshal.ReleaseComObject(videoRenderer);
                }
                videoRenderer = null;

                if (fileSink != null)
                {
                    Marshal.ReleaseComObject(fileSink);
                }
                fileSink = null;

                if (builder != null)
                {
                    Marshal.ReleaseComObject(builder);
                }
                builder = null;

                if (graph != null)
                {
                    Marshal.ReleaseComObject(graph);
                }
                graph = null;
                #endregion
            }
        }
Esempio n. 6
0
        /// <summary>
        /// カメラの接続
        /// </summary>
        /// <param name="filterInfo"></param>
        /// <param name="pinno"></param>
        /// <param name="frameSize"></param>
        private void Camera_Connect(CxFilterInfo filterInfo, int pinno, Size frameSize)
        {
            #region グラフビルダーの生成:
            {
                Graph = (IGraphBuilder)Axi.CoCreateInstance(GUID.CLSID_FilterGraph);
                if (Graph == null)
                {
                    throw new System.IO.IOException("Failed to create a GraphBuilder.");
                }

                Builder = (ICaptureGraphBuilder2)Axi.CoCreateInstance(GUID.CLSID_CaptureGraphBuilder2);
                if (Builder == null)
                {
                    throw new System.IO.IOException("Failed to create a GraphBuilder.");
                }
                Builder.SetFiltergraph(Graph);
            }
            #endregion

            #region  像入力用: ソースフィルタを生成します.
            {
                VideoSource = Axi.CreateFilter(GUID.CLSID_VideoInputDeviceCategory, filterInfo.CLSID, filterInfo.Index);
                if (VideoSource == null)
                {
                    throw new System.IO.IOException("Failed to create a VideoSource.");
                }
                Graph.AddFilter(VideoSource, "VideoSource");

                // フレームサイズを設定します.
                // ※注) この操作は、ピンを接続する前に行う必要があります.
                IPin pin = Axi.FindPin(VideoSource, pinno, PIN_DIRECTION.PINDIR_OUTPUT);
                Axi.SetFormatSize(pin, frameSize.Width, frameSize.Height);
            }
            #endregion

            #region  像捕獲用: サンプルグラバーを生成します.
            {
                VideoGrabber = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_SampleGrabber);
                if (VideoGrabber == null)
                {
                    throw new System.IO.IOException("Failed to create a VideoGrabber.");
                }
                Graph.AddFilter(VideoGrabber, "VideoGrabber");

                // サンプルグラバフィルタの入力形式設定.
                // SetMediaType で必要なメディア タイプを指定します。
                //   http://msdn.microsoft.com/ja-jp/library/cc369546.aspx
                // ※AM_MEDIA_TYPE 構造体のメンバをすべて設定する必要はない。
                // ※デフォルトでは、サンプル グラバに優先メディア タイプはない。
                // ※サンプル グラバを正しいフィルタに確実に接続するには、フィルタ グラフを作成する前にこのメソッドを呼び出す。
                // majortype: http://msdn.microsoft.com/ja-jp/library/cc370108.aspx
                // subtype  : http://msdn.microsoft.com/ja-jp/library/cc371040.aspx
                {
                    var grabber = (ISampleGrabber)VideoGrabber;

                    var mt = new AM_MEDIA_TYPE();
                    mt.majortype  = new Guid(GUID.MEDIATYPE_Video);
                    mt.subtype    = new Guid(GUID.MEDIASUBTYPE_RGB24);
                    mt.formattype = new Guid(GUID.FORMAT_VideoInfo);
                    grabber.SetMediaType(mt);
                    grabber.SetBufferSamples(false);                                    // サンプルコピー 無効.
                    grabber.SetOneShot(false);                                          // One Shot 無効.
                    //grabber.SetCallback(VideoGrabberCB, 0);	// 0:SampleCB メソッドを呼び出すよう指示する.
                    grabber.SetCallback(VideoGrabberCB, 1);                             // 1:BufferCB メソッドを呼び出すよう指示する.
                }
            }
            #endregion

            #region  像出力用: レンダラーを生成します.
            {
                VideoRenderer = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_NullRenderer);
                if (VideoRenderer == null)
                {
                    throw new System.IO.IOException("Failed to create a VideoRenderer.");
                }
                Graph.AddFilter(VideoRenderer, "VideoRenderer");
            }
            #endregion

            #region フィルタの接続:
            unsafe
            {
                var mediatype = new Guid(GUID.MEDIATYPE_Video);
                var hr        = (HRESULT)Builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype), VideoSource, VideoGrabber, VideoRenderer);
                if (hr < HRESULT.S_OK)
                {
                    throw new CxDSException(hr);
                }
            }
            #endregion

            // 同期用: サンプルグラバーのイベント登録:
            VideoGrabberCB.Enable  = true;
            VideoGrabberCB.Notify += VideoGrabberCB_Notify;
            VideoInfoHeader        = Axi.GetVideoInfo((ISampleGrabber)VideoGrabber);

            // カメラ制御インターフェースの抽出.
            CameraControl = Axi.GetInterface <IAMCameraControl>(this.Graph);
        }
Esempio n. 7
0
        /// <summary>
        /// カメラから画像を取り込み、動画ファイル(avi)へ保存する処理
        /// </summary>
        /// <remarks>
        ///		AVI 形式で保存する場合は音声入力は省略可能です。<br/>
        ///		<br/>
        ///		RenderStream (NULL, MEDIATYPE_Video, source, grabber, renderner)<br/>
        ///		<pre>
        ///		 source        grabber       renderer
        ///		+-------+     +-------+     +-------+
        ///		|       0 --- 0       0 --- 0       |
        ///		|       1     |       |     |       |
        ///		+-------+     +-------+     +-------+
        ///		</pre>
        ///		※ 本例では grabber は省略しています。<br/>
        /// </remarks>
        public static void Sample12()
        {
            string __FUNCTION__ = MethodBase.GetCurrentMethod().Name;

            Console.WriteLine(__FUNCTION__);

            IGraphBuilder         graph         = null;
            ICaptureGraphBuilder2 builder       = null;
            IBaseFilter           videoSource   = null;
            IBaseFilter           videoRenderer = null;
            IFileSinkFilter       fileSink      = null;
            string filename = Path.Combine(Results, __FUNCTION__ + ".avi");

            try
            {
                #region グラフビルダーの生成:
                {
                    graph = (IGraphBuilder)Axi.CoCreateInstance(GUID.CLSID_FilterGraph);
                    if (graph == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }

                    builder = (ICaptureGraphBuilder2)Axi.CoCreateInstance(GUID.CLSID_CaptureGraphBuilder2);
                    if (builder == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }
                    builder.SetFiltergraph(graph);
                }
                #endregion

                #region  像入力用: ソースフィルタを生成します.
                {
                    videoSource = Axi.CreateFilter(GUID.CLSID_VideoInputDeviceCategory, null, 0);
                    if (videoSource == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoSource.");
                    }
                    graph.AddFilter(videoSource, "VideoSource");

                    // フレームサイズを設定します.
                    // ※注) この操作は、ピンを接続する前に行う必要があります.
                    IPin pin = Axi.FindPin(videoSource, 0, PIN_DIRECTION.PINDIR_OUTPUT);
                    Axi.SetFormatSize(pin, 640, 480);
                }
                #endregion

                #region  像出力用: 保存する動画ファイル名を設定します.
                unsafe
                {
                    // 動画ファイルを保存する設定:
                    var     filetype = new Guid(GUID.MEDIASUBTYPE_Avi);
                    HRESULT hr       = (HRESULT)builder.SetOutputFileName(new IntPtr(&filetype), filename, ref videoRenderer, ref fileSink);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }
                }
                #endregion

                #region フィルタの接続:
                unsafe
                {
                    // フィルタの接続:
                    var     mediatype = new Guid(GUID.MEDIATYPE_Video);
                    HRESULT hr        = (HRESULT)builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype), videoSource, null, videoRenderer);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }
                }
                #endregion

                // ------------------------------

                #region 取り込み処理:
                {
                    var mediaControl = (IMediaControl)graph;
                    var mediaEvent   = (IMediaEvent)graph;

                    var watch = new Stopwatch();
                    watch.Start();

                    // 露光開始.
                    Console.WriteLine("Run ...");
                    {
                        HRESULT hr;
                        int     state;
                        hr = (HRESULT)mediaControl.Run();
                        hr = (HRESULT)mediaControl.GetState(1000, out state);
                    }
                    Console.WriteLine("Running ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);

                    // 取り込み待機.
                    while (watch.ElapsedMilliseconds < 3000)
                    {
                        System.Threading.Thread.Sleep(1);
                    }

                    // 露光停止.
                    Console.WriteLine("Stop ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                    {
                        HRESULT hr;
                        int     state;
                        hr = (HRESULT)mediaControl.Stop();
                        hr = (HRESULT)mediaControl.GetState(1000, out state);
                    }

                    Console.WriteLine("Completed. {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("{0}", ex.StackTrace);
            }
            finally
            {
                #region 解放:
                if (videoSource != null)
                {
                    Marshal.ReleaseComObject(videoSource);
                }
                videoSource = null;

                if (videoRenderer != null)
                {
                    Marshal.ReleaseComObject(videoRenderer);
                }
                videoRenderer = null;

                if (fileSink != null)
                {
                    Marshal.ReleaseComObject(fileSink);
                }
                fileSink = null;

                if (builder != null)
                {
                    Marshal.ReleaseComObject(builder);
                }
                builder = null;

                if (graph != null)
                {
                    Marshal.ReleaseComObject(graph);
                }
                graph = null;
                #endregion
            }
        }
Esempio n. 8
0
        /// <summary>
        /// カメラから画像を取り込む処理
        /// </summary>
        /// <remarks>
        ///		この方法が最も単純です。<br/>
        ///		<br/>
        ///		RenderStream (NULL, MEDIATYPE_Video, source, grabber, renderner)<br/>
        ///		<pre>
        ///		 source        grabber       renderer
        ///		+-------+     +-------+     +-------+
        ///		|       0 --- 0       0 --- 0       |
        ///		|       1     |       |     |       |
        ///		+-------+     +-------+     +-------+
        ///		</pre>
        /// </remarks>
        public static void Sample11()
        {
            string __FUNCTION__ = MethodBase.GetCurrentMethod().Name;

            Console.WriteLine(__FUNCTION__);

            IGraphBuilder         graph         = null;
            ICaptureGraphBuilder2 builder       = null;
            IBaseFilter           videoSource   = null;
            IBaseFilter           videoGrabber  = null;
            IBaseFilter           videoRenderer = null;
            var videoGrabberCB = new CxSampleGrabberCB();

            try
            {
                #region グラフビルダーの生成:
                {
                    // 必須:
                    graph = (IGraphBuilder)Axi.CoCreateInstance(GUID.CLSID_FilterGraph);
                    if (graph == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }

                    // 任意: 当例に於いては必須ではありませんが、後述のフィルタ接続を簡潔に記述できます.
                    builder = (ICaptureGraphBuilder2)Axi.CoCreateInstance(GUID.CLSID_CaptureGraphBuilder2);
                    if (builder == null)
                    {
                        throw new System.IO.IOException("Failed to create a GraphBuilder.");
                    }
                    builder.SetFiltergraph(graph);
                }
                #endregion

                #region  像入力用: ソースフィルタを生成します.
                {
                    videoSource = Axi.CreateFilter(GUID.CLSID_VideoInputDeviceCategory, null, 0);
                    if (videoSource == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoSource.");
                    }
                    graph.AddFilter(videoSource, "VideoSource");

                    // フレームサイズを設定します.
                    // ※注) この操作は、ピンを接続する前に行う必要があります.
                    IPin pin = Axi.FindPin(videoSource, 0, PIN_DIRECTION.PINDIR_OUTPUT);
                    Axi.SetFormatSize(pin, 640, 480);
                }
                #endregion

                #region  像捕獲用: サンプルグラバーを生成します.
                {
                    videoGrabber = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_SampleGrabber);
                    if (videoGrabber == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoGrabber.");
                    }
                    graph.AddFilter(videoGrabber, "videoGrabber");

                    // サンプルグラバフィルタの入力形式設定.
                    // SetMediaType で必要なメディア タイプを指定します。
                    //   http://msdn.microsoft.com/ja-jp/library/cc369546.aspx
                    // ※AM_MEDIA_TYPE 構造体のメンバをすべて設定する必要はない。
                    // ※デフォルトでは、サンプル グラバに優先メディア タイプはない。
                    // ※サンプル グラバを正しいフィルタに確実に接続するには、フィルタ グラフを作成する前にこのメソッドを呼び出す。
                    // majortype: http://msdn.microsoft.com/ja-jp/library/cc370108.aspx
                    // subtype  : http://msdn.microsoft.com/ja-jp/library/cc371040.aspx
                    {
                        var grabber = (ISampleGrabber)videoGrabber;

                        var mt = new AM_MEDIA_TYPE();
                        mt.majortype  = new Guid(GUID.MEDIATYPE_Video);
                        mt.subtype    = new Guid(GUID.MEDIASUBTYPE_RGB24);
                        mt.formattype = new Guid(GUID.FORMAT_VideoInfo);
                        grabber.SetMediaType(mt);
                        grabber.SetBufferSamples(false);                                        // サンプルコピー 無効.
                        grabber.SetOneShot(false);                                              // One Shot 無効.
                        //grabber.SetCallback(videoGrabberCB, 0);	// 0:SampleCB メソッドを呼び出すよう指示する.
                        grabber.SetCallback(videoGrabberCB, 1);                                 // 1:BufferCB メソッドを呼び出すよう指示する.
                    }
                }
                #endregion

                #region  像出力用: レンダラーを生成します.
                {
                    videoRenderer = (IBaseFilter)Axi.CoCreateInstance(GUID.CLSID_NullRenderer);
                    if (videoRenderer == null)
                    {
                        throw new System.IO.IOException("Failed to create a videoRenderer.");
                    }
                    graph.AddFilter(videoRenderer, "videoRenderer");
                }
                #endregion

                #region フィルタの接続:
                if (builder != null)
                {
                    unsafe
                    {
                        var mediatype = new Guid(GUID.MEDIATYPE_Video);
                        var hr        = (HRESULT)builder.RenderStream(IntPtr.Zero, new IntPtr(&mediatype), videoSource, videoGrabber, videoRenderer);
                        if (hr < HRESULT.S_OK)
                        {
                            throw new CxDSException(hr);
                        }
                    }
                }
                else
                {
                    // ピンの取得.
                    IPin videoSourceOutput  = Axi.FindPin(videoSource, 0, PIN_DIRECTION.PINDIR_OUTPUT);
                    IPin videoGrabberInput  = Axi.FindPin(videoGrabber, 0, PIN_DIRECTION.PINDIR_INPUT);
                    IPin videoGrabberOutput = Axi.FindPin(videoGrabber, 0, PIN_DIRECTION.PINDIR_OUTPUT);
                    IPin videoRendererInput = Axi.FindPin(videoRenderer, 0, PIN_DIRECTION.PINDIR_INPUT);

                    // ピンの接続.
                    graph.Connect(videoSourceOutput, videoGrabberInput);
                    graph.Connect(videoGrabberOutput, videoRendererInput);
                }
                #endregion

                // ------------------------------

                #region 取り込み処理:
                {
                    var mediaControl = (IMediaControl)graph;

                    // 映像サイズの取得.
                    var vih    = Axi.GetVideoInfo((ISampleGrabber)videoGrabber);
                    var images = new List <Bitmap>();

                    var watch = new Stopwatch();
                    watch.Start();

                    // 取り込み処理.
                    videoGrabberCB.Notify += delegate(object _sender, CxSampleGrabberEventArgs _e)
                    {
                        Console.WriteLine("{0}: SampleTime={1:F6}", images.Count, _e.SampleTime);
                        images.Add(_e.ToImage(vih));
                    };

                    // 露光開始.
                    Console.WriteLine("Run ...");
                    {
                        HRESULT hr;
                        int     state;
                        hr = (HRESULT)mediaControl.Run();
                        hr = (HRESULT)mediaControl.GetState(1000, out state);
                    }
                    Console.WriteLine("Running ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);

                    // 取り込み待機.
                    while (watch.ElapsedMilliseconds < 3000)
                    {
                        System.Threading.Thread.Sleep(1);
                    }

                    // 露光停止.
                    Console.WriteLine("Stop ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                    {
                        HRESULT hr;
                        int     state;
                        hr = (HRESULT)mediaControl.Stop();
                        hr = (HRESULT)mediaControl.GetState(1000, out state);
                    }

                    // 確認用:
                    Console.WriteLine("Save ... {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                    {
                        string subdir = Path.Combine(Results, __FUNCTION__);
                        if (Directory.Exists(subdir) == false)
                        {
                            Directory.CreateDirectory(subdir);
                        }

                        for (int i = 0; i < images.Count; i++)
                        {
                            var filename = string.Format("image{0}.png", i);
                            images[i].Save(Path.Combine(subdir, filename));
                        }
                    }

                    Console.WriteLine("Completed. {0:F3} msec", watch.Elapsed.TotalMilliseconds);
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("{0}", ex.StackTrace);
            }
            finally
            {
                #region 解放:
                if (videoSource != null)
                {
                    Marshal.ReleaseComObject(videoSource);
                }
                videoSource = null;

                if (videoGrabber != null)
                {
                    Marshal.ReleaseComObject(videoGrabber);
                }
                videoGrabber = null;

                if (videoRenderer != null)
                {
                    Marshal.ReleaseComObject(videoRenderer);
                }
                videoRenderer = null;

                if (builder != null)
                {
                    Marshal.ReleaseComObject(builder);
                }
                builder = null;

                if (graph != null)
                {
                    Marshal.ReleaseComObject(graph);
                }
                graph = null;
                #endregion
            }
        }