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

28

好的,这是我到目前为止的情况。我已经在Android上构建了FFmpeg,并且能够正常使用它。通过从Java端传递所选文件名,我已能将视频加载到FFmpeg中。为了节省性能,我正在使用NDK编写视频播放器,而不是通过JNI从FFmpeg传递帧到Java。我想将视频帧发送到OpenGL表面。我遇到了问题,无法弄清楚如何获取每一帧视频并将其呈现到OpenGL表面上。我已经困在这个问题上几周了,但没有成功。希望有人能指点我正确的方向。

谢谢!


嗨Kieran,我正在尝试使用FFmpeg和Android NDK转换格式并播放音频或视频。 我在网上找不到任何资源或指导。 经过长时间的搜索,我找到了这个链接https://github.com/havlenapetr/FFMpeg。 但是我无法编译和运行此示例。 请帮助我或给我参考链接--如何在Android中使用FFmpeg文件播放音频/视频....谢谢 - praveenb
Praveenb, 我在Android上编译和使用FFmpeg遇到了一些困难。我不得不稍微调整configure脚本。我也没有使用最新版本的FFmpeg。我下载了一个稍旧的版本,仍然使用sws_scale函数来使其工作。我可以尽力帮助你让它工作,只要告诉我你现在的进展情况以及你遇到的错误类型。获取静态库进行构建应该不难。 - DRiFTy
嗨,我正在努力为Android构建FFmpeg。你能告诉我你是如何构建Android的静态库的吗?有没有类似的git仓库之类的东西可以让我开始使用?那个configure脚本怎么样 - 需要设置什么? - j00hi
1个回答

21

有一种方法可以实现,就是将帧的像素绘制到纹理中,然后使用OpenGL渲染该纹理。

我以前写过一篇博客,介绍如何实现这个方法,主要是为了旧式像素视频游戏,但对于你的情况也适用。这篇博客是Android Native Coding in C,我还在github上设置了一个示例的代码库。使用这种技术,我甚至能够在第一代硬件上获得60 FPS的速度。

编辑 关于glTexImage2D和glTexSubImage2D的选择。

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

如果你更新整个纹理,那么调用其中任何一个都没有太大区别,事实上glTexImage2D通常更快。但如果您只更新纹理的一部分,则glTexSubImage2D速度更快。

您必须使用2的幂次方纹理大小,因此在高分辨率设备上覆盖屏幕需要一个1024x512的纹理,在中等分辨率上需要一个512x512的纹理。纹理比屏幕区域大(高分辨率约为800x400),这意味着您只需要更新其中一部分,因此glTexSubImage2D是更好的选择。


4
我最终使用FFmpeg和OpenGL ES成功地在屏幕上显示了视频帧... 如果有人对我是如何使其工作感兴趣,请告诉我,我会尽力帮助。最终问题在于使用正确的像素格式转换从FFmpeg中获取视频,并将其映射到OpenGL中的正确像素格式以及使用正确的纹理坐标。但其中一件事情是手机上的.3gp解码比如.mp4解码非常慢。我的原始Droid只能达到大约11fps的效果。但是Droid X可以达到约22fps... 我仍在努力改善它。 - DRiFTy
@slhck 当然,我可以提供一些示例。只要告诉我你需要帮助的内容,我会尽力帮忙。一旦你弄清楚了,所有的东西都非常简单明了,只是一开始让它们都正常工作有点困难。 - DRiFTy
@Kieran 那太棒了。我下周左右开始实施,也许我们可以私下交流一下? - slhck
嗨,DiscGolfer,你能否提供一些使用FFMPEG在OPENGLES上渲染视频帧的示例源代码吗? - Vipul Narkhede
听起来有些奇怪,glTexImage 比 glTexSubImage 更快。 - Viktor Sehr
显示剩余12条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接