public static void tビデオレンダラをグラフから除去する(IGraphBuilder graphBuilder) { int hr = 0; IBaseFilter videoRenderer = null; IPin renderInputPin = null; IPin connectedOutputPin = null; try { // videoRenderer を探す。 CDirectShow.tビデオレンダラとその入力ピンを探して返す(graphBuilder, out videoRenderer, out renderInputPin); if (videoRenderer == null || renderInputPin == null) { return; // なかった } #region [ renderInputPin へ接続している前段の出力ピン connectedOutputPin を探す。 ] //----------------- renderInputPin.ConnectedTo(out connectedOutputPin); //----------------- #endregion if (connectedOutputPin == null) { return; // なかった } // 前段の出力ピンとビデオレンダラの入力ピンを切断する。双方向から切断しないとグラフから切り離されないので注意。 renderInputPin.Disconnect(); connectedOutputPin.Disconnect(); // ビデオレンダラをグラフから除去。 graphBuilder.RemoveFilter(videoRenderer); } finally { CCommon.tReleaseComObject(ref connectedOutputPin); CCommon.tReleaseComObject(ref renderInputPin); CCommon.tReleaseComObject(ref videoRenderer); } }
public CDirectShow(string fileName, IntPtr hWnd, bool bオーディオレンダラなし) { // 初期化。 this.n幅px = 0; this.n高さpx = 0; this.b上下反転 = false; this.nスキャンライン幅byte = 0; this.nデータサイズbyte = 0; this.b音声のみ = false; this.graphBuilder = null; this.MediaCtrl = null; this.b再生中 = false; this.bループ再生 = false; // 静的リストに登録し、インスタンスIDを得る。 CDirectShow.tインスタンスを登録する(this); // 並列処理準備。 if (CDirectShow.n並列度 == 0) // 算出がまだなら算出する。 { CDirectShow.n並列度 = Environment.ProcessorCount; // 並列度=CPU数とする。 } unsafe { this.dgライン描画ARGB32 = new DGライン描画[CDirectShow.n並列度]; this.dgライン描画XRGB32 = new DGライン描画[CDirectShow.n並列度]; for (int i = 0; i < CDirectShow.n並列度; i++) { this.dgライン描画ARGB32[i] = new DGライン描画(this.tライン描画ARGB32); this.dgライン描画XRGB32[i] = new DGライン描画(this.tライン描画XRGB32); } } try { int hr = 0; // グラフビルダを生成。 this.graphBuilder = (IGraphBuilder) new FilterGraph(); #if DEBUG // ROT への登録。 this.rot = new DsROTEntry(graphBuilder); #endif // QueryInterface。存在しなければ null。 this.MediaCtrl = this.graphBuilder as IMediaControl; this.MediaEventEx = this.graphBuilder as IMediaEventEx; this.MediaSeeking = this.graphBuilder as IMediaSeeking; this.BasicAudio = this.graphBuilder as IBasicAudio; // IMemoryRenderer をグラフに挿入。 AMMediaType mediaType = null; this.memoryRendererObject = new MemoryRenderer(); this.memoryRenderer = (IMemoryRenderer)this.memoryRendererObject; var baseFilter = (IBaseFilter)this.memoryRendererObject; hr = this.graphBuilder.AddFilter(baseFilter, "MemoryRenderer"); DsError.ThrowExceptionForHR(hr); // fileName からグラフを自動生成。 hr = this.graphBuilder.RenderFile(fileName, null); // IMediaControl.RenderFile() は推奨されない DsError.ThrowExceptionForHR(hr); // 音声のみ? { IBaseFilter videoRenderer; IPin videoInputPin; CDirectShow.tビデオレンダラとその入力ピンを探して返す(this.graphBuilder, out videoRenderer, out videoInputPin); if (videoRenderer == null) { this.b音声のみ = true; } else { CCommon.tReleaseComObject(ref videoInputPin); CCommon.tReleaseComObject(ref videoRenderer); } } // イメージ情報を取得。 if (!this.b音声のみ) { long n; int m; this.memoryRenderer.GetWidth(out n); this.n幅px = (int)n; this.memoryRenderer.GetHeight(out n); this.n高さpx = (int)n; this.memoryRenderer.IsBottomUp(out m); this.b上下反転 = (m != 0); this.memoryRenderer.GetBufferSize(out n); this.nデータサイズbyte = (int)n; this.nスキャンライン幅byte = (int)this.nデータサイズbyte / this.n高さpx; // CCommon.tReleaseComObject( ref baseFilter ); なんかキャスト元のオブジェクトまで解放されるので解放禁止。 } // グラフを修正する。 if (bオーディオレンダラなし) { WaveFormat dummy1; byte[] dummy2; CDirectShow.tオーディオレンダラをNullレンダラに変えてフォーマットを取得する(this.graphBuilder, out dummy1, out dummy2); } // その他の処理。 this.t再生準備開始(); // 1回以上 IMediaControl を呼び出してないと、IReferenceClock は取得できない。 this.t遷移完了まで待って状態を取得する(); // 完全に Pause へ遷移するのを待つ。(環境依存) // イベント用ウィンドウハンドルを設定。 this.MediaEventEx.SetNotifyWindow(hWnd, (int)WM_DSGRAPHNOTIFY, new IntPtr(this.nインスタンスID)); } #if !DEBUG catch (Exception e) { CCommon.t例外の詳細をログに出力する(e); this.Dispose(); throw; // 例外発出。 } #endif finally { } }