メディア シンク

メディア シンク は、メディア データを受信するパイプライン オブジェクトです。 メディア シンクは、1 つ以上のメディア ストリームの宛先です。 メディア シンクは、次の 2 つの一般的なカテゴリに分類されます。

  • レンダラーは、再生用のデータを表示するメディア シンクです。 拡張ビデオ レンダラー (EVR) はビデオ フレームを表示し、オーディオ レンダラーはサウンド カードまたはその他のオーディオ デバイスを介してオーディオ ストリームを再生します。

  • アーカイブ シンクは、ファイルまたはその他のストレージにデータを書き込むメディア シンクです。

メイン違いは、アーカイブ シンクが一定の再生速度でデータを使用しないということです。 代わりに、受け取ったデータをできるだけ早く書き込みます。

メディア シンクは、 IMFMediaSink インターフェイスを 公開します。 各メディア シンクには、1 つ以上の ストリーム シンクが含まれています。 各ストリーム シンクは、1 つのストリームからデータを受信します。 ストリーム シンクは、 IMFStreamSink インターフェイスを 公開します。 通常、アプリケーションはメディア シンクを直接作成しません。 代わりに、アプリケーションは、メディア セッションがシンクの作成に使用する 1 つ以上のアクティブ化オブジェクトを作成します。 シンクに対する他のすべての操作はメディア セッションによって処理され、アプリケーションはメディア シンクまたはストリーム シンクのメソッドを呼び出しません。 アクティブ化オブジェクトの詳細については、「アクティブ オブジェクト」を参照してください。

カスタム メディア シンクを作成する場合、またはメディア セッションなしでメディア シンクを直接使用する場合は、このトピックの残りの部分をお読みください。

ストリーム シンク

メディア シンクには、固定数のストリーム シンクを含めることができます。または、ストリーム シンクの追加と削除をサポートすることもできます。 固定数のストリーム シンクがある場合、 IMFMediaSink::GetCharacteristics メソッドは MEDIASINK_FIXED_STREAMS フラグを返します。 それ以外の場合は、ストリーム シンクを追加および削除できます。 新しいストリーム シンクを追加するには、 IMFMediaSink::AddStreamSink を呼び出します。 ストリーム シンクを削除するには、 IMFMediaSink::RemoveStreamSink を呼び出します。 MEDIASINK_FIXED_STREAMS フラグは、メディア シンクでこれら 2 つのメソッドがサポートされていないことを示します。 (シンクの作成時に初期化パラメーターを設定するなど、ストリームの数を構成する他の方法がサポートされている場合があります)。ストリーム シンクの一覧は順序付けされます。 インデックス値で列挙するには、 IMFMediaSink::GetStreamSinkByIndex メソッドを呼び出します。

ストリーム シンクにも識別子があります。 ストリーム識別子はメディア シンク内で一意ですが、連続する必要はありません。 メディア シンクによっては、ストリーム識別子にコンテンツに関連する意味がある場合があります。 たとえば、アーカイブ シンクは、ストリーム識別子をファイル ヘッダーに書き込む場合があります。 それ以外の場合は任意です。 ストリーム シンクを識別子で取得するには、 IMFMediaSink::GetStreamSinkById を呼び出します。

プレゼンテーションクロック

メディア シンクがサンプルを消費する速度は、 プレゼンテーション クロックによって制御されます。 メディア セッションは、プレゼンテーション クロックを選択し、メディア シンクの IMFMediaSink::SetPresentationClock メソッドを呼び出してメディア シンクに設定します。 ストリーミングを開始するには、メディア シンクでプレゼンテーション クロックを設定する必要があります。 すべてのメディア シンクを実行するには、プレゼンテーション クロックが必要です。 メディア シンクは、次の 2 つの目的でプレゼンテーション クロックを使用します。

  • ストリーミングの開始または停止時に通知を受信する。 メディア シンクは、すべてのメディア シンクが実装する必要がある IMFClockStateSink インターフェイスを介してこれらの通知を受け取ります。

  • サンプルをレンダリングするタイミングを決定します。 メディア シンクは、新しいサンプルを受け取ると、サンプルからタイム スタンプを取得し、そのプレゼンテーション時にサンプルのレンダリングを試みます。

プレゼンテーション クロックは、プレゼンテーション タイム ソースと呼ばれる別のオブジェクトからクロック時間を派生 させます。 プレゼンテーション時間ソースは、 IMFPresentationTimeSource インターフェイスを 公開します。 一部のメディア シンクでは、正確なクロックにアクセスできるため、このインターフェイスが公開されます。 つまり、メディア シンクは、独自のクロックによって提供される時間に対してサンプルをスケジュールする可能性があります。 ただし、メディア シンクでは、これが当てはまるとは想定できません。 プレゼンテーション クロックがメディア シンク自体または他のクロックによって駆動されているかどうかに関係なく、プレゼンテーション クロックからの時刻を常に使用する必要があります。

メディア シンクがそれ自体以外のクロックとレートを一致させることができない場合、 GetCharacteristics メソッドは MEDIASINK_CANNOT_MATCH_CLOCK フラグを返します。 このフラグが存在し、プレゼンテーション クロックで別のプレゼンテーションタイム ソースが使用されている場合、メディア シンクのパフォーマンスが低下する可能性があります。 たとえば、再生中に不具合が発生する可能性があります。

レートレス シンクは、サンプルのタイム スタンプを無視し、各サンプルが到着するとすぐにデータを使用するメディア シンクです。 レートレス メディア シンクは 、GetCharacteristics メソッドからMEDIASINK_RATELESS フラグを返します。 通常、このフラグはアーカイブ シンクに適用されます。 パイプライン内のすべてのメディア シンクがレートレスの場合、メディア セッションでは特別なレートなしのプレゼンテーション クロックが使用されます。 このクロックは、シンクがサンプルを消費するのと同じくらい迅速に実行されます。

ストリーム形式

メディア シンクがサンプルを受け取る前に、クライアントはストリーム シンクにメディアの種類を設定する必要があります。 メディアの種類を設定するには、ストリーム シンクの IMFStreamSink::GetMediaTypeHandler メソッドを 呼び出します。 このメソッドは、 IMFMediaTypeHandler インターフェイスへのポインターを返します。 このインターフェイスを使用して、優先メディアの種類の一覧を取得し、現在のメディアの種類を取得し、メディアの種類を設定します。

優先されるメディアの種類の一覧を取得するには、 IMFMediaTypeHandler::GetMediaTypeByIndex を呼び出します。 推奨される型は、クライアントのヒントとして使用する必要があります。 リストが不完全であるか、部分的なメディアタイプが含まれている可能性があります。 部分メディア・タイプは、有効な形式を記述するために必要なすべての属性を持たないタイプです。 たとえば、部分的なビデオの種類では、イメージの幅や高さではなく、色空間とビット深度を指定できます。 部分的なオーディオの種類では、圧縮形式とサンプル レートを指定できますが、オーディオ チャネルの数は指定できません。

ストリーム シンクの現在のメディアの種類を取得するには、 IMFMediaTypeHandler::GetCurrentMediaType を呼び出します。 ストリーム シンクが最初に作成されるときに、既定のメディアの種類が既に設定されているか、クライアントがメディアの種類を設定するまでメディアの種類がない可能性があります。

メディアの種類を設定するには、 IMFMediaTypeHandler::SetCurrentMediaType を呼び出します。 一部のストリーム シンクでは、 が設定された後の型の変更がサポートされない場合があります。 そのため、メディアの種類を設定する前にテストすると便利です。 メディア シンクが (型を設定せずに) メディアの種類を受け入れるかどうかをテストするには、 IMFMediaTypeHandler::IsMediaTypeSupported を呼び出します。

Data Flow

メディア シンクでは プル モデルが使用されます。つまり、ストリーム シンクは必要に応じてデータを要求します。 クライアントは、不具合を回避するためにタイムリーに応答する必要があります。

一部のメディア シンクでは 、事前登録がサポートされています。 事前登録は、プレゼンテーション クロックが開始される前にメディア シンクにデータを提供するプロセスです。 メディア シンクでプリロールがサポートされている場合、メディア シンクは IMFMediaSinkPreroll インターフェイスを公開し、 GetCharacteristics メソッドは MEDIASINK_CAN_PREROLL フラグを返します。 事前登録により、プレゼンテーション クロックの開始時にメディア シンクで最初のサンプルを表示する準備が整います。 メディア シンクでサポートされている場合は、再生中のグリッチやギャップを防ぐことができるため、クライアントは常に事前登録することをお勧めします。

メディア シンクへのデータ フローは、次のように機能します。

  1. クライアントは、メディアの種類とプレゼンテーションクロックを設定します。 メディア シンクは、クロック状態の変更に関する通知を受け取るために、プレゼンテーション クロックに自身を登録します。
  2. 必要に応じて、クライアントは IMFMediaSinkPreroll を照会します。 メディア シンクがこのインターフェイスを公開している場合、クライアントは IMFMediaSinkPreroll::NotifyPreroll を呼び出します。 それ以外の場合、クライアントは手順 5 に進みます。
  3. 各ストリーム シンクは、1 つ以上 の MEStreamSinkRequestSample イベントを 送信します。 これらの各イベントに応答して、クライアントはそのストリームのデータの次のサンプルを取得し 、IMFStreamSink::P rocessSample を呼び出します。
  4. 各ストリーム シンクは、十分なプリロール データを受信すると、 MEStreamSinkPrerolled イベントを 送信します。
  5. クライアントは IMFPresentationClock::Start を呼び出してプレゼンテーション クロックを開始します。
  6. プレゼンテーション クロックは、 IMFClockStateSink::OnClockStart を呼び出すことによって、クロックが開始されていることをメディア シンクに通知します。
  7. より多くのデータを取得するために、各ストリーム シンクは MEStreamSinkRequestSample イベントを 送信します。 これらの各イベントに応答して、クライアントは次のサンプルを取得し、 ProcessSample を呼び出します。 この手順は、プレゼンテーションが終了するまで繰り返されます。

ほとんどのメディア シンクはサンプルを非同期的に処理するため、ストリーム シンクは一度に複数のサンプル要求を送信できます。

ストリーミング中、クライアントはいつでも IMFStreamSink::P laceMarkerIMFStreamSink::Flush を呼び出すことができます。 マーカーについては、次のセクションで説明します。 フラッシュすると、キューに入っているがレンダリングされていないサンプルがストリーム シンクによって削除されます。

マーカー

マーカーは、クライアントがストリーム内の特定のポイントを示す方法を提供します。 マーカーは、次の情報で構成されます。

  • MFSTREAMSINK_MARKER_TYPE列挙体のメンバーとして定義されたマーカーの種類。
  • マーカーに関連付けられているデータ。 データの意味は、マーカーの種類によって異なります。 一部のマーカーの種類にはデータがありません。
  • クライアント独自の使用のためのオプションのデータ。

マーカーを配置するために、クライアントは IMFStreamSink::P laceMarker を呼び出します。 ストリーム シンクは 、PlaceMarker 呼び出しの前に受信したサンプルの処理を完了し、 MEStreamSinkMarker イベントを送信します。

ほとんどのメディア シンクでは、保留中のサンプルのキューが保持され、非同期的に処理されます。 マーカー イベントはサンプル処理でシリアル化する必要があるため、メディア シンクはマーカーを同じキューに配置する必要があります。 たとえば、クライアントが次のメソッド呼び出しを行うとします。

  1. ProcessSample (サンプル #1)
  2. ProcessSample (サンプル #2)
  3. PlaceMarker (マーカー #1)
  4. ProcessSample (サンプル #3)
  5. PlaceMarker (マーカー #2)

この例では、ストリーム シンクは、サンプル #2 を処理した後にマーカー #1 の MEStreamSinkMarker イベントを送信し、サンプル #3 を処理した後のマーカー #2 のイベントを送信する必要があります。

クライアントがストリーム シンクをフラッシュすると、ストリーム シンクはキューにあったマーカーを直ちに処理します。 これらのイベントにE_ABORT状態コードを設定します。

一部のマーカーには、メディア シンクに関連する情報が含まれています。

  • MFSTREAMSINK_MARKER_TICK: ストリームにギャップがあることを示します。 次のサンプルは不連続です。
  • MFSTREAMSINK_MARKER_ENDOFSEGMENT: セグメントの末尾またはストリームの末尾を示します。 次のサンプル (ある場合) は不連続である可能性があります。
  • MFSTREAMSINK_MARKER_EVENT: イベントが含まれています。 イベントの種類とメディア シンクの実装によっては、メディア シンクがイベントを処理したり、無視したりする場合があります。

State Changes (状態の変化)

メディア シンクには、メディア シンクの IMFClockStateSink インターフェイスを介して、プレゼンテーション クロックの状態の変化が通知されます。 クライアントがプレゼンテーション クロックを設定すると、メディア シンクは IMFPresentationClock::AddClockStateSink を呼び出して、クロックからの通知に自身を登録します。 次の表は、クロック状態の変化に応じてメディア シンクがどのように動作するかをまとめたものです。

クロック状態の変更 サンプル処理 マーカー処理
OnClockStart タイム スタンプがクロック開始時刻以上のサンプルを処理します。 マーカーが処理される前にすべてのサンプルを受信したときに MEStreamSinkMarker イベントを送信します。
OnClockPause メディア シンクは、一時停止中に ProcessSample に失敗する可能性があります。
メディア シンクが一時停止中にサンプルを受け入れる場合は、クロックが再起動されるまでキューに入れる必要があります。 一時停止中は、キューに登録されたサンプルを処理しないでください。
キューに入っているサンプルがある場合は、マーカーを同じキューに配置します。 クロックが再起動したときにマーカー イベントを送信します。
それ以外の場合は、マーカー イベントをすぐに送信します。
OnClockRestart 一時停止中にキューに入れられていたサンプルを処理し、 OnClockStart と同じように処理します。 キューに置かれているマーカー (サンプル処理でシリアル化) の MEStreamSinkMarker イベントを送信し、 OnClockStart と同じように処理します。
OnClockStop キューに登録されているすべてのサンプルを削除します。 ProcessSample のそれ以上の呼び出しは失敗する可能性があります。 キューに登録されたマーカー イベントを送信します。 PlaceMarker の後続の呼び出しで、マーカー イベントをすぐに送信します。

 

さらに、ストリーム シンクは、状態遷移が完了したときに次のイベントを送信する必要があります。

終了処理中

一部のメディア シンクでは、最後のサンプルが配信された後に追加の処理手順が必要です。 通常、この要件は、ヘッダーまたはインデックスをファイルに書き込む必要があるアーカイブ シンクに適用されます。 メディア シンクで最終的な処理が必要な場合は、 IMFFinalizableMediaSink インターフェイスが公開されます。

クライアントが最後のサンプルを提供した後、クライアントはこのインターフェイスに対してクエリを実行します。 メディア シンクで インターフェイスがサポートされている場合、クライアント は IMFFinalizableMediaSink::BeginFinalize を呼び出して、最終的な処理を非同期的に実行します。 このメソッドは、「 非同期コールバック メソッド」で説明されている標準的な Media Foundation 非同期モデルに従います。 メディア シンクは、クライアントが BeginFinalize を呼び出すと想定できます。 BeginFinalize の呼び出しに失敗すると、ファイルが正しく作成されない可能性があります。

シャットダウン

クライアントがメディア シンクを使用して完了すると、クライアントは IMFMediaSink::Shutdown を呼び出します。 このメソッド内では、メディア シンクは循環参照数を中断する必要があります。 通常、メディア シンクとストリーム シンクの間には循環参照があります。

イベント キュー ヘルパー オブジェクトを使用して IMFMediaEventGenerator を実装する場合は、イベント キューで IMFMediaEventQueue::Shutdown を呼び出します。 このメソッドは、イベント キューをシャットダウンし、現在イベントを待機している呼び出し元に通知します。

シャットダウン後、メディア シンク上のすべてのメソッドは、 IUnknown メソッドを除き、MF_E_SHUTDOWNを返します。

メディア シンク インターフェイス

次の表は、メディア シンクが QueryInterface を介して公開できる標準インターフェイスの一覧です。 メディア シンクでは、カスタム インターフェイスを公開することもできます。

インターフェイス 説明
IMFMediaSink メディア シンクのプライマリ インターフェイス。 (必須)
IMFClockStateSink プレゼンテーション クロックの状態が変化したときにメディア シンクに通知するために使用されます。 (必須)
IMFFinalizableMediaSink メディア シンクが最終的な処理手順を実行する必要がある場合に を実装します。 (省略可能)
IMFGetService メディア シンクがサービス インターフェイスを公開する場合は を実装します。 (省略可能)
IMFMediaEventGenerator メディア シンクがイベントを送信する場合は を実装します。 (省略可能)
IMFMediaSinkPreroll メディア シンクがプリロールをサポートしている場合は を実装します。 (省略可能)
IMFPresentationTimeSource メディア シンクがプレゼンテーション クロックのタイム ソースを提供できるかどうかを実装します。 (省略可能)
IMFQualityAdvise メディア シンクが再生品質を調整できるかどうかを実装します。 (省略可能)

 

必要に応じて、メディア シンクは次のインターフェイスをサービスとして実装できます。

サービス インターフェイス Description
IMFRateSupport サポートされている再生レートの範囲を報告します。

 

サービス インターフェイスと IMFGetService の詳細については、「 サービス インターフェイス」を参照してください。

ストリーム シンク インターフェイス

ストリーム シンクは、 QueryInterface を介して次のインターフェイスを公開する必要があります。

インターフェイス 説明
IMFStreamSink ストリーム シンクのプライマリ インターフェイス。 (必須)
IMFMediaEventGenerator イベントをキューに入れます。 IMFStreamSink インターフェイスはこのインターフェイスを継承します。 (必須)

 

現在、ストリーム シンクのサービス インターフェイスは定義されていません。

Stream Sink イベント

次の表に、汎用ストリーム シンクに対して定義されているイベントを示します。 ストリーム シンクは、ここに記載されていないカスタム イベントを送信することもできます。

Event 説明
MEStreamSinkFormatChanged ストリーム シンクのメディアの種類が無効になっています。 (省略可能)
MEStreamSinkMarker マーカーが処理されました。 (必須)
MEStreamSinkPaused ストリーム シンクが一時停止しました。 (必須)
MEStreamSinkPrerolled 事前登録が完了しました。 (省略可能)
MEStreamSinkRateChanged ストリーム シンクの再生速度が変更されました。 (省略可能)
MEStreamSinkRequestSample 新しいサンプルが要求されます。 (必須)
MEStreamSinkScrubSampleComplete スクラブ要求が完了しました。 (省略可能)
MEStreamSinkStarted ストリーム シンクが開始されました。 (必須)
MEStreamSinkStopped ストリーム シンクが停止しました。 (必須)

 

現在、メディア シンクに対して汎用イベントは定義されていません。 メディア シンクによっては、カスタム イベントが送信される場合があります。

Media Foundation パイプライン

メディア ファンデーションのアーキテクチャ