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

发布于 2024-10-11 21:55:40 字数 255 浏览 1 评论 0原文

好的,这就是我到目前为止所拥有的。我已经在 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.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

溺ぐ爱和你が 2024-10-18 21:55:40

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

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

关于这种方法的 glTexImage2D 与 glTexSubImage2D 的编辑

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

如果更新全部纹理,那么调用其中一个或另一个几乎没有什么区别,事实上 glTexImage2D 通常更快。但如果您只更新纹理的一部分,glTexSubImage2D 会在速度上胜出。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文