ファイルへのプロジェクトの書き込み
ここでは、ビデオ編集プロジェクトをファイルに書き込む方法について説明する。最初に、基本レンダリング エンジンを使ってファイルを書き込む方法について説明する。次に、スマート レンダリング エンジンを使ったスマート再圧縮について説明する。
Microsoft® DirectShow® 編集サービスでのプロジェクトのレンダリングの概要については、「レンダリング エンジンについて」を参照すること。
基本レンダリング エンジンの使用
次のように、グラフのフロント エンドを最初に作成する。
- レンダリング エンジンを作成する。
- タイムラインを指定する。
- レンダリング範囲を設定する ("オプション")。
- グラフのフロント エンドを作成する。
次のサンプル コードは、これらの手順を示している。
IRenderEngine *pRender = NULL;
hr = CoCreateInstance(CLSID_RenderEngine, NULL, CLSCTX_INPROC,
IID_IRenderEngine, (void**) &pRender);
hr = pRender->SetTimelineObject(pTL);
hr = pRender->ConnectFrontEnd( );
次に、フィルタ グラフにマルチプレクサおよびファイル ライタ フィルタを追加する。その最も簡単な方法は、キャプチャ グラフを作成するための DirectShow コンポーネントであるキャプチャ グラフ ビルダを使うことである。キャプチャ グラフ ビルダは、ICaptureGraphBuilder2 インターフェイスを公開する。次の手順を実行する。
- キャプチャ グラフ ビルダのインスタンスを作成する。
- グラフへのポインタを取得し、グラフ ビルダに渡す。
- 出力ファイルの名前とメディア タイプを指定する。この手順によって、後で必要になる mux フィルタへのポインタも取得する。
次のサンプル コードは、これらの手順を示している。
CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **)&pBuilder);
// グラフのフロント エンドへのポインタを取得する。
IGraphBuilder *pGraph;
pRender->GetFilterGraph(&pGraph);
pBuilder->SetFiltergraph(pGraph);
// ファイル書き込みセクションを作成する。
IBaseFilter *pMux;
pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,
OLESTR("Output.avi"), &pMux, NULL);
最後に、mux フィルタにフロント エンドの出力ピンを接続する。
- グループ数を取得する。
- 各ピンごとに、ピンへのポインタを取得する。
- オプションで、圧縮フィルタのインスタンスを作成し、ストリームを圧縮する。コンプレッサのタイプは、グループのメディア タイプによって異なる。システム デバイス列挙子を使って、利用可能な圧縮フィルタを列挙できる。詳細については、「デバイスとフィルタの列挙」を参照すること。
- オプションで、キー フレーム レートなどの圧縮パラメータを設定する。この手順については、後で詳細に説明する。
- ICaptureGraphBuilder2::RenderStream を呼び出す。このメソッドは、ピン、圧縮フィルタ (ある場合)、マルチプレクサへの各ポインタを受け取る。
次のサンプル コードは、出力ピンの接続方法を示している。
long NumGroups;
pTimeline->GetGroupCount(&NumGroups);
// グループ内をループし、出力ピンを取得する。
for (i = 0; i < NumGroups; i++)
{
IPin *pPin;
if (pRender->GetGroupOutputPin(i, &pPin) == S_OK)
{
IBaseFilter *pCompressor;
// コンプレッサ フィルタを作成する (省略)。
// 圧縮パラメータを設定する (省略)。
// ピンを接続する。
pBuilder->RenderStream(NULL, NULL, pPin, pCompressor, pMux);
pCompressor->Release();
pPin->Release();
}
}
圧縮パラメータを設定する (前の手順 4) には、IAMVideoCompression インターフェイスを使う。このインターフェイスは、圧縮フィルタの出力ピンに公開される。圧縮フィルタのピンを列挙し、IAMVideoCompression について、各出力ピンに問い合わせる。ピン列挙の詳細については、「ピンの列挙」を参照すること。この手順において取得したすべてのインターフェイス ポインタは、必ず解放すること。
フィルタ グラフを作成した後は、フィルタ グラフ マネージャで IMediaControl::Run メソッドを呼び出す。フィルタ グラフは、実行されるとファイルにデータを書き込む。イベント通知を使って、再生が完了するのを待つ。詳細については、「イベントへの応答」を参照すること。再生が終了したら、IMediaControl::Stop を明示的に呼び出して、フィルタ グラフを停止しなければならない。このようにしないと、ファイルは正しく書き込まれない。
スマート レンダリング エンジンの使用
スマート再圧縮の利点を得るためには、基本レンダリング エンジンの代わりにスマート レンダリング エンジンを使う。グラフの作成手順は、おおよそ同じである。主な違いは、ファイルの書き込みセクションではなく、グラフのフロント エンドで圧縮が行われることである。
重要 : **スマート レンダリング エンジンは、**Windows Media ファイルの読み取りや書き込みに使ってはならない。
各ビデオ グループには、そのグループの圧縮フォーマットを指定するプロパティがある。圧縮フォーマットは、高さ、幅、ビット深度、フレーム レートについて、グループの非圧縮フォーマットに完全に一致しなければならない。スマート レンダリング エンジンは、グラフ作成の際に圧縮フォーマットを使う。圧縮フォーマットを設定する前に、必ず IAMTimelineGroup::SetMediaType を呼び出して、そのグループに非圧縮フォーマットを指定する。
グループの圧縮フォーマットを設定するには、IAMTimelineGroup::SetSmartRecompressFormat メソッドを呼び出す。このメソッドは、SCompFmt0 構造体へのポインタを受け取る。SCompFmt0 構造体には 2 つのメンバがある。1 つは nFormatId であり、このメンバはゼロでなくてはならない。もう 1 つは MediaType であり、これは AM_MEDIA_TYPE 構造体である。フォーマット情報を使って AM_MEDIA_TYPE 構造体を初期化する。
注 : 最終的なプロジェクトにソース ファイルの 1 つと同じフォーマットを持たせる場合は、メディア ディテクタを使ってソース ファイルから直接 AM_MEDIA_TYPE 構造体を取得できる。詳細については、「IMediaDet::get_StreamMediaType」を参照すること。
次のサンプル コードに示すように、SCompFmt0 変数を long 型のポインタにキャストする。
SCompFmt0 *pFormat = new SCompFmt0;
memset(pFormat, 0, sizeof(SCompFmt0));
pFormat->nFormatId = 0;
// pFormat->MediaType を初期化する (省略)。
pGroup->SetSmartRecompressFormat( (long*) pFormat );
スマート レンダリング エンジンは、自動的に互換性のある圧縮フィルタを検索する。ISmartRenderEngine::SetGroupCompressor を呼び出して、グループの圧縮フィルタを指定することも可能である。
グラフを作成するには、前に「基本レンダリング エンジンの使用」で説明したのと同じ手順を実行する。その違いは、次に示すものだけである。
- 基本レンダリング エンジンではなく、スマート レンダリング エンジンを使う。クラス識別子は CLSID_SmartRenderEngine である。
- フロント エンドの作成後には圧縮パラメータを設定するが、出力ピンをレンダリングする "前" に行う。ISmartRenderEngine::GetGroupCompressor メソッドを呼び出し、グループの圧縮フィルタへのポインタを取得する。次に、前に説明したように IAMVideoCompression インターフェイスについて問い合わせる。
- 出力ピンをレンダリングする際には、圧縮フィルタを挿入する必要はない。ストリームは、既に圧縮されている。