เจาะลึก: VideoNG

Dale Curtis
Dale Curtis

ผมชื่อ Dale Curtis เป็นหัวหน้าทีมวิศวกรรมด้านการเล่นสื่อใน Chromium ทีมของฉันมีหน้าที่ดูแล API สำหรับเว็บในการเล่นวิดีโอ เช่น MSE และ WebCodecs รวมถึงระบบภายในเฉพาะแพลตฟอร์มที่เกี่ยวข้องกับการลดทรัพยากร ถอดรหัส ตลอดจนแสดงผลเสียงและวิดีโอ

ในบทความนี้ เราจะแนะนำสถาปัตยกรรมการแสดงผลวิดีโอของ Chromium แม้ว่ารายละเอียดบางอย่างเกี่ยวกับความสามารถในการขยายการใช้งานมักจะมีไว้สำหรับ Chromium แต่แนวคิดและการออกแบบส่วนใหญ่ที่กล่าวถึงในที่นี้จะนำไปใช้กับเครื่องมือแสดงผลอื่นๆ และแม้แต่แอปการเล่นแบบเนทีฟ

สถาปัตยกรรมการเล่นของ Chromium ได้เปลี่ยนแปลงไปอย่างมากในช่วงหลายปีที่ผ่านมา แม้ว่าเราจะไม่ได้เริ่มต้นด้วยแนวคิดของพีระมิดแห่งความสำเร็จตามที่อธิบายไว้ในโพสต์แรกในซีรีส์นี้ แต่ท้ายที่สุดแล้ว เราได้ทำตามขั้นตอนที่คล้ายกัน คือ ความน่าเชื่อถือ ประสิทธิภาพ และความสามารถในการขยาย

ในช่วงเริ่มต้น การแสดงผลวิดีโอค่อนข้างง่าย โดยใช้เพียงการวนซ้ำเพื่อเลือกซอฟต์แวร์ที่จะถอดรหัสเฟรมวิดีโอเพื่อส่งไปยังผู้ทำองค์ประกอบ สำหรับหลายปี เรื่องนี้มีความเสถียรมากพอ แต่เมื่อเว็บมีความซับซ้อนมากขึ้น ความต้องการประสิทธิภาพและประสิทธิภาพที่เพิ่มขึ้นทำให้เกิดการเปลี่ยนแปลงทางสถาปัตยกรรม การปรับปรุงหลายอย่างต้องอาศัยพื้นฐานเฉพาะของระบบปฏิบัติการ ดังนั้น สถาปัตยกรรมของเราจึงต้องขยายตัวเพิ่มมากขึ้นเพื่อเข้าถึงทุกแพลตฟอร์มของ Chromium

แผนภาพแสดงโฟลว์การแสดงผลไปยังแพลตฟอร์ม Chromium ต่างๆ

การแสดงภาพวิดีโออาจแบ่งออกได้เป็น 2 ขั้นตอน ได้แก่ การเลือกสิ่งที่จะแสดงและแสดงข้อมูลอย่างมีประสิทธิภาพ เพื่อให้อ่านได้ง่าย ฉันจะพูดถึงเรื่องการนำส่งที่มีประสิทธิภาพก่อนเจาะลึกว่า Chromium เลือกวิธีที่จะแสดงผลอย่างไร

คำศัพท์และเลย์เอาต์บางส่วน

เนื่องจากบทความนี้มุ่งเน้นไปที่การแสดงผล ฉันขอเล่าสั้นๆ ถึงแง่มุมเรื่องการลดจำนวนและถอดรหัสของไปป์ไลน์

ไบต์ที่เข้ามาและแพ็กเก็ตที่มีโครงสร้างไหลออก

การถอดรหัสและการลดความซับซ้อนในโลกที่คำนึงถึงความปลอดภัยสมัยใหม่ของเราต้องใช้ความระมัดระวังพอสมควร โปรแกรมแยกวิเคราะห์ไบนารีคือสภาพแวดล้อมเป้าหมายที่สมบูรณ์และการเล่นสื่อจะเต็มไปด้วยการแยกวิเคราะห์ไบนารี ด้วยเหตุนี้ ปัญหาด้านความปลอดภัยในโปรแกรมแยกวิเคราะห์สื่อจึงเป็นเรื่องปกติ

Chromium นำการป้องกันอย่างเจาะลึกไปใช้เพื่อลดความเสี่ยงที่จะเกิดปัญหาด้านความปลอดภัยต่อผู้ใช้ ในทางปฏิบัติ การถอดรหัสซอฟต์แวร์และการถอดรหัสซอฟต์แวร์จะเกิดขึ้นในกระบวนการที่มีสิทธิพิเศษต่ำเสมอ ในขณะที่การถอดรหัสฮาร์ดแวร์จะเกิดขึ้นในกระบวนการที่มีสิทธิ์เพียงพอที่จะสื่อสารกับ GPU ของระบบ

แซนด์บ็อกซ์ Chromium สำหรับโหมดแสดงภาพ, GPU และการประมวลผลเสียง

กลไกการสื่อสารข้ามกระบวนการของ Chromium เรียกว่า Mojo แม้ว่าเราจะไม่ได้กล่าวถึงรายละเอียดของ Mojo ในบทความนี้ เนื่องจากเป็นเลเยอร์ Abstraction ระหว่างกระบวนการต่างๆ ซึ่งถือเป็นรากฐานที่สำคัญของไปป์ไลน์สื่อที่ขยายได้ของ Chromium คุณต้องตระหนักถึงเรื่องนี้ในขณะที่เราเดินไปตามไปป์ไลน์การเล่น เนื่องจากระบบจะบอกกระบวนการที่ซับซ้อนของคอมโพเนนต์แบบข้ามกระบวนการที่โต้ตอบเพื่อรับ ถอดรหัส ถอดรหัส และแสดงสื่อในท้ายที่สุด

มีหลายบิตมาก

การทำความเข้าใจไปป์ไลน์การแสดงผลวิดีโอในปัจจุบันต้องอาศัยความรู้ว่าเหตุใดวิดีโอจึงมีความพิเศษ ซึ่งก็คือแบนด์วิดท์ การเล่นความละเอียด 3840x2160 (4K) ที่ 60 เฟรมต่อวินาที จะใช้แบนด์วิดท์หน่วยความจำระหว่าง 9-12 กิกะบิต/วินาที แม้ว่าระบบสมัยใหม่อาจมีแบนด์วิดท์สูงสุดเป็นจำนวนหลายร้อยกิกะบิตต่อวินาที การเล่นวิดีโอยังคงเป็นสัดส่วนที่ค่อนข้างสูง หากไม่ระวัง แบนด์วิดท์ทั้งหมดจะเพิ่มขึ้นได้ง่ายเนื่องจากมีการคัดลอกหรือย้ายระหว่าง GPU กับหน่วยความจำของ CPU

เป้าหมายของเครื่องมือเล่นวิดีโอสมัยใหม่โดยคำนึงถึงประสิทธิภาพ คือการลดแบนด์วิดท์ระหว่างตัวถอดรหัสและขั้นตอนการแสดงผลขั้นสุดท้าย ด้วยเหตุนี้ การแสดงภาพวิดีโอจึงแยกออกจากไปป์ไลน์การแสดงผลหลักของ Chromium จากมุมมองของไปป์ไลน์การแสดงภาพหลักของเรา วิดีโอจะเป็นเพียงรูขนาดคงที่ที่มีความทึบแสง Chromium บรรลุเป้าหมายนี้โดยใช้แนวคิดที่เรียกว่า Surfaces ซึ่งแต่ละวิดีโอจะสื่อสารกับ Viz โดยตรง

หน้าเว็บที่มีช่องและลูกศรเขียนว่า "ใส่วิดีโอที่นี่"

เนื่องจากความนิยมของการประมวลผลบนอุปกรณ์เคลื่อนที่ พลังและประสิทธิภาพกลายเป็นสิ่งที่ให้ความสำคัญอย่างมากในรุ่นปัจจุบัน ผลที่ได้คือ การถอดรหัสและการแสดงผลมีการเชื่อมโยงกันมากขึ้นในระดับฮาร์ดแวร์ ส่งผลให้วิดีโอดูเหมือนเป็นรูที่มีความทึบแสง แม้แต่กับระบบปฏิบัติการเองก็ตาม ตัวถอดรหัสระดับแพลตฟอร์มมักจะให้เฉพาะบัฟเฟอร์ทึบแสงที่ Chromium ผ่านไปยังระบบประกอบระดับแพลตฟอร์มในรูปแบบของการวางซ้อน

หน้าเว็บที่มีช่องและลูกศรเขียนว่า "วิดีโอมาที่นี่" ซึ่งล้อมรอบด้วยกล่องที่แสดงถึงระบบปฏิบัติการ

ทุกแพลตฟอร์มมีรูปแบบการวางซ้อนที่ API การถอดรหัสแพลตฟอร์มทำงานอย่างสอดคล้องกัน Windows มี องค์ประกอบโดยตรงและ Media Foundation Transforms, macOS มี CoreAnimation Layers และ VideoToolbox, Android มี SurfaceView และ MediaCodec และ Linux มี VASurfaces และ VA-API นามธรรมของ Chromium สําหรับแนวคิดเหล่านี้ได้รับการจัดการโดยอินเทอร์เฟซ OverlayProcessor และ mojo::VideoDecoder ตามลำดับ

ในบางกรณี บัฟเฟอร์เหล่านี้สามารถแมปไปยังหน่วยความจำของระบบได้ เพื่อไม่ให้เป็นส่วนที่ทึบและไม่กินแบนด์วิดท์จนกว่าจะเข้าถึง โดย Chromium จะเรียกบัฟเฟอร์เหล่านี้ว่า GpuMemoryBuffers บน Windows จะมีบัฟเฟอร์ DXGI ใน macOS IOSurfaces ใน Android AHardwareBuffers และบัฟเฟอร์ DMA ของ Linux แม้ว่าโดยทั่วไปการเล่นวิดีโอจะไม่ต้องมีสิทธิ์เข้าถึงนี้ แต่บัฟเฟอร์เหล่านี้มีความสำคัญต่อการจับภาพวิดีโอเพื่อให้มีแบนด์วิดท์ระหว่างอุปกรณ์บันทึกกับโปรแกรมเปลี่ยนไฟล์สุดท้ายน้อยที่สุด

แผนภาพของบัฟเฟอร์ที่กล่าวถึงในข้อความก่อนหน้า

เนื่องจาก GPU มักจะเป็นทั้งการถอดรหัสและการแสดง ตามที่ได้กล่าวไปก่อนหน้า การรักษาข้อมูลใน GPU เป็นสิ่งสำคัญอย่างมากต่อประสิทธิภาพ โดยเฉพาะที่ความละเอียดและอัตราเฟรมสูง

ยิ่งเราสามารถใช้ประโยชน์จากพื้นฐานของระบบปฏิบัติการ เช่น การซ้อนทับและบัฟเฟอร์ GPU มากเท่าไร ระบบก็จะยิ่งใช้แบนด์วิดท์สับเปลี่ยนไบต์ของวิดีโอน้อยลงโดยไม่จำเป็น การเก็บทุกอย่างไว้ในที่เดียว ตั้งแต่การถอดรหัสไปจนถึงการแสดงภาพจะช่วยประหยัดพลังงานอย่างไม่น่าเชื่อ ตัวอย่างเช่น เมื่อ Chromium เปิดใช้การวางซ้อนใน macOS การใช้พลังงานระหว่างการเล่นวิดีโอแบบเต็มหน้าจอลดลงครึ่งหนึ่ง! บนแพลตฟอร์มอื่นๆ เช่น Windows, Android และ ChromeOS เราสามารถใช้การวางซ้อนแม้ในเคสที่ไม่ใช่เต็มหน้าจอ ซึ่งทำให้ประหยัดพื้นที่ได้ถึง 50% ในเกือบทุกที่

การแสดงผล

ตอนนี้เราก็ได้พูดถึงกลไกการนำส่งที่ดีที่สุดกันแล้ว เราสามารถพูดคุยถึงวิธีที่ Chromium เลือกสิ่งที่จะแสดง ชุดการเล่นของ Chromium ใช้สถาปัตยกรรมแบบ "พุล" ซึ่งหมายความว่าแต่ละคอมโพเนนต์ในสแต็กจะขออินพุตจากคอมโพเนนต์ที่อยู่ด้านล่างตามลำดับ ที่ด้านบนของสแต็กคือการแสดงภาพเฟรมเสียงและวิดีโอ ส่วนถัดไปที่อยู่ด้านล่างคือการถอดรหัส ตามด้วยการแยกหน้าจอ และสุดท้ายคือ I/O เฟรมเสียงที่แสดงผลแต่ละเฟรมจะเลื่อนไปยังนาฬิกาที่ใช้เลือกเฟรมวิดีโอสำหรับการแสดงผลเมื่อรวมกับช่วงเวลาการนำเสนอ

ในแต่ละช่วงการนำเสนอ (รีเฟรชจอแสดงผลแต่ละครั้ง) ระบบจะขอให้ตัวแสดงผลวิดีโอระบุเฟรมวิดีโอโดยใช้ CompositorFrameSink ที่แนบอยู่กับ SurfaceLayer ที่กล่าวถึงไปก่อนหน้านี้ สำหรับเนื้อหาที่มีอัตราเฟรมต่ำกว่าอัตราการแสดงผล ซึ่งหมายถึงการแสดงเฟรมเดียวกันมากกว่า 1 ครั้ง ในขณะที่อัตราเฟรมสูงกว่าอัตราการแสดงผล เฟรมบางรายการจะไม่แสดงเลย

การซิงค์เสียงและวิดีโอในแบบที่น่าพึงพอใจสำหรับผู้ชมยังมีอีกมากมาย ดู Project Butter สำหรับการพูดคุยเพิ่มเติมเกี่ยวกับการทำให้วิดีโอราบรื่นที่สุดใน Chromium ซึ่งอธิบายวิธีการแบ่งการแสดงผลของวิดีโอออกเป็นลำดับที่เหมาะสม ซึ่งแสดงถึงจำนวนครั้งที่ควรแสดงแต่ละเฟรม ตัวอย่างเช่น "1 เฟรมทุกๆ ช่วงเวลาการแสดงผล ([1], 60 FPS ใน 60 Hz)", "1 เฟรมทุกๆ 2 ช่วงเวลา ([2], 30 fps ใน 60 Hz)" หรือรูปแบบที่ซับซ้อนกว่าอย่าง [2:3:2:3:2] (25 fps ใน 60 Hz) โดยครอบคลุมหลายเฟรม และครอบคลุมหลายเฟรม ยิ่งตัวแสดงผลวิดีโอใกล้เคียงกับรูปแบบในอุดมคตินี้มากเท่าใด ผู้ใช้ก็มีแนวโน้มที่จะรู้สึกว่าการเล่นลื่นไหลมากขึ้นเท่านั้น

ลำดับของการลดทรัพยากร การถอดรหัส และการแสดงผล

แม้ว่าแพลตฟอร์ม Chromium ส่วนใหญ่จะแสดงผลแบบเฟรมต่อเฟรม แต่ไม่ใช่ทั้งหมด สถาปัตยกรรมที่ยืดหยุ่นได้ของเราทำให้สามารถแสดงผลเป็นแบบกลุ่มได้เช่นกัน การแสดงผลแบบกลุ่มเป็นเทคนิคประสิทธิภาพที่ระบบแจ้งตัวจัดวางองค์ประกอบระดับระบบปฏิบัติการเกี่ยวกับหลายเฟรมล่วงหน้า และจัดการกับการปล่อยเฟรมเหล่านั้นตามกำหนดการเวลาที่แอปพลิเคชันระบุไว้

อนาคตคืออะไร

เรามุ่งเน้นที่วิธีที่ Chromium ใช้ประโยชน์จากพื้นฐานของระบบปฏิบัติการเพื่อมอบประสบการณ์การเล่นที่ดีที่สุด แล้วเว็บไซต์ที่ต้องการมากกว่าการเล่นวิดีโอแบบพื้นฐานล่ะ เราจะนำเสนอข้อมูลพื้นฐานที่ทรงประสิทธิภาพแบบเดียวกับที่ Chromium เองใช้ในการนําไปสู่เนื้อหาเว็บรุ่นใหม่ได้หรือไม่

เราคิดว่าคำตอบคือใช่ การขยายการใช้งานคือหัวใจสำคัญของความคิดเกี่ยวกับแพลตฟอร์มเว็บในปัจจุบัน เราได้ทำงานร่วมกับเบราว์เซอร์และนักพัฒนาซอฟต์แวร์อื่นๆ เพื่อสร้างเทคโนโลยีใหม่ๆ เช่น WebGPU และ WebCodecs เพื่อให้นักพัฒนาเว็บสามารถใช้แบบพื้นฐานที่ Chromium ทำเช่นกันเมื่อพูดกับระบบปฏิบัติการ WebGPU รองรับบัฟเฟอร์ GPU และ WebCodecs นำการถอดรหัสแพลตฟอร์มและการเข้ารหัสพื้นฐานที่เข้ากันได้กับการวางซ้อนและระบบบัฟเฟอร์ GPU ที่กล่าวถึงข้างต้น

ความสัมพันธ์ระหว่าง WebCodecs กับ WebGPU

สิ้นสุดสตรีม

ขอขอบคุณที่อ่าน ผมหวังว่าคุณจะเข้าใจระบบการเล่นที่ทันสมัยยิ่งขึ้น และรู้ว่า Chromium ช่วยเพิ่มเวลาในการรับชมหลายร้อยล้านชั่วโมงในแต่ละวันได้อย่างไร หากต้องการอ่านเพิ่มเติมเกี่ยวกับตัวแปลงรหัสและวิดีโอบนเว็บแบบใหม่ เราขอแนะนำ H.264 is Magic โดย Sid Bala, How Modern Video Players Work โดย Erica Beaves และการจัดแพ็กเกจรายการที่ได้รับรางวัลด้วยเทคโนโลยีที่ได้รับรางวัล โดย Cyril Concolato

ภาพหนึ่ง (สวยดีนะ) โดย Una Kravets