硬件加速Android上的H.264 / HEVC视频解码到OpenGL FBO或纹理

时间:2018-04-25 05:46:01

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

我想解码视频流并将解码后的帧写入FBO opengl纹理或其他内存表示形式,OpenGL可以轻松地将其用于应用其他过滤器或转换(通过着色器)。

在当前的Android中使用MediaCodec加速标准吗?我可以使用结果曲面作为OpenGL的输入吗?

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

3 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

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

如果您想在原生

中进行,可以查看herehere

答案 2 :(得分:-1)

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

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

  • 如果您想确保它是版权和DRM内容,那么必须 使用Surface和DRM接口,无法进行任何处理。

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

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