拜读雷神的 OpenGL播放YUV420P 感觉很牛强大,可惜就是不能实际使用,所以这里做了一个直接YUV2图像显示的例子!
基本知识参考: YUV2像素, OpenGL纹理有效格式, 着色器函数
基本原理:
1. yuv2 是 422 所以需要取除当前像素外的前后三个像素
2. 根据三个像素与当前的奇偶值,分别取出YUV,
3. 与RGB进行转化
4. 完成! 简单吧!
自已截屏一张:
基本代码大家自己学习这里只是给出实际使用的着色器:
varying vec2 textureOut; \
varying vec4 texturePos; \
uniform sampler2D tex_video; \
uniform float tex_offset_x; \
uniform float tex_offset_y; \
void main(void) \
{
vec3 yuv; \
vec3 rgb; \
float pos_offset ; \
float img_pos_x = (texturePos.x + 1.0)*0.5; \
float img_pos_y = (texturePos.y + 1.0)*0.5; \
vec4 tmp_current = texture2D(tex_video, vec2(img_pos_x, img_pos_y )); \
vec4 tmp_before = texture2D(tex_video, vec2(img_pos_x - tex_offset_x, img_pos_y )); \
vec4 tmp_after = texture2D(tex_video, vec2(img_pos_x + tex_offset_x, img_pos_y )); \
float pixel_row = floor(img_pos_x / tex_offset_x + 0.5);
float pixel_row_helf = floor(pixel_row*0.5) * 2; \
float pixel_row_offset = pixel_row - pixel_row_helf; \
if (pixel_row_offset < 1.0) {
yuv.x = tmp_current.x; \
yuv.y = tmp_current.y - 0.5; \
yuv.z = tmp_after.y - 0.5; \ \
} else { \
yuv.x = tmp_current.x; \
yuv.y = tmp_before.y - 0.5;
yuv.z = tmp_current.y - 0.5;
}
rgb = mat3(1.0, 1.0, 1.0, 0, -0.39465, 2.03211, 1.13983, -0.58060, 0) * yuv; \
gl_FragColor = vec4(rgb, 1.0); \
}";