在前面的实战中,我们已经通过SurfaceView成功渲染视频了。虽然功能上我们是实现了视频的解码和渲染,但是这里有一个性能方面的问题:就是在解码渲染视频的时候CPU使用率会很高。
对于一个大型的应用,CPU这种稀缺资源本来就紧张,仅仅为了播放视频就耗费大把的CPU显然是不合理的,这样会导致一些重要的任务进入等待状态。
其实对于视频的播放,主要的性能损耗就是在解码和YUV转换为RGB这两个功能上。其中YUV转换为RGB更是耗费了大量的CPU使用率,可以说比解码损耗的大得多。
那么能不能不转换了,直接渲染YUV数据呢?只适合OpenGL就派上用场啦。
OpenGL对于笔者来说真是一个心结啊。一直都觉得OpenGL是一个高大上的东西,所以很想吃透它,但是奈何工作项目中一直没有用到OpenGL的相关知识,所以我对OpenGL的学习并不深入。
正所谓:
不以结婚为目的的恋爱都是耍流氓
不以实践为铺垫的学习都是自欺欺人啊,毕竟纸上得来终觉浅,不实践你很快就会忘掉了。
Let’s go…
OpenGL技术术语
1、 EGL
EGL 是渲染 API(如 OpenGL ES)和原生窗口系统之间的接口,EGL作为 OpenGL 和原生窗口系统之间的桥梁。
OpenGL作为一种跨平台的东西,那么OpenGL的底层如何与各个平台直接的窗口进行渲染数据的交换呢?答案就是EGL这个中间层。
EGL就像媒人一样,把帅气的小伙子和貌美的姑娘凑合在一起。
2、 着色器
着色器(Shader)是运行在GPU上的小程序。着色器又分为顶点着色器和片元着色器。
- 顶点着色器
顶点着色器负责的功能是把输入的数据进行各种计算,⽣成/变换纹理坐标,并且把位置和纹理坐标这样的参数发送到片段着色器。
通俗地讲顶点着色器就是计算每个像素点所在的位置坐标。
如图,左边主要是输入变量,右边是输出变量,也就是经过顶点着色器计算处理后的结果数据。
- 片元着色器
片元着色器可以了解为针对每个像素点都计算一次,用于确定每个像素点的颜色值。
和顶点着色器一样,左边也是输入变量,右边是经过着色器处理后的输出变量。
有了位置信息和色彩信息,我们的OpenGL就能渲染出图像了。
3、 GLSL
GLSL:着色器语言,是一门用在OpenGL中编写着色器的语言。
我去,为了学习OpenGL我还得再学习一门语言,我学不动了,我要放弃。
庆幸的是这是一门语法与C语言基本相同的简单语言,对于NDK开发者来说完全没有障碍啊。
因为GLSL是为图形计算量身定制的,所以GLSL提供了大量内置的函数来提供丰富的扩展功能,其次还完美支持矩阵和向量操作。
着色器的开头总是要声明版本,接着是输入和输出变量、uniform和main函数。每个着色器的入口点都是main函数,在这个函数中我们处理所有的输入变量,并将结果输出到输出变量中。
一个典型的着色器有下面的结构:
#version 版本号
// 注意如果是2.x的版本,in对应的是attribute
// out对应的是varying
in 类型 输入变量名;
in 类型 输入变量名;
out 类型 输出变量名;
uniform type uniform_name;
int main()
{
// 处理输入并进行一些图形操作
...
// 输出处理过的结果到输出变量
输出变量名 = 计算结果;
}
对于程序中出现的uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。
首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。
第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。
更多关于GLSL的语法知识点建议学者们网上自行学习,这里就不再多说了。
4、纹理(Texture)
在OpenGL中渲染图形时,有时为了使场景更加逼真,会使用图片编码后进行填充(可以理解成贴图,即每个像素都从图片中获取后进行填充,不再使用单纯的颜色填充)。这个图片在OpenGL中被称为纹理。
5、 坐标
主要包括OpenGL坐标、屏幕坐标以及纹理坐标(有些资料也叫材质坐标)。
- OpenGL坐标
OpenGL坐标是以中心点为坐标原点,X向右为正,Y向上为正。最大与最小值为1和-1,这是经过归一化处理的。这样设计是为了显卡计算方便。
- 屏幕坐标
相信移动开发者都知道屏幕坐标是以屏幕的左上角为坐标原点,X向右为正,Y向下为正的二维坐标系统。
- 纹理坐标
纹理坐标也是做了归一化处理,一般以图像的左下角为坐标原点,X向右为正,Y向上为正。
其中顶点着色器要做的其中一件事情就是将屏幕坐标转换成纹理坐标输出给片元着色器。
结束
本文只是简单地讲述了一下OpenGL的一些简单技术术语,并没有深入讲解OpenGL在Android中的使用。对于如何在Android中使用OpenGL,学者们可以参照谷歌官方的APIDemo中的例子学习,
当然网上也有比较全的系列资料,学者们可自行搜索学习。
OpenGL是一个比较庞大的东西,根据笔者的经验,如果你一开始就想全面弄懂几乎很难做到,因为我看它的很多概念都是云里雾里的感觉。笔者比较喜欢的方法是先粗略看一遍心里有个底,然后结合实践,看看在项目中都用到了那些知识点,然后再有针对地各个击破。
在后面的实战中我们将会结合ffmpeg和OpenGL并肩作战,一个解码霸王,一个渲染霸王,定会所向披靡啊。
最后如果你对音视频开发感兴趣可扫码关注,笔者在各个知识点学习完毕之后也会使用ffmepg从零开始编写一个多媒体播放器,包括本地播放及网络流播放等等。欢迎关注,后续我们共同探讨,共同进步。
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/19849.html