Stempel waktu real-time
Grafik kalkulator MediaPipe sering digunakan untuk memproses streaming video atau audio
{i>frame<i} untuk aplikasi interaktif. Framework MediaPipe hanya memerlukan
paket yang berurutan akan diberi stempel waktu
yang meningkat secara monoton. Menurut
konvensi, kalkulator {i>real-time<i} dan grafik
menggunakan waktu perekaman atau
waktu presentasi setiap frame sebagai stempel waktunya, dengan setiap stempel waktu menunjukkan
mikrodetik sejak Jan/1/1970:00:00:00
. Hal ini memungkinkan paket dari berbagai
sumber diproses dalam urutan yang konsisten secara global.
Penjadwalan real-time
Biasanya, setiap Kalkulator berjalan segera setelah semua paket inputnya untuk stempel waktu tersedia. Biasanya, ini terjadi ketika kalkulator memiliki selesai memproses {i>frame<i} sebelumnya, dan masing-masing kalkulator menghasilkan {i>input<i}nya telah selesai memproses {i>frame<i} saat ini. Penjadwal MediaPipe memanggil setiap kalkulator segera setelah kondisi ini terpenuhi. Lihat Sinkronisasi untuk detail selengkapnya.
Batas stempel waktu
Ketika kalkulator tidak menghasilkan paket {i> output<i} apa pun untuk stempel waktu tertentu, sebagai gantinya dapat menghasilkan "timestamp bound" yang menunjukkan bahwa tidak ada paket yang akan untuk stempel waktu tersebut. Indikasi ini diperlukan untuk mengizinkan downstream kalkulator untuk berjalan pada stempel waktu itu, meskipun tidak ada paket yang tiba untuk {i>stream<i} tertentu untuk stempel waktu tersebut. Hal ini sangat penting untuk grafik dalam aplikasi interaktif, di mana sangat penting bahwa setiap kalkulator segera memulai pemrosesan.
Perhatikan grafik seperti berikut:
node {
calculator: "A"
input_stream: "alpha_in"
output_stream: "alpha"
}
node {
calculator: "B"
input_stream: "alpha"
input_stream: "foo"
output_stream: "beta"
}
Misalkan: pada stempel waktu T
, node A
tidak mengirimkan paket pada aliran outputnya
alpha
. Node B
mendapatkan paket di foo
pada stempel waktu T
dan sedang menunggu
paket di alpha
pada stempel waktu T
. Jika A
tidak mengirimkan B
, batas stempel waktu
update untuk alpha
, B
akan terus menunggu paket tiba di alpha
.
Sementara itu, antrean paket foo
akan mengumpulkan paket di T
, T+1
, dan
dan seterusnya.
Untuk menghasilkan output paket di aliran data, kalkulator menggunakan fungsi API
CalculatorContext::Outputs
dan OutputStream::Add
. Sebagai gantinya, untuk menghasilkan output
stempel waktu yang terikat pada suatu streaming, kalkulator dapat menggunakan fungsi API
CalculatorContext::Outputs
dan CalculatorContext::SetNextTimestampBound
. Tujuan
batas yang ditentukan adalah stempel waktu
terendah yang diizinkan untuk paket berikutnya pada
stream output yang ditentukan. Ketika tidak ada paket yang keluar, kalkulator biasanya akan
lakukan sesuatu seperti:
cc->Outputs().Tag("output_frame").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
Fungsi Timestamp::NextAllowedInStream
menampilkan stempel waktu yang berurutan.
Misalnya, Timestamp(1).NextAllowedInStream() == Timestamp(2)
.
Menerapkan batas stempel waktu
Kalkulator yang akan digunakan dalam grafik real-time harus menentukan output
batas stempel waktu berdasarkan batas stempel waktu input untuk mengizinkan downstream
kalkulator untuk dijadwalkan
dengan segera. Pola yang umum adalah
agar kalkulator
paket {i>output<i} dengan stempel waktu
yang sama dengan paket inputnya. Dalam kasus ini,
cukup menghasilkan output paket di setiap panggilan ke Calculator::Process
untuk menentukan batas stempel waktu output.
Namun, kalkulator tidak perlu mengikuti pola umum ini untuk {i>output<i} stempel waktu, hanya diperlukan untuk memilih output yang meningkat secara monoton stempel waktu. Akibatnya, kalkulator tertentu harus menghitung batas stempel waktu secara eksplisit. MediaPipe menyediakan beberapa alat untuk menghitung stempel waktu yang tepat terikat untuk setiap kalkulator.
1. SetNextTimestampBound() dapat digunakan untuk menentukan batas stempel waktu, t +
1
, untuk streaming output.
cc->Outputs.Tag("OUT").SetNextTimestampBound(t.NextAllowedInStream());
Atau, paket kosong dengan stempel waktu t
dapat dibuat untuk menentukan
batas waktu t + 1
.
cc->Outputs.Tag("OUT").Add(Packet(), t);
Batas stempel waktu dari streaming input ditunjukkan oleh paket atau pada aliran data input.
Timestamp bound = cc->Inputs().Tag("IN").Value().Timestamp();
2. TimestampOffset() dapat ditentukan untuk menyalin secara otomatis stempel waktu dari stream input ke stream output.
cc->SetTimestampOffset(0);
Pengaturan ini memiliki keuntungan yaitu menyebarkan batas stempel waktu secara otomatis, meskipun hanya batas stempel waktu yang tiba dan Calculator::Process tidak dipanggil.
3. ProcessTimestampBounds() dapat ditentukan untuk memanggil
Calculator::Process
untuk setiap "stempel waktu penyelesaian" baru, dengan nilai "selesai
stempel waktu" adalah stempel waktu tertinggi yang baru di bawah batas stempel waktu saat ini.
Tanpa ProcessTimestampBounds()
, Calculator::Process
hanya dipanggil dengan
satu atau lebih paket
yang tiba.
cc->SetProcessTimestampBounds(true);
Setelan ini memungkinkan kalkulator melakukan penghitungan batas stempel waktu sendiri
dan penerapan, bahkan saat hanya stempel waktu input yang diperbarui. Model ini dapat digunakan untuk
mereplikasi efek TimestampOffset()
, tetapi juga dapat digunakan untuk
menghitung batas waktu yang
memperhitungkan faktor tambahan.
Misalnya, untuk mereplikasi SetTimestampOffset(0)
, kalkulator dapat
lakukan hal berikut:
absl::Status Open(CalculatorContext* cc) {
cc->SetProcessTimestampBounds(true);
}
absl::Status Process(CalculatorContext* cc) {
cc->Outputs.Tag("OUT").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
}
Penjadwalan Kalkulator::Open dan Calculator::Close
Calculator::Open
dipanggil jika semua paket samping input yang diperlukan telah
diproduksi. Paket samping input dapat diberikan oleh aplikasi yang menyertakan atau dengan
"kalkulator paket sampingan" di dalam grafik. {i>Side-packet<i} dapat ditentukan dari
di luar grafik menggunakan CalculatorGraph::Initialize
API dan
CalculatorGraph::StartRun
. Paket samping dapat ditentukan
oleh kalkulator di dalam
grafik menggunakan CalculatorGraphConfig::OutputSidePackets
dan
OutputSidePacket::Set
.
Kalkulator::Close dipanggil saat semua streaming input menjadi Done
dengan
ditutup atau mencapai batas stempel waktu Timestamp::Done
.
Catatan: Jika grafik menyelesaikan semua eksekusi kalkulator yang tertunda dan menjadi
Done
, sebelum beberapa streaming menjadi Done
, MediaPipe akan memanggil metode
panggilan yang tersisa ke Calculator::Close
, sehingga setiap kalkulator dapat menghasilkan
output akhir.
Penggunaan TimestampOffset
memiliki beberapa implikasi untuk Calculator::Close
. J
kalkulator yang menetapkan SetTimestampOffset(0)
akan secara desain menunjukkan bahwa semua
stream output-nya telah mencapai Timestamp::Done
saat semua stream input-nya
telah mencapai Timestamp::Done
, sehingga tidak ada output lebih lanjut yang mungkin dihasilkan.
Hal ini mencegah kalkulator seperti itu
memancarkan paket apa pun selama
Calculator::Close
. Jika kalkulator perlu menghasilkan
paket ringkasan selama
Calculator::Close
, Calculator::Process
harus menentukan batas stempel waktu seperti
bahwa setidaknya satu stempel waktu (misalnya Timestamp::Max
) tetap tersedia selama
Calculator::Close
. Ini berarti bahwa kalkulator seperti itu biasanya
tidak dapat mengandalkan
SetTimestampOffset(0)
dan harus menentukan batas stempel waktu secara eksplisit
menggunakan SetNextTimestampBounds()
.