目录
一、Android音视频硬解码篇:
二、使用OpenGL渲染视频画面篇
- 1,初步了解OpenGL ES
- 2,使用OpenGL渲染视频画面
- 3,OpenGL渲染多视频,实现画中画
- 4,深入了解OpenGL之EGL
- 5,OpenGL FBO数据缓冲区
- 6,Android音视频硬编码:生成一个MP4
三、Android FFmpeg音视频解码篇
- 1,FFmpeg so库编译
- 2,Android 引入FFmpeg
- 3,Android FFmpeg视频解码播放
- 4,Android FFmpeg+OpenSL ES音频解码播放
- 5,Android FFmpeg+OpenGL ES播放视频
- 6,Android FFmpeg简单合成MP4:视屏解封与重新封装
- 7,Android FFmpeg视频编码
本文你可以了解到
如何在 NDK 层调用 OpenGL ES ,以及使用 OpenGL ES 来渲染 FFmpeg 解码出来的视频数据。
一、渲染流程介绍
在 Java 层,Android 已经为我们提供了 GLSurfaceView 用于 OpenGL ES 的渲染,我们不必关心 OpenGL ES 中关于 EGL 部分的内容,也无需关注 OpenGL ES 的渲染流程。
在 NDK 层,就没有那么幸运了,Android 没有为我们提供封装好 OpenGL ES 工具,所以想要使用 OpenGL ES ,一切就只有从头做起了。
但是也不必担心,关于 EGL 的使用,在前面文章【深入了解OpenGL之EGL】中专门做了详细的介绍,在 NDK 层,也是一样的,不过是使用 C/C++ 实现一遍而已。
下图,是本文整个解码和渲染的流程图。

渲染流程
在【Android FFmpeg视频解码播放】中,我们建立了 FFMpeg 解码线程,并且将解码数据输出到本地窗口进行渲染,只用到了一个线程。
而使用 OpenGL ES 来渲染视频,则需要建立另外一个独立线程与 OpenGL ES 进行绑定。
因此,这里涉及到两个线程之间的数据同步问题,这里,我们将 FFmpeg 解码出来的数据送到 绘制器 中,等待 OpenGL ES 线程的调用。
特别说明一下
这里,OpenGL 线程渲染的过程中,不是直接调用绘制器去渲染,而是通过一个代理来间接调用,这样 OpenGL 线程就不需要关心有多少个绘制器需要调用,统统交给代理去管理就好了。
二、创建 OpenGL ES 渲染线程
与 Java 层一样,先对 EGL 相关的内容进行封装。
EGLCore 封装 EGL 底层操作,如
init初始化eglCreateWindowSurface/eglCreatePbufferSurface创建渲染表面MakeCurrent绑定 OpenGL 线程SwapBuffers交换数据缓冲- ......
EGLSurface 对 EGLCore 进一步封装,主要是对 EGLCore 创建的 EGLSurface 进行管理,并对外提供更加简洁的调用方法。
EGL原理请阅读《深入了解OpenGL之EGL》一文,这里将不再具体介绍。
封装 EGLCore
头文件 elg_core.h
// egl_core.h
extern "C" {
#include <EGL/egl.h>
#include <EGL/eglext.h>
};
class EglCore {
private:
const char *TAG = "EglCore";
// EGL显示窗口
EGLDisplay m_egl_dsp = EGL_NO_DISPLAY;
// EGL上线问
EGLContext m_egl_cxt = EGL_NO_CONTEXT;
// EGL配置
EGLConfig m_egl_cfg;
EGLConfig GetEGLConfig();
public:
EglCore();
~EglCore();
bool Init(EGLContext share_ctx);
// 根据本地窗口创建显示表面
EGLSurface CreateWindSurface(ANativeWindow *window);
EGLSurface CreateOffScreenSurface(int width, int height);
// 将OpenGL上下文和线程进行绑定
void MakeCurrent(EGLSurface egl_surface);
// 将缓存数据交换到前台进行显示
void SwapBuffers(EGLSurface egl_surface);
// 释放显示
void DestroySurface(EGLSurface elg_surface);
// 释放ELG
void Release();
};
具体实现 egl_core.cpp
// egl_core.cpp
bool EglCore::Init(EGLContext share_ctx) {
if (m_egl_dsp != EGL_NO_DISPLAY) {
LOGE(TAG, "EGL already set up")
return true;
}

本文详细介绍了如何在Android中结合FFmpeg和OpenGL ES播放视频,包括渲染流程、创建OpenGL ES渲染线程和绘制器。通过NDK层调用OpenGL ES,使用OpenGL ES渲染FFmpeg解码的视频数据,解决线程间数据同步问题,并提供了具体的代码实现和流程图。
最低0.47元/天 解锁文章
520

被折叠的 条评论
为什么被折叠?



