צוללים לעומק: VideoNG

Dale Curtis
Dale Curtis

שמי דייל קרטיס, ואני מנהל מהנדסי התוכנה בתחום הפעלת מדיה ב-Chromium. הצוות שלי אחראי על ממשקי ה-API שפונים לאינטרנט להפעלת סרטונים כמו MSE ו-WebCodecs, ועל רכיבי הפנימיים הספציפיים לפלטפורמה שקשורים לדמוקס, פענוח ועיבוד של אודיו ווידאו.

במאמר הזה אפרט את הארכיטקטורה של עיבוד הווידאו ב-Chromium. פרטים מסוימים לגבי יכולת הרחבה הם ככל הנראה ספציפיים ל-Chromium, אבל רוב המושגים והעיצובים שמתוארים כאן רלוונטיים למנועי רינדור אחרים ואפילו לאפליקציות הפעלה מקוריות.

ארכיטקטורת ההפעלה של Chromium השתנתה באופן משמעותי במהלך השנים. אמנם לא התחלנו עם הרעיון של פירמידה של הצלחה כפי שמתואר בפוסט הראשון בסדרה הזו, אבל בסופו של דבר ביצענו שלבים דומים: אמינות, ביצועים ולאחר מכן יכולת הרחבה.

בהתחלה, רינדור הווידאו היה פשוט למדי – רק לולאת <for> שבה היה צריך לבחור אילו פריימים של וידאו מפוענחים ולשלוח למרכיב. במשך שנים זה היה מהימן מספיק, אבל ככל שהמורכבות של האינטרנט הלכה וגדלה, הצורך בשיפור הביצועים והיעילות גרם לשינויים בארכיטקטורה. כדי לבצע שיפורים רבים, היה צורך בפרימיטיבים מסוימים שספציפיים למערכת ההפעלה. כדי לעשות זאת, היה צורך להרחיב את הארכיטקטורה שלנו כדי להגיע לכל הפלטפורמות של Chromium.

תרשים של זרימת העיבוד לפלטפורמות שונות של Chromium.

ניתן לחלק את עיבוד הווידאו לשני שלבים: בחירה מה להציג ומסירת המידע ביעילות. כדי לשפר את הקריאות, אסביר על אופן האספקה יעיל לפני שנרחיב על האופן שבו Chromium בוחר מה לספק.

תנאים ופריסה מסוימים

מכיוון שמאמר זה מתמקד ברינדור, אתייחס רק בקצרה להיבטים של הדמוקס והפענוח של צינור עיבוד הנתונים.

בייטים שזורמים ומנות מובנות יוצאות.

פענוח הקוד והדמקס (deuxing) בעולם המודרני עם מודעות האבטחה, דורש קצת טיפול. מנתחים בינאריים הם סביבות יעד עשירות, והפעלת המדיה מלאה בניתוח בינארי. לכן, בעיות אבטחה בכלי הניתוח של מדיה הן נפוצות מאוד.

Chromium מתבסס על הגנה לעומק כדי לצמצם את הסיכון לבעיות אבטחה למשתמשים. מבחינה מעשית, המשמעות היא שדמוקס ופענוח התוכנה מתרחשים תמיד בתהליך עם הרשאות נמוכות, ופענוח החומרה מתרחש בתהליך עם הרשאות מספיקות כדי לתקשר עם ה-GPU של המערכת.

ארגזי החול של Chromium לתהליכי כלי הרינדור, ה-GPU ותהליכי האודיו.

מנגנון התקשורת חוצה-התהליכים של Chromium נקרא Mojo. אמנם לא ניכנס לפרטים של Mojo במאמר זה, אך בתור שכבת ההפשטה בין תהליכים, הוא מהווה אבן יסוד בצינור המדיה הניתן להרחבה של Chromium. חשוב להיות מודעים לכך בזמן שאנחנו עוברים על צינור עיבוד הנתונים של ההפעלה, כי הוא מבוסס על התזמור המורכב של רכיבים בתהליכים שונים שמקיימים אינטראקציה כדי לקבל, לדמו, לפענח ולבסוף להציג מדיה.

כל כך הרבה ביטים

כדי להבין את צינורות עיבוד הנתונים כיום לעיבוד וידאו, צריך לדעת למה וידאו הוא מיוחד: רוחב פס. הפעלה ברזולוציה של 3840x2160 (4K) בקצב של 60 FPS משתמשת ברוחב פס זיכרון של 9-12 ג'יגה-ביט לשנייה. במערכות מודרניות יש רוחב פס שיא של מאות ג'יגה-ביט לשנייה, אבל הפעלת הסרטונים עדיין מהווה חלק משמעותי. בלי זהירות, רוחב הפס הכולל יכול להכפיל בקלות את הנתונים שלו בעקבות עותקים או נסיעות בין ה-GPU לזיכרון המעבד (CPU).

כל מנוע מודרני להפעלת סרטונים מתוך מחשבה על יעילות הוא לצמצם את רוחב הפס בין המפענח לבין שלב הרינדור הסופי. לכן, עיבוד הווידאו מופרד ברובו מצינור עיבוד הנתונים הראשי של Chromium. באופן ספציפי, מנקודת המבט של צינור עיבוד הנתונים הראשי שלנו, הסרטון הוא פשוט חור בגודל קבוע עם אטימות. כך אפשר לעשות זאת ב-Chromium באמצעות קונספט שנקרא פלטפורמות, שבו כל סרטון קשור ישירות ל-Viz.

דף אינטרנט עם חור וחץ שכתוב בהם &#39;הסרטון מתחיל כאן&#39;.

בגלל הפופולריות של המחשוב הנייד, כוח ויעילות הפכו לחלק משמעותי בדור הנוכחי. כתוצאה מכך, פענוח ועיבוד מחוברים יותר מתמיד ברמת החומרה, וכתוצאה מכך הווידאו פשוט נראה כמו חור עם אטימות, גם למערכת ההפעלה עצמה! בדרך כלל, מפענחים ברמת הפלטפורמה מספקים רק מאגרים אטומים ש-Chromium מעביר למערכת האיחוד ברמת הפלטפורמה, בצורת שכבות-על.

דף אינטרנט עם חור וחץ שכתוב בהם &#39;הסרטון מופיע כאן&#39;, שמוקף בתיבה שמייצגת את מערכת ההפעלה.

לכל פלטפורמה יש סוג משלה של שכבות-על, שממשקי ה-API לפענוח קוד של הפלטפורמה עובדים איתן בתיאום. ב-Windows יש את Direct Composition וגם Media Foundation Transforms, ב-macOS יש CoreAnimation Layers ו-VideoToolbox, ב-Android יש SurfaceView ו-MediaCodec, וב-Linux יש VASurfaces וגם VA-API. ההפשטות של Chromium למושגים האלה מטופלות על ידי הממשק OverlayProcessor ו-mojo::VideoDecoder בהתאמה.

במקרים מסוימים, אפשר למפות את מאגרי האחסון האלה לזיכרון המערכת, כך שהם אפילו לא צריכים להיות אטומים ולא צורכים רוחב פס עד לגישה — Chromium קורא ל-GpuMemoryBuffers האלה. ב-Windows הקבצים האלה מגובים על ידי מאגרי DXGI, ב-IOSurfaces של macOS, ב-AHardwareBuffers וב-מאגרי DMA של Linux. בדרך כלל הפעלת וידאו לא צריכה את הגישה הזו, אבל המאגרים האלה חשובים לצילום וידאו, כדי להבטיח רוחב פס מינימלי בין מכשיר הצילום למקודדים הסופיים.

תרשים של מאגרי האחסון המוזכרים בטקסט הקודם.

מכיוון שה-GPU אחראי לעיתים קרובות גם לפענוח וגם להצגה, השימוש במאגרים אטומים (לעיתים קרובות גם) מבטיח שנתוני וידאו ברוחב פס גבוה אף פעם לא יוצאים מה-GPU. כמו שהסברנו קודם, שמירת הנתונים ב-GPU חשובה מאוד ליעילות, במיוחד ברזולוציות גבוהות ובקצב פריימים גבוה.

ככל שאנחנו יכולים לנצל בצורה טובה יותר את התכונות הבסיסיות של מערכת ההפעלה, כמו שכבות-על ומאגרי GPU, כך אנחנו מבזבזים פחות רוחב פס לערבוב של בייטים של וידאו שלא לצורך. אחסון הכול במקום אחד, מפענוח ועד העיבוד, יכול להוביל ליעילות מדהימה בחשמל. לדוגמה, כש-Chromium הפעיל שכבות-על ב-macOS, צריכת החשמל בזמן הפעלת סרטונים במסך מלא הופחתה בחצי! בפלטפורמות אחרות כמו Windows, Android ו-ChromeOS אנחנו יכולים להשתמש בשכבות-על גם במקרים שלא מוצגים במסך מלא, וכך לחסוך עד 50% כמעט בכל מקום.

רינדור

אחרי שהסברנו את המנגנונים האופטימליים להעברה, נוכל לדבר על האופן שבו Chromium בוחר מה לספק. בסטאק ההפעלה של Chromium נעשה שימוש בארכיטקטורה מבוססת 'שליפה'. כלומר, כל רכיב במקבץ מבקש את הקלט שנמצא מתחתיו, לפי סדר היררכי. בחלק העליון של הערימה נמצא הרינדור של פריימים של אודיו ווידאו. החלק התחתון ביותר הוא פענוח, פענוח הקוד, לדמוקס ולבסוף העיבוד של קלט/פלט (I/O). כל פריים אודיו שעבר עיבוד מקדם שעון שמשמש לבחירת פריימים של וידאו לעיבוד, בשילוב עם מרווח זמן להצגה.

בכל מרווח זמן בין שיתוף המסך (בכל רענון של המסך), המערכת של רינדור הווידאו מתבקשת לספק פריים בסרטון באמצעות CompositorFrameSink שמוצמד ל-SurfaceLayer שהוזכר קודם. במקרה של תוכן עם קצב פריימים נמוך מקצב התצוגה, זה אומר שתוצג אותה פריים יותר מפעם אחת. לעומת זאת, אם קצב הפריימים גבוה מקצב התצוגה, חלק מהפריימים אף פעם לא יוצגו.

יש הרבה יותר אפשרויות לסנכרון של אודיו ווידאו באופן שמעניין את הצופים. תוכלו לקרוא את Project Butter לדיון ארוך יותר על תהליך ההחלקה האופטימלית של סרטונים ב-Chromium. במאמר הזה מוסבר איך אפשר לחלק את עיבוד הווידאו לרצפים אידיאליים שמייצגים את מספר הפעמים שכל פריים צריך להופיע. לדוגמה: "1 פריים בכל מרווח תצוגה ([1], 60 fps ב-60 Hz)", "פריים 1 כל 2 מרווחים ([2], 30 fps ב-60 Hz)", או דפוסים מורכבים יותר כמו &lbrack;2:3:2:3:2&rbrack; (25 fps במרווחי זמן נפרדים של 60 Hz) ככל שמעבד הווידאו נצמד לדפוס האידיאלי הזה, כך עולה הסבירות שהמשתמש יבחין בהפעלה חלקה.

הרצף של הדמוקס, הפענוח והעיבוד.

רוב הפלטפורמות של Chromium מעבדות פריים אחרי פריים, אבל לא כולן כן. הארכיטקטורה הניתנת להרחבה שלנו מאפשרת גם עיבוד ברצף. רינדור אצווה הוא שיטה של יעילות שבה הקומפוזיטור ברמת מערכת ההפעלה מקבל מידע על מספר פריימים מראש, ומטפל בשחרורם בהתאם ללוח זמנים שסופק על ידי האפליקציה.

העתיד הוא עכשיו?

התמקדנו באופן שבו Chromium מנצל את התכונות הבסיסיות של מערכת ההפעלה כדי לספק את חוויית ההפעלה הטובה ביותר בקטגוריה. אבל מה לגבי אתרים שלא מעוניינים יותר מהפעלה בסיסית של סרטונים? האם נוכל להציע להם את אותם עקרונות בסיסיים ש-Chromium משתמש בהם כדי שישמש את הדור הבא של תוכן האינטרנט?

אנו חושבים שהתשובה היא כן! הגמישות נמצאת בליבה של התפיסה שלנו על פלטפורמת האינטרנט בימים אלה. אנחנו עובדים בשיתוף עם דפדפנים ומפתחים אחרים כדי ליצור טכנולוגיות חדשות כמו WebGPU ו-WebCodecs כדי שמפתחי אתרים יוכלו להשתמש באותם פיצ'רים פרימיטיביים ש-Chromium משתמש בהם כשהם מדברים עם מערכת ההפעלה. WebGPU כולל תמיכה במאגרי GPU, ו-WebCodecs כוללים פרימיטיבים לפענוח ולקידוד של פלטפורמות שתואמות למערכות שכבת-העל ומערכות האחסון הזמני של GPU.

הקשר בין WebCodecs ל-WebGPU.

סוף השידור

תודה על שקראת מידע זה! אני מקווה שהצלחתם להבין טוב יותר את מערכות ההפעלה המודרניות ואת האופן שבו Chromium תומך במאות מיליון שעות צפייה בכל יום. אם אתם מחפשים מידע נוסף על רכיבי קודק וסרטוני אינטרנט מודרניים, מומלץ H.264 הוא קסם של סיד באלה, How Modern Video Players Work מאת אריקה ביבס, ותוכניות זוכות פרסים עם טכנולוגיה עטורת פרסים של סיריל קונקולטו.

איור אחד (היפהפה!) של אונה קראבטס.