前文已经实现显示一张图片,本文要做的是从文件中读取YUV数据(相当于一张一张的图片),以一定的帧率进行播放。
要播放YUV数据,需要将YUV转换成RGB格式,这有两个选择:
1.在CPU上进行转换,也就是从文件读取YUV数据后,直接按照公式在代码中进行转换,然后传给着色器,直接进行显示。
2.在GPU上进行转换,也就是从文件读取YUV数据后,把Y、U、V三个分量的数据分别传给着色器,在着色器内按照转换公式进行转换。
本文打算采用第二种方式,充分利用GPU,提高效率。
注:相关的转换公示有很多种,可以参考1.FFmpeg学习笔记 - YUV & RGB。本文用的网上搜寻的另一种公式。
程序输入的YUV文件格式是YUV420p格式,宽高848x480。
相关代码前文已提及,本文只提重要代码。
先说着色器,顶点着色器无变化,下面是片段着色器:
uniform sampler2D texture_y;
uniform sampler2D texture_u;
uniform sampler2D texture_v;
void main()
{
float y = texture2D(texture_y, varyTextCoord).r;
float u = texture2D(texture_u, varyTextCoord).r - 0.5;
float v = texture2D(texture_v, varyTextCoord).r - 0.5;
float r = y + 1.402 * v;
float g = y - 0.344 * u - 0.714 * v;
float b = y + 1.772 * u;
gl_FragColor = vec4(r, g, b, 1.0);
}
片段着色器定义了三个采样器(texture_y,texture_u,texture_v),分别用于采样Y、U、V三分量的数据,然后通过main函数里的转换公式,转成rgb格式。
OpenGL ES的Shader中会把内存中0~255的整数数值换算为0.0~1.0的