リアルタイム ストリーム

リアルタイムのタイムスタンプ

MediaPipe 計算グラフは、動画や音声のストリームを処理するためによく使用される インタラクティブなアプリ用のフレームです。MediaPipe フレームワークで必要なのは、 連続するパケットには、単調に増加するタイムスタンプを付けて割り当てられます。方法 従来の計算ツール、リアルタイム計算ツール、グラフでは記録時間または 各フレームの表示時刻をタイムスタンプとして指定し、 Jan/1/1970:00:00:00 以降のマイクロ秒。これにより、さまざまな送信元から グローバルに一貫した順序で処理する。

リアルタイムのスケジュール設定

通常、各計算ツールは特定の入力パケットがすべて入力されるとすぐに タイムスタンプを取得できます。通常これは電卓が 前のフレームの処理が終了し、各計算機が前のフレームを 入力が現在のフレームの処理を完了したことを示します。MediaPipe スケジューラ は、これらの条件が満たされるとすぐに各計算ツールを呼び出します。詳しくは、 同期をご覧ください。

タイムスタンプの範囲

計算ツールが特定のタイムスタンプに対して出力パケットを生成しない場合、 「timestamp-bound」を出力できます。すべてのパケットが 表示されます。この表示は、ダウンストリーム 計算ツールは、パケットが到着していなくてもそのタイムスタンプで そのタイムスタンプの特定のストリームが表示されます。特にリアルタイムのユースケースでは グラフをインタラクティブなアプリケーションで表示し、 できるだけ早く処理を開始することをおすすめします

次のようなグラフについて考えてみましょう。

node {
   calculator: "A"
   input_stream: "alpha_in"
   output_stream: "alpha"
}
node {
   calculator: "B"
   input_stream: "alpha"
   input_stream: "foo"
   output_stream: "beta"
}

タイムスタンプ T で、ノード A がその出力ストリームでパケットを送信していないとします。 alpha。ノード B はタイムスタンプ Tfoo のパケットを取得し、 (タイムスタンプ Talpha)のパケット。AB を送信しない場合、タイムスタンプ バウンドが送信されます。 alpha の更新のため、Balpha でのパケットの到着を待機し続けます。 一方、foo のパケットキューには、TT+1、および できます。

ストリーム上のパケットを出力するために、計算ツールは API 関数を使用して CalculatorContext::OutputsOutputStream::Add。代わりに 計算には、API 関数を使用して、 CalculatorContext::OutputsCalculatorContext::SetNextTimestampBound。「 指定された境界は、パケットの次のパケットに 出力ストリームの属性を変更します。パケットが出力されない場合、計算ツールは通常、 次のような操作を行います。

cc->Outputs().Tag("output_frame").SetNextTimestampBound(
  cc->InputTimestamp().NextAllowedInStream());

関数 Timestamp::NextAllowedInStream は、連続したタイムスタンプを返します。 例: Timestamp(1).NextAllowedInStream() == Timestamp(2)

タイムスタンプ境界の伝播

リアルタイム グラフで使用する計算機では、出力を定義する必要があります。 ダウンストリームを許可するために、入力タイムスタンプ境界に基づくタイムスタンプ境界。 計算ツールが迅速にスケジュールされます。一般的なパターンは、 出力パケットのタイムスタンプが入力パケットと同じになります。この例では Calculator::Process を呼び出すたびにパケットを出力するだけで十分です。 出力タイムスタンプの範囲を定義します。

ただし、計算ツールでは出力用にこの一般的なパターンに従う必要はありません。 出力を選択する場合は、単調に増加する出力を選択する あります。そのため、特定の計算ツールではタイムスタンプの範囲を計算する必要があります。 明示的に指定することもできます。MediaPipe は適切なタイムスタンプを計算するためのいくつかのツールを提供 計算できます

1. SetNextTimestampBound() を使用すると、出力ストリームのタイムスタンプ範囲(t + 1)を指定できます。

cc->Outputs.Tag("OUT").SetNextTimestampBound(t.NextAllowedInStream());

または、タイムスタンプが t の空のパケットを生成して、 タイムスタンプの範囲は t + 1 です。

cc->Outputs.Tag("OUT").Add(Packet(), t);

入力ストリームのタイムスタンプ境界は、パケットまたは空で示される 計算します。

Timestamp bound = cc->Inputs().Tag("IN").Value().Timestamp();

2. TimestampOffset() を指定すると、 入力ストリームから出力ストリームへのタイムスタンプ バウンド。

cc->SetTimestampOffset(0);

この設定には、タイムスタンプの範囲が自動的に伝播されるという利点があります。 到着したのがタイムスタンプ境界のみで、Calculator::Process が呼び出されない場合でも同じです。

3. ProcessTimestampBounds() を指定して、 新しい「決済されたタイムスタンプ」ごとに Calculator::Process。 タイムスタンプ」と現在のタイムスタンプ境界の下にある新しい最も高いタイムスタンプです。 ProcessTimestampBounds() がない場合、Calculator::Process は、次の場合にのみ呼び出されます。 受信パケットを表します。

cc->SetProcessTimestampBounds(true);

この設定により、計算ツールで独自のタイムスタンプ境界を計算できます。 入力タイムスタンプだけが更新された場合でも、すべてのロジックとプロパゲーションを維持できます。これは、 TimestampOffset() の効果を複製しますが、以下の目的でも使用できます。 他の要因を考慮したタイムスタンプの範囲を計算できます。

たとえば、SetTimestampOffset(0) を再現するために、電卓で 次の操作を行います。

absl::Status Open(CalculatorContext* cc) {
  cc->SetProcessTimestampBounds(true);
}

absl::Status Process(CalculatorContext* cc) {
  cc->Outputs.Tag("OUT").SetNextTimestampBound(
      cc->InputTimestamp().NextAllowedInStream());
}

計算ツール::開く、計算ツール::閉じるのスケジュール

Calculator::Open は、必要な入力サイドパケットがすべて完了すると呼び出されます。 生成します。入力サイドパケットは、包含アプリケーションまたは "サイドパケット計算機"表示されます。サイドパケットは、 API の CalculatorGraph::Initialize とグラフの外側を使用して、 CalculatorGraph::StartRun。サイドパケットは Google Cloud Platform 内の CalculatorGraphConfig::OutputSidePackets を使用してグラフを表示し、 OutputSidePacket::Set

計算ツール::Close は、すべての入力ストリームがDone 営業時間が終了しているか、タイムスタンプの範囲 Timestamp::Done に達しています。

注: 保留中の計算ツールの実行がすべて終了し、グラフが Done の場合、一部のストリームは Done になる前に、MediaPipe は 残りの Calculator::Close を呼び出し、すべての計算ツールで 生成します。

TimestampOffset を使用すると、Calculator::Close に影響が及びます。 SetTimestampOffset(0) を指定する計算ツールは、設計上、すべての すべての入力ストリームが入力され、出力ストリームが Timestamp::Done に達した Timestamp::Done に達したため、これ以上の出力はできません。 こうすることで、パケットを送出する Calculator::Close。計算処理でサマリー パケットを生成する必要がある場合は、 Calculator::CloseCalculator::Process には、次のようなタイムスタンプ境界を指定する必要があります。 少なくとも 1 つのタイムスタンプ(Timestamp::Max など)を、 Calculator::Close。つまり、通常このような計算ツールでは、 SetTimestampOffset(0)。代わりにタイムスタンプの範囲を明示的に指定する必要があります。 SetNextTimestampBounds() を使用します。