簡體   English   中英

如何直接從Android Surface訪問EGL圖像以用於MediaCodec視頻解碼器?

[英]How to access EGL Image directly from Android Surface for use in MediaCodec video decoder?

我正在編寫一個Android應用程序,我需要緩存視頻幀,以便我可以輕松地來回轉移,幾乎沒有延遲。

現在我通過向MediaCodec對象的Configure調用提供Surface並調用releaseOutputBuffer並將render標志設置為true來讓android解碼視頻幀。

我發現訪問解碼表面數據的唯一方法(除了解碼返回的bytebuffer,其格式似乎與設備有關)是調用鏈接到Surface的SurfaceTexture上的updateTeximage ,將其附加到GL_TEXTURE_EXTERNAL_OES目標並將其渲染到GL_TEXTURE2D我自己創建的目標紋理是為了緩存它。

我想優化這個緩存過程,並能夠解碼不同線程上的幀。 使用我當前的方法,這意味着我將不得不為視頻解碼器創建另一個EGL上下文,共享上下文等...

我的問題是: 是否可以在不調用 updateTexImage 情況下訪問與Surface關聯的EGL圖像或本機緩沖區數據

這樣我就可以緩存egl圖像(根據EGL_ANDROID_image_native_buffer不需要EGL上下文)。 這也將以YUV格式緩存,這比我現在緩存的原始RGB紋理更具存儲效率。

簡答:不。

更長的答案: Surface封裝了一個緩沖區隊列 編輯: 此處詳細解釋了系統。)當您調用updateTexImage() ,如果有新的數據幀可用,則會丟棄頭部的緩沖區,隊列中的下一個緩沖區將變為當前狀態。 調用updateTexImage()是查看連續幀所必需的; 沒有機制可以檢查不在頭部的緩沖區。

一個SurfaceTexture包裝的實例GLConsumer 該消費者要求制作者(視頻解碼器)以可以用作“硬件紋理”的格式生成數據,即設備的GL實現可以理解的東西。 它可能是也可能不是YUV。 更重要的是,消費者不要求緩沖區可用於“軟件”,這意味着您不能假設您可以直接訪問數據 - 您需要使用GLES。 (有關標志的完整列表,請參閱gralloc標頭 。)

這里最好的是能夠將緩沖區從BufferQueue的頭部BufferQueue到單獨的數據結構( BufferArrayList ?)而無需進行格式轉換,但目前還沒有類似的機制(Android 4.3)。 我不知道比你描述的更好的方式(共享EGL上下文等)。

更新:我的辦公室伙伴提出了一個建議:使用着色器將緩沖區渲染為兩個紋理,一個用於Y和用於CbCr(在GLES 3中,您可以使用RG紋理)。 這保留了GLES中的所有操作,而不會擴展為完整的RGB。 在內部,它會將MediaCodec輸出轉換為RGB並通過它進行兩次研磨,但這可能比將其復制到用戶空間並在CPU上自行完成更便宜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM