2017-04-19 128 views
3

我對使用Android MediaCodec進行解碼並將YUV通過Surface輸入OpenGL紋理有了很好的理解。我想和Vulkan做類似的事情。但是我沒有找到任何文檔或示例代碼。如何將Android MediaCodec Surface連接到Vulkan

我的問題是:我將如何連接以下管道?

MediaCodec Video Decoder ⇨ Surface ⇨ texture ⇨ Vulkan 

詳細

的OpenGL比較

0123配置

爲了進行比較,在OpenGL的情況下,Android的表面構造和像這樣

textureId = glGenTextures(&textureId) 
surface = new Surface(new SurfaceTexture(textureId)) 
mediaCodec.configure(surface) 

回答

2

僅供參考使用:我不知道Android的很好。

創建Vulkan「紋理」用vkCreateImage完成。與您的OpenGL ES示例不同,顯式管理內存有一些額外的工作(使用vkAllocateMemoryvkBindImageMemory)。

下一步將是艱難的。 Vulkan(尚未)顯然沒有SurfaceTexture

從Vulkan方面有效的工作最近發佈了。 也就是說VK_KHX_external_memory和Vulkan的相關擴展。所以希望Vulkan的官方Android SurfaceTexture也可以使用。

這就是說,你可以自己實現一個新的SurfaceTexture。或者至少將Vulkan圖像「導入」OpenGL ES。這樣做的問題是:

  • 的擴展名被認爲是實驗 UPDATE:不再
  • 驅動程序可能不支持擴展反正(還)
  • 它可能是不平凡的程序,也可能需要在Android上使用一些低級別的Linux API。

因此,現在最好的辦法是創建一些墊片,它複製數據。
我想:

1)看來MediaCodec能夠與ByteBuffer而不是Surface工作。而ByteBuffer可以包裝生bytes[]

2)克里特島01​​和VkBuffer。設備內存上的圖像(我們想要的結果對象)。和主機端的緩衝區(以方便複製)。

3)映射(vkMapMemory),並用MediaCodec使用的ByteBuffer包裝主機端緩衝區。

4)每當有新數據複製時,在Vulkan提交vkCmdCopyBufferToImage

我喜歡很多樣板(特別是同步),但希望你能明白。

+0

感謝您的回答。你真的希望比用於大視頻的GL更快嗎?在我看來,額外的副本將壓倒你從使用Vulkan而不是GL獲得的開銷減少。 – griffin2000

+0

@ griffin2000如果這就是您所說的「大視頻」,我不希望普通視頻在Vulkan播放時獲得原始性能提升。 – krOoze

+0

但它會顯着更慢?我的懷疑是做這裏描述的會比GL的速度慢。因此,通過複製所有視頻幀(除非你有非常低的視頻分辨率,或大量的3D繪製調用),在應用程序的其他部分進行更快的3D調用的開銷將會被完全抵消。這看起來是否正確? – griffin2000

2

這是目前不可能的,因爲沒有辦法從Vulkan外部或任何可以導出Surface的SDK Vulkan對象導入內存對象。看看VK_KHX_external_memory以及相關擴展,以瞭解將來如何工作。