[OpenGL] use OpenGL shader to convert YUV to RGB-(GPU implementation is called directly, hardware-only, and high efficiency)

Source: Internet
Author: User

During this time, we have been engaged in video format conversion. Finally, we have successfully converted the YUV format of an image to the RGB format. The following is an introduction:

Because my project is in vs2008 and contains some related header files and libraries, I will only list some of the core code below, not all of the Code.


1. to download a file containing YUV data, you can also create one by yourself: YUV data file 2. Read the YUV data in the YUV data file. The key code is as follows: 2.1 read the file code.
unsigned char * readYUV(char *path){FILE *fp;unsigned char * buffer;long size = 1280 * 720 * 3 / 2;if((fp=fopen(path,"rb"))==NULL){   printf("cant open the file");   exit(0);}buffer = new unsigned char[size];memset(buffer,'\0',size);fread(buffer,size,1,fp);fclose(fp);return buffer;}
2.2 read data and create three textures for YUV data.
GLuint texYId;GLuint texUId;GLuint texVId;void loadYUV(){int width ;intheight ;width = 640;height = 480;unsigned char *buffer = NULL;buffer = readYUV("1.yuv");   glGenTextures ( 1, &texYId );   glBindTexture ( GL_TEXTURE_2D, texYId );   glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );   glGenTextures ( 1, &texUId );   glBindTexture ( GL_TEXTURE_2D, texUId );   glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer + width * height);   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );   glGenTextures ( 1, &texVId );   glBindTexture ( GL_TEXTURE_2D, texVId );   glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer + width * height * 5 / 4 );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );}

In the above Code, 1. YUV is the YUV data file. 3. Pass the texture to OpenGL shader for display.

3.1 vertex shader and fragment shader code 
 GLbyte vShaderStr[] =        "attribute vec4 vPosition;    \n"  "attribute vec2 a_texCoord;\n"  "varying vec2 tc;\n"      "void main()                  \n"      "{                            \n"      "   gl_Position = vPosition;  \n"  "  tc = a_texCoord;\n"      "}                            \n";      GLbyte fShaderStr[] =        "precision mediump float;\n"  "uniform sampler2D tex_y;\n"  "uniform sampler2D tex_u;\n"  "uniform sampler2D tex_v;\n"  "varying vec2 tc;\n"      "void main()                                  \n"      "{                                            \n"  "  vec4 c = vec4((texture2D(tex_y, tc).r - 16./255.) * 1.164);\n"  "  vec4 U = vec4(texture2D(tex_u, tc).r - 128./255.);\n"  "  vec4 V = vec4(texture2D(tex_v, tc).r - 128./255.);\n"  "  c += V * vec4(1.596, -0.813, 0, 0);\n"  "  c += U * vec4(0, -0.392, 2.017, 0);\n"  "  c.a = 1.0;\n"  "  gl_FragColor = c;\n"      "}                                            \n";
The shader in the above part is obtained based on the YUV-to-RGB formula. That is to say, it is implemented in the shader. 4. The result is as follows: Note: The shader is in OpenGL ES format, which is slightly different from the shader in OpenGL format.

 

  • Previous Article: [Video Codec] install FFMPEG and ffplay in Linux
  • Next article: [Linux] solution to the "the system is running in Low-graphics mode" Problem in Ubuntu
  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.