מרקם פני השטח

SurfaceTexture הוא שילוב של משטח ומרקם OpenGL ES (GLES) . מופעי SurfaceTexture משמשים כדי לספק משטחים שיוצאים למרקמי GLES.

SurfaceTexture מכיל מופע של BufferQueue שעבורו אפליקציות הן הצרכן. ה- onFrameAvailable() callback מודיע לאפליקציות כאשר המפיק מעמיד בתור מאגר חדש. לאחר מכן, יישומים קוראים ל- updateTexImage() , אשר משחרר את המאגר שהוחזק קודם לכן, רוכש את המאגר החדש מהתור, ועושה קריאות EGL כדי להפוך את המאגר זמין ל-GLES כמרקם חיצוני.

מרקמי GLES חיצוניים

מרקמי GLES חיצוניים ( GL_TEXTURE_EXTERNAL_OES ) שונים ממרקמי GLES מסורתיים ( GL_TEXTURE_2D ) בדרכים הבאות:

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

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

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

חותמות זמן ותמורות

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

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

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

מקרה מבחן: לכידה מתמשכת של גרפיקה

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

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

זרימה זו כוללת שלושה תורי חיץ:

  • App - האפליקציה משתמשת במופע SurfaceTexture כדי לקבל פריימים מהמצלמה, וממירה אותם למרקם GLES חיצוני.
  • SurfaceFlinger - האפליקציה מכריזה על מופע SurfaceView כדי להציג את הפריימים.
  • MediaServer - הגדר מקודד MediaCodec עם משטח קלט ליצירת הווידאו.

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

פעילות לכידה רציפה של Grafika

איור 1. פעילות הלכידה המתמשכת של Grafika

וידאו מקודד H.264 עובר למאגר עגול ב-RAM בתהליך האפליקציה. כאשר משתמש לוחץ על לחצן הלכידה, מחלקת MediaMuxer כותבת את הסרטון המקודד לקובץ MP4 בדיסק.

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

בעת שימוש במחלקה SurfaceView , ה-callback surfaceCreated() יוצר את המופעים EGLContext ו- EGLSurface עבור התצוגה ומקודד הווידאו. כאשר מגיעה מסגרת חדשה, SurfaceTexture מבצעת ארבע פעילויות:
  1. רוכש את המסגרת.
  2. הופך את המסגרת לזמינה כמרקם GLES.
  3. מעבד את המסגרת עם פקודות GLES.
  4. מעביר את ההמרה וחותמת הזמן עבור כל מופע של EGLSurface .

לאחר מכן חוט המקודד מושך את הפלט המקודד מ- MediaCodec ומאחסן אותו בזיכרון.

השמעת וידאו במרקם מאובטח

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

השמעת וידאו בטקסטורה מאובטחת

איור 2. השמעת וידאו במרקם מאובטח

התמיכה מופעלת באמצעות שתי ההרחבות הבאות:

  • הרחבת EGL — ( EGL_EXT_protected_content ) מאפשרת יצירת הקשרים ומשטחים מוגנים של GL, שיכולים לפעול שניהם על תוכן מוגן.
  • תוסף GLES — ( GL_EXT_protected_textures ) מאפשר תיוג מרקמים כמוגנים כך שניתן להשתמש בהם כקבצים מצורפים של טקסטורת מסגרת מאיץ.

אנדרואיד מאפשר SurfaceTexture ו-ACodec ( libstagefright.so ) לשלוח תוכן מוגן גם אם משטח החלון אינו עומד בתור ל- SurfaceFlinger ומספק משטח וידאו מוגן לשימוש בהקשר מוגן. זה נעשה על ידי הגדרת ביט הצרכן המוגן ( GRALLOC_USAGE_PROTECTED ) על משטחים שנוצרו בהקשר מוגן (אומת על ידי ACodec).

השמעת וידאו בטקסטורה מאובטחת מציבה את הבסיס ליישום DRM חזק בסביבת OpenGL ES. ללא יישום DRM חזק, כגון Widevine Level 1, ספקי תוכן רבים אינם מאפשרים עיבוד של התוכן בעל הערך הגבוה שלהם בסביבת OpenGL ES, ומונעים מקרי שימוש חשובים ב-VR כגון צפייה בתוכן מוגן DRM ב-VR.

AOSP כולל קוד מסגרת להפעלת וידאו במרקם מאובטח. תמיכת מנהלי התקנים היא עד יצרני OEM. מיישמי מכשירים חייבים ליישם GL_EXT_protected_textures extensions EGL_EXT_protected_content ו-GL_EXT_protected_textures . כאשר אתה משתמש בספריית ה-codec שלך (כדי להחליף libstagefright ), שים לב לשינויים ב- /frameworks/av/media/libstagefright/SurfaceUtils.cpp av/media/libstagefright/SurfaceUtils.cpp המאפשרים שליחת מאגרים המסומנים ב- GRALLOC_USAGE_PROTECTED אל ANativeWindow (גם אם ANativeWindow לא עומד בתור ישירות ל- יוצר חלון) כל עוד סיביות השימוש לצרכן מכילות GRALLOC_USAGE_PROTECTED . לתיעוד מפורט על הטמעת ההרחבות, עיין ברישום של Khronos ( EGL_EXT_protected_content ו- GL_EXT_protected_textures ).