OpenGL PBO渲染视频数据 [转]
OpenGL PBO渲染视频数据 [转]
目录
OpenGL PBO渲染视频数据 [转]
PBO
双PBO
PBO
#pragma once #include <assert.h> class ShaderId { public:ShaderId(){_shaderId = -1;}int _shaderId; };/** * 程序 */ class ProgramId { public:int _programId;ShaderId _vertex;ShaderId _fragment; public:ProgramId(){_programId = -1;} public:/*** 加载函数*/bool createProgram( const char* vertex,const char* fragment ){bool error = false;do {if (vertex){_vertex._shaderId = glCreateShader( GL_VERTEX_SHADER );glShaderSource( _vertex._shaderId, 1, &vertex, 0 );glCompileShader( _vertex._shaderId );GLint compileStatus;glGetShaderiv( _vertex._shaderId, GL_COMPILE_STATUS, &compileStatus );error = compileStatus == GL_FALSE;if( error ){GLchar messages[256];glGetShaderInfoLog( _vertex._shaderId, sizeof(messages), 0,messages);assert( messages && 0 != 0);break;}}if (fragment){_fragment._shaderId = glCreateShader( GL_FRAGMENT_SHADER );glShaderSource( _fragment._shaderId, 1, &fragment, 0 );glCompileShader( _fragment._shaderId );GLint compileStatus;glGetShaderiv( _fragment._shaderId, GL_COMPILE_STATUS, &compileStatus );error = compileStatus == GL_FALSE;if( error ){GLchar messages[256];glGetShaderInfoLog( _fragment._shaderId, sizeof(messages), 0,messages);assert( messages && 0 != 0);break;}}_programId = glCreateProgram( );if (_vertex._shaderId){glAttachShader( _programId, _vertex._shaderId);}if (_fragment._shaderId){glAttachShader( _programId, _fragment._shaderId);}glLinkProgram( _programId );GLint linkStatus;glGetProgramiv( _programId, GL_LINK_STATUS, &linkStatus );if (linkStatus == GL_FALSE){GLchar messages[256];glGetProgramInfoLog( _programId, sizeof(messages), 0, messages);break;}glUseProgram(_programId);} while(false);if (error){if (_fragment._shaderId){glDeleteShader(_fragment._shaderId);_fragment._shaderId = 0;}if (_vertex._shaderId){glDeleteShader(_vertex._shaderId);_vertex._shaderId = 0;}if (_programId){glDeleteProgram(_programId);_programId = 0;}}return true;}/*** 使用程序*/virtual void begin(){glUseProgram(_programId);}/*** 使用完成*/virtual void end(){glUseProgram(0);} };class PROGRAM_YUV1 :public ProgramId { public:typedef int attribute; typedef int uniform; public:attribute _position;attribute _uvY;attribute _uvU;attribute _uvV;uniform _MVP;uniform _textureYUV; public:PROGRAM_YUV1(){_position = -1;_uvY = -1;_uvU = -1;_uvV = -1;_MVP = -1;_textureYUV = -1;}~PROGRAM_YUV1(){}/// 初始化函数virtual bool initialize(){const char* vs = {"precision lowp float; ""uniform mat4 _MVP;""attribute vec2 _position;""attribute vec2 _uvY;""attribute vec2 _uvU;""attribute vec2 _uvV;""varying vec2 _outUVY;""varying vec2 _outUVU;""varying vec2 _outUVV;""void main()""{"" _outUVY = _uvY;"" _outUVU = _uvU;"" _outUVV = _uvV;"" vec4 pos = vec4(_position,0,1);"" gl_Position = _MVP * pos;""}"};const char* ps = {"precision lowp float; ""uniform sampler2D _textureYUV;""varying vec2 _outUVY;""varying vec2 _outUVU;""varying vec2 _outUVV;""void main()""{"" vec3 yuv;"" vec3 rgb; " " yuv.x = texture2D(_textureYUV, _outUVY).a;"" yuv.y = texture2D(_textureYUV, _outUVU).a - 0.5;"" yuv.z = texture2D(_textureYUV, _outUVV).a - 0.5;"" rgb = mat3( 1, 1, 1,"" 0, -0.39465, 2.03210,"" 1.13983, -0.58060, 0) * yuv;" " gl_FragColor = vec4(rgb, 1);""}"};bool res = createProgram(vs,ps);if(res){_position = glGetAttribLocation(_programId,"_position");_uvY = glGetAttribLocation(_programId,"_uvY");_uvU = glGetAttribLocation(_programId,"_uvU");_uvV = glGetAttribLocation(_programId,"_uvV");_textureYUV = glGetUniformLocation(_programId,"_textureYUV");_MVP = glGetUniformLocation(_programId,"_MVP");}return res;}/*** 使用程序*/virtual void begin(){glUseProgram(_programId);glEnableVertexAttribArray(_position);glEnableVertexAttribArray(_uvY);glEnableVertexAttribArray(_uvU);glEnableVertexAttribArray(_uvV);}/*** 使用完成*/virtual void end(){glDisableVertexAttribArray(_position);glDisableVertexAttribArray(_uvY);glDisableVertexAttribArray(_uvU);glDisableVertexAttribArray(_uvV);glUseProgram(0);} };
#include <windows.h> #include <tchar.h> #include "glew/glew.h" #include "FFVideoReader.hpp" #include "Thread.hpp" #include "Timestamp.hpp" #include "GLContext.h" #include "CELLShader.hpp" #include "CELLMath.hpp"#define WM_UPDATE_VIDEO WM_USER + 100void getResourcePath(HINSTANCE hInstance,char pPath[1024]) {char szPathName[1024];char szDriver[64];char szPath[1024];GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));_splitpath( szPathName, szDriver, szPath, 0, 0 );sprintf(pPath,"%s%s",szDriver,szPath); }class DecodeThread :public Thread { public:FFVideoReader _ffReader;HWND _hWnd;bool _exitFlag;Timestamp _timestamp;GLContext _glContext;unsigned _textureYUV;PROGRAM_YUV1 _shaderTex;unsigned _pbo; public:DecodeThread(){_exitFlag = false;_hWnd = 0;_pbo = 0;}virtual void setup(HWND hwnd,const char* fileName = "11.flv"){_hWnd = hwnd;_ffReader.setup();_ffReader.load(fileName);_glContext.setup(hwnd,GetDC(hwnd));glewInit();glEnable(GL_TEXTURE_2D);_textureYUV = createTexture(_ffReader._screenW,_ffReader._screenH + _ffReader._screenH/2);_shaderTex.initialize();/*** 创建PBuffer*/_pbo = createPBuffer(_ffReader._screenW,_ffReader._screenH + _ffReader._screenH/2);}/*** 加载文件*/virtual void load(const char* fileName){_ffReader.load(fileName);}virtual void shutdown(){_exitFlag = true;Thread::join();_glContext.shutdown();}/*** 线程执行函数*/virtual bool run(){_timestamp.update();while(!_exitFlag){FrameInfor* infor = new FrameInfor();if (!_ffReader.readFrame(*infor)){break;}double tims = infor->_pts * infor->_timeBase * 1000;//! 这里需要通知窗口进行重绘制更新,显示更新数据PostMessage(_hWnd,WM_UPDATE_VIDEO,(WPARAM)infor,0);double elsped = _timestamp.getElapsedTimeInMilliSec();double sleeps = (tims - elsped);if (sleeps > 1){Sleep((DWORD)sleeps);}}return true;}void updateImage(GLubyte* dst,int x,int y,int w,int h,void* data){int pitch = _ffReader._screenW; GLubyte* dst1 = dst + y * pitch + x;GLubyte* src = (GLubyte*)(data);int size = w;for (int i = 0 ; i < h ; ++ i){memcpy(dst1,src,w);dst1 += pitch;src += w;}}void updateTexture(FrameInfor* infor){int w = _ffReader._screenW;int h = _ffReader._screenH + _ffReader._screenH/2;glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pbo);GLubyte* dst = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);if( dst != 0){memcpy(dst,infor->_data->data[0],_ffReader._screenW * _ffReader._screenH);updateImage(dst,0, _ffReader._screenH,_ffReader._screenW/2,_ffReader._screenH/2,infor->_data->data[1]);updateImage(dst,_ffReader._screenW/2, _ffReader._screenH,_ffReader._screenW/2,_ffReader._screenH/2,infor->_data->data[2]);glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);}glBindTexture(GL_TEXTURE_2D,_textureYUV);glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,GL_ALPHA,GL_UNSIGNED_BYTE,0);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);}void render(){struct Vertex{CELL::float2 pos;CELL::float2 uvY;CELL::float2 uvU;CELL::float2 uvV;};RECT rt;GetClientRect(_hWnd,&rt);int w = rt.right - rt.left;int h = rt.bottom - rt.top;glClear(GL_COLOR_BUFFER_BIT);glClearColor(1,0,0,1);glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(0,w,h,0,-100,100);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glBindTexture(GL_TEXTURE_2D,_textureYUV);float yv = (float)_ffReader._screenH/(float)(_ffReader._screenH + _ffReader._screenH/2);float fw = _ffReader._screenW;float fh = _ffReader._screenH;float x = 0;float y = 0;float Yv = (float)fh/(float)(fh + fh/2);float Uu0 = 0;float Uv0 = Yv;float Uu1 = 0.5f;float Uv1 = 1.0f;float Vu0 = 0.5f;float Vv0 = Yv;float Vu1 = 1.0f;float Vv1 = 1.0f;Vertex vertex[] = {CELL::float2(x,y), CELL::float2(0,0), CELL::float2(Uu0,Uv0), CELL::float2(Vu0,Vv0),CELL::float2(x + w,y), CELL::float2(1,0), CELL::float2(Uu1,Uv0), CELL::float2(Vu1,Vv0),CELL::float2(x,y + h), CELL::float2(0,Yv), CELL::float2(Uu0,Uv1), CELL::float2(Vu0,Vv1), CELL::float2(x + w, y + h), CELL::float2(1,Yv), CELL::float2(Uu1,Uv1), CELL::float2(Vu1,Vv1),};_shaderTex.begin();CELL::matrix4 matMVP = CELL::ortho<float>(0,w,h,0,-100,100);glUniformMatrix4fv(_shaderTex._MVP, 1, false, matMVP.data());glUniform1i(_shaderTex._textureYUV, 0);glVertexAttribPointer(_shaderTex._position,2,GL_FLOAT, false, sizeof(Vertex),vertex);glVertexAttribPointer(_shaderTex._uvY, 2,GL_FLOAT, false, sizeof(Vertex),&vertex[0].uvY);glVertexAttribPointer(_shaderTex._uvU, 2,GL_FLOAT, false, sizeof(Vertex),&vertex[0].uvU);glVertexAttribPointer(_shaderTex._uvV, 2,GL_FLOAT, false, sizeof(Vertex),&vertex[0].uvV);glDrawArrays(GL_TRIANGLE_STRIP,0,4);_shaderTex.end();_glContext.swapBuffer();}protected:unsigned createTexture(int w,int h){unsigned texId;glGenTextures(1,&texId);glBindTexture(GL_TEXTURE_2D,texId);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,w,h,0,GL_ALPHA,GL_UNSIGNED_BYTE,0);return texId;}unsigned createPBuffer(int w,int h){ unsigned pbuffer = 0;glGenBuffers(1, &pbuffer);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbuffer);glBufferData(GL_PIXEL_UNPACK_BUFFER, w* h, 0, GL_STREAM_DRAW);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);return pbuffer;} };DecodeThread g_decode;LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch(msg){case WM_UPDATE_VIDEO:{FrameInfor* infor = (FrameInfor*)wParam;g_decode.updateTexture(infor);delete infor;g_decode.render();}break;case WM_SIZE:break;case WM_CLOSE:case WM_DESTROY:g_decode.shutdown();PostQuitMessage(0);break;default:break;}return DefWindowProc( hWnd, msg, wParam, lParam ); }int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) {// 1 注册窗口类::WNDCLASSEXA winClass;winClass.lpszClassName = "FFVideoPlayer";winClass.cbSize = sizeof(::WNDCLASSEX);winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;winClass.lpfnWndProc = windowProc;winClass.hInstance = hInstance;winClass.hIcon = 0;winClass.hIconSm = 0;winClass.hCursor = LoadCursor(NULL, IDC_ARROW);winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);winClass.lpszMenuName = NULL;winClass.cbClsExtra = 0;winClass.cbWndExtra = 0;RegisterClassExA(&winClass);// 2 创建窗口HWND hWnd = CreateWindowExA(NULL,"FFVideoPlayer","FFVideoPlayer",WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,0,0,480,320, 0, 0,hInstance, 0);UpdateWindow( hWnd );ShowWindow(hWnd,SW_SHOW);char szPath[1024];char szPathName[1024];getResourcePath(hInstance,szPath);sprintf(szPathName,"%sdata/11.flv",szPath);g_decode.setup(hWnd,szPathName);g_decode.start();MSG msg = {0};while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}g_decode.shutdown();return 0; }
双PBO
#pragma once#include <assert.h>class ShaderId { public:ShaderId(){_shaderId = -1;}int _shaderId; };/** * 程序 */ class ProgramId { public:int _programId;ShaderId _vertex;ShaderId _fragment; public:ProgramId(){_programId = -1;} public:/*** 加载函数*/bool createProgram(const char* vertex, const char* fragment){bool error = false;do{if (vertex){_vertex._shaderId = glCreateShader(GL_VERTEX_SHADER);glShaderSource(_vertex._shaderId, 1, &vertex, 0);glCompileShader(_vertex._shaderId);GLint compileStatus;glGetShaderiv(_vertex._shaderId, GL_COMPILE_STATUS, &compileStatus);error = compileStatus == GL_FALSE;if (error){GLchar messages[256];glGetShaderInfoLog(_vertex._shaderId, sizeof(messages), 0, messages);assert(messages && 0 != 0);break;}}if (fragment){_fragment._shaderId = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(_fragment._shaderId, 1, &fragment, 0);glCompileShader(_fragment._shaderId);GLint compileStatus;glGetShaderiv(_fragment._shaderId, GL_COMPILE_STATUS, &compileStatus);error = compileStatus == GL_FALSE;if (error){GLchar messages[256];glGetShaderInfoLog(_fragment._shaderId, sizeof(messages), 0, messages);assert(messages && 0 != 0);break;}}_programId = glCreateProgram();if (_vertex._shaderId){glAttachShader(_programId, _vertex._shaderId);}if (_fragment._shaderId){glAttachShader(_programId, _fragment._shaderId);}glLinkProgram(_programId);GLint linkStatus;glGetProgramiv(_programId, GL_LINK_STATUS, &linkStatus);if (linkStatus == GL_FALSE){GLchar messages[256];glGetProgramInfoLog(_programId, sizeof(messages), 0, messages);break;}glUseProgram(_programId);} while (false);if (error){if (_fragment._shaderId){glDeleteShader(_fragment._shaderId);_fragment._shaderId = 0;}if (_vertex._shaderId){glDeleteShader(_vertex._shaderId);_vertex._shaderId = 0;}if (_programId){glDeleteProgram(_programId);_programId = 0;}}return true;}/*** 使用程序*/virtual void begin(){glUseProgram(_programId);}/*** 使用完成*/virtual void end(){glUseProgram(0);} };class PROGRAM_YUV1 :public ProgramId { public:typedef int attribute;typedef int uniform; public:attribute _position;attribute _uvY;attribute _uvU;attribute _uvV;uniform _MVP;uniform _textureYUV; public:PROGRAM_YUV1(){_position = -1;_uvY = -1;_uvU = -1;_uvV = -1;_MVP = -1;_textureYUV = -1;}~PROGRAM_YUV1(){}/// 初始化函数virtual bool initialize(){const char* vs ={"precision lowp float; ""uniform mat4 _MVP;""attribute vec2 _position;""attribute vec2 _uvY;""attribute vec2 _uvU;""attribute vec2 _uvV;""varying vec2 _outUVY;""varying vec2 _outUVU;""varying vec2 _outUVV;""void main()""{"" _outUVY = _uvY;"" _outUVU = _uvU;"" _outUVV = _uvV;"" vec4 pos = vec4(_position,0,1);"" gl_Position = _MVP * pos;""}"};const char* ps ={"precision lowp float; ""uniform sampler2D _textureYUV;""varying vec2 _outUVY;""varying vec2 _outUVU;""varying vec2 _outUVV;""void main()""{"" vec3 yuv;"" vec3 rgb; "" yuv.x = texture2D(_textureYUV, _outUVY).a;"" yuv.y = texture2D(_textureYUV, _outUVU).a - 0.5;"" yuv.z = texture2D(_textureYUV, _outUVV).a - 0.5;"" rgb = mat3( 1, 1, 1,"" 0, -0.39465, 2.03210,"" 1.13983, -0.58060, 0) * yuv;"" gl_FragColor = vec4(rgb, 1);""}"};bool res = createProgram(vs, ps);if (res){_position = glGetAttribLocation(_programId, "_position");_uvY = glGetAttribLocation(_programId, "_uvY");_uvU = glGetAttribLocation(_programId, "_uvU");_uvV = glGetAttribLocation(_programId, "_uvV");_textureYUV = glGetUniformLocation(_programId, "_textureYUV");_MVP = glGetUniformLocation(_programId, "_MVP");}return res;}/*** 使用程序*/virtual void begin(){glUseProgram(_programId);glEnableVertexAttribArray(_position);glEnableVertexAttribArray(_uvY);glEnableVertexAttribArray(_uvU);glEnableVertexAttribArray(_uvV);}/*** 使用完成*/virtual void end(){glDisableVertexAttribArray(_position);glDisableVertexAttribArray(_uvY);glDisableVertexAttribArray(_uvU);glDisableVertexAttribArray(_uvV);glUseProgram(0);} };
#include <windows.h> #include <tchar.h> #include "glew/glew.h" #include "FFVideoReader.hpp" #include "Thread.hpp" #include "Timestamp.hpp" #include "GLContext.h" #include "CELLShader.hpp" #include "CELLMath.hpp"#define WM_UPDATE_VIDEO WM_USER + 100void getResourcePath(HINSTANCE hInstance,char pPath[1024]) {char szPathName[1024];char szDriver[64];char szPath[1024];GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));_splitpath( szPathName, szDriver, szPath, 0, 0 );sprintf(pPath,"%s%s",szDriver,szPath); }class DecodeThread :public Thread { public:FFVideoReader _ffReader;HWND _hWnd;bool _exitFlag;Timestamp _timestamp;GLContext _glContext;unsigned _textureYUV;PROGRAM_YUV1 _shaderTex;unsigned _pbo[2];int _DMA;int _WRITE;void* _dmaPtr; public:DecodeThread(){_exitFlag = false;_hWnd = 0;_DMA = 0;_WRITE = 1;_dmaPtr = 0;}virtual void setup(HWND hwnd,const char* fileName = "11.flv"){_hWnd = hwnd;_ffReader.setup();_ffReader.load(fileName);_glContext.setup(hwnd,GetDC(hwnd));glewInit();glEnable(GL_TEXTURE_2D);_textureYUV = createTexture(_ffReader._screenW,_ffReader._screenH + _ffReader._screenH/2);_shaderTex.initialize();/*** 创建PBuffer*/_pbo[0] = createPBuffer(_ffReader._screenW,_ffReader._screenH + _ffReader._screenH/2);_pbo[1] = createPBuffer(_ffReader._screenW,_ffReader._screenH + _ffReader._screenH/2);}/*** 加载文件*/virtual void load(const char* fileName){_ffReader.load(fileName);}virtual void shutdown(){_exitFlag = true;Thread::join();_glContext.shutdown();}/*** 线程执行函数*/virtual bool run(){_timestamp.update();while(!_exitFlag){FrameInfor* infor = new FrameInfor();if (!_ffReader.readFrame(*infor)){break;}double tims = infor->_pts * infor->_timeBase * 1000;//! 这里需要通知窗口进行重绘制更新,显示更新数据if ( infor->_data->data[0] == 0 || infor->_data->data[1] == 0 || infor->_data->data[2] == 0 ){continue;}PostMessage(_hWnd,WM_UPDATE_VIDEO,(WPARAM)infor,0);double elsped = _timestamp.getElapsedTimeInMilliSec();double sleeps = (tims - elsped);if (sleeps > 1){Sleep((DWORD)sleeps);}}return true;}void updateImage(GLubyte* dst,int x,int y,int w,int h,void* data){int pitch = _ffReader._screenW; GLubyte* dst1 = dst + y * pitch + x;GLubyte* src = (GLubyte*)(data);int size = w;for (int i = 0 ; i < h ; ++ i){memcpy(dst1,src,w);dst1 += pitch;src += w;}}void updateTexture(FrameInfor* infor){int w = _ffReader._screenW;int h = _ffReader._screenH + _ffReader._screenH/2;glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pbo[_WRITE]);GLubyte* dst = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);if( dst != 0){memcpy(dst,infor->_data->data[0],_ffReader._screenW * _ffReader._screenH);updateImage(dst,0, _ffReader._screenH,_ffReader._screenW/2,_ffReader._screenH/2,infor->_data->data[1]);updateImage(dst,_ffReader._screenW/2, _ffReader._screenH,_ffReader._screenW/2,_ffReader._screenH/2,infor->_data->data[2]);glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);}glBindBuffer(GL_PIXEL_UNPACK_BUFFER,_pbo[_DMA]);glBindTexture(GL_TEXTURE_2D,_textureYUV);glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,GL_ALPHA,GL_UNSIGNED_BYTE,0);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);std::swap(_DMA,_WRITE);}void render(){struct Vertex{CELL::float2 pos;CELL::float2 uvY;CELL::float2 uvU;CELL::float2 uvV;};RECT rt;GetClientRect(_hWnd,&rt);int w = rt.right - rt.left;int h = rt.bottom - rt.top;glClear(GL_COLOR_BUFFER_BIT);glClearColor(1,0,0,1);glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(0,w,h,0,-100,100);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glBindTexture(GL_TEXTURE_2D,_textureYUV);float yv = (float)_ffReader._screenH/(float)(_ffReader._screenH + _ffReader._screenH/2);float fw = _ffReader._screenW;float fh = _ffReader._screenH;float x = 0;float y = 0;float Yv = (float)fh/(float)(fh + fh/2);float Uu0 = 0;float Uv0 = Yv;float Uu1 = 0.5f;float Uv1 = 1.0f;float Vu0 = 0.5f;float Vv0 = Yv;float Vu1 = 1.0f;float Vv1 = 1.0f;Vertex vertex[] = {CELL::float2(x,y), CELL::float2(0,0), CELL::float2(Uu0,Uv0), CELL::float2(Vu0,Vv0),CELL::float2(x + w,y), CELL::float2(1,0), CELL::float2(Uu1,Uv0), CELL::float2(Vu1,Vv0),CELL::float2(x,y + h), CELL::float2(0,Yv), CELL::float2(Uu0,Uv1), CELL::float2(Vu0,Vv1), CELL::float2(x + w, y + h), CELL::float2(1,Yv), CELL::float2(Uu1,Uv1), CELL::float2(Vu1,Vv1),};_shaderTex.begin();CELL::matrix4 matMVP = CELL::ortho<float>(0,w,h,0,-100,100);glUniformMatrix4fv(_shaderTex._MVP, 1, false, matMVP.data());glUniform1i(_shaderTex._textureYUV, 0);glVertexAttribPointer(_shaderTex._position,2,GL_FLOAT, false, sizeof(Vertex),vertex);glVertexAttribPointer(_shaderTex._uvY, 2,GL_FLOAT, false, sizeof(Vertex),&vertex[0].uvY);glVertexAttribPointer(_shaderTex._uvU, 2,GL_FLOAT, false, sizeof(Vertex),&vertex[0].uvU);glVertexAttribPointer(_shaderTex._uvV, 2,GL_FLOAT, false, sizeof(Vertex),&vertex[0].uvV);glDrawArrays(GL_TRIANGLE_STRIP,0,4);_shaderTex.end();_glContext.swapBuffer();}protected:unsigned createTexture(int w,int h){unsigned texId;glGenTextures(1,&texId);glBindTexture(GL_TEXTURE_2D,texId);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,w,h,0,GL_ALPHA,GL_UNSIGNED_BYTE,0);return texId;}unsigned createPBuffer(int w,int h){ unsigned pbuffer = 0;glGenBuffers(1, &pbuffer);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbuffer);glBufferData(GL_PIXEL_UNPACK_BUFFER, w* h, 0, GL_STREAM_DRAW);glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);return pbuffer;}};DecodeThread g_decode;LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch(msg){case WM_UPDATE_VIDEO:{FrameInfor* infor = (FrameInfor*)wParam;g_decode.updateTexture(infor);delete infor;g_decode.render();}break;case WM_SIZE:break;case WM_CLOSE:case WM_DESTROY:g_decode.shutdown();PostQuitMessage(0);break;default:break;}return DefWindowProc( hWnd, msg, wParam, lParam ); }int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) {// 1 注册窗口类::WNDCLASSEXA winClass;winClass.lpszClassName = "FFVideoPlayer";winClass.cbSize = sizeof(::WNDCLASSEX);winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;winClass.lpfnWndProc = windowProc;winClass.hInstance = hInstance;winClass.hIcon = 0;winClass.hIconSm = 0;winClass.hCursor = LoadCursor(NULL, IDC_ARROW);winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);winClass.lpszMenuName = NULL;winClass.cbClsExtra = 0;winClass.cbWndExtra = 0;RegisterClassExA(&winClass);// 2 创建窗口HWND hWnd = CreateWindowExA(NULL,"FFVideoPlayer","FFVideoPlayer",WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,0,0,480,320, 0, 0,hInstance, 0);UpdateWindow( hWnd );ShowWindow(hWnd,SW_SHOW);char szPath[1024];char szPathName[1024];getResourcePath(hInstance,szPath);sprintf(szPathName,"%sdata/11.flv",szPath);g_decode.setup(hWnd,szPathName);g_decode.start();MSG msg = {0};while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}g_decode.shutdown();return 0; }
OpenGL PBO渲染视频数据 [转]相关推荐
- OpenGL如何渲染NV12数据
OpenGL如何渲染NV12数据 引言 参考资料 创建纹理 shader脚本 如何readpixel回yuvByte流 引言 其实自己也是个GL小白,刚入门没多久.最近接手一个项目,由于种种原因吧,对 ...
- C++ Qt D3D渲染视频数据
在Qt中显示视频画面,可以把每一帧的数据存为QImage然后显示出来,也可以使用OpenGL或DirectX来进行绘制,直接操作显卡显示,之前我在做视频解码播放时,都是用QImage的方式,本篇将 ...
- Android音视频学习系列(六) — 掌握视频基础知识并使用OpenGL ES 2.0渲染YUV数据
系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...
- OpenGL/OpenGL ES入门:渲染YUV数据实践
纹理:GPU中的一块数据结构,YUV数据先经过采样,转成rgb显示. 着色器代码,先通过compile编译成GPU能识别的机器语言,再交由GPU进行显示. shader着色器,texture纹理,Ut ...
- Windows平台OpenGL渲染视频
我之前写过一个简单的RTSP播放器(https://github.com/greenjim301/rtsp),当时的视频渲染是用D3D实现的.一直想尝试一下用OpenGL来渲染视频,但却不得空,最近有 ...
- OBS视频数据输出流程(模块加载,编码,推流)详细说明
声明:本文章内容仅代表个人观点,不能保证完全的正确性,仅供参考! 先上个自己画的图,结合流程图和文字解释,理解起来会更快些 1.视频输出初始化程序运行时,初始化OBS,视频相关的初始化是再mainWi ...
- 基于Surface的视频编解码与OpenGL ES渲染
http://blog.csdn.net/gh_home/article/details/52399959 1. 概述 这篇文章所做的事情是这样的: 1. 从一个.mp4文件中解码视频流到surfa ...
- Android音视频学习系列(五) — 掌握音频基础知识并使用AudioTrack、OpenSL ES渲染PCM数据
系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...
- OpenGL渲染视频(二)
目录 一.前言 二.openGL渲染介绍 1.OpenGl渲染管线的流程 2.顶点着色器的介绍 3.片元着色器的介绍 三.openGL着色器语言GLSL介绍 1.数据类型 2.限定符 3.二维图像渲染 ...
最新文章
- 新概念C语言能力教程练习3答案,新概念C语言教程答案参考(自做)中国电力
- oracle中姓名取姓氏,Oracle SQL - 解析一個名稱字符串並將其轉換爲第一個姓氏和名字...
- hdu2203 KMP水的问题
- 25 个在 Web 中嵌入图表的免费资源
- C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
- 搭建了Pycharm对话平台
- C++,std::shared_future的使用
- 8.1 复用(组合/继承)
- SQL盲注及python脚本编写
- html左侧浮动广告代码,网站侧边栏广告固定浮动效果的实现
- win10如何安装Java虚拟机_vmware 安装win10虚拟机
- Office中常见度量单位(转)
- 如何添加BigBoss的Cydia源地址
- matlab视频行人检测,利用MATLAB实现了视频图像行人识别与检测
- 回归中的相关度和决定系数
- html5怎么做电子请帖,如何制作H5婚礼邀请函?
- 什么是浏览器指纹? 浏览器指纹技术应用有哪些?
- python里的self
- 【龙印】用龙芯1c实现3D打印机的总体思路
- elasticsearch性能测试工具rally深入详解
热门文章
- 1993年入市一老股民愤然离场 今年已亏55万
- 一篇好文,在迷茫时阅读
- Infortrend存储性能稳定,吸引南通市智慧交通监控大力采购
- 搬书 hnust校赛
- 计算机网络专业现状,计算机网络的发展现状及网络体系结构涵义分析论文
- 一个数如果恰好等于它的因子之和,这个数就称为完数。例如6=1+2+3.编程 找出1000以内的所有完数
- 马化腾和张一鸣的灰度思维:普通人追求安全感,高手拥抱不确定性
- ValueError: Expected parameter scale of distribution Normal to satisfy the constraint GreaterThan
- Linux为fluent配置环境变量,Ubuntu 9.10下安装Fluent lnx86-6.3.26成功
- Selenium WebDriver API 进阶使用,模块化参数化进行自动化测试设计