Microsoft DirectX 8.0

マルチメディア ストリーミング アーキテクチャについて

ここでは、マルチメディア ストリーミングのアーキテクチャと、ソフトウェア開発者がツールまたはアプリケーションでストリームを使用するときの標準的な使い方について説明する。また、データ転送の基盤としてのストリーミングの利点、およびマルチメディア プログラミングの要点 (ストリーミング アプリケーションでのデータ転送、パフォーマンスの最適化、タイム スタンプ処理など) についても説明する。マルチメディア ストリーミングを使用するプログラマは、COM プログラミングの概念を十分理解している必要がある。

以下の項で構成される。

マルチメディア ストリーミングの利点

マルチメディア ストリーミングを使用すると、フォーマット固有のプログラム量を大幅に削減できる。通常、アプリケーションからファイルやハードウェアのメディア データを取得するには、データ フォーマットおよびハードウェア デバイスについてわからないことがあってはならない。接続、データ転送、必要なデータ変換、および実際のデータ レンダリングやファイル格納を、すべて処理する必要があるからである。フォーマットおよびデバイスはそれそれ微妙に異なるため、この処理は複雑で煩雑なものになることが多い。対照的に、マルチメディア ストリーミングを使用すると、ソースからアプリケーションに渡されるデータの転送と変換が自動的にネゴシエートされる。ストリーミング インターフェイスは、データのアクセスと制御のための均一でわかりやすいメソッドを提供する。アプリケーションでは、これらのメソッドを使用することによって、ソースやフォーマットにかかわりなく、データを簡単に再生することができる。

以下のステップは、ハードウェア デバイスからレンダリング再生へのストリーミングの実装方法を示す。

  1. ビデオ データのソース (Microsoft® DirectShow® など) が、ストリーミング インターフェイスを公開する。
  2. アプリケーション開発者が、マルチメディア ストリーミング インターフェイスを使用して、データ フォーマットを変換する。
  3. アプリケーション開発者が、Microsoft DirectDraw® インターフェイスを使用して、得られたデータをレンダリングする。

マルチメディア ストリームの仕様は、複数のインターフェイスから構成され、各インターフェイスは、ストリーム処理の特定の性質を制御するメソッドや、特定の種類のデータを処理するメソッドから構成される。詳細については、「マルチメディア ストリーミング インターフェイスの一覧」を参照すること。

オブジェクトの階層構造

次の図は、マルチメディア ストリーミングに使用する基本的なオブジェクトの階層構造を示す。

オブジェクトの階層構造

マルチメディア ストリーミング アーキテクチャには、以下の 3 種類の基本オブジェクトが定義されている。

  1. IMultiMediaStream インターフェイスをサポートするマルチメディア ストリーム。
  2. IMediaStream インターフェイスをサポートするデータ固有のメディア ストリーム。すべてのマルチメディア ストリームには、このメディア ストリームが少なくとも 1 つ含まれる。
  3. メディア ストリームによって作成され、IStreamSample インターフェイスをサポートするストリーム サンプル。このオブジェクトはストリームの基本的な処理単位である。

マルチメディア ストリーム オブジェクトとストリーム サンプルの作成

IMultiMediaStream インターフェイスをサポートするオブジェクトは、マルチメディア データ ストリームのための基本的なコンテナである。IMultiMediaStream インターフェイスには、オブジェクトのデータ ストリームを列挙するメソッドが含まれる。これらのストリームには、通常、ビデオ データおよびオーディオ データが含まれるが、クローズド キャプション、プレーン テキスト、SMPTE タイムコードなどの任意のフォーマットのデータを含めることができる。IMultiMediaStream インターフェイスは汎用コンテナだが、開発者はこのインターフェイスから特定のデータ フォーマットをサポートする別バージョンのインターフェイスを作成できる。たとえば、IAMMultiMediaStream インターフェイスを実装するオブジェクトは、DirectShow の任意のデータ フォーマットを持つストリームを列挙および制御できる。個々のデータ ストリームはフォーマット固有なので、これらのオブジェクトは、異なったインターフェイスを少なくとも 2 つ (汎用インターフェイスとデータ固有のインターフェイス) サポートする。すべてのストリームは、そのフォーマットとストリーム自体へのポインタを取得するメソッドを提供する IMediaStream インターフェイスをサポートする。一方、IDirectDrawMediaStream インターフェイスには、ビデオ データのレンダリングを専門に処理するメソッドが含まれる。IMultiMediaStream から派生するすべてのインターフェイスは、ストリーム サンプル (データ ストリーミングの基本単位) の作成もサポートする。

マルチメディア サンプルは、メディア データが格納されたオブジェクトへの参照である。ビデオ イメージでは、これが DirectDraw サーフェスとなる。サンプルの正確な内容は、メディアの種類 (サウンドやテキストなど) によって異なる。サンプルはデータ オブジェクトへの単なる参照なので、任意の数のストリーム サンプルから 1 つのサンプル オブジェクトを参照することができる。IStreamSample インターフェイスは、サンプルの特性 (開始タイム、終了タイム、状態、およびストリームとの関連) を取得および設定するメソッドを提供する。IStreamSample::Update メソッドは、ストリームが読み取り可能であれば、サンプルのデータに最新状態を反映する。また、ストリームが書き込み可能であれば、サンプルのデータをストリームに書き込む。通常、Update メソッドは、ストリーミング データをレンダリング、転送、または格納するループで使用する。

アプリケーションでのマルチメディア ストリームの使い方

マルチメディア ストリーミング インターフェイスは、ハードウェア ソースまたはソフトウェア ソースの特定の特性への依存性を排除し、Microsoft DirectX® の全メディア フォーマットのサポートを提供することにより、マルチメディア データの処理を大幅に単純化する。ストリームによってデータが非常に高いレベルまで抽象化されるため、アプリケーションでは、フォーマットをまったく意識せずに、データを別のストリームに移動できる。

マルチメディア ストリームを作成するには、以下のステップを実行する。

  1. マルチメディア ストリームを作成する。ストリームを作成および初期化するメソッドは、アーキテクチャ固有である。DirectShow は、ストリームの初期化に使用する IAMMultiMediaStream インターフェイスをサポートする。IMultiMediaStream のその他のインプロセス サーバー実装は、別のメカニズムを使用して作成および初期化される。
  2. マルチメディア ストリーム オブジェクトを初期化した後、アプリケーションでは、QueryInterface を使用してそのオブジェクトに対応する IMultiMediaStream インターフェイスを取得する。このインターフェイスを使用して、ストリームのプロパティを判断し、ストリーム自体を列挙する。個々のストリームを取得するには、目的 ID を指定して IMultiMediaStream::GetMediaStream メソッドを呼び出す。ビデオのプライマリ ストリームを表す MSPID_PrimaryVideo と、オーディオのプライマリ ストリームを表す MSPID_PrimaryAudio は、最もよく使用される目的 ID である。
  3. IUnknown::QueryInterface を呼び出して、ストリームのメディア タイプに固有のインターフェイスを照会する。たとえば、ビデオ ストリームをレンダリングするには、その IDirectDrawMediaStream インターフェイスを取得する。メディア固有のインターフェイスには、フォーマットの能力を十分引き出すために必要な追加メソッドが定義されている。
  4. ストリーム データから 1 つ以上のサンプルを作成する。すべてのメディア ストリームは、サンプルを作成する IMediaStream::CreateSharedSample メソッドをサポートする。作成されたサンプルは、サンプルとその特性の制御を提供する IStreamSample インターフェイスをサポートする。通常、メディア ストリームでは、この IStreamSample メソッドより強力なフォーマット固有のサンプル作成メソッドがサポートされる。たとえば、IDirectDrawMediaStream では、希望の DirectDraw サーフェスおよびクリッピング矩形にアタッチされたサンプルを作成できる。ただし、状況によっては、データのフォーマットを知らずにデータを処理しなければならないことがある。フォーマットに依存しない方法でデータをストリームするには、IMediaStream::CreateSharedSample メソッドを使用してデータ サンプルを作成する。
  5. 希望のストリーム サンプルをすべて作成した後、パラメータに STREAMSTATE_RUN フラグを指定して IMultiMediaStream::SetState メソッドを呼び出すことにより、ストリームを開始する。
  6. IStreamSample::Update を呼び出してストリーム サンプルを更新する。IStreamSample::Update メソッドが終了すると、サンプルのデータにアクセスできる。更新から戻ったときに特定のイベントを発行するか、または特定の関数を呼び出すには、IStreamSample::Update メソッドに適切なポインタを渡す。

マルチメディア ストリーミング インターフェイスの詳細については、「マルチメディア ストリーミング」を参照すること。

ストリーム間のデータ共有

マルチメディア データの処理には、通常、大量のシステム リソースが必要になる。したがって、データのコピーはできる限り避けなければならない。ストリーミング アーキテクチャは、データをコピーぜすに別のストリームに移動するためのメカニズムである、共有ストリーム サンプルをサポートする。このバッファを使用すると、基盤となるデータ フォーマットが転送先ストリームで明確にサポートされていなくても、2 つのストリーム間で効率よくデータを転送できる。

たとえば、3 つのデータ ストリーム (ビデオ、オーディオ、およびビデオ コンテンツに対応するタイム スタンプが入った URL データ) を持つマルチメディア ストリームがあり、ビデオ フレームすべてに著作権表記を追加し、保存のためにデータを別のストリームに書き込むアプリケーションを作成したいが、アプリケーションがビデオ ストリーム以外のデータ フォーマットを理解できないものと想定する。ビデオ ストリームについて、希望の DirectDraw サーフェスにアタッチされたサンプルを作成する。次に、同じサーフェスへのポインタを指定して IDirectDrawMediaStream::CreateSample メソッドを呼び出すか、または IMediaStream::CreateSharedSample を呼び出して、出力ストリームを作成する。どちらの場合も、入力ストリームと出力ストリームは DirectDraw サーフェスを共有する。ビデオ フォーマットは理解できるので、このサーフェスには必要に応じてアクセスすることができる。

その他のソース ストリーム ポインタ (オーディオおよび URL) を取得するには、ソース コンテナ ストリームを列挙して、ビデオ以外のストリームへのポインタを把握する。これらの各ソース ストリームには、出力ストリーム コンテナ内の出力ストリームが関連付けられている。ソース ストリーム ポインタそれぞれについて、出力コンテナ上の IMultiMediaStream::GetMediaStream メソッドを呼び出してこれらの出力ポインタを取得する。この処理は以下のステップで行われる。

  1. IMultiMediaStream::EnumMediaStreams を呼び出してソース ストリームへのポインタを取得する。ビデオ ストリームのフォーマットは既に理解しているので、ビデオ ストリームでないことを確認する。
  2. ステップ 1 で得られたポインタを指定して出力コンテナ ストリーム上の IMultiMediaStream::GetMediaStream を呼び出す。目的の出力ストリームへのポインタが返される。
  3. ソース ストリーム上の AllocateSample を呼び出す。
  4. 出力ストリーム上の CreateSharedSample を呼び出す。
  5. ソース ストリーム上の Update を呼び出してデータを読み取る。
  6. 出力ストリーム上の Update を呼び出してデータを書き込む。

フォーマットをサポートしないストリームそれぞれについて、これらのステップを繰り返す。両方のサンプルが更新を終了すると、ソース ストリームのデータがすべて出力ストリームに渡され、処理が完了する。