Gerçek Zamanlı Akışlar

Gerçek zamanlı zaman damgaları

MediaPipe hesaplayıcı grafikleri genellikle etkileşimli uygulamalar için video veya ses çerçevesi akışlarını işlemekte kullanılır. MediaPipe çerçevesi yalnızca ardışık paketlerin tekdüze şekilde artan zaman damgalarına atanmasını gerektirir. Gerçek zamanlı hesaplayıcılar ve grafikler, zaman damgası olarak her karenin kayıt süresini veya sunum zamanını kullanır. Her zaman damgası, Jan/1/1970:00:00:00 tarihinden itibaren geçen mikrosaniyeyi gösterir. Bu, çeşitli kaynaklardan gelen paketlerin küresel olarak tutarlı bir sırada işlenmesini sağlar.

Gerçek zamanlı planlama

Normalde her Hesap Makinesi, belirli bir zaman damgası için tüm giriş paketleri kullanılabilir hale gelir gelmez çalışır. Normalde bu işlem, hesap makinesi önceki kareyi işlemeyi tamamladığında ve girdilerini üreten hesaplayıcıların her biri geçerli kareyi işlemeyi tamamladığında gerçekleşir. MediaPipe planlayıcısı, koşullar karşılanır sağlanmaz her hesap makinesini çağırır. Daha fazla bilgi için Senkronizasyon bölümüne bakın.

Zaman damgası sınırları

Hesap makinesi belirli bir zaman damgası için herhangi bir çıkış paketi üretmediğinde, söz konusu zaman damgası için hiçbir paket oluşturulmayacağını belirten bir "zaman damgası sınırı" oluşturabilir. Bu gösterge, söz konusu zaman damgası için belirli akışlara herhangi bir paket ulaşmamış olsa bile aşağı akış hesaplayıcılarının bu zaman damgasında çalışmasına izin vermek için gereklidir. Bu, özellikle her hesap makinesinin mümkün olan en kısa sürede işlemeye başlaması gereken etkileşimli uygulamalardaki gerçek zamanlı grafikler için önemlidir.

Aşağıdaki gibi bir grafik elde edebilirsiniz:

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

Örneğin, T zaman damgasında A düğümünün çıkış akışında paket göndermediğini alpha varsayalım. B düğümü T zaman damgasında foo konumunda bir paket alıyor ve T zaman damgasında alpha konumunda bir paket bekliyor. A, B kullanıcısına alpha için zaman damgası sınırlı güncelleme göndermezse B, alpha içinde gönderilen paketi beklemeye devam eder. Bu arada, foo paketinin paket sırası T, T+1 gibi yerlerde paket toplar.

Akışta paket çıktısı vermek için hesaplayıcı, CalculatorContext::Outputs ve OutputStream::Add API işlevlerini kullanır. Bunun yerine, akışa bağlı bir zaman damgası çıktısı almak için hesap makinesi, CalculatorContext::Outputs ve CalculatorContext::SetNextTimestampBound API işlevlerini kullanabilir. Belirtilen sınır, belirtilen çıkış akışındaki bir sonraki paket için izin verilen en düşük zaman damgasıdır. Paket çıkışı olmadığında hesap makinesi genellikle aşağıdaki gibi bir işlem yapar:

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

Timestamp::NextAllowedInStream işlevi ardışık zaman damgasını döndürür. Örneğin, Timestamp(1).NextAllowedInStream() == Timestamp(2).

Zaman damgası sınırları uygulanıyor

Gerçek zamanlı grafiklerde kullanılacak hesap makinelerinin, aşağı akış hesaplayıcıların zamanında planlanabilmesi için giriş zaman damgası sınırlarına göre çıkış zaman damgası sınırları tanımlaması gerekir. Yaygın olarak kullanılan bir kalıp, hesaplayıcıların giriş paketleriyle aynı zaman damgalarına sahip paketlerin çıkışını vermesidir. Bu durumda, çıkış zaman damgası sınırlarını tanımlamak için Calculator::Process öğesine yapılan her çağrıda paket çıkışı yeterlidir.

Ancak hesaplayıcıların çıkış zaman damgaları için bu yaygın kalıbı izlemesi gerekmez. Yalnızca tekdüze şekilde artan çıkış zaman damgalarını seçmeleri gerekir. Sonuç olarak, bazı hesaplayıcıların zaman damgası sınırlarını açık bir şekilde hesaplaması gerekir. MediaPipe, her hesap makinesine uygun zaman damgasını hesaplamanız için çeşitli araçlar sunar.

1. SetNextTimestampBound(), çıkış akışı için zaman damgası sınırını (t + 1) belirtmek amacıyla kullanılabilir.

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

Alternatif olarak, t + 1 zaman damgası sınırını belirtmek için t zaman damgasına sahip boş bir paket üretilebilir.

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

Giriş akışının zaman damgası sınırı, giriş akışındaki paket veya boş paket ile gösterilir.

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

2. Giriş akışlarından çıkış akışlarına bağlı zaman damgasını otomatik olarak kopyalamak için TimestampOffset() belirtilebilir.

cc->SetTimestampOffset(0);

Bu ayar, yalnızca zaman damgası sınırları geldiğinde ve Hesap Makinesi::İşlemi çağrılmadığında bile zaman damgası sınırlarını otomatik olarak yayma avantajına sahiptir.

3. Her yeni "settled timestamp" değeri için Calculator::Process yöntemini çağırmak amacıyla ProcessTimestampBounds() belirtilebilir. Bu durumda "settled timestamp", geçerli zaman damgası sınırlarının altındaki en yüksek yeni zaman damgasıdır. ProcessTimestampBounds() olmadığında Calculator::Process, yalnızca bir veya daha fazla gelen paketle çağrılır.

cc->SetProcessTimestampBounds(true);

Bu ayar, yalnızca giriş zaman damgaları güncellendiğinde bile hesap makinesinin kendi zaman damgası aralığı hesaplamasını ve yayılımını gerçekleştirmesini sağlar. Bu, TimestampOffset() etkisinin etkisini yeniden oluşturmak için kullanılabilir ancak ek faktörleri dikkate alan bir zaman damgası sınırı hesaplamak için de kullanılabilir.

Örneğin, SetTimestampOffset(0) işlemini çoğaltmak için hesap makinesi aşağıdakileri yapabilir:

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

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

Hesap Makinesi Zamanlaması::Açık ve Hesap Makinesi::Kapat

Calculator::Open, gerekli tüm giriş yan paketleri oluşturulduğunda çağrılır. Giriş yan paketleri, çevreleyen uygulama tarafından veya grafik içindeki "yan paket hesaplayıcıları" ile sağlanabilir. Yan paketler, API'nin CalculatorGraph::Initialize ve CalculatorGraph::StartRun değerleri kullanılarak grafiğin dışından belirtilebilir. Yan paketler, CalculatorGraphConfig::OutputSidePackets ve OutputSidePacket::Set kullanılarak grafikteki hesaplayıcılarla belirtilebilir.

Hesap Makinesi::Kapatma işlemi, tüm giriş akışları kapatılarak veya Timestamp::Done zaman damgası sınırına ulaşıldığında Done hale geldiğinde çağrılır.

Not: Grafik, bekleyen tüm hesap makinesi yürütme işlemi biter ve Done durumuna gelirse ve bazı akışlar Done olmadan önce MediaPipe, kalan Calculator::Close çağrılarını çağırarak her hesap makinesinin son çıktılarını üretebilmesini sağlar.

TimestampOffset kullanımının Calculator::Close üzerinde bazı etkileri vardır. SetTimestampOffset(0) belirten bir hesaplayıcı, tasarım gereği, giriş akışlarının tümü Timestamp::Done değerine ulaştığında tüm çıkış akışlarının Timestamp::Done değerine ulaştığını ve bu nedenle başka çıkış alınamayacağını belirtir. Böylece, bu tür bir hesap makinesinin Calculator::Close sırasında paket çıkarması engellenir. Hesap makinesinin Calculator::Close sırasında bir özet paketi oluşturması gerekiyorsa Calculator::Process, Calculator::Close sırasında en az bir zaman damgası (Timestamp::Max gibi) kalacak şekilde zaman damgası sınırlarını belirtmelidir. Diğer bir deyişle, bu tür bir hesap makinesi normalde SetTimestampOffset(0)'e güvenemez ve bunun yerine SetNextTimestampBounds() kullanarak zaman damgası sınırlarını açıkça belirtmesi gerekir.