首先提出一个公式,yuv转换为rgb的公式:
如果把 RGB 和YUV 的范围都放缩到 [0,255][0,255],那么常用的转换公式是这样的。
static const char* S_f_shader_yuv4xx1 =
"varying lowp vec2 v_texCoord;
uniform sampler2D tex_y;
uniform sampler2D tex_u;
uniform sampler2D tex_v;
void main(void)
{
float r, g, b, y, u, v;
y = texture2D(tex_y, v_texCoord).r;
u = texture2D(tex_u, v_texCoord).r - 0.5;
v = texture2D(tex_v, v_texCoord).r - 0.5;
r = y + 1.13983*v;
g = y - 0.39465*u - 0.58060*v;
b = y + 2.03211*u;
gl_FragColor = vec4(r, g, b, 1.0);
}";
如果为NV12,其排列方式为Y集中排列,UV交错排列
YYYYUVUV
根据这种交错的性质,UV当成一个整体来看,则恰好是Y的1/2,让其宽度增大2倍,则恰好模拟情形应该如下:
A R G B
U0 V0 U0 V0
所以需要将UV作为一个整体,给OpenGL,设置宽度为width/2,高度为height,则R为V0,A为U0
static const char* S_f_shader_nv12 =
"precision highp float;
varying vec2 v_texCoord;
uniform sampler2D tex_y;
uniform sampler2D tex_u;
void main (void){
float r, g, b, y, u, v;
y = texture2D(tex_y, v_texCoord).r;
u = texture2D(tex_u, v_texCoord).a - 0.5;
v = texture2D(tex_u, v_texCoord).r - 0.5;
r = y + 1.13983*v;
g = y - 0.39465*u - 0.58060*v;
b = y + 2.03211*u;
gl_FragColor = vec4(r, g, b, 1.0);
}";