การประทับเวลาแบบเรียลไทม์
กราฟเครื่องคำนวณ MediaPipe มักใช้ในการประมวลผลสตรีมวิดีโอหรือเสียง
เฟรมสำหรับแอปพลิเคชันแบบอินเทอร์แอกทีฟ เฟรมเวิร์ก MediaPipe ต้องการเพียง
แพ็กเก็ตที่ต่อเนื่องจะได้รับการกำหนดการประทับเวลาที่เพิ่มขึ้นอย่างต่อเนื่อง โดย
เครื่องคิดเลขและกราฟแบบเรียลไทม์ใช้เวลาบันทึก หรือ
เวลานำเสนอของแต่ละเฟรมเป็นการประทับเวลา โดยการประทับเวลาแต่ละจุดแสดงถึง
ไมโครวินาทีตั้งแต่ Jan/1/1970:00:00:00 ซึ่งจะทำให้แพ็กเก็ตจาก
แหล่งที่มาที่ได้รับการประมวลผลในลำดับที่สอดคล้องกันทั่วโลก
การวางกำหนดการแบบเรียลไทม์
โดยปกติแล้ว เครื่องคิดเลขแต่ละรายการจะทำงานทันทีที่แพ็กเก็ตอินพุตทั้งหมดของ การประทับเวลาจะสามารถใช้งานได้ โดยปกติแล้ว ปัญหานี้จะเกิดขึ้นเมื่อเครื่องคำนวณ ประมวลผลเฟรมก่อนหน้าเสร็จแล้ว และเครื่องคำนวณแต่ละรายการ อินพุตประมวลผลเฟรมปัจจุบันเสร็จแล้ว เครื่องจัดตารางเวลา MediaPipe จะเรียกเครื่องคำนวณแต่ละเครื่องทันทีที่ตรงตามเงื่อนไขเหล่านี้ โปรดดู การซิงค์สำหรับรายละเอียดเพิ่มเติม
ขอบเขตของการประทับเวลา
เมื่อเครื่องคำนวณไม่สร้างแพ็กเก็ตเอาต์พุตใดๆ สำหรับการประทับเวลาที่ระบุ สามารถแสดงผล "ขอบเขตการประทับเวลา" แทน ซึ่งระบุว่าจะไม่มีแพ็กเก็ตใด ที่สร้างขึ้นสำหรับการประทับเวลานั้นๆ จำเป็นต้องมีตัวบ่งชี้นี้เพื่ออนุญาตให้ดำเนินการดาวน์สตรีม ที่จะเรียกใช้ในการประทับเวลาดังกล่าว แม้ว่าจะไม่มีแพ็คเก็ตที่ไปถึง สตรีมบางรายการสำหรับการประทับเวลานั้น การดำเนินการนี้สำคัญอย่างยิ่งสำหรับแบบเรียลไทม์ ในแอปพลิเคชันแบบอินเทอร์แอกทีฟ ซึ่งจำเป็นที่จะต้องให้เครื่องคำนวณ เริ่มประมวลผลโดยเร็วที่สุด
ลองพิจารณากราฟที่มีลักษณะดังต่อไปนี้
node {
calculator: "A"
input_stream: "alpha_in"
output_stream: "alpha"
}
node {
calculator: "B"
input_stream: "alpha"
input_stream: "foo"
output_stream: "beta"
}
สมมติว่าที่การประทับเวลา T โหนด A ไม่ส่งแพ็กเก็ตในสตรีมเอาต์พุต
alpha โหนด B ได้รับแพ็กเก็ตใน foo ที่การประทับเวลา T และกำลังรอ
แพ็กเก็ตใน alpha ที่การประทับเวลา T หาก A ไม่ได้ส่งการเชื่อมโยงการประทับเวลาให้ B
อัปเดตสำหรับ alpha, B จะรอรับแพ็กเก็ตมาถึงใน alpha
ในขณะเดียวกัน คิวแพ็กเก็ตของ foo จะรวบรวมแพ็กเก็ตที่ T, T+1 และ
เป็นต้น
เครื่องคิดเลขจะใช้ฟังก์ชัน API เพื่อเอาต์พุตแพ็กเก็ตในสตรีม
CalculatorContext::Outputs และ OutputStream::Add เพื่อเอาต์พุต
การประทับเวลาเชื่อมโยงกับสตรีม เครื่องคิดเลขสามารถใช้ฟังก์ชัน API
CalculatorContext::Outputs และ CalculatorContext::SetNextTimestampBound
ขอบเขตที่ระบุคือการประทับเวลาต่ำสุดที่อนุญาตสำหรับแพ็กเก็ตถัดไปใน
สตรีมเอาต์พุตที่ระบุ เมื่อไม่มีเอาต์พุตเป็นแพ็กเก็ต เครื่องคิดเลขมักจะ
เช่น
cc->Outputs().Tag("output_frame").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
ฟังก์ชัน Timestamp::NextAllowedInStream จะแสดงผลการประทับเวลาต่อเนื่อง
เช่น Timestamp(1).NextAllowedInStream() == Timestamp(2)
กำลังเผยแพร่ขอบเขตของการประทับเวลา
เครื่องคิดเลขที่จะใช้ในกราฟแบบเรียลไทม์จำเป็นต้องกำหนดผลลัพธ์
ขอบเขตการประทับเวลาตามขอบเขตการประทับเวลาของอินพุตเพื่ออนุญาตให้ดำเนินการดาวน์สตรีม
เครื่องคิดเลขให้กำหนดอย่างทันท่วงทีได้ รูปแบบทั่วไปสำหรับเครื่องคำนวณ
เอาต์พุตของแพ็กเก็ตที่มีการประทับเวลาเดียวกับแพ็กเก็ตอินพุต ในกรณีนี้
เพียงการแสดงแพ็กเก็ตในทุกการเรียกไปยัง Calculator::Process ก็เพียงพอแล้ว
เพื่อกำหนดขอบเขตของการประทับเวลาเอาต์พุต
อย่างไรก็ตาม ไม่จำเป็นต้องใช้เครื่องคำนวณเพื่อให้เป็นไปตามรูปแบบทั่วไปนี้สำหรับเอาต์พุต แต่จำเป็นต่อการเลือก เอาต์พุตเพียงอย่างเดียวที่เพิ่มขึ้น ของคุณ ดังนั้น เครื่องคำนวณบางอย่างจึงต้องคำนวณขอบเขตของการประทับเวลา อย่างชัดเจน MediaPipe มีเครื่องมือมากมายสำหรับการคำนวณการประทับเวลาที่เหมาะสม สำหรับเครื่องคิดเลขแต่ละเครื่อง
1. คุณสามารถใช้ SetNextTimestampBound() เพื่อระบุขอบเขตการประทับเวลาเป็น t +
1 สำหรับสตรีมเอาต์พุตได้
cc->Outputs.Tag("OUT").SetNextTimestampBound(t.NextAllowedInStream());
หรือจะสร้างแพ็กเกตเปล่าที่มีการประทับเวลา t เพื่อระบุพารามิเตอร์
ขอบเขตการประทับเวลา t + 1
cc->Outputs.Tag("OUT").Add(Packet(), t);
ขอบเขตการประทับเวลาของสตรีมอินพุตระบุด้วยแพ็กเก็ตหรือข้อมูลที่ว่างเปล่า แพ็กเก็ตบนสตรีมอินพุต
Timestamp bound = cc->Inputs().Tag("IN").Value().Timestamp();
2. สามารถระบุ TimestampOffset() เพื่อคัดลอก การประทับเวลาที่เชื่อมโยงจากสตรีมอินพุตไปยังสตรีมเอาต์พุต
cc->SetTimestampOffset(0);
การตั้งค่านี้มีข้อดีคือ เผยแพร่ขอบเขตการประทับเวลาโดยอัตโนมัติ แม้ในขณะที่มาถึงขอบเขตการประทับเวลาเท่านั้น และเครื่องคิดเลข::กระบวนการไม่ทำงาน
3. สามารถระบุ ProcessTimestampBounds() เพื่อเรียก
Calculator::Process สำหรับแต่ละ "การประทับเวลาที่ตกลงกันแล้ว" ใหม่แต่ละรายการ โดยที่แท็ก "ชำระเงินแล้ว"
การประทับเวลา" เป็นการประทับเวลาสูงสุดใหม่ที่ต่ำกว่าขอบเขตการประทับเวลาปัจจุบัน
หากไม่มี ProcessTimestampBounds() ระบบจะเรียกใช้ Calculator::Process ด้วย
แพ็กเก็ตที่มาถึง
cc->SetProcessTimestampBounds(true);
การตั้งค่านี้ช่วยให้เครื่องคำนวณทำการคำนวณขอบเขตการประทับเวลาของตัวเองได้
และการนำไปใช้ แม้ว่าจะอัปเดตเฉพาะการประทับเวลาของอินพุตก็ตาม ซึ่งใช้เพื่อ
จำลองเอฟเฟกต์ของ TimestampOffset() แต่ยังสามารถใช้เพื่อ
คำนวณขอบเขตของการประทับเวลาที่ต้องพิจารณาปัจจัยอื่นๆ เพิ่มเติม
ตัวอย่างเช่น ในการจำลอง SetTimestampOffset(0) เครื่องคำนวณสามารถ
ให้ทำดังนี้
absl::Status Open(CalculatorContext* cc) {
cc->SetProcessTimestampBounds(true);
}
absl::Status Process(CalculatorContext* cc) {
cc->Outputs.Tag("OUT").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
}
การวางกำหนดการเครื่องคิดเลข::เปิดและเครื่องคิดเลข::ปิด
เรียกใช้ Calculator::Open เมื่อมีการแพ็กเก็ตด้านข้างของอินพุตที่จำเป็นทั้งหมดแล้ว
การผลิต อินพุตด้านข้างอาจจัดเตรียมโดยแอปพลิเคชันที่แนบมาหรือโดย
"เครื่องคำนวณแบบ Side-packet" ภายในกราฟ ระบุแพ็กเก็ตด้านข้างได้จาก
นอกกราฟโดยใช้ CalculatorGraph::Initialize ของ API และ
CalculatorGraph::StartRun เครื่องคิดเลขภายในสามารถระบุแพ็กเก็ตด้านข้าง
กราฟโดยใช้ CalculatorGraphConfig::OutputSidePackets และ
OutputSidePacket::Set
เครื่องคิดเลข::ระบบจะเรียกใช้การปิดเมื่อสตรีมอินพุตทั้งหมดกลายเป็น Done โดย
ถูกปิดหรือถึงขอบเขตการประทับเวลา Timestamp::Done
หมายเหตุ: หากกราฟประมวลผลเครื่องคำนวณที่รอดำเนินการอยู่ทั้งหมดเสร็จและเปลี่ยนเป็น
Done ก่อนที่สตรีมบางรายการจะกลายเป็น Done จากนั้น MediaPipe จะเรียกใช้เมธอด
เหลือการโทรไปยัง Calculator::Close เพื่อให้เครื่องคิดเลขทุกเครื่องสามารถ
ผลลัพธ์สุดท้าย
การใช้ TimestampOffset มีผลบางอย่างกับ Calculator::Close ต
เครื่องคิดเลขที่ระบุ SetTimestampOffset(0) จะใช้สัญญาณการออกแบบว่า
สตรีมเอาต์พุตถึง Timestamp::Done เมื่อสตรีมอินพุตทั้งหมด
ถึง Timestamp::Done แล้ว ดังนั้นจึงไม่สามารถแสดงเอาต์พุตเพิ่มเติมได้
วิธีนี้จะช่วยป้องกันไม่ให้เครื่องคิดเลขดังกล่าวปล่อยแพ็กเก็ตใดๆ ระหว่าง
Calculator::Close หากเครื่องคิดเลขจำเป็นต้องสร้างชุดสรุปในระหว่าง
Calculator::Close, Calculator::Process ต้องระบุขอบเขตของการประทับเวลาเช่น
ว่าการประทับเวลาอย่างน้อย 1 รายการ (เช่น Timestamp::Max) ยังคงใช้ได้ระหว่าง
Calculator::Close ซึ่งหมายความว่า เครื่องคำนวณดังกล่าวไม่สามารถพึ่งพา
SetTimestampOffset(0) และต้องระบุขอบเขตของการประทับเวลาอย่างชัดเจนแทน
ด้วย SetNextTimestampBounds()