【问题标题】:Hardware accelerated H.264/HEVC video decode on Android to OpenGL FBO or textureAndroid 上的硬件加速 H.264/HEVC 视频解码到 OpenGL FBO 或纹理
【发布时间】:2018-10-05 11:45:24
【问题描述】:

我想对视频流进行解码,并将解码后的帧写入 FBO opengl 纹理或其他内存表示,OpenGL 可以轻松地使用这些表示来对其应用额外的过滤器或转换(通过着色器)。

使用 MediaCodec 是当前 Android 中的加速标准吗?我可以使用生成的表面作为 OpenGL 的输入吗?

由于在桌面开发中执行此操作,我知道许多方法可能会不必要地减慢此过程(例如,使用 CPU 而不是专用芯片或 GPU 进行解码、在 GPU 中解码并将结果转储到系统内存然后复制再次到 VRAM 等)。我不确定这些问题在 Android 上是否重要。例如,在java可用内存和opengl可用内存之间进行复制的成本是否也很高,或者可以忽略不计?

【问题讨论】:

标签: android opengl-es video-streaming video-processing android-mediacodec


【解决方案1】:

一般而言,对于 OpenGL ES,您可以直接导入 YUV 视频表面,如果将表面作为外部 EGL 图像导入,则可以在本地访问它们(请参阅此处的扩展名 https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt)。

图形驱动程序将在正确的颜色空间中处理从 YUV 到 RGB 的颜色转换(假设解码器无论如何都会报告正确的颜色空间......),这都是零拷贝,所以绝对是正确的方法等等如果你想使用 OpenGL ES,比滚动你自己的颜色转换着色器更有效。

在 Android 上,Java 领域中的这个外部表面导入功能是通过 SurfaceTexture 类 (https://developer.android.com/reference/android/graphics/SurfaceTexture) 提供的。

【讨论】:

  • 太棒了!从你和 E. Abdel 的回答中总结,我可以配置一个 MediaCodec 解码器,其输出表面是从 SurfaceTexture (内部使用 OES_EGL_image_external 扩展)创建的。这是零拷贝,驱动程序甚至为我处理颜色转换。只要我记得在我的着色器中声明扩展,任何后处理都应该可以正常工作。
【解决方案2】:

是的,you can configure 具有输出表面的 MediaCodec 解码器并使用 GLSurfaceView 通过着色器应用更改,这是最好的方法,因为您只使用必要的内存,尤其是颜色转换(您无法提前知道什么为您的解码器使用着色),并用于 YUV2RGB 转换。

如果你想用原生的,你可以看看herehere

【讨论】:

    【解决方案3】:

    您必须使用 MediaCodec 来访问硬件解码器(这将通过 libstagefright 和 OpenMAX 完成 - 在引擎盖下)。

    • 如果要进行任何处理,则需要获取解码图像 (通常是 YUV420p 类型)并进行 YUV2RGB 和任何其他所需的处理,在将纹理传递给消费者之前,所有这些都可以作为 OGL 纹理/GLSL 等完成。但是,这意味着您必须进行所有音频和视频同步等操作。如果不需要,请避免。

    • 如果您想确保它是版权和 DRM 内容,则必须 使用Surface和DRM接口,不能做任何处理。

    • 如果你只是想做直接显示,那么可以使用 Surface,它可以 也做 YUV2RGB 或只使用 ExoPlayer。

    我不知道你是否可以将 Surface 的纹理读入任何 OGL 纹理。我已经实现了上面的第一个选项。

    【讨论】:

      猜你喜欢
      • 2012-05-25
      • 2012-12-01
      • 2014-07-24
      • 2016-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      • 2012-02-16
      相关资源
      最近更新 更多