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.