如何将Android MediaCodec Surface连接到Vulkan

时间:2017-04-19 23:08:59

标签: android mediacodec vulkan

我非常了解使用Android MediaCodec解码并通过Surface将YUV提供给OpenGL纹理。我想和Vulkan做类似的事情。但是,我没有成功找到任何文档或示例代码。

我的问题是:我如何连接以下管道?

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

详情

OpenGL比较

为了进行比较,在OpenGL案例中,Android Surface的构造和使用方式如此

=SUMPRODUCT((B$3:B9-1/16)*(B$3:B9>1/16))

2 个答案:

答案 0 :(得分:2)

仅供参考:我不太了解Android。

创建Vulkan"纹理"已完成vkCreateImage。与您的OpenGL ES示例不同,还有一些额外的工作可以明确地管理内存(使用vkAllocateMemoryvkBindImageMemory)。

下一步将是艰难的一步。对于Vulkan来说,显然没有SurfaceTexture

最近发布了Vulkan方面的高效工作。 即VK_KHX_external_memory以及Vulkan的相关扩展。所以希望Vulkan的官方Android SurfaceTexture也来了。

话虽这么说,你可以自己实现一个新的SurfaceTexture。或者至少" import" Vulkan Image进入OpenGL ES。这个问题是:

  • 扩展名被视为实验性更新:不再是
  • 驱动程序可能不支持扩展(尚未)
  • 编程可能不是一件容易的事,也可能需要在Android上搞乱一些低级别的linux API。

所以,现在最好的方法是创建一些复制数据的垫片 我会:

1)似乎MediaCodec能够使用ByteBuffer代替SurfaceByteBuffer可以换行原始bytes[]

2)克里特岛VkImagesVkBuffer。设备内存上的图像(我们想要的结果对象)。和主机端的缓冲区(以方便复制)。

3)映射(vkMapMemory),并使用ByteBuffer使用的MediaCodec包装主机端缓冲区。

4)每次有新数据复制,并在Vulkan中提交vkCmdCopyBufferToImage

我省略了很多样板(尤其是同步),但希望你能得到这个想法。

答案 1 :(得分:2)

目前无法实现这一点,因为无法从Vulkan外部导入内存对象,也无法导出可导出Surface的任何SDK Vulkan对象。请查看VK_KHX_external_memory及其相关扩展,了解其中部分内容将来如何发挥作用。

编辑2018-05-23:现在可以使用VK_ANDROID_external_memory_android_hardware_buffer扩展程序及其所依赖的扩展程序。您可以使用AImageReader_newWithUsage创建与GPU采样兼容的AImageReader。从AImageReader获取ANativeWindow并将其用作AMediaCodec的输出表面。然后,对于您收到的每个图像,获取AHardwareBuffer并使用扩展名将其导入VkDeviceMemory / VkImage对。