Microsoft DirectX 8.0

ファイルへのプロジェクトの書き込み

ここでは、ビデオ編集プロジェクトをファイルに書き込む方法について説明する。最初に、基本レンダリング エンジンを使ってファイルを書き込む方法について説明する。次に、スマート レンダリング エンジンを使ったスマート再圧縮について説明する。ここには、次のトピックが含まれている。

Microsoft® DirectShow® 編集サービスでのプロジェクトのレンダリング概要については、「レンダリング エンジンについて」を参照すること。

基本レンダリング エンジンの使用

次のように、グラフのフロント エンドを最初に構築する。

  1. レンダリング エンジンを作成する。
  2. タイムラインを指定する。
  3. グラフのフロント エンドを構築する。

次のサンプル コードは、そのステップを示している。

IRenderEngine *pRender = NULL; 
hr = CoCreateInstance(CLSID_RenderEngine, NULL, CLSCTX_INPROC,
    IID_IRenderEngine, (void**) &pRender);

hr = pRender->SetTimelineObject(pTL);
hr = pRender->ConnectFrontEnd( );

次に、フィルタ グラフにマルチプレクサおよびファイル ライタ フィルタを追加する。その最も簡単な方法は、キャプチャ グラフを構築するための DirectShow コンポーネントであるキャプチャ グラフ ビルダを書くことである。キャプチャ グラフ ビルダは、ICaptureGraphBuilder2 インターフェイスを公開する。次のステップを実行する。

  1. キャプチャ グラフ ビルダのインスタンスを作成する。
  2. グラフへのポインタを取得し、グラフ ビルダに渡す。
  3. 出力ファイルの名前とメディア タイプを指定する。このステップによって、後で必要になる 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, L"Output.avi", &pMux, NULL);

最後に、mux フィルタにフロント エンドの出力ピンを接続する。

  1. グループ数を取得する。
  2. 各ピンごとに、ピンへのポインタを取得する。
  3. オプションで、圧縮フィルタのインスタンスを作成し、ストリームを圧縮する。コンプレッサのタイプは、グループのメディア タイプによって異なる。システム デバイス列挙子を使って、利用可能な圧縮フィルタを列挙できる。詳細については、「デバイスとフィルタの列挙」を参照すること。
  4. オプションで、キー フレーム レートなどの圧縮パラメータを設定する。このステップについては、後で詳細に説明する。
  5. 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 を明示的に呼び出して、フィルタ グラフを停止しなければならない。このようにしないと、ファイルは正しく書き込まれない。

スマート レンダリング エンジンの使用

スマート再圧縮の利点を得るためには、基本レンダリング エンジンの代わりにスマート レンダリング エンジンを使用する。グラフの構築ステップは、おおよそ同じである。主な違いは、ファイルの書き込みセクションではなく、グラフのフロント エンドで圧縮が行われることである。

各ビデオ グループには、そのグループの圧縮フォーマットを指定するプロパティがある。圧縮フォーマットは、高さ、幅、ビット数、およびフレーム レートについて、グループの非圧縮フォーマットに完全に一致しなければならない。スマート レンダリング エンジンは、グラフ構築の際に圧縮フォーマットを使用する。圧縮フォーマットを設定する前に、必ず IAMTimelineGroup::SetMediaType を呼び出して、そのグループに非圧縮フォーマットを指定する。

グループの圧縮フォーマットを設定するには、IAMTimelineGroup::SetSmartRecompressFormat メソッドを呼び出す。このメソッドは、ポインタを 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 を呼び出しても、グループの圧縮フィルタを指定できる。

グラフの構築

グラフを構築するには、「基本レンダリング エンジンの使用」で説明したのと同じステップを使う。その違いは、次に示すものだけである。