メディア シンク
メディア シンク は、メディア データを受信するパイプライン オブジェクトです。 メディア シンクは、1 つ以上のメディア ストリームの宛先です。 メディア シンクは、次の 2 つの一般的なカテゴリに分類されます。
レンダラー は、再生用のデータを提示するメディア シンクです。 拡張ビデオ レンダラー (EVR) はビデオ フレームを表示し、オーディオ レンダラーはサウンド カードまたはその他のオーディオ デバイスを介してオーディオ ストリームを再生します。
アーカイブ シンク は、ファイルまたはその他のストレージにデータを書き込むメディア シンクです。
それらの主な違いは、アーカイブ シンクが固定再生レートでデータを使用しないことです。 代わりに、受信したデータをできるだけ早く書き込みます。
メディア シンクは、IMFMediaSink インターフェイスを公開します。 各メディア シンクには、1 つ以上のストリーム シンクが含まれています。 各ストリーム シンクは、1 つのストリームからデータを受信します。 ストリーム シンクは、IMFStreamSink インターフェイスを公開します。 通常、アプリケーションはメディア シンクを直接作成しません。 代わりに、アプリケーションによって 1 つ以上のアクティブ化オブジェクトが作成されます。このオブジェクトは、メディア セッションがシンクの作成に使用します。 シンクに対するその他のすべての操作はメディア セッションによって処理され、アプリケーションはメディア シンクまたはストリーム シンクのメソッドを呼び出しません。 アクティブ化オブジェクトの詳細については、「アクティブ化オブジェクトの をする」を参照してください。
カスタム メディア シンクを作成する場合、またはメディア セッションなしで直接メディア シンクを使用する場合は、このトピックの残りの部分を読む必要があります。
- ストリーム シンク
- プレゼンテーション クロック
- ストリーム形式の
- データ フローの
- マーカーの
- 状態の変更
- finalizing
- シャットダウン
- メディア シンク インターフェイス
- ストリーム シンク インターフェイスの
- ストリーム シンク イベント
- 関連トピック
ストリーム シンク
メディア シンクには、固定数のストリーム シンクを含めることができます。また、ストリーム シンクの追加と削除をサポートすることもできます。 固定数のストリーム シンクがある場合、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呼び出します。
データ フロー
メディア シンクは、プル モデルを使用します。つまり、ストリーム シンクは必要に応じてデータを要求します。 クライアントは、障害を回避するために、タイムリーに応答する必要があります。
一部のメディア シンクでは、プリロールがサポートされています。 事前登録は、プレゼンテーション クロックが開始する前にメディア シンクにデータを渡すプロセスです。 メディア シンクでプリロールがサポートされている場合、メディア シンクは IMFMediaSinkPreroll インターフェイスを公開し、GetCharacteristics メソッドはMEDIASINK_CAN_PREROLL フラグを返します。 事前登録により、プレゼンテーション クロックの開始時にメディア シンクで最初のサンプルを表示する準備が整います。 メディア シンクでサポートされている場合は、再生中にグリッチやギャップを防ぐことができるため、クライアントは常にプリロールすることをお勧めします。
メディア シンクへのデータ フローは次のように機能します。
- クライアントは、メディアの種類とプレゼンテーションクロックを設定します。 メディア シンクは、プレゼンテーション クロックに自身を登録して、クロック状態の変更に関する通知を受け取ります。
- 必要に応じて、クライアントは IMFMediaSinkPrerollクエリを実行します。 メディア シンクがこのインターフェイスを公開している場合、クライアントは IMFMediaSinkPreroll::NotifyPrerollを呼び出します。 それ以外の場合、クライアントは手順 5 に進みます。
- 各ストリーム シンクは、MEStreamSinkRequestSample イベント 1 つ以上を送信します。 これらの各イベントに応答して、クライアントはそのストリームのデータの次のサンプルを取得し、IMFStreamSink::P rocessSample呼び出します。
- 各ストリーム シンクは、十分なプリロール データを受信すると、MEStreamSinkPrerolled イベントを送信します。
- クライアントは、IMFPresentationClock::Start呼び出して、プレゼンテーション クロックを開始します。
- プレゼンテーション クロックは、IMFClockStateSink::OnClockStart呼び出すことによって、クロックが開始されていることをメディア シンクに通知します。
- より多くのデータを取得するために、各ストリーム シンクは MEStreamSinkRequestSample イベント 送信します。 これらの各イベントに応答して、クライアントは次のサンプルを取得し、ProcessSample呼び出します。 この手順は、プレゼンテーションが終了するまで繰り返されます。
ほとんどのメディア シンクはサンプルを非同期的に処理するため、ストリーム シンクは一度に複数のサンプル要求を送信できます。
ストリーミング中に、クライアントは IMFStreamSink::P laceMarker を呼び出し、いつでも IMFStreamSink::Flushをできます。 マーカーについては、次のセクションで説明します。 フラッシュすると、ストリーム シンクは、キューに入れられていますが、まだレンダリングされていないサンプルを削除します。
マーカー
マーカーは、クライアントがストリーム内の特定のポイントを示す方法を提供します。 マーカーは、次の情報で構成されます。
- MFSTREAMSINK_MARKER_TYPE 列挙体のメンバーとして定義されたマーカーの種類。
- マーカーに関連付けられているデータ。 データの意味は、マーカーの種類によって異なります。 一部のマーカーの種類にはデータがありません。
- クライアント自身が使用するオプションのデータ。
マーカーを配置するために、クライアントは IMFStreamSink::P laceMarker呼び出します。 ストリーム シンクは、PlaceMarker 呼び出しの前に受信したサンプルの処理を完了し、MEStreamSinkMarker イベントを送信します。
ほとんどのメディア シンクでは、保留中のサンプルのキューが保持され、非同期的に処理されます。 マーカー イベントはサンプル処理でシリアル化する必要があるため、メディア シンクはマーカーを同じキューに配置する必要があります。 たとえば、クライアントが次のメソッド呼び出しを行うとします。
- ProcessSample (サンプル #1)
- ProcessSample (サンプル #2)
- PlaceMarker (マーカー #1)
- ProcessSample (サンプル #3)
- PlaceMarker (マーカー #2)
この例では、ストリーム シンクは、サンプル #2 を処理した後にマーカー #1 の MEStreamSinkMarker イベントを送信し、サンプル #3 を処理した後にマーカー #2 のイベントを送信する必要があります。
クライアントがストリーム シンクをフラッシュすると、ストリーム シンクはキューにあったマーカーを直ちに処理します。 これらのイベントにE_ABORT状態コードを設定します。
一部のマーカーには、メディア シンクに関連する情報が含まれています。
- MFSTREAMSINK_MARKER_TICK: ストリームにギャップがあることを示します。 次のサンプルは不連続です。
- MFSTREAMSINK_MARKER_ENDOFSEGMENT: セグメントの末尾またはストリームの末尾を示します。 次のサンプル (ある場合) は不連続である可能性があります。
- MFSTREAMSINK_MARKER_EVENT: イベントが含まれています。 イベントの種類とメディア シンクの実装によっては、メディア シンクがイベントを処理したり、無視したりする場合があります。
状態の変更
メディア シンクは、メディア シンクの IMFClockStateSink インターフェイスを介して、プレゼンテーション クロックの状態変化を通知します。 クライアントがプレゼンテーション クロックを設定すると、メディア シンクは IMFPresentationClock::AddClockStateSink呼び出して、クロックからの通知に自身を登録します。 次の表は、クロック状態の変化に応じてメディア シンクがどのように動作するかをまとめたものです。
クロック状態の変化 | サンプル処理 | マーカー処理 |
---|---|---|
OnClockStartをする | タイム スタンプがクロック開始時刻以上のサンプルを処理します。 | マーカーが処理される前に受け取ったすべてのサンプルが処理されたときに、MEStreamSinkMarker イベントを送信します。 |
OnClockPauseをする | メディア シンクは、一時停止中に ProcessSample失敗する可能性があります。 メディア シンクが一時停止中にサンプルを受け入れる場合は、クロックが再起動するまでそれらをキューに入れる必要があります。 一時停止中は、キューに置かれたサンプルを処理しないでください。 |
キューに置かれたサンプルがある場合は、マーカーを同じキューに配置します。 クロックが再起動したときにマーカー イベントを送信します。 それ以外の場合は、マーカー イベントをすぐに送信します。 |
OnClockRestartの | 一時停止中にキューに置かれたサンプルを処理し、OnClockStartと同じ処理を行います。 | キュー マーカー (サンプル処理でシリアル化) の MEStreamSinkMarker イベントを送信し、OnClockStartと同じように処理します。 |
OnClockStopをする | キューに登録されているすべてのサンプルを削除します。 ProcessSample のその他の呼び出しは失敗する可能性があります。 | キューに登録されたマーカー イベントを送信します。 PlaceMarkerをする後続の呼び出しでは、マーカー イベントをすぐに送信します。 |
さらに、ストリーム シンクは、状態遷移が完了したときに次のイベントを送信する必要があります。
- OnClockStart、OnClockRestart: MEStreamSinkStarted イベント
- OnClockPause: MEStreamSinkPaused イベントを します
- OnClockStop: MEStreamSinkStopped イベントを します
確定
一部のメディア シンクでは、最後のサンプルの配信後に追加の処理手順が必要です。 通常、この要件は、ヘッダーまたはインデックスをファイルに書き込む必要があるアーカイブ シンクに適用されます。 メディア シンクで最終的な処理が必要な場合は、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 | メディア シンクが再生品質を調整できるかどうかを実装します。 (省略可能)。) |
必要に応じて、メディア シンクは次のインターフェイスをサービスとして実装できます。
サービス インターフェイス | 形容 |
---|---|
IMFRateSupportをする | サポートされている再生レートの範囲を報告します。 |
サービス インターフェイスと IMFGetServiceの詳細については、「サービス インターフェイスの」を参照してください。
ストリーム シンク インターフェイス
ストリーム シンクは、QueryInterfaceを介して次のインターフェイスを公開する必要があります。
インターフェイス | 形容 |
---|---|
IMFStreamSink | ストリーム シンクのプライマリ インターフェイス。 (必須)。) |
IMFMediaEventGeneratorの | キュー イベント。 IMFStreamSink インターフェイスはこのインターフェイスを継承します。 (必須)。) |
現在、ストリーム シンクに対してサービス インターフェイスは定義されていません。
Stream Sink イベント
次の表に、汎用ストリーム シンクに定義されているイベントを示します。 ストリーム シンクは、ここに記載されていないカスタム イベントを送信することもできます。
出来事 | 形容 |
---|---|
MEStreamSinkFormatChanged の | ストリーム シンクのメディアの種類が無効です。 (省略可能)。) |
MEStreamSinkMarker の | マーカーが処理されました。 (必須)。) |
MEStreamSinkPaused の | ストリーム シンクが一時停止しました。 (必須)。) |
MEStreamSinkPrerolled の | プリロールが完了しました。 (省略可能)。) |
MEStreamSinkRateChanged の | ストリーム シンクの再生速度が変更されました。 (省略可能)。) |
MEStreamSinkRequestSample の | 新しいサンプルが要求されます。 (必須)。) |
MEStreamSinkScrubSampleComplete | スクラブ要求が完了しました。 (省略可能)。) |
MEStreamSinkStarted の | ストリーム シンクが開始されました。 (必須)。) |
MEStreamSinkStopped | ストリーム シンクが停止しました。 (必須)。) |
現在、メディア シンクに対して汎用イベントは定義されていません。 一部のメディア シンクでは、カスタム イベントが送信される場合があります。
関連トピック