使用 NDK、OpenGL ES 和 FFmpeg 的 Android 视频播放器

Android Video Player Using NDK, OpenGL ES, and FFmpeg

好的,这就是我目前所拥有的。我已经在 android 上构建了 FFmpeg,并且能够很好地使用它。从 java 端传递选择的文件名后,我已经能够将视频加载到 FFmpeg 中。为了节省性能,我在 NDK 中编写视频播放器,而不是通过 JNI 将帧从 FFmpeg 传递到 java。我想将视频中的帧发送到 OpenGL 表面。我无法弄清楚如何获取每一帧视频并将其渲染到 OpenGL 表面上。几个星期以来,我一直在试图解决这个问题,但没有运气。希望有人能指出我正确的方向。

谢谢!


想到的一种方法是将帧的像素绘制到纹理中,然后使用 OpenGL 渲染该纹理。

不久前我写了一篇关于如何解决此问题的博文,主要针对基于像素的老式视频游戏,但它也适用于您的情况。帖子是 C 中的 Android Native Coding,我用一个例子建立了一个 github 存储库。使用这种技术,我已经能够获得 60 FPS,即使在第一代硬件上也是如此。

针对此方法编辑 glTexImage2D 与 glTexSubImage2D。

调用 glTexImage2D 将为您的纹理分配视频内存并将您传递给它的像素复制到该内存中(如果您不传递 NULL)。调用 glTexSubImage2D 将更新您在已分配纹理中指定的像素。

如果您更新所有纹理,那么调用其中一个或另一个几乎没有区别,实际上 glTexImage2D 通常更快。但是如果你只更新纹理的一部分,glTexSubImage2D 会在速度上胜出。

您必须使用 2 的幂次方纹理尺寸,因此在高分辨率设备上覆盖屏幕需要 1024x512 纹理,在中等分辨率下需要 512x512 纹理。纹理大于屏幕区域(高分辨率为 800x400-ish),这意味着您只需要更新它的一部分,因此 glTexSubImage2D 是要走的路。