สตรีมแบบเรียลไทม์

การประทับเวลาแบบเรียลไทม์

กราฟเครื่องคำนวณ 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()