OpenGL写的播放器 在播放高清文件的时候,有些电脑上会明显变慢

时间:2021-12-13 19:04:28
    如题,OpenGL不是很熟,应该是说是个新手,之前写了一个 基于ffmpeg+OpenGL的播放器,发现在播放高清文件的时候,在有些电脑上会变慢,跟踪代码发现主要耗时在glTexSubImage2D这个更新纹理的函数上面,差不多每一帧都花费了100+ms,不知道是不是我代码初始化部分有问题,请前辈们指教!
OpenGL部分,主要代码:
//设置像素格式
bool XXX::SetupPixelFormat(HWND hWndO)
{
hWnd = hWndO;
hDC = GetDC(hWnd);
PIXELFORMATDESCRIPTOR pfd = 
{
        sizeof(PIXELFORMATDESCRIPTOR),    // size of this pfd
        1,                               // version number
        PFD_DRAW_TO_WINDOW |            // support window
          PFD_SUPPORT_OPENGL |
  PFD_DOUBLEBUFFER,  // support OpenGL
        PFD_TYPE_RGBA,                   // RGBA type
        24,                              // 24-bit color depth
        0,  0,  0,  0,  0,  0,                // color bits ignored
        0,                               // no alpha buffer
        0,                               // shift bit ignored
        0,                               // no accumulation buffer
        0,  0,  0,  0,                      // accum bits ignored
        32,                              // 32-bit z-buffer
        0,                               // no stencil buffer
        0,                               // no auxiliary buffer
        PFD_MAIN_PLANE,                  // main layer
        0,                               // reserved
        0,  0,  0                         // layer masks ignored
    };

//选择硬件所支持的像素格式与 pfd 最接近的一个
    int nPixelformat;
    if ((nPixelformat = ChoosePixelFormat(hDC,   &pfd)) == 0 )
    {
        return FALSE;
    }

//设置已经匹配的像素格式
    if (SetPixelFormat(hDC, nPixelformat, &pfd) == FALSE)
    {
        return FALSE;
    }
hRC = wglCreateContext(hDC);          //获取渲染描述句柄,渲染不能夸线程使用(它是线程安全的)
    return TRUE;
}

bool XXX::Initialize(int width, int height)
{
wglMakeCurrent(hDC, hRC);             //激活渲染描述句柄

while(i_width < width || i_height < height)//根据视频文件的分辨率,来确定需要初始化多大的空纹理 {
if (i_width < width)
i_width = i_width * 2;
if (i_height < height)
i_height = i_height * 2;
}                        
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,/*GL_NEAREST*/GL_LINEAR);       //线性滤波
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,/*GL_NEAREST*/GL_LINEAR);       //线性滤波
glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_WRAP_S,  GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_WRAP_T,  GL_CLAMP);
  glEnable(GL_TEXTURE_2D);    
//生成空纹理
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, i_width, i_height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE,NULL );
glMatrixMode(GL_PROJECTION);    
glLoadIdentity();
gluOrtho2D(-1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glFlush();
return true;
}
//绘图函数
void XXX::Draw(unsigned char* data, int width, int height)
{
glClearColor(0.0f,0.0f,0.0f,0.0f);
GetClientRect(hWnd,&nRect);
         //播放窗口大小改变时
if (nWidth != (nRect.right-nRect.left) || nHeighth != (nRect.bottom-nRect.top) || g_poschanged) 
{
glViewport(0,0,(float)(nRect.right-nRect.left)*i_width/width,(float)(nRect.bottom-nRect.top)*i_height/height);
//glViewport(0,0,i_width,i_height);
nWidth = nRect.right-nRect.left;
nHeighth = nRect.bottom-nRect.top;
g_poschanged = false;
}
//更新纹理
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGR_EXT, GL_UNSIGNED_BYTE, data);
         glBegin(GL_QUADS);
  glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f,-1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f,1.0f);
  glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,1.0f);
  glEnd();
SwapBuffers(hDC);
}

11 个解决方案

#1


没人知道吗?
在线等啊……

#2


不懂opengl,慢的机器用的是集成显卡吗?

#3


是的,但是我在自己公司的电脑上测试的时候也是用的集成显卡,播放很正常,不正常的电脑应该显卡也不会很太低,因为他们说暴风、vlc这些去播放高清的时候是没问题,显卡性能应该是够了,不过不知道暴风和vlc是不是用directshow或者其它的去完成绘制的,现在就是不清楚使用OpenGL纹理的效率跟显卡性能的那些参数有关?比如显存?更新驱动是否有效?

#4


自己顶……

#5


该回复于2011-03-24 11:00:29被版主删除

#6


如果使用纯然件解码,播放高清对机器性能要求很高,除非使用显卡的硬件加速功能,这样可以提高很多效率,OPENGL的画只是显示部分,不知道你解码器是软件还是硬件

#7


解码是用的ffmpeg软解,但我在代码中加过日志打印的,解码一帧高清的视频,花费的时间在20ms左右,这个是能达到正常播放要求的,主要花时在glTexSubImage2D()这个纹理更新函数上面,至于显卡的硬件加速,显卡的底层驱动已经做好了的吧?如果它支持对OpenGL的加速,是不是应该在使用一些OpenGL函数的时候,就会通过显卡去计算处理,从而达到加速的效果?不知道这样理解对不对……底层的东西不了解啊 囧

#8


主要花时在glTexSubImage2D()这个纹理更新函数上面,可能是函数调用的设置部队,或者重复了某些调用导致效率底下,建议使用D3D API

#9


加入一个opengl的显示列表,它会自动优化显示过程中的矩阵运算,加快显示速度

#10


引用 8 楼 oexpress 的回复:
主要花时在glTexSubImage2D()这个纹理更新函数上面,可能是函数调用的设置部队,或者重复了某些调用导致效率底下,建议使用D3D API


恩,我也怀疑设置不对,用D3D不能实现跨平台。。我再找找解决办法,还是要谢谢你哈!

#11


引用 9 楼 csuestc 的回复:
加入一个opengl的显示列表,它会自动优化显示过程中的矩阵运算,加快显示速度


opengl的显示列表是不是 就是把很多小数据,拼成一个大数据,一次性显示? 我是用来绘制视频帧,数据是不停变化的,可行吗?

#1


没人知道吗?
在线等啊……

#2


不懂opengl,慢的机器用的是集成显卡吗?

#3


是的,但是我在自己公司的电脑上测试的时候也是用的集成显卡,播放很正常,不正常的电脑应该显卡也不会很太低,因为他们说暴风、vlc这些去播放高清的时候是没问题,显卡性能应该是够了,不过不知道暴风和vlc是不是用directshow或者其它的去完成绘制的,现在就是不清楚使用OpenGL纹理的效率跟显卡性能的那些参数有关?比如显存?更新驱动是否有效?

#4


自己顶……

#5


该回复于2011-03-24 11:00:29被版主删除

#6


如果使用纯然件解码,播放高清对机器性能要求很高,除非使用显卡的硬件加速功能,这样可以提高很多效率,OPENGL的画只是显示部分,不知道你解码器是软件还是硬件

#7


解码是用的ffmpeg软解,但我在代码中加过日志打印的,解码一帧高清的视频,花费的时间在20ms左右,这个是能达到正常播放要求的,主要花时在glTexSubImage2D()这个纹理更新函数上面,至于显卡的硬件加速,显卡的底层驱动已经做好了的吧?如果它支持对OpenGL的加速,是不是应该在使用一些OpenGL函数的时候,就会通过显卡去计算处理,从而达到加速的效果?不知道这样理解对不对……底层的东西不了解啊 囧

#8


主要花时在glTexSubImage2D()这个纹理更新函数上面,可能是函数调用的设置部队,或者重复了某些调用导致效率底下,建议使用D3D API

#9


加入一个opengl的显示列表,它会自动优化显示过程中的矩阵运算,加快显示速度

#10


引用 8 楼 oexpress 的回复:
主要花时在glTexSubImage2D()这个纹理更新函数上面,可能是函数调用的设置部队,或者重复了某些调用导致效率底下,建议使用D3D API


恩,我也怀疑设置不对,用D3D不能实现跨平台。。我再找找解决办法,还是要谢谢你哈!

#11


引用 9 楼 csuestc 的回复:
加入一个opengl的显示列表,它会自动优化显示过程中的矩阵运算,加快显示速度


opengl的显示列表是不是 就是把很多小数据,拼成一个大数据,一次性显示? 我是用来绘制视频帧,数据是不停变化的,可行吗?