Codes temporels en temps réel
Les graphiques du calculateur MediaPipe sont souvent utilisés pour traiter des flux vidéo ou audio
des cadres pour
les applications interactives. Le framework MediaPipe requiert uniquement
les paquets successifs reçoivent des horodatages
augmentant de manière monotone. Par
les calculs et les graphiques en temps réel utilisent la durée d'enregistrement ou
l'heure de présentation de chaque trame en tant qu'horodatage, chaque horodatage indiquant
microsecondes depuis Jan/1/1970:00:00:00
. Cela permet aux paquets de différents
sources à traiter dans un ordre cohérent à l'échelle mondiale.
Planification en temps réel
Normalement, chaque calculateur s'exécute dès que tous ses paquets d'entrée pour une le code temporel devient disponible. Normalement, cela se produit lorsque le simulateur a a terminé le traitement de l'image précédente, et chacun des calculateurs générant ses entrées ont fini de traiter la trame actuelle. Planificateur MediaPipe invoque chaque calculateur dès que ces conditions sont remplies. Voir Synchronisation.
Limites d'horodatage
Lorsqu'un calculateur ne produit aucun paquet de sortie pour un horodatage donné, il nous pouvons à la place générer une valeur "limitée par le code temporel" indiquant qu'aucun paquet ne sera générées pour cet horodatage. Cette indication est nécessaire pour permettre de calcul à cet horodatage, même si aucun paquet n'est arrivé certains flux pour cet horodatage. C'est particulièrement important pour les tests en temps réel graphiques dans les applications interactives, où il est crucial que chaque calculateur commencer le traitement dès que possible.
Prenons l'exemple d'un graphique semblable à celui-ci:
node {
calculator: "A"
input_stream: "alpha_in"
output_stream: "alpha"
}
node {
calculator: "B"
input_stream: "alpha"
input_stream: "foo"
output_stream: "beta"
}
Supposons que le nœud A
n'envoie pas de paquet dans son flux de sortie au code temporel T
.
alpha
Le nœud B
reçoit un paquet dans foo
au code temporel T
et attend une
paquet dans alpha
au code temporel T
. Si A
n'envoie pas B
de code temporel limité
mise à jour pour alpha
, B
continuera d'attendre l'arrivée d'un paquet dans alpha
.
Pendant ce temps, la file d'attente de paquets de foo
accumule des paquets à T
, T+1
et
ainsi de suite.
Pour générer un paquet sur un flux, un calculateur utilise les fonctions de l'API
CalculatorContext::Outputs
et OutputStream::Add
. Pour générer à la place une
liées à un flux, un calculateur peut utiliser les fonctions de l'API
CalculatorContext::Outputs
et CalculatorContext::SetNextTimestampBound
. La
la limite spécifiée est le code temporel le plus bas autorisé pour le prochain paquet sur le
flux de sortie spécifié. Lorsqu'aucun paquet n'est en sortie, un calculateur
faites quelque chose comme:
cc->Outputs().Tag("output_frame").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
La fonction Timestamp::NextAllowedInStream
renvoie les codes temporels successifs.
Exemple :Timestamp(1).NextAllowedInStream() == Timestamp(2)
Propager des limites d'horodatage
Les calculateurs qui seront utilisés dans les graphiques en temps réel doivent définir la sortie
des limites de code temporel basées sur les limites
d'horodatage d'entrée afin d'autoriser
calculatrices doivent
être programmés rapidement. Un modèle courant
est que les calculatrices
paquets de sortie avec les mêmes horodatages
que leurs paquets d'entrée. Dans ce cas,
Il suffit de générer un paquet à chaque appel de Calculator::Process
.
pour définir les limites
d'horodatage de sortie.
Cependant, les calculatrices ne sont pas obligées de suivre ce modèle courant de sortie horodatages, ils ne doivent choisir que des valeurs de sortie monotones croissantes codes temporels. Par conséquent, certains calculateurs doivent calculer les limites d'horodatage explicitement. MediaPipe fournit plusieurs outils permettant de calculer le code temporel approprié limite pour chaque calculateur.
1. SetNextTimestampBound() permet de spécifier la limite d'horodatage, t +
1
, pour un flux de sortie.
cc->Outputs.Tag("OUT").SetNextTimestampBound(t.NextAllowedInStream());
Un paquet vide avec le code temporel t
peut également être produit pour spécifier le
t + 1
lié à un horodatage.
cc->Outputs.Tag("OUT").Add(Packet(), t);
La limite d'horodatage d'un flux d'entrée est indiquée par le paquet ou paquet sur le flux d'entrée.
Timestamp bound = cc->Inputs().Tag("IN").Value().Timestamp();
2. TimestampOffset() peut être spécifié afin de copier automatiquement la valeur le code temporel des flux d'entrée aux flux de sortie.
cc->SetTimestampOffset(0);
Ce paramètre a l’avantage de propager automatiquement les limites d’horodatage, même lorsque seuls les codes temporels arrivent et que le calculateur::Process n'est pas appelé.
3. ProcessTimestampBounds() peut être spécifié pour appeler
Calculator::Process
pour chaque nouvel "horodatage réglé", où la valeur "settled
code temporel" correspond au nouveau code temporel le plus élevé
en dessous des limites d'horodatage actuelles.
Sans ProcessTimestampBounds()
, Calculator::Process
n'est appelé qu'avec
un ou plusieurs paquets entrants.
cc->SetProcessTimestampBounds(true);
Ce paramètre permet à un calculateur d'effectuer son propre calcul des limites d'horodatage
et la propagation, même lorsque seuls les
horodatages d'entrée sont mis à jour. Il peut être utilisé pour
reproduire l'effet de TimestampOffset()
, mais il peut aussi servir à
calculer une limite d'horodatage qui
prend en compte des facteurs supplémentaires.
Par exemple, pour répliquer SetTimestampOffset(0)
, un calculateur peut
effectuer les opérations suivantes:
absl::Status Open(CalculatorContext* cc) {
cc->SetProcessTimestampBounds(true);
}
absl::Status Process(CalculatorContext* cc) {
cc->Outputs.Tag("OUT").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
}
Planification de la calculatrice::Ouvrir et Calculatrice::Fermer
Calculator::Open
est appelé lorsque tous les paquets secondaires d'entrée requis ont été
produits. Les paquets latéraux d'entrée peuvent être fournis par l'application englobante ou par
"calculateurs de paquets latéraux" dans le graphique. Les paquets latéraux peuvent être spécifiés
en dehors du graphique à l'aide du CalculatorGraph::Initialize
de l'API,
CalculatorGraph::StartRun
Les paquets secondaires peuvent être
spécifiés par des calculateurs dans
le graphique à l'aide de CalculatorGraphConfig::OutputSidePackets
, puis
OutputSidePacket::Set
Calculator::Close est appelé lorsque tous les flux d'entrée sont devenus Done
en
en cours de fermeture ou atteignant le code temporel Timestamp::Done
.
Remarque:Si le graphique termine toutes les exécutions en attente du calculateur et devient
Done
, avant que certains flux ne deviennent Done
, MediaPipe appellera
les appels restants à Calculator::Close
, de sorte que chaque calculatrice puisse produire son
les résultats finaux.
L'utilisation de TimestampOffset
a des conséquences pour Calculator::Close
. A
calculatrice spécifiant SetTimestampOffset(0)
indiquera par conception que tous
ses flux de sortie ont atteint Timestamp::Done
lorsque tous ses flux d'entrée
ont atteint Timestamp::Done
. Par conséquent, aucun autre résultat n'est possible.
Cela empêche un tel calculateur d'émettre des paquets pendant
Calculator::Close
Si un calculateur doit produire
un pack récapitulatif pendant
Calculator::Close
, Calculator::Process
doit spécifier des limites d'horodatage telles que
qu'au moins un code temporel (tel que Timestamp::Max
) reste disponible pendant
Calculator::Close
Cela signifie qu'un tel calculateur
ne peut normalement pas compter sur
SetTimestampOffset(0)
et doit spécifier explicitement les limites d'horodatage
avec SetNextTimestampBounds()
.