غواصی عمیق: VideoNG

دیل کورتیس
Dale Curtis

من دیل کورتیس هستم، مدیر مهندسی برای پخش رسانه در Chromium. تیم من مسئول APIهای رو به روی وب برای پخش ویدیو مانند MSE و WebCodecs و اجزای داخلی خاص پلتفرم است که در دموکس کردن، رمزگشایی، و رندر صدا و تصویر نقش دارند.

در این مقاله، معماری رندر ویدیویی Chromium را به شما معرفی خواهم کرد. در حالی که برخی از جزئیات در مورد توسعه‌پذیری احتمالاً مختص Chromium هستند، بیشتر مفاهیم و طرح‌های مورد بحث در اینجا برای سایر موتورهای رندر و حتی برنامه‌های پخش بومی اعمال می‌شوند.

معماری پخش Chromium در طول سال ها به طور قابل توجهی تغییر کرده است. در حالی که ما با ایده هرم موفقیت همانطور که در پست اول این مجموعه توضیح داده شد شروع نکردیم، اما در نهایت مراحل مشابهی را دنبال کردیم: قابلیت اطمینان، عملکرد و سپس توسعه پذیری.

در ابتدا ، رندر ویدئو بسیار ساده بود - فقط یک حلقه برای انتخاب نرم افزار رمزگشایی فریم های ویدئویی برای ارسال به کامپوزیتور. برای سال ها این به اندازه کافی قابل اعتماد بود، اما با افزایش پیچیدگی وب، نیاز به عملکرد و کارایی بیشتر منجر به تغییرات معماری شد. بسیاری از بهبودها به اصول اولیه مخصوص سیستم عامل نیاز داشتند. بنابراین، معماری ما نیز باید برای دسترسی به تمام پلتفرم‌های Chromium توسعه‌پذیرتر می‌شد.

نمودار رندر جریان به پلتفرم های مختلف Chromium.

رندر ویدیو را می توان به دو مرحله تقسیم کرد: انتخاب چیزی که باید ارائه شود و ارائه آن اطلاعات به طور موثر. به منظور خوانایی، قبل از بررسی نحوه انتخاب Chromium چه چیزی را برای ارائه انتخاب می کند، تحویل کارآمد را پوشش خواهم داد.

برخی از اصطلاحات و طرح

از آنجایی که این مقاله بر روی رندر تمرکز دارد، من فقط به طور خلاصه به جنبه‌های دموکسینگ و رمزگشایی خط لوله می‌پردازم.

جریان بایت ها و خروج بسته های ساختار یافته

رمزگشایی و دموکس کردن در دنیای مدرن امروزی ما نیازمند کمی دقت است. تجزیه کننده های باینری محیط های هدف غنی هستند و پخش رسانه ها پر از تجزیه باینری است. به این ترتیب، مسائل امنیتی در تجزیه کننده های رسانه بسیار رایج است.

Chromium دفاع عمیقی انجام می دهد تا خطر مشکلات امنیتی را برای کاربران کاهش دهد. در عمل، این بدان معناست که رمزگشایی و رمزگشایی نرم‌افزاری همیشه در یک فرآیند با امتیاز پایین اتفاق می‌افتد، در حالی که رمزگشایی سخت‌افزاری در فرآیندی با امتیاز کافی برای صحبت با GPU سیستم اتفاق می‌افتد.

جعبه‌های ایمنی Chromium برای پردازش‌های رندر، GPU و صدا.

مکانیسم ارتباط متقابل Chromium Mojo نام دارد. در حالی که در این مقاله وارد جزئیات Mojo نمی شویم، به عنوان لایه انتزاعی بین فرآیندها، این سنگ بنای خط لوله رسانه توسعه پذیر Chromium است. مهم است که هنگام عبور از خط لوله پخش، از این موضوع آگاه باشیم، زیرا به هماهنگی پیچیده اجزای فرآیند متقابلی که برای دریافت، دموکس، رمزگشایی و در نهایت نمایش رسانه در تعامل هستند، اطلاع می دهد.

اینهمه بیت

درک خطوط لوله رندر ویدیوی امروزی مستلزم آگاهی از دلیل خاص بودن ویدئو است: پهنای باند. پخش با رزولوشن 3840x2160 (4K) با سرعت 60 فریم بر ثانیه بین 9-12 گیگابیت بر ثانیه از پهنای باند حافظه استفاده می کند. در حالی که سیستم‌های مدرن ممکن است حداکثر پهنای باند در صدها گیگابیت در ثانیه داشته باشند، پخش ویدیو همچنان بخش قابل توجهی را نشان می‌دهد. بدون مراقبت، کل پهنای باند می تواند به راحتی به دلیل کپی ها یا سفرهای بین حافظه GPU و CPU چند برابر شود.

هدف هر موتور پخش ویدئویی مدرن با در نظر گرفتن کارایی، به حداقل رساندن پهنای باند بین رمزگشا و مرحله رندر نهایی است. به همین دلیل، رندر ویدیو تا حد زیادی از خط لوله رندر اصلی Chromium جدا شده است. به طور خاص، از منظر خط لوله رندر اصلی ما، ویدیو فقط یک حفره با اندازه ثابت با کدورت است. Chromium با استفاده از مفهومی به نام سطوح به این امر دست می‌یابد — به موجب آن هر ویدیو مستقیماً با Viz صحبت می‌کند.

یک صفحه وب با یک سوراخ و یک پیکان که می‌گوید «ویدیو اینجا می‌رود».

با توجه به محبوبیت محاسبات تلفن همراه، قدرت و کارایی در نسل کنونی به یک تمرکز قابل توجه تبدیل شده است. نتیجه این امر این است که رمزگشایی و رندر در سطح سخت‌افزاری بیش از هر زمان دیگری با هم مرتبط شده‌اند و در نتیجه ویدیو فقط مانند یک سوراخ با کدورت به نظر می‌رسد، حتی برای خود سیستم‌عامل! رمزگشاهای سطح پلت فرم اغلب فقط بافرهای مات را ارائه می دهند که کروم از آنها به سیستم ترکیبی سطح پلت فرم به شکل پوشش عبور می کند.

یک صفحه وب با یک سوراخ و فلشی که می‌گوید «ویدیو اینجا می‌رود»، که توسط کادری که نشان‌دهنده سیستم عامل است پیچیده شده است.

هر پلتفرمی شکل مخصوص به خود را دارد که APIهای رمزگشایی پلتفرم آنها به طور هماهنگ با آنها کار می کنند. Windows دارای Direct Composition و Media Foundation Transforms است ، macOS دارای لایه های CoreAnimation و VideoToolbox ، اندروید دارای SurfaceView و MediaCodec و لینوکس دارای VASurfaces و VA-API است. انتزاعات Chromium برای این مفاهیم به ترتیب توسط رابط های OverlayProcessor و mojo::VideoDecoder انجام می شود.

در برخی موارد این امکان وجود دارد که این بافرها در حافظه سیستم نگاشت شوند، بنابراین حتی نیازی به غیرشفاف بودن و مصرف پهنای باندی تا زمان دسترسی ندارند—Chromium این بافرها را GpuMemoryBuffers می نامد. در ویندوز اینها توسط بافرهای DXGI ، در macOS IOSurfaces ، در Android AHardwareBuffers و در لینوکس بافرهای DMA پشتیبانی می شوند. در حالی که پخش ویدیو معمولاً به این دسترسی نیاز ندارد، این بافرها برای ضبط ویدیو مهم هستند تا از حداقل پهنای باند بین دستگاه ضبط و رمزگذارهای نهایی اطمینان حاصل شود.

نمودار بافرهای ذکر شده در متن قبل.

از آنجایی که GPU اغلب مسئول رمزگشایی و نمایش است، استفاده از این بافرهای غیرشفاف (همچنین اغلب) تضمین می کند که داده های ویدئویی با پهنای باند بالا هرگز از GPU خارج نمی شوند. همانطور که قبلاً بحث کردیم، نگهداری داده ها روی GPU برای کارایی فوق العاده مهم است. به خصوص در رزولوشن بالا و نرخ فریم.

هر چه بیشتر بتوانیم از مزایای اولیه سیستم عامل مانند پوشش‌ها و بافرهای GPU استفاده کنیم، پهنای باند کمتری صرف به هم زدن بایت‌های ویدئویی می‌شود. نگه داشتن همه چیز در یک مکان از رمزگشایی گرفته تا رندر می تواند منجر به بهره وری انرژی باورنکردنی شود. به عنوان مثال، وقتی Chromium پوشش‌ها را در macOS فعال کرد ، مصرف انرژی در حین پخش ویدیوی تمام صفحه به نصف کاهش یافت! در سایر پلتفرم‌ها مانند Windows ، Android و ChromeOS ، ما می‌توانیم از پوشش‌ها حتی در موارد غیرتمام‌صفحه استفاده کنیم و تقریباً در همه جا تا 50 درصد صرفه‌جویی می‌کنیم.

تفسیر

اکنون که مکانیسم‌های تحویل بهینه را پوشش داده‌ایم، می‌توانیم درباره نحوه انتخاب Chromium چه چیزی را برای تحویل انتخاب می‌کند بحث کنیم. پشته پخش Chromium از معماری مبتنی بر «کشش» استفاده می‌کند، به این معنی که هر جزء در پشته ورودی‌های خود را از زیر آن به ترتیب سلسله مراتبی درخواست می‌کند. در بالای پشته، رندر فریم های صوتی و تصویری، پایین تر، رمزگشایی، به دنبال دموکسینگ، و در نهایت I/O قرار دارد. هر فریم صوتی رندر شده یک ساعت را به پیش می‌برد که برای انتخاب فریم‌های ویدئویی برای رندر زمانی که با یک بازه ارائه ترکیب می‌شود، استفاده می‌شود.

در هر بازه ارائه (هر بازخوانی نمایشگر)، از رندرکننده ویدیو خواسته می‌شود که یک فریم ویدیویی توسط CompositorFrameSink متصل به SurfaceLayer که قبلاً ذکر شد، ارائه دهد. برای محتوایی با نرخ فریم کمتر از نرخ نمایش، این به معنای نمایش یک فریم بیش از یک بار است، در حالی که اگر نرخ فریم بیشتر از نرخ نمایش باشد، برخی از فریم ها هرگز نشان داده نمی شوند.

همگام‌سازی صدا و ویدیو به روش‌هایی که برای بینندگان خوشایند است، چیزهای بیشتری وجود دارد. برای بحث طولانی تر در مورد اینکه چگونه نرمی بهینه ویدیو در Chromium انجام می شود، به Project Butter مراجعه کنید. توضیح می‌دهد که چگونه رندر ویدیو را می‌توان به دنباله‌های ایده‌آل تقسیم کرد که نشان‌دهنده چند بار نمایش هر فریم است. به عنوان مثال: "1 فریم در هر بازه نمایش ([1]، 60 فریم در ثانیه در 60 هرتز)"، "1 فریم در هر 2 بازه ([2]، 30 فریم در ثانیه در 60 هرتز)"، یا الگوهای پیچیده تر مانند [2:3 :2:3:2] (25 فریم در ثانیه در 60 هرتز) چندین فریم متمایز و فواصل نمایش را پوشش می دهد. هر چه یک رندر ویدیویی به این الگوی ایده آل نزدیک تر باشد، احتمال بیشتری وجود دارد که کاربر یک پخش را روان درک کند.

دنباله دموکسینگ، رمزگشایی و رندرینگ.

در حالی که اکثر پلتفرم‌های Chromium فریم به فریم رندر می‌شوند، همه این کار را نمی‌کنند. معماری توسعه پذیر ما امکان رندر دسته ای را نیز فراهم می کند. رندر دسته‌ای یک تکنیک کارآمد است که در آن به ترکیب‌کننده سطح سیستم‌عامل از قبل درباره فریم‌های متعدد گفته می‌شود و انتشار آن‌ها را در برنامه زمان‌بندی ارائه‌شده برنامه مدیریت می‌کند.

آینده اکنون است؟

ما بر این تمرکز کرده‌ایم که Chromium چگونه از مزایای اولیه سیستم عامل برای ارائه بهترین تجربه پخش در کلاس استفاده می‌کند. اما در مورد وب‌سایت‌هایی که می‌خواهند از پخش اولیه ویدیو فراتر بروند، چطور؟ آیا می‌توانیم همان اصول اولیه قدرتمندی را که خود Chromium برای معرفی نسل بعدی محتوای وب به کار می‌برد، به آنها ارائه دهیم؟

ما فکر می کنیم که پاسخ مثبت است! توسعه پذیری در قلب طرز فکر ما در مورد پلتفرم وب این روزها است. ما با مرورگرها و توسعه‌دهندگان دیگر کار کرده‌ایم تا فناوری‌های جدیدی مانند WebGPU و WebCodecs ایجاد کنیم تا توسعه‌دهندگان وب بتوانند از همان کارهای ابتدایی Chromium در هنگام صحبت با سیستم‌عامل استفاده کنند. WebGPU پشتیبانی از بافرهای GPU را به همراه دارد و WebCodecs رمزگشایی و رمزگذاری پلتفرم اولیه را به همراه دارد که با همپوشانی فوق الذکر و سیستم های بافر GPU سازگار است.

ارتباط بین WebCodec و WebGPU.

پایان جریان

با تشکر برای خواندن! امیدوارم با درک بهتری از سیستم‌های پخش مدرن و نحوه عملکرد Chromium برای چند صد میلیون ساعت زمان تماشا در روز، آشنا شده باشید. اگر به دنبال مطالعه بیشتر در مورد کدک ها و ویدیوهای وب مدرن هستید ، H.264 is Magic توسط سید بالا، How Modern Video Players Work توسط Erica Beaves، و بسته بندی نمایش های برنده جایزه با فناوری برنده جایزه توسط Cyril Concolato را توصیه می کنم.

یک تصویر (زیبا!) توسط Una Kravets.