AVI ファイルへのビデオのキャプチャ
次の図は、AVI ファイルにビデオをキャプチャできる最も簡単なグラフを示している。
AVI Mux フィルタはキャプチャ ピンからビデオ ストリームを受け取り、AVI ストリームにパッケージ化する。オーディオ ストリームも AVI Mux フィルタに接続できる。その場合、Mux は 2 つのストリームをインターリーブする。ファイル ライタ フィルタは AVI ストリームをディスクに書き込む。
グラフを作成するには、次のように初めに ICaptureGraphBuilder2::SetOutputFileName メソッドを呼び出す。
IBaseFilter *pMux;
hr = pBuild->SetOutputFileName(
&MEDIASUBTYPE_Avi, // ターゲット ファイルの AVI を指定する。
L"C:\\Example.avi", // ファイル名。
&pMux, // Mux へのポインタを受け取る。
NULL); // (省略可能) ファイル シンクへのポインタを受け取る。
最初の引数にはファイル タイプを指定する。この場合、ファイル タイプは AVI である。2 番目の引数にはファイル名を指定する。AVI の場合、SetOutputFileName メソッドは AVI Mux フィルタとファイル ライタ フィルタを一緒に作成し、グラフに追加する。また、SetOutputFileName メソッドは IFileSinkFilter::SetFileName メソッドを呼び出してファイル ライタ フィルタにファイル名を設定し、2 つのフィルタを接続する。3 番目の引数でこのメソッドは AVI Mux へのポインタを返す。オプションとして、4 番目の引数では IFileSinkFilter インターフェイスへのポインタを返す。このインターフェイスが必要ない場合は、前の例のように、この引数を NULL に設定する。
次に、以下のように ICaptureGraphBuilder2::RenderStream メソッドを呼び出し、キャプチャ フィルタを AVI Mux に接続する。
hr = pBuild->RenderStream(
&PIN_CATEGORY_CAPTURE, // ピン カテゴリ。
&MEDIATYPE_Video, // メディア タイプ。
pCap, // キャプチャ フィルタ。
NULL, // 中間フィルタ (省略可能)。
pMux); // Mux フィルタまたはファイル シンク フィルタ。
// Mux フィルタを解放する。
pMux->Release();
最初の引数にはピン カテゴリを指定する。キャプチャの場合は、PIN_CATEGORY_CAPTURE である。2 番目の引数にはメディア タイプを指定する。3 番目の引数はキャプチャ フィルタの IBaseFilter インターフェイスへのポインタである。4 番目の引数は省略可能である。この引数を使うと、ビデオ ストリームをエンコーダなどの中間フィルタにルーティングした後に Mux フィルタに渡せる。必要ない場合は、前の例に示したように、この引数を NULL に設定すること。5 番目の引数は Mux フィルタへのポインタである。このポインタは SetOutputFileName メソッドを呼び出して取得する。
オーディオをキャプチャするには、メディア タイプ MEDIATYPE_Audio を使って RenderStream を呼び出す。2 つの異なるデバイスからオーディオとビデオをキャプチャする場合は、オーディオ ストリームをマスタ ストリームにすることを推奨する。このようにすると、AVI Mux フィルタがビデオ ストリームの再生レートを調整してオーディオ ストリームに一致させるため、2 つのストリーム間のずれを防ぐことができる。マスタ ストリームを設定するには、AVI Mux フィルタに対して IConfigAviMux::SetMasterStream メソッドを呼び出す。
IConfigAviMux *pConfigMux = NULL;
hr = pMux->QueryInterface(IID_IConfigAviMux, (void**)&pConfigMux);
if (SUCCEEDED(hr))
{
pConfigMux->SetMasterStream(1);
pConfigMux->Release();
}
SetMasterStream のパラメータはストリーム番号である。この番号は RenderStream を呼び出す順序によって決まる。たとえば、初めにビデオに対し、次にオーディオに対して RenderStream を呼び出した場合、ビデオはストリーム 0 であり、オーディオはストリーム 1 である。
IConfigInterleaving::put_Mode メソッドを呼び出すことで、AVI Mux フィルタがどのようにオーディオ ストリームとビデオ ストリームをインターリーブするかを設定することもできる。
IConfigInterleaving *pInterleave = NULL;
hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
if (SUCCEEDED(hr))
{
pInterleave->put_Mode(INTERLEAVE_CAPTURE);
pInterleave->Release();
}
INTERLEAVE_CAPTURE フラグを指定すると、AVI Mux はビデオ キャプチャに適したレートでインターリーブを実行する。インターリーブなしを示す INTERLEAVE_NONE も指定できる。この値を指定すると、AVI Mux はデータを到着順に書き込む。INTERLEAVE_FULL フラグは、AVI Mux がインターリーブを完全に実行することを意味する。ただし、このモードはオーバーヘッドが最大になるため、ビデオ キャプチャには適さない。
ビデオ ストリームのエンコード
ビデオ ストリームをエンコードするには、キャプチャ フィルタと AVI Mux フィルタの間にエンコード フィルタを挿入する。エンコード フィルタを選択するには、System Device Enumerator かフィルタ マッパーを使う。 (詳細については、「デバイスとフィルタの列挙」を参照すること。)
次の例に太字で示されているように、RenderStream の 4 番目のパラメータとしてエンコーダ フィルタを指定する。
IBaseFilter *pEncoder;
/* エンコーダ フィルタを作成する (省略)。 */
// フィルタ グラフに追加する。
pGraph->AddFilter(pEncoder, L"Encoder);
/* 前に示したように、SetOutputFileName を呼び出す。 */
// ストリームをレンダリングする。
hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pCap, pEncoder, pMux);
pEncoder->Release();
エンコーダ フィルタはエンコード パラメータの設定用に IAMVideoCompression または他のインターフェイスをサポートしていることがある。利用可能なインターフェイスの一覧については、「ファイルのエンコードおよびデコードのインターフェイス」を参照すること。