Example #1
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;
                    IBaseFilter audioRenderer;
                    IPin        audioInputPin;
#if MemoryRenderer
                    CDirectShow.tビデオレンダラとその入力ピンを探して返す(this.graphBuilder, out videoRenderer, out videoInputPin);
#else
                    CDirectShow.SearchMMRenderers(this.graphBuilder, out videoRenderer, out videoInputPin, out audioRenderer, out audioInputPin);
#endif
                    if (videoRenderer == null && audioRenderer != null)
                    {
                        this.b音声のみ = true;
                    }
                    else
                    {
                        C共通.tCOMオブジェクトを解放する(ref videoInputPin);
                        C共通.tCOMオブジェクトを解放する(ref videoRenderer);
                        C共通.tCOMオブジェクトを解放する(ref audioInputPin);
                        C共通.tCOMオブジェクトを解放する(ref audioRenderer);
                    }
                }


                // イメージ情報を取得。

                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;
                    // C共通.tCOMオブジェクトを解放する( 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)
            {
                C共通.t例外の詳細をログに出力する(e);
                this.Dispose();
                throw;                  // 例外発出。
            }
#endif
            finally
            {
            }
        }