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

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

问题描述

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

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.

谢谢!

推荐答案

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

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

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

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.

编辑关于此方法的 glTexImage2D 与 glTexSubImage2D.

EDIT regarding glTexImage2D vs glTexSubImage2D for this approach.

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

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.

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

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.

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

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.

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

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