Example #1
0
        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);
            }
        }
Example #2
0
        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
            {
            }
        }