仮想WebカメラをOpenCVに認識させるためのDirectShowについての予備知識メモ

#メモの概要
DirectShowの知識が皆無であるため、勉強用のメモで、基本的に出典からの情報を掲載している。
技術概要を片っ端から読み進めたものである。

#出典
[Microsoft　DeveloperNetwork](https://msdn.microsoft.com/ja-jp/library/cc369391.aspx)

#DirectShowの概要

>Microsoft® DirectShow® は、Microsoft Windows® プラットフォームにおけるメディア ストリーミングのアーキテクチャである。DirectShow は、マルチメディア ストリームの高品質なキャプチャと再生を実現する。サポートするフォーマットは広範囲にわたり、ASF (Advanced Systems Format)、MPWG (Motion Picture Experts Group)、AVI (Audio-Video Interleaved)、MP3 (MPEG Audio Layer-3)、WAV サウンド ファイルを含む。WDM (Windows Driver Model) デバイスおよび従来の Video for Windows デバイスを使ったキャプチャをサポートする。DirectShow は、他の DirectX テクノロジと統合されている。DirectShow は、ビデオおよびオーディオ アクセラレーション ハードウェアが使用可能な場合にはハードウェアを自動的に検出して使うが、アクセラレーション ハードウェアのないシステムもサポートしている。
**DirectShow では、メディア再生、フォーマット変換、キャプチャの作業を簡単に行える。**同時に、カスタム ソリューションを必要とするアプリケーションに対し、基盤となるストリーム制御アーキテクチャへのアクセスを提供する。新しいフォーマットまたはカスタム エフェクトをサポートする独自の DirectShow コンポーネントを作成することもできる。
DirectShow を使って作成できるアプリケーションの種類の例として、DVD プレーヤ、ビデオ編集アプリケーション、AVI から ASF へのコンバータ、MP3 プレーヤ、デジタル **ビデオ キャプチャ アプリケーション**がある。
DirectShow は COM (Component Object Model) に基づいている。DirectShow アプリケーションを作成するには、COM クライアント プログラミングを理解している必要がある。ほとんどのアプリケーションでは、独自の COM オブジェクトを実装する必要はない。DirectShow にはユーザーが必要とするコンポーネントが用意されている。ただし、独自のコンポーネントを作成して DirectShow を拡張する場合は、コンポーネントを COM オブジェクトとして実装する必要がある。

#DirectShow アプリケーション プログラミングの概要
>##フィルタとフィルタ グラフ
DirectShow を構成する要素は、**"フィルタ" と呼ばれるソフトウェア コンポーネント**である。**フィルタは、マルチメディア ストリームに対して何らかの操作を実行するソフトウェア コンポーネントである。**たとえば、DirectShow のフィルタでは次のような操作を実行できる。
・**ファイルを読み取る**
・**ビデオ キャプチャ デバイスからビデオを取得する**
・**MPEG-1 ビデオなどのさまざまなストリーム フォーマットをデコードする**
・**グラフィック カードまたはサウンド カードにデータを渡す**
**フィルタは入力を受け取り、出力を生成する。**たとえば、フィルタが MPEG-1 ビデオをデコードする場合、入力は MPEG でエンコードされたストリームであり、出力は一連の圧縮されていないビデオ フレームである。
DirectShow では、フィルタ チェーンを接続し、あるフィルタからの出力を別のフィルタの入力にすることによって、アプリケーションはあらゆるタスクを実行できる。**接続されたフィルタの集合は、"フィルタ グラフ" と呼ばれる。**たとえば、次の図は AVI ファイルを再生するためのフィルタ グラフを示している。
AVI ファイルを再生するフィルタ グラフ 
![IC28754.gif](https://qiita-image-store.s3.amazonaws.com/0/139645/bbe9865d-94d2-74c1-d4eb-080d7561c13f.gif)
ファイル ソース フィルタはハード ディスクから AVI ファイルを読み取る。AVI スプリッタ フィルタは、ファイルを解析し、圧縮ビデオ ストリームとオーディオ ストリームにする。AVI デコンプレッサ フィルタはビデオ フレームをデコードする。ビデオ レンダラ フィルタは、DirectDraw または GDI を使って、ディスプレイにフレームを描画する。デフォルト DirectSound デバイス フィルタは、DirectSound を使って、オーディオ ストリームを再生する。
**アプリケーションで、これらのデータの流れのすべてを管理する必要はない。アプリケーションの代わりに、フィルタ グラフ マネージャと呼ばれる上位レベルのコンポーネントがフィルタを制御する。**アプリケーションでは、"Run" (グラフの開始から終わりまでデータを移動する) や "Stop" (データの流れを停止する) などの上位レベルの API 呼び出しを行う。ストリーム操作をより細かく制御する必要がある場合は、COM インターフェイスを通してフィルタに直接アクセスできる。また、フィルタ グラフ マネージャはアプリケーションにイベント通知を渡す。
フィルタ グラフ マネージャにはもう 1 つ別の用途がある。フィルタを接続してフィルタ グラフを作成するためのメソッドをアプリケーションに提供することである。DirectShow では、この処理を簡素化するためのさまざまなヘルパー オブジェクトも用意している。これらについては、ドキュメントの中で詳しく説明されている。
##DirectShow アプリケーションの作成
広い意味で、DirectShow アプリケーションが実行しなければならないタスクは 3 つある。これらのタスクを次の図に示す。
標準的な DirectShow アプリケーション
![IC97858.gif](https://qiita-image-store.s3.amazonaws.com/0/139645/e2c7ecb1-51f0-eb11-5294-3db42abd2fbb.gif)
・フィルタ グラフ マネージャの**インスタンスを作成**する。
・フィルタ グラフ マネージャを使って**フィルタ グラフを作成**する。グラフに含まれるフィルタは、アプリケーションによって異なる。
・フィルタ グラフ マネージャを使って、フィルタグラフ、およびフィルタを通過する**ストリーム データを制御**する。この処理が行われている間、アプリケーションはフィルタ グラフ マネージャからのイベントにも応答する。
処理が完了すると、アプリケーションはフィルタ グラフ マネージャとすべてのフィルタを解放する。
DirectShow は COM に基づいており、フィルタ グラフ マネージャおよびフィルタはすべて COM オブジェクトである。DirectShow のプログラミングを始めるには、COM クライアントのプログラミングに関する一般的な知識が必要である。この概要については、DirectX SDK ドキュメントの「COM の使い方」を参照すること。これ以外にも、COM プログラミングについては多くの書籍がある。
DirectShow を使って作業を開始するには、「ファイルの再生法」を参照すること。ここでは、ビデオ ファイルを再生する簡単なコンソール アプリケーションを紹介している。DirectShow のアーキテクチャの詳細については、「DirectShow について」を参照すること。また、キャプチャ、ビデオ編集、DVD 再生、テレビなど、DirectShow でサポートされる主なシナリオについては、「DirectShow の使い方」を参照すること。

#DirectShow FAQ
>**DirectShow について説明した書籍はあるか？**
現在、DirectShow についてのみ書かれた書籍は 1 冊だけである。
『Programming Microsoft DirectShow』Michael Linetsky 著 (Wordware Publishing Inc.)

このように書籍や情報があまりないことで、とっつきづらい分野なのかもしれない。

cap_dshow.cppではISampleGrabberクラス部分のSetMediaTypeとかでピンを受け取っているのかもしれない。
詳細はさらにべきょうしてまとめる。