Streaming Real-time

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