且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-09-22 13:44:05

p>一种让人想到的方法是将框架的像素绘制成纹理,然后使用OpenGL渲染纹理。



我写了一篇博客文章关于如何去做,主要是为了基于老式的基于像素的视频游戏,但它也适用于你的情况。该帖子是 Android本机编码C,并且我设置了一个 github仓库,并附了一个例子。关于glTexImage2D vs glTexSubImage2D,使用这种技术,即使是第一代硬件,也可以得到60 FPS。



编辑 / p>

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



如果您更新纹理的所有,那么调用一个或者其他的,其实glTexImage2D通常比较快。但是,如果您只更新部分纹理glTexSubImage2D的速度赢了。



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


Ok so here is what I have so far. I have built FFmpeg on android and am able to use it fine. I have been able to load a video into FFmpeg after passing the chosen filename from the java side. To save on performance I am writing video player in the NDK rather than passing frames from FFmpeg to java through JNI. I want to send frames from the video to an OpenGL surface. I am having trouble figuring out how to get each frame of video and render it onto the OpenGL surface. I have been stuck trying to figure this out for a couple weeks now with no luck. Hopefully someone can point me in the right direction.

Thanks!

One way that springs to mind is to draw the pixels of your frame into a texture and then render that texture using OpenGL.

I wrote a blog post a while back on how to go about this, primarily for old-skool pixel-based video games, but it also applies for your situation. The post is Android Native Coding in C, and I set up a github repository with an example. Using this technique I have been able to get 60 FPS, even on first generation hardware.

EDIT regarding glTexImage2D vs glTexSubImage2D for this approach.

Calling glTexImage2D will allocate video memory for your texture and copy the pixels you pass it into that memory (if you don't pass NULL). Calling glTexSubImage2D will update the pixels you specify in an already-allocated texture.

If you update all of the texture then there's little difference calling one or the other, in fact glTexImage2D is usually faster. But if you only update part of the texture glTexSubImage2D wins out on speed.

You have to use power-of-2 texture sizes, so in covering the screen on hi-res devices requires a 1024x512 texture, and a 512x512 texture on medium resolutions. The texture is larger than the screen area (hi-res is 800x400-ish), which means you only need to update part of it, so glTexSubImage2D is the way to go.