Diffusions en temps réel

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().