好的,这是我到目前为止的情况。我已经在Android上构建了FFmpeg,并且能够正常使用它。通过从Java端传递所选文件名,我已能将视频加载到FFmpeg中。为了节省性能,我正在使用NDK编写视频播放器,而不是通过JNI从FFmpeg传递帧到Java。我想将视频帧发送到OpenGL表面。我遇到了问题,无法弄清楚如何获取每一帧视频并将其呈现到OpenGL表面上。我已经困在这个问题上几周了,但没有成功。希望有人能指点我正确的方向。
谢谢!
好的,这是我到目前为止的情况。我已经在Android上构建了FFmpeg,并且能够正常使用它。通过从Java端传递所选文件名,我已能将视频加载到FFmpeg中。为了节省性能,我正在使用NDK编写视频播放器,而不是通过JNI从FFmpeg传递帧到Java。我想将视频帧发送到OpenGL表面。我遇到了问题,无法弄清楚如何获取每一帧视频并将其呈现到OpenGL表面上。我已经困在这个问题上几周了,但没有成功。希望有人能指点我正确的方向。
谢谢!
有一种方法可以实现,就是将帧的像素绘制到纹理中,然后使用OpenGL渲染该纹理。
我以前写过一篇博客,介绍如何实现这个方法,主要是为了旧式像素视频游戏,但对于你的情况也适用。这篇博客是Android Native Coding in C,我还在github上设置了一个示例的代码库。使用这种技术,我甚至能够在第一代硬件上获得60 FPS的速度。
编辑 关于glTexImage2D和glTexSubImage2D的选择。
调用glTexImage2D会为纹理分配视频内存,并将您传递给它的像素复制到该内存中(如果您没有传递NULL)。调用glTexSubImage2D将更新已分配纹理中您指定的像素。
如果你更新整个纹理,那么调用其中任何一个都没有太大区别,事实上glTexImage2D通常更快。但如果您只更新纹理的一部分,则glTexSubImage2D速度更快。
您必须使用2的幂次方纹理大小,因此在高分辨率设备上覆盖屏幕需要一个1024x512的纹理,在中等分辨率上需要一个512x512的纹理。纹理比屏幕区域大(高分辨率约为800x400),这意味着您只需要更新其中一部分,因此glTexSubImage2D是更好的选择。