Google致力於提高黑人社區的種族平等。 怎麼看。
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

表面紋理

SurfaceTexture是曲面和OpenGL ES(GLES)紋理的組合。 SurfaceTextures用於提供輸出為GLES紋理的表面。

SurfaceTexture包含一個BufferQueue,其應用程序是使用方。當生產者將新緩衝區排隊時, onFrameAvailable()回調通知應用程序。然後,應用程序調用updateTexImage() ,釋放先前保留的緩衝區,從隊列中獲取新緩衝區,並進行EGL調用以使該緩衝區可作為外部紋理供GLES使用。

外部GLES紋理

外部GLES紋理( GL_TEXTURE_EXTERNAL_OES )從傳統的GLES紋理(不同GL_TEXTURE_2D通過以下方式):

  • 外部紋理直接根據從BufferQueue接收的數據來渲染帶紋理的多邊形。
  • 外部紋理渲染器的配置與傳統的GLES紋理渲染器不同。
  • 外部紋理不能執行所有傳統的GLES紋理活動。

外部紋理的主要優點是它們可以直接從BufferQueue數據進行渲染的能力。表面紋理設置消費者使用的標誌,以GRALLOC_USAGE_HW_TEXTURE時,它創造了外部紋理BufferQueues確保在緩衝區中的數據是通過識別GLES。

因為SurfaceTexture與EGL上下文進行交互,所以只有擁有紋理的EGL上下文在調用線程上處於最新狀態時,應用程序才能調用其方法。有關更多信息,請參見SurfaceTexture類文檔。

時間戳和轉換

SurfaceTexture包括用於獲取時間戳的getTimeStamp()方法和用於獲取轉換矩陣的getTransformMatrix()方法。調用updateTexImage()設置時間戳和轉換矩陣。 BufferQueue傳遞的每個緩衝區都包含轉換參數和時間戳。

轉換參數對於提高效率很有用。在某些情況下,源數據的使用方向可能不正確。與其在將數據發送給使用者之前旋轉數據,不如通過校正數據的方向發送數據。使用數據時,可以將轉換矩陣與其他轉換合併,以最大程度地減少開銷。

時間戳對於與時間有關的緩衝區源很有用。例如,當setPreviewTexture()將生產者接口連接到攝像機的輸出時,攝像機的幀可用於創建視頻。每個幀都需要具有從捕獲幀時開始的演示時間戳記,而不是從應用收到幀時開始。攝像機代碼設置了緩衝區隨附的時間戳,從而產生了更為一致的一系列時間戳。

案例研究:Grafika的不斷捕獲

Grafika的連續捕獲包括從設備的攝像機記錄幀並將這些幀顯示在屏幕上。要記錄幀,請使用MediaCodec類的createInputSurface()方法創建一個表面,並將該表面傳遞給相機。要顯示框架,請創建一個SurfaceView並將曲面傳遞給setPreviewDisplay() 。但是,記錄幀並同時顯示它們是一個更複雜的過程。

連續拍攝活動會在錄製視頻時顯示來自攝像機的視頻。在這種情況下,編碼的視頻將被寫入內存中的循環緩衝區,該緩衝區可隨時保存到磁盤。

此流程涉及三個BufferQueues:

  • App —應用程序使用SurfaceTexture從相機接收幀,並將其轉換為外部GLES紋理。
  • SurfaceFlinger —應用程序聲明一個SurfaceView以顯示框架。
  • MediaServer —使用輸入界面配置MediaCodec編碼器以創建視頻。
格拉菲卡連續捕捉活動

在下圖中,箭頭指示從攝像機傳播的數據。 BufferQueues是彩色的(生產者是藍綠色,消費者是綠色)。

圖1. Grafika的連續捕獲活動。

編碼的H.264視頻在應用過程中進入RAM中的循環緩衝區。當用戶按下捕獲按鈕時, MediaMuxer類將編碼的視頻寫入磁盤上的MP4文件。

所有BufferQueues在應用程序中使用單個EGL上下文處理,而GLES操作在UI線程上執行。編碼數據的處理(管理循環緩衝區並將其寫入磁盤)是在單獨的線程上完成的。

SurfaceView的surfaceCreated()回調為顯示和視頻編碼器創建EGLContext和EGLSurfaces。當新框架到達時,SurfaceTexture將執行四個活動:

  1. 獲取框架。
  2. 使框架可作為GLES紋理使用。
  3. 使用GLES命令渲染框架。
  4. 轉發每個EGLSurface的轉換和時間戳。

然後,編碼器線程從MediaCodec中提取編碼後的輸出,並將其存儲在內存中。

安全紋理視頻播放

Android支持受保護的視頻內容的GPU後處理。這使應用程序可以使用GPU來處理複雜的非線性視頻效果(例如扭曲),將受保護的視頻內容映射到紋理上以用於常規圖形場景(例如,使用GLES)和虛擬現實(VR)。

安全紋理視頻播放

圖2.安全紋理視頻播放

使用以下兩個擴展來啟用支持:

  • EGL擴展 —( EGL_EXT_protected_content )啟用受保護的GL上下文和表面的創建,它們都可以對受保護的內容進行操作。
  • GLES擴展名 —( GL_EXT_protected_textures )使標籤紋理受保護,因此可以將它們用作幀緩衝區紋理附件。

Android使SurfaceTexture和ACodec( libstagefright.so )可以發送受保護的內容,即使窗口的表面沒有排隊到SurfaceFlinger並提供受保護的視頻表面也可以在受保護的上下文中使用。這是通過在受保護的上下文(由ACodec驗證)中創建的表面上設置受保護的使用者位( GRALLOC_USAGE_PROTECTED )來完成的。

安全的紋理視頻回放為在OpenGL ES環境中實現強大的DRM實現奠定了基礎。如果沒有強大的DRM實現(例如Widevine Level 1),許多內容提供商將不允許在OpenGL ES環境中呈現其高價值內容,從而阻止了重要的VR用例,例如在VR中觀看受DRM保護的內容。

AOSP包括用於安全紋理視頻回放的框架代碼。驅動程序支持取決於OEM。設備實現者必須實現EGL_EXT_protected_contentGL_EXT_protected_textures extensions 。使用自己的編解碼器庫(替換libstagefright )時,請注意/frameworks/av/media/libstagefright/SurfaceUtils.cpp中的更改,該更改允許將標有GRALLOC_USAGE_PROTECTED緩衝區發送到ANativeWindows(即使ANativeWindow不會直接排隊到窗口GRALLOC_USAGE_PROTECTED ),只要使用者使用位包含GRALLOC_USAGE_PROTECTED 。有關實現擴展的詳細文檔,請參閱Khronos註冊中心( EGL_EXT_protected_contentGL_EXT_protected_textures )。