Echtzeit-Zeitstempel
Die Grafiken des MediaPipe-Rechners werden häufig zur Verarbeitung von Video- oder Audiostreams verwendet.
Frames für interaktive Anwendungen. Für das MediaPipe-Framework ist nur Folgendes erforderlich:
aufeinanderfolgende Pakete erhalten
monoton ansteigende Zeitstempel. Von
verwenden Echtzeitrechner und Grafiken die Aufzeichnungszeit oder die
Präsentationszeit jedes Frames als Zeitstempel, wobei jeder Zeitstempel
Mikrosekunden seit Jan/1/1970:00:00:00
. Dadurch werden Pakete von verschiedenen
in einer global konsistenten Reihenfolge verarbeitet werden.
Terminplanung in Echtzeit
Normalerweise wird jeder Rechner sofort ausgeführt, sobald alle Eingabepakete verfügbar. Normalerweise geschieht dies, wenn der Rechner die Verarbeitung des vorherigen Frames abgeschlossen und alle Rechner, die sie produziert haben, die Verarbeitung des aktuellen Frames abgeschlossen ist. MediaPipe-Planer Ruft jeden Rechner auf, sobald diese Bedingungen erfüllt sind. Weitere Informationen finden Sie unter Synchronisierung.
Zeitstempelgrenzen
Wenn ein Rechner keine Ausgabepakete für einen bestimmten Zeitstempel erzeugt, kann stattdessen eine „Zeitstempelgrenze“ deutet darauf hin, dass kein Paket die für diesen Zeitstempel produziert wurden. Diese Angabe ist notwendig, um zu diesem Zeitpunkt ausgeführt werden, obwohl kein Paket für bestimmte Streams für diesen Zeitstempel. Das ist besonders wichtig für Echtzeit- in interaktiven Anwendungen darstellen. Dabei ist es wichtig, so schnell wie möglich mit der Verarbeitung begonnen.
Stellen Sie sich ein Diagramm wie das folgende vor:
node {
calculator: "A"
input_stream: "alpha_in"
output_stream: "alpha"
}
node {
calculator: "B"
input_stream: "alpha"
input_stream: "foo"
output_stream: "beta"
}
Angenommen: Beim Zeitstempel T
sendet Knoten A
in seinem Ausgabestream kein Paket.
alpha
Knoten B
erhält ein Paket in foo
mit dem Zeitstempel T
und wartet auf
Paket in alpha
mit dem Zeitstempel T
. Wenn A
keine Zeitstempelgrenze an B
sendet
Update für alpha
wartet B
weiter auf das Eintreffen eines Pakets in alpha
.
In der Zwischenzeit sammelt die Paketwarteschlange von foo
Pakete unter T
, T+1
und
so weiter.
Zur Ausgabe eines Pakets in einen Stream verwendet ein Rechner die API-Funktionen
CalculatorContext::Outputs
und OutputStream::Add
. Um stattdessen eine Ausgabe von
an einen Stream gebunden ist, kann ein Rechner die API-Funktionen
CalculatorContext::Outputs
und CalculatorContext::SetNextTimestampBound
. Die
angegebene Grenze ist der niedrigste zulässige Zeitstempel für das nächste Paket im
angegebenen Ausgabestream. Wenn kein Paket ausgegeben wird,
beispielsweise:
cc->Outputs().Tag("output_frame").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
Die Funktion Timestamp::NextAllowedInStream
gibt den aufeinanderfolgenden Zeitstempel zurück.
Beispiel: Timestamp(1).NextAllowedInStream() == Timestamp(2)
.
Zeitstempelgrenzen weitergeben
Rechner, die in Echtzeitgrafiken verwendet werden, müssen die Ausgabe definieren
Zeitstempelgrenzen basierend auf Eingabezeitstempelgrenzen, um Downstream-
um schnell einen Termin zu vereinbaren. Ein gängiges Muster ist,
Ausgabepakete mit denselben Zeitstempeln wie ihre Eingabepakete. In diesem Fall
Es reicht aus, einfach bei jedem Aufruf von Calculator::Process
ein Paket auszugeben.
um Zeitstempelgrenzen für die Ausgabe zu definieren.
Rechner müssen sich bei der Ausgabe jedoch nicht an dieses allgemeine Muster halten. müssen nur monoton ansteigende Ausgabewerte Zeitstempel. Daher müssen bestimmte Rechner Zeitstempelgrenzen berechnen, explizit auf. MediaPipe bietet verschiedene Tools zur Berechnung des geeigneten Zeitstempels für jeden Rechner definiert.
1. SetNextTimestampBound() kann zur Angabe der Zeitstempelgrenze t +
1
für einen Ausgabestream verwendet werden.
cc->Outputs.Tag("OUT").SetNextTimestampBound(t.NextAllowedInStream());
Alternativ kann ein leeres Paket mit dem Zeitstempel t
erzeugt werden, um den Wert für
Zeitstempelgrenze von t + 1
.
cc->Outputs.Tag("OUT").Add(Packet(), t);
Die Zeitstempelgrenze eines Eingabestreams wird durch das Paket oder das leere Feld angegeben Paket im Eingabestream.
Timestamp bound = cc->Inputs().Tag("IN").Value().Timestamp();
2. TimestampOffset() angeben, um den Parameter Zeitstempel, der von Eingabestreams zu Ausgabestreams gebunden ist.
cc->SetTimestampOffset(0);
Diese Einstellung hat den Vorteil, dass Zeitstempelgrenzen automatisch weitergegeben werden, auch wenn nur Zeitstempelgrenzen eintreffen und Calculator::Process nicht aufgerufen wird.
3. ProcessTimestampBounds() zum Aufrufen von
Calculator::Process
für jeden neuen „settled timestamp“, wobei der „settled timestamp“
Zeitstempel“ ist der neue höchste Zeitstempel unterhalb der aktuellen Zeitstempelgrenzen.
Ohne ProcessTimestampBounds()
wird Calculator::Process
nur mit
ein oder mehrere eingehende Pakete.
cc->SetProcessTimestampBounds(true);
Mit dieser Einstellung kann ein Rechner seine eigenen Zeitstempelgrenzen berechnen
auch wenn nur Zeitstempel
der Eingabe aktualisiert werden. Sie kann verwendet werden, um
die Wirkung von TimestampOffset()
nachbilden, aber sie kann auch verwendet werden,
eine Zeitstempelgrenze berechnen,
die zusätzliche Faktoren berücksichtigt.
Um beispielsweise SetTimestampOffset(0)
zu replizieren, könnte ein Rechner
Gehen Sie so vor:
absl::Status Open(CalculatorContext* cc) {
cc->SetProcessTimestampBounds(true);
}
absl::Status Process(CalculatorContext* cc) {
cc->Outputs.Tag("OUT").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
}
Planung von Rechner::Öffnen und Rechner::Schließen
Calculator::Open
wird aufgerufen, wenn alle erforderlichen Eingabe-Seitenpakete erstellt wurden
produziert wurden. Eingabe-Seitenpakete können von der einschließenden Anwendung oder durch
„side-packet rechner“ im Diagramm. Nebenpakete können über
außerhalb des Diagramms mit CalculatorGraph::Initialize
der API und
CalculatorGraph::StartRun
. Nebenpakete können mithilfe von Rechnern in
das Diagramm mit CalculatorGraphConfig::OutputSidePackets
und
OutputSidePacket::Set
.
Rechner::Close wird aufgerufen, wenn alle Eingabestreams Done
durch
geschlossen wird oder die Zeitstempelgrenze von Timestamp::Done
erreicht.
Hinweis:Wenn für die Grafik alle ausstehenden Rechnerausführungen abgeschlossen sind und
Done
festlegen, bevor einige Streams zu Done
werden, ruft MediaPipe den
verbleibende Aufrufe an Calculator::Close
, sodass jeder Rechner
und die Endergebnisse.
Die Verwendung von TimestampOffset
hat einige Auswirkungen auf Calculator::Close
. A
Der Rechner mit SetTimestampOffset(0)
signalisiert, dass alle
seine Ausgabestreams haben Timestamp::Done
erreicht, wenn alle Eingabestreams
haben Timestamp::Done
erreicht, daher sind keine weiteren Ausgaben mehr möglich.
So wird verhindert, dass ein solcher Rechner während der
Calculator::Close
Wenn ein Rechner während der Laufzeit
Calculator::Close
, Calculator::Process
muss Zeitstempelgrenzen angeben wie
dass mindestens ein Zeitstempel (z. B. Timestamp::Max
) im Zeitraum
Calculator::Close
Daher kann sich ein solcher Rechner normalerweise nicht darauf verlassen,
SetTimestampOffset(0)
und muss stattdessen Zeitstempelgrenzen explizit angeben
mit SetNextTimestampBounds()
.