การประทับเวลาแบบเรียลไทม์
กราฟเครื่องคำนวณ 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()