OpenGL显示YUV视频
来源:互联网 发布:知鸟保险基础1500题库 编辑:程序博客网 时间:2024/05/18 01:40
某次有用到opengl显示YUV视频,网上一直没找到完整的代码,后凑齐了,就贴在这里,vs2010工程完整代码下载地址http://download.csdn.net/detail/himulakensin/6339791
// windows平台#define WindowWidth 960#define WindowHeight 560#define WindowTitle "OpenGL_showYUV"#include "GL/glew.h"#include "GL/glut.h"#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <string.h>#include <Windows.h>#pragma comment (lib, "glew32.lib")/* 记时的类,不用理这个类 */class KsTime{private: __int64 m_base, m_start, m_stop; bool m_print;public: KsTime(bool e_print = false); ~KsTime(); void restart(); void elapsed(); double get_elapsed(); void set_print(bool e_print);};KsTime::KsTime(bool e_print) : m_print(e_print){ QueryPerformanceFrequency((LARGE_INTEGER *)(&m_base)); restart();}KsTime::~KsTime() { if (m_print) elapsed(); }void KsTime::restart(){ QueryPerformanceCounter((LARGE_INTEGER *)(&m_start)); }void KsTime::elapsed(){ QueryPerformanceCounter((LARGE_INTEGER *)(&m_stop)); printf("%.6f\n", (double)(m_stop - m_start) / m_base); }double KsTime::get_elapsed(){ QueryPerformanceCounter((LARGE_INTEGER *)(&m_stop)); return (double)(m_stop - m_start) / m_base; }void KsTime::set_print(bool e_print) { m_print = e_print; }/* I420的yuv数据,如果没有现成的,有ffmpeg.exe也行 * cmd里执行类似 * ffmpeg -t 10 -i D:\w.mp4 D:\w.yuv */const int w = 1920, h = 1080;FILE *infile = fopen("D:\\Data\\parkjoy.1920x1080.yuv", "rb");unsigned char buf[w*h*3/2];unsigned char *plane[3];GLuint p; // program id,着色器相关GLuint id_y, id_u, id_v; // 纹理idGLuint textureUniformY, textureUniformU,textureUniformV;#define ATTRIB_VERTEX 3#define ATTRIB_TEXTURE 4void display(void){ /* 对于1080P的I420,此读文件操作时非常耗时的,且一般不稳定 */ if (fread(buf, 1, w*h*3/2, infile) != w*h*3/2) { // 循环都I420文件 fseek(infile, 0, SEEK_SET); fread(buf, 1, w*h*3/2, infile); } glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, id_y); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, plane[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, id_u); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/2, h/2, 0, GL_RED, GL_UNSIGNED_BYTE, plane[1]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, id_v); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/2, h/2, 0, GL_RED, GL_UNSIGNED_BYTE, plane[2]); //glClearColor(0.0, 0.6, 0.0, 1.0); //glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, id_y); glUniform1i(textureUniformY, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, id_u); glUniform1i(textureUniformU, 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, id_v); glUniform1i(textureUniformV, 2); // Draw glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glutSwapBuffers();}KsTime kst;void timeFunc(int value){ kst.restart(); display(); int d = 40 - (int)(kst.get_elapsed()*1000); if (d <= 0) d = 0; // 大约25fps glutTimerFunc(d, timeFunc, 0);}char *textFileRead(char * filename){ char *s = (char *)malloc(8000); memset(s, 0, 8000); FILE *infile = fopen(filename, "rb"); int len = fread(s, 1, 8000, infile); fclose(infile); s[len] = 0; return s;}void setShaders(){ GLint vertCompiled, fragCompiled, linked; // 测试执行结果的 GLint v, f; const char *vs,*fs; v = glCreateShader(GL_VERTEX_SHADER); f = glCreateShader(GL_FRAGMENT_SHADER); vs = textFileRead("Shader.vsh"); fs = textFileRead("Shader.fsh"); glShaderSource(v, 1, &vs,NULL); glShaderSource(f, 1, &fs,NULL); glCompileShader(v); glGetShaderiv(v, GL_COMPILE_STATUS, &vertCompiled); glCompileShader(f); glGetShaderiv(f, GL_COMPILE_STATUS, &fragCompiled); p = glCreateProgram(); glAttachShader(p,v); glAttachShader(p,f); glBindAttribLocation(p, ATTRIB_VERTEX, "position"); glBindAttribLocation(p, ATTRIB_TEXTURE, "TexCoordIn"); glLinkProgram(p); glGetProgramiv(p, GL_LINK_STATUS, &linked); glUseProgram(p); static const GLfloat squareVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; static const GLfloat coordVertices[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; textureUniformY = glGetUniformLocation(p, "tex_y"); textureUniformU = glGetUniformLocation(p, "tex_u"); textureUniformV = glGetUniformLocation(p, "tex_v"); glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); glEnableVertexAttribArray(ATTRIB_VERTEX); glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, 0, 0, coordVertices); glEnableVertexAttribArray(ATTRIB_TEXTURE); glGenTextures(1, &id_y); glBindTexture(GL_TEXTURE_2D, id_y); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_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, &id_u); glBindTexture(GL_TEXTURE_2D, id_u); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_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, &id_v); glBindTexture(GL_TEXTURE_2D, id_v); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_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);}int main(int argc, char* argv[]){ plane[0] = buf; plane[1] = plane[0] + w*h; plane[2] = plane[1] + w*h/4; // GLUT初始化 glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA /*| GLUT_STENCIL | GLUT_DEPTH*/); glutInitWindowPosition(100, 100); glutInitWindowSize(WindowWidth, WindowHeight); glutCreateWindow(WindowTitle); printf("%s\n", glGetString(GL_VERSION)); GLenum l = glewInit(); if (glewIsSupported("GL_VERSION_2_0")) printf("Ready for OpenGL 2.0\n"); else{ printf("OpenGL 2.0 not supported\n"); return 0; } glutDisplayFunc(&display); glutTimerFunc(40, timeFunc, 0); setShaders(); // 开始显示 glutMainLoop(); return 0;}
GLSL相关的两个小文件
attribute vec4 position; attribute vec2 TexCoordIn;varying vec2 TexCoordOut;void main(void){ gl_Position = position; TexCoordOut = TexCoordIn;}varying vec2 TexCoordOut;uniform sampler2D tex_y;uniform sampler2D tex_u;uniform sampler2D tex_v;void main(void){ vec3 yuv; vec3 rgb; yuv.x = texture2D(tex_y, TexCoordOut).r; yuv.y = texture2D(tex_u, TexCoordOut).r - 0.5; yuv.z = texture2D(tex_v, TexCoordOut).r - 0.5; rgb = mat3( 1, 1, 1, 0, -0.39465, 2.03211, 1.13983, -0.58060, 0) * yuv; gl_FragColor = vec4(rgb, 1);}
- OpenGL显示YUV视频
- qt采用opengl显示yuv视频数据
- OpenGL播放yuv视频
- OpenGL播放yuv视频
- OpenGL播放yuv视频
- OpenGL播放yuv视频
- yuv视频用opengl播放
- c++ OpenGL显示YUV数据
- 使用DirectDraw显示YUV视频
- ddraw 显示YUV视频数据
- iOS中OpenGL-ES渲染YUV视频
- android OpenGL 显示视频
- 通过opengl来实现yuv的显示
- 使用DirectDraw直接显示YUV视频数据
- 利用Qt + OpenGL 渲染 YUV数据,播放视频 mac版
- 通过opengl es 2.0来实现yuv的显示
- socket 传输 mediacodec 编码 yuv H264 opengl实时显示
- 通过opengl es 2.0来实现yuv(NV21)的显示
- Android深入浅出之Audio 第二部分 AudioFlinger分析
- 【热门主题:加勒比海盗桌面主题】
- 关于cvAbsDiff的那些事
- OCX控件的注册卸载,以及判断是否注册
- solaris 11NFS共享配置
- OpenGL显示YUV视频
- java 常用方法的加密解密
- linux中/usr的由来及内容
- [OGRE]看备注学编程(03):打地鼠02-设置地鼠随机出现
- Oracle百问百答(三)
- ubuntu 下二进制 ,十进制,十六进制的转换
- 验证码生成器
- Android(AIDL)自动重复拨号及挂断/接听电话
- SkipList 跳表