目录
一、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();
};
具体实现