Android视频播放器使用NDK,OpenGL ES和FFmpeg [英] Android Video Player Using NDK, OpenGL ES, and FFmpeg

查看:526
本文介绍了Android视频播放器使用NDK,OpenGL ES和FFmpeg的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



谢谢!

解决方案

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.

这篇关于Android视频播放器使用NDK,OpenGL ES和FFmpeg的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆