Strumienie w czasie rzeczywistym

sygnatury czasowe w czasie rzeczywistym;

Wykresy kalkulatora MediaPipe są często używane do przetwarzania strumieni wideo lub audio dla aplikacji interaktywnych. Struktura MediaPipe wymaga tylko tych kolejne pakiety otrzymują monotonicznie rosnące sygnatury czasowe. Według kalkulatory i wykresy czasu rzeczywistego korzystają z czasu rejestrowania lub czas prezentacji każdej klatki jako jej sygnaturę czasową, przy czym każda sygnatura czasowa wskazuje w mikrosekundach od Jan/1/1970:00:00:00. Pozwala to na przesyłanie pakietów z różnych muszą być przetworzone w spójnej globalnie kolejności.

Planowanie w czasie rzeczywistym

Zwykle kalkulator uruchamia się, gdy tylko wszystkie jego pakiety wejściowe dla danego sygnatura czasowa jest dostępna. Zwykle dzieje się tak, gdy kalkulator i zakończenie przetwarzania poprzedniej klatki, a każdy kalkulator generuje jego dane wejściowe zakończyły przetwarzanie bieżącej klatki. Algorytm szeregowania MediaPipe wywołuje każdy kalkulator, gdy tylko te warunki zostaną spełnione. Zobacz Synchronizacja: więcej szczegółów.

Granice sygnatury czasowej

Jeśli kalkulator nie wygeneruje pakietów wyjściowych dla danej sygnatury czasowej, może zamiast tego wyświetlać „powiązanie z sygnaturą czasową” co oznacza, że żaden pakiet nie zostanie dla danej sygnatury czasowej. To oznaczenie jest konieczne, aby umożliwić pobieranie aby kalkulatory uruchamiały się z tą sygnaturą czasową, nawet jeśli nie odebrano żadnego pakietu dla wybranych strumieni z danej sygnatury czasowej. Jest to szczególnie ważne w przypadku reklam w czasie rzeczywistym w interaktywnych aplikacjach, w których każdy kalkulator jak najszybciej rozpocząć przetwarzanie.

Weźmy pod uwagę taki wykres:

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

Załóżmy, że w sygnaturze czasowej T węzeł A nie wysyła pakietu w strumieniu wyjściowym alpha Węzeł B otrzymuje pakiet w folderze foo w sygnaturze czasowej T i czeka na pakiet w alpha w sygnaturze czasowej T. Jeśli A nie wysyła elementu B powiązany z sygnaturą czasową aktualizacja pakietu alpha, B będzie nadal czekać na pakiet w: alpha. W międzyczasie kolejka pakietów foo będzie gromadzić pakiety w punktach T, T+1 oraz i tak dalej.

Aby wyświetlić pakiet ze strumieniem, kalkulator korzysta z funkcji interfejsu API CalculatorContext::Outputs i OutputStream::Add. Aby zamiast tego wysłać błąd w postaci sygnatury czasowej związanej ze strumieniem, kalkulator może korzystać z funkcji interfejsu API CalculatorContext::Outputs i CalculatorContext::SetNextTimestampBound. określona granica to najniższa dopuszczalna sygnatura czasowa następnego pakietu w określony strumień wyjściowy. Kiedy nie zostanie wysłany żaden pakiet, kalkulator zwykle zrób coś takiego:

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

Funkcja Timestamp::NextAllowedInStream zwraca kolejne sygnatury czasowe. Na przykład: Timestamp(1).NextAllowedInStream() == Timestamp(2).

Propaguję granice sygnatury czasowej

Kalkulatory, które będą używane na wykresach w czasie rzeczywistym, muszą określać dane wyjściowe. granice sygnatury czasowej na podstawie granic wejściowej sygnatury czasowej, aby umożliwić pobieranie aby szybko planować ich generowanie. Typowym wzorcem są kalkulatory do pakiety wyjściowe o tych samych sygnaturach czasowych co pakiety wejściowe. W tym przypadku wystarczy wysłać pakiet przy każdym wywołaniu do Calculator::Process aby zdefiniować granice sygnatury czasowej wyjściowej.

ale kalkulatory nie muszą opierać się na tym wspólnym wzorcu danych wyjściowych sygnatur czasowych, są one wymagane tylko do wybierania danych wyjściowych o rosnącej monotonicznie sygnatury czasowe. W efekcie niektóre kalkulatory muszą obliczać granice sygnatury czasowej bezpośrednio. MediaPipe udostępnia kilka narzędzi do obliczania odpowiednich sygnatur czasowych dla każdego kalkulatora.

1. Funkcja SetNextTimestampBound() może służyć do określania sygnatury czasowej strumienia wyjściowego (t + 1).

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

Można też utworzyć pusty pakiet z sygnaturą czasową t w celu określenia powiązany z sygnaturą czasową t + 1.

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

Powiązanie z sygnaturą czasową strumienia wejściowego jest wskazywane przez pakiet lub pusty w strumieniu wejściowym.

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

2. Można określić TimestampOffset(), aby automatycznie skopiować parametr sygnatura czasowa powiązana ze strumieniami wejściowymi do strumieni wyjściowych;

cc->SetTimestampOffset(0);

Zaletą tego ustawienia jest automatyczne propagowanie granic sygnatur czasowych, nawet jeśli dotarły tylko granice sygnatury czasowej, a kalkulator::Proces nie został wywołany.

3. W celu wywołania można określić metodę ProcessTimestampBounds() Calculator::Process dla każdej nowej „ustalonej sygnatury czasowej”, gdzie „rozliczone timestamp” to nowa najwyższa sygnatura czasowa poniżej bieżących granic sygnatury czasowej. Bez metody ProcessTimestampBounds() funkcja Calculator::Process jest wywoływana tylko z co najmniej jedna przesyłka.

cc->SetProcessTimestampBounds(true);

To ustawienie pozwala kalkulatorowi samodzielnie obliczać granice sygnatur czasowych i rozpowszechniania, nawet wtedy, gdy aktualizowane są tylko sygnatury czasowe. Może służyć do: powieli efekt TimestampOffset(), ale może też być używany do obliczać ograniczenie sygnatury czasowej, które uwzględnia dodatkowe czynniki.

Aby na przykład powielić zmienną SetTimestampOffset(0), kalkulator może: wykonaj te czynności:

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

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

Harmonogram Kalkulatora::Otwórz i Kalkulator::Zamknij

Pole Calculator::Open jest wywoływane, gdy wszystkie wymagane wejściowe pakiety poboczne zostały z całego świata. Wejściowe pakiety boczne mogą zostać dostarczone przez aplikację otaczającą lub przez „kalkulatory pakietów bocznych” wewnątrz wykresu. Pakiety boczne można określić z: poza wykresem za pomocą funkcji CalculatorGraph::Initialize i interfejsów API CalculatorGraph::StartRun Pakiety boczne mogą być określane przez kalkulatory w wykres za pomocą funkcji CalculatorGraphConfig::OutputSidePackets i OutputSidePacket::Set

Kalkulator::Zamknij jest wywoływany, gdy wszystkie strumienie wejściowe mają wartość Done przez jest zamykana lub osiąga wartość powiązaną z sygnaturą czasową Timestamp::Done.

Uwaga: jeśli wykres zakończy wszystkie oczekujące wykonanie kalkulatora i stanie się Done, zanim niektóre strumienie zmienią się na Done, MediaPipe wywoła metodę pozostałych wywołań funkcji Calculator::Close, by każdy kalkulator mógł wygenerować z wynikami końcowymi.

Używanie właściwości TimestampOffset może mieć wpływ na działanie funkcji Calculator::Close. O kalkulator określający SetTimestampOffset(0) będzie z projektowania zasygnalizuje, że wszystkie strumienie wyjściowe osiągnęły Timestamp::Done, gdy wszystkie strumienie wejściowe osiągnięto Timestamp::Done, dlatego dalsze dane wyjściowe nie są dostępne. Dzięki temu kalkulator nie będzie wysyłać pakietów podczas Calculator::Close Jeśli kalkulator musi wygenerować pakiet podsumowania podczas Calculator::Close, Calculator::Process musi określać granice sygnatury czasowej takie jak że co najmniej jedna sygnatura czasowa (np. Timestamp::Max) jest dostępna Calculator::Close Oznacza to, że kalkulator zwykle nie może polegać na SetTimestampOffset(0) i muszą w sposób jawny określić granice sygnatury czasowej za pomocą: SetNextTimestampBounds().