表示時間のシーケンス
このトピックでは、再生中に Sequencer Source がプレゼンテーション時間を処理する方法について説明します。
概要
シーケンサー ソースでは、プレイリスト シーケンスと編集シーケンスという 2 つの異なるモードがサポートされています。
編集シーケンスでは、アプリケーションは再生を開始する前に、各セグメントの期間を事前に指定します。 プレイリストシーケンスでは、アプリケーションは事前に期間を指定しません。 (実際には、期間が不明な場合があります)。
どちらの場合も、セグメントのメディア開始時間とメディア停止時間を指定できます。 これらの時間は、セグメントが開始および終了するソース ファイル内の位置を指定します。 たとえば、ソース ファイルの長さが 90 秒であるとします。 最初の 10 秒と最後の 10 秒をトリミングする場合は、次の値を指定します。
- メディアの開始: 10 秒
- メディア停止: 80 秒
メディアの開始時刻を指定するには、ソース ノードで MF_TOPONODE_MEDIASTART 属性を設定します。 メディアの停止時間を指定するには、ソース ノードで MF_TOPONODE_MEDIASTOP 属性を設定します。
編集シーケンスを作成するには、メディア セッションの作成時に MF_SESSION_GLOBAL_TIME 属性を設定します。 それ以外の場合、メディア セッションではプレイリスト シーケンスが必要です。 編集シーケンスでは、すべてのセグメント トポロジに MF_TOPOLOGY_PROJECTSTART 属性と MF_TOPOLOGY_PROJECTSTOP 属性が必要です。
プレイリスト シーケンス
プレイリスト シーケンスでは、プレゼンテーション クロックは 0 から始まり、セグメント境界を越えて続行されます。 ネイティブ ソースは、メディア時間と等しいタイムスタンプを含むサンプルを提供します。 パイプラインは、タイムスタンプを次のように正しいプレゼンテーション時刻に変換します。
- 新しいタイム スタンプ = メディア時間 + オフセット - メディアの開始
offset の値は、前のセグメントが終了したプレゼンテーション時刻です。 最初のセグメントの場合、オフセットは 0 です。 これらのタイムスタンプ変換の計算方法の 2 つの例を次に示します。
- 例 1: 最初のセグメント (S1) の長さが 10 秒で、2 番目のセグメント (S2) のメディア開始時刻が 0 であるとします。 ネイティブ ソースでは、タイム スタンプにメディア時間が使用されるため、S2 からの最初のサンプルのタイム スタンプは 0 です。 オフセットは 10 秒 (S1 の期間) であるため、調整されたタイム スタンプは:0 + 10 - 0 = 10 秒です。
- 例 2: セグメント S1 の長さが 10 秒で、S2 のメディア開始時刻が 5 秒であるとします。 S2 からの最初のサンプルのタイムスタンプは 5 秒 (メディア時間) です。 オフセットは 10 秒であるため、調整されたタイム スタンプは 5 + 10 - 5 = 10 秒です。
ソース ノードから下流にあるすべてのパイプライン コンポーネントは、調整されたタイム スタンプを含むサンプルを受け取ります。 トポロジ内のソース ノードには異なるメディア開始時刻を設定できるため、調整はトポロジのブランチごとに個別に計算されます。
プレゼンテーションが次のセグメントに切り替わると、プレゼンテーション クロックが停止またはリセットされず、プレゼンテーション時間が単調に増加します。 新しいセグメントが開始される前に、メディア セッションはアプリケーションに MESessionNotifyPresentationTime イベントを 送信します。 イベントは、プレゼンテーション クロックを基準としたセグメントの開始時刻とオフセットの値を指定します。 新しいセグメントが開始されると、パイプラインは値 VT_EMPTYを使用してシーケンサー ソースで Start を呼び出します。 シーケンサー ソースは、開始時刻なしで MESourceStarted イベントを送信します。
シークするために、アプリケーションはセグメント識別子とセグメント内の時間オフセットを指定します。 シークの後、プレゼンテーション クロックは セグメント オフセットから開始されます。 そのプロセスのしくみの例を次に示します。
- 例 3: アプリケーションは、セグメント オフセットが 10 秒のセグメント S3 をシークします。 プレゼンテーション クロックは 10 秒 (セグメント オフセット) から始まります。 オフセットには、セグメント S1 と S2 の継続時間は含まれません。 シーケンサー ソースは、セグメント オフセット (10 秒) と等しい開始時刻を持つ MESourceStarted イベントを送信します。
シーク後、再生が次のセグメントに続く場合、オフセットにスキップされたセグメントが含まれていない点を除き、画面切り替えは前の例と同様に機能します。
サンプルのタイムスタンプ付け方法に影響を与える詳細を次に示します。
- デコーダーでは、メディアの停止時間を超えるデータが必要になる場合があります。 パイプラインは、デコーダーに必要な量のデータをソースからプルし、デコーダーの出力サンプルをトリミングします。
- 変換によってデータがバッファーに格納される場合があります。 たとえば、オーディオ効果でこれを行う必要がある場合があります。 セグメントが終了すると、変換が一部のデータを保持しているため、変換の最後のサンプルのタイム スタンプはセグメントの末尾よりも前になります。 次のセグメントが開始されると、最初のサンプルのタイム スタンプはセグメントの開始より少し早くなります。 タイム スタンプにギャップがないため、メディア シンクに到達するデータは連続しています。 最後のセグメントが終了すると、パイプラインによって変換がドレインされるため、データは失われません。
- 前のキー フレームを取得するには、メディアの開始時刻より少し早くソースを開始する必要がある場合があります。 したがって、調整後、最初のサンプルのプレゼンテーション時間が負になる可能性があります。
シーケンスの編集
編集シーケンスでは、アプリケーションは、 MF_TOPOLOGY_PROJECTSTART 属性と MF_TOPOLOGY_PROJECTSTOP 属性を設定することによって、セグメント境界を事前に指定します。 パイプラインは、プレイリスト シーケンスの場合とほぼ同じ方法でタイムスタンプの調整を計算します。
オフセットでは、セグメントの観測された終端を使用する代わりに、 MF_TOPOLOGY_PROJECTSTARTの値を使用します。
シークの場合、オフセットでは、セグメントの MF_TOPOLOGY_PROJECTSTART 値にセグメント オフセットを加えた値が使用されます。
したがって、アプリケーションが別のセグメントをシークする場合でも、編集シーケンス内のプレゼンテーション時間は常にプレゼンテーションの開始に対して相対的になります。
関連トピック