用OpenGL shader 实现将YUV转RGB(直接调用GPU实现)

这段时间一直在搞视频格式的转换问题,终于最近将一个图片的YUV格式转RGB格式转换成功了。下面就来介绍一下:


由于我的工程是在vs2008中的,其中包含一些相关头文件和库,所以下面只是列出部分核心代码,并不是全部代码。


1、下载一个包含YUV数据的文件也可以自己制作一个该文件

下载地址: YUV数据文件

2、读入YUV数据文件中的yuv数据:

关键代码如下:

2.1读文件代码

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. unsigned char * readYUV(char *path)  
  2. {  
  3.   
  4.     FILE *fp;  
  5.     unsigned char * buffer;  
  6.     long size = 1280 * 720 * 3 / 2;  
  7.   
  8.     if((fp=fopen(path,"rb"))==NULL)  
  9.     {  
  10.        printf("cant open the file");  
  11.        exit(0);  
  12.     }  
  13.   
  14.     buffer = new unsigned char[size];  
  15.     memset(buffer,'\0',size);  
  16.     fread(buffer,size,1,fp);  
  17.     fclose(fp);  
  18.     return buffer;  
  19. }  

2.2读入数据,并将YUV数据分别制作成3个纹理

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. GLuint texYId;  
  2. GLuint texUId;  
  3. GLuint texVId;  
  4.   
  5.   
  6. void loadYUV(){  
  7.     int width ;  
  8.     int height ;  
  9.   
  10.     width = 640;  
  11.     height = 480;  
  12.   
  13.     unsigned char *buffer = NULL;  
  14.     buffer = readYUV("1.yuv");  
  15.   
  16.    glGenTextures ( 1, &texYId );  
  17.    glBindTexture ( GL_TEXTURE_2D, texYId );  
  18.    glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer );  
  19.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );  
  20.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );  
  21.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );  
  22.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );  
  23.   
  24.    glGenTextures ( 1, &texUId );  
  25.    glBindTexture ( GL_TEXTURE_2D, texUId );  
  26.    glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer + width * height);  
  27.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );  
  28.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );  
  29.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );  
  30.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );  
  31.   
  32.    glGenTextures ( 1, &texVId );  
  33.    glBindTexture ( GL_TEXTURE_2D, texVId );  
  34.    glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer + width * height * 5 / 4 );  
  35.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );  
  36.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );  
  37.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );  
  38.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );  
  39.   
  40. }  

上述代码中1.yuv就是YUV数据文件

3、将纹理传入OpenGL shader进行显示

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. </pre></h1><h2>3.1 顶点shader和片段shader代码</h2><div><pre name="code" class="cpp"> GLbyte vShaderStr[] =    
  2.       "attribute vec4 vPosition;    \n"  
  3.       "attribute vec2 a_texCoord;   \n"  
  4.       "varying vec2 tc;     \n"  
  5.       "void main()                  \n"  
  6.       "{                            \n"  
  7.       "   gl_Position = vPosition;  \n"  
  8.       "   tc = a_texCoord;  \n"  
  9.       "}                            \n";  
  10.      
  11.    GLbyte fShaderStr[] =    
  12.       "precision mediump float;\n"  
  13.       "uniform sampler2D tex_y;                 \n"  
  14.       "uniform sampler2D tex_u;                 \n"  
  15.       "uniform sampler2D tex_v;                 \n"  
  16.       "varying vec2 tc;                         \n"  
  17.       "void main()                                  \n"  
  18.       "{                                            \n"  
  19.       "  vec4 c = vec4((texture2D(tex_y, tc).r - 16./255.) * 1.164);\n"  
  20.       "  vec4 U = vec4(texture2D(tex_u, tc).r - 128./255.);\n"  
  21.       "  vec4 V = vec4(texture2D(tex_v, tc).r - 128./255.);\n"  
  22.       "  c += V * vec4(1.596, -0.813, 0, 0);\n"  
  23.       "  c += U * vec4(0, -0.392, 2.017, 0);\n"  
  24.       "  c.a = 1.0;\n"  
  25.       "  gl_FragColor = c;\n"  
  26.       "}                                            \n";  

上述片段shader中就是根据yuv转rgb的公式得来的。也就是说是在shader中实现转换的。

4、显示结果

结果如下:

注意:该shader是OpenGL ES格式的,与OpenGL格式的shader有一点差别。

其它链接:http://www.cnblogs.com/weinyzhou/archive/2012/07/07/2592453.html?ADUIN=517436588&ADSESSION=1405491322&ADTAG=CLIENT.QQ.5329_.0&ADPUBNO=26349

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值