【问题标题】:How to connect Android MediaCodec Surface to Vulkan如何将 Android MediaCodec Surface 连接到 Vulkan
【发布时间】:2017-09-16 09:07:21
【问题描述】:

我对使用 Android MediaCodec 进行解码以及通过 Surface 将 YUV 输入 OpenGL 纹理有很好的理解。我想对 Vulkan 做类似的事情。但是我没有成功找到任何文档或示例代码。

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

MediaCodec Video Decoder ⇨ Surface ⇨ texture ⇨ Vulkan

详情

OpenGL 比较

为了比较,在 OpenGL 情况下,Android Surface 的构造和使用方式如下

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

【问题讨论】:

    标签: android android-mediacodec vulkan


    【解决方案1】:

    目前这是不可能的,因为无法从 Vulkan 外部导入内存对象,或者任何可以导出 Surface 的 SDK Vulkan 对象。查看VK_KHX_external_memory 和相关扩展,了解其中的某些部分在未来可能如何工作。

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

    【讨论】:

      【解决方案2】:

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

      使用vkCreateImage 创建 Vulkan“纹理”。与您的 OpenGL ES 示例不同,显式管理内存需要一些额外的工作(使用 vkAllocateMemoryvkBindImageMemory)。

      下一步将是艰难的一步。 Vulkan 显然还没有SurfaceTexture

      从 Vulkan 方面提高效率的工作最近才发布。 IE。 VK_KHX_external_memory 和 Vulkan 的相关扩展。所以希望 Vulkan 的官方 Android SurfaceTexture 也即将推出。

      话虽如此,您可以自己实现一个新的SurfaceTexture。或者至少将 Vulkan 图像“导入”到 OpenGL ES 中。这样做的问题是:

      • 这些扩展被认为是实验性的更新:不再是
      • 驱动程序可能不支持扩展(目前)
      • 编程可能并非易事,还可能需要在 Android 上使用一些低级 linux API。

      因此,目前最好的方法是创建一些 shim 来复制数据。
      我会:

      1. 似乎MediaCodec 能够使用ByteBuffer 而不是Surface。而ByteBuffer 可以包装原始的bytes[]

      2. 创建VkImagesVkBuffer。设备内存上的图像(我们想要的结果对象)。以及Host端的Buffer(方便复制)。

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

      4. 每次有新数据时,通过在 Vulkan 中提交 vkCmdCopyBufferToImage 进行复制。

      我省略了很多样板文件(尤其是同步),但希望你能明白。

      【讨论】:

      • 感谢您的回答。你真的会期望它比使用 GL 处理大型视频更快吗?在我看来,额外的副本将压倒您使用 Vulkan 而不是 GL 所减少的任何开销。
      • @griffin2000 如果这就是您所说的“大视频”,我不希望 Vulkan 中普通视频播放的原始性能提升。
      • 但它会明显变慢吗?我的怀疑是做这里描述的事情会比 GL 等价物慢。因此,在应用程序的其余部分中进行更快的 3D 调用所带来的开销可以通过复制所有视频帧来完全抵消(除非你有一个非常低分辨率的视频,或者很多 3D 绘图调用)。这看起来对吗?
      • @griffin2000 我没有信心回答这个问题。可能取决于复制的设备、大小和频率,以及“应用程序其余部分中的 3D 调用”是什么。但是...,现代 RAM 可以快速推送大量数据。不过,我提供上述方法只是作为一种绝望或懒惰的解决方法。
      • 我需要以 30 fps 的速度处理 4K 视频。由于复制,这种“垫片”解决方案太慢了;结果不到 10fps。
      猜你喜欢
      • 2013-10-15
      • 1970-01-01
      • 2015-12-03
      • 2014-01-24
      • 2017-08-03
      • 1970-01-01
      • 2020-09-08
      • 2013-02-19
      • 2018-05-14
      相关资源
      最近更新 更多