//nv12render.cpp #include "nv12render.h" #include#include #include"debug.h" #include"RKbaseFunc.h" #include #if 1 void Nv12Render::initialize() { initializeOpenGLFunctions(); glClearColor(0.0f,0.0f,0.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT); const char *vsrc = " attribute vec4 vertexIn; attribute vec4 textureIn; varying vec4 textureOut; void main(void) { gl_Position = vertexIn; textureOut = textureIn; }"; //Hi3536的openGL ES2着色器必须要先设置精度 const char *fsrc = " precision mediump float; varying mediump vec4 textureOut; uniform sampler2D textureY; uniform sampler2D textureUV; void main(void) { vec3 yuv; vec3 rgb; yuv.x = texture2D(textureY, textureOut.st).r - 0.0625; yuv.y = texture2D(textureUV, textureOut.st).r - 0.5; yuv.z = texture2D(textureUV, textureOut.st).g - 0.5; rgb = mat3( 1, 1, 1, 0, -0.39465, 2.03211, 1.13983, -0.58060, 0) * yuv; gl_FragColor = vec4(rgb, 1); }"; program.addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,vsrc); program.addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,fsrc); program.link(); GLfloat points[]{ -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 0.0f,0.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f,1.0f }; vbo.create(); vbo.bind(); vbo.allocate(points,sizeof(points)); GLuint ids[2]; glGenTextures(2,ids); idY = ids[0]; idUV = ids[1]; // 创建1个缓冲区 // glGenBuffers(1, &m_Buffer); // glBindBuffer(GL_ARRAY_BUFFER, m_Buffer); // glBufferData(GL_ARRAY_BUFFER, 1920*1088*3/2, NULL, GL_DYNAMIC_COPY); // glBindBuffer(GL_ARRAY_BUFFER, 0); #if 0 #if 1 m_pNV12Buffer = new unsigned char[1920*1088*3/2]; #else #if 0 void* m_pframeBuffer = CRKbaseFunc::RK_GetMPPBuffer(1920*1088*3/2); //m_pNV12Buffer = (unsigned char*)CRKbaseFunc::RK_GetVideoBufferPtr(m_pframeBuffer); m_pNV12Buffer = (uint8_t *)mmap(0, 1920*1088*3/2, PROT_READ | PROT_WRITE, MAP_SHARED, CRKbaseFunc::RK_GetVideoBufferFd(m_pframeBuffer), 0); #else m_pDrmMemCtrl = IDRMMemCtrl::Create(); RKDRM_MEM_INFO memInfo; memset(&memInfo, 0, sizeof(RKDRM_MEM_INFO)); memInfo.nSize = 1920 * 1088 * 2; m_pDrmMemCtrl->DRMAlloc(memInfo); m_pNV12Buffer = (unsigned char*)memInfo.vitualPtr; #endif #endif #endif #if 1 m_pOpenglBuffer[0] = new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer); m_pOpenglBuffer[0]->create(); m_pOpenglBuffer[0]->bind(); m_pOpenglBuffer[0]->allocate(1920*1088); m_pOpenglBuffer[0]->release(); m_pOpenglBuffer[1] = new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer); m_pOpenglBuffer[1]->create(); m_pOpenglBuffer[1]->bind(); m_pOpenglBuffer[1]->allocate(1920*1088/2); m_pOpenglBuffer[1]->release(); #endif } #endif void Nv12Render::render(uchar *nv12Ptr, int w, int h) { if(!nv12Ptr)return; #if 0 memcpy(m_pNV12Buffer,nv12Ptr,1920*1088*3/2); uchar* pNv12Data = m_pNV12Buffer; // memset(pNv12Data,0,1920*1088*3/2); #else uchar* pNv12Data = nv12Ptr; #endif RAIITimer time123("Nv12Render::render"); // glClearColor(0.5f, 0.5f, 0.7f, 1.0f); // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // glDisable(GL_DEPTH_TEST); program.bind(); vbo.bind(); program.enableAttributeArray("vertexIn"); program.enableAttributeArray("textureIn"); program.setAttributeBuffer("vertexIn",GL_FLOAT, 0, 2, 2*sizeof(GLfloat)); program.setAttributeBuffer("textureIn",GL_FLOAT,2 * 4 * sizeof(GLfloat),2,2*sizeof(GLfloat)); m_pOpenglBuffer[0]->bind(); void* buffer_data = m_pOpenglBuffer[0]->map(QOpenGLBuffer::ReadWrite); memcpy(buffer_data,nv12Ptr,1920*1088); m_pOpenglBuffer[0]->unmap(); glActiveTexture(GL_TEXTURE0 + 1); //测试发现使用"+ 0"会异常 glBindTexture(GL_TEXTURE_2D,idY); 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); // glTexImage2D(GL_TEXTURE_2D,0,GL_RED,w,h,0,GL_RED,GL_UNSIGNED_BYTE,pNv12Data); glTexImage2D(GL_TEXTURE_2D,0,GL_RED,w,h,0,GL_RED,GL_UNSIGNED_BYTE,NULL); m_pOpenglBuffer[1]->bind(); buffer_data = m_pOpenglBuffer[1]->map(QOpenGLBuffer::ReadWrite); memcpy(buffer_data,nv12Ptr+1920*1088,1920*1088/2); m_pOpenglBuffer[1]->unmap(); glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D,idUV); 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); // glTexImage2D(GL_TEXTURE_2D,0,GL_RG,w >> 1,h >> 1,0,GL_RG,GL_UNSIGNED_BYTE,pNv12Data + w*h); glTexImage2D(GL_TEXTURE_2D,0,GL_RG,w >> 1,h >> 1,0,GL_RG,GL_UNSIGNED_BYTE,NULL); program.setUniformValue("textureUV",0); program.setUniformValue("textureY",1); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); m_pOpenglBuffer[0]->release(); m_pOpenglBuffer[1]->release(); program.disableAttributeArray("vertexIn"); program.disableAttributeArray("textureIn"); program.release(); }



