用QOpenGLwidget播放本地yuv文件
时间: 2023-12-10 16:39:01 浏览: 59
可以使用OpenGL来播放本地yuv文件,具体步骤如下:
1. 创建一个继承自QOpenGLWidget的类,并在其构造函数中初始化OpenGL相关设置:
```cpp
class YUVPlayer : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
YUVPlayer(QWidget *parent = nullptr);
~YUVPlayer();
protected:
void initializeGL() override;
void paintGL() override;
void resizeGL(int w, int h) override;
void cleanupGL() override;
private:
GLuint m_textureY;
GLuint m_textureU;
GLuint m_textureV;
GLsizei m_videoWidth;
GLsizei m_videoHeight;
};
```
```cpp
YUVPlayer::YUVPlayer(QWidget *parent)
: QOpenGLWidget(parent)
{
// 初始化OpenGL函数
initializeOpenGLFunctions();
// 设置背景色
glClearColor(0, 0, 0, 1);
// 创建纹理
glGenTextures(1, &m_textureY);
glGenTextures(1, &m_textureU);
glGenTextures(1, &m_textureV);
}
```
2. 在initializeGL()函数中加载yuv文件,创建纹理并绑定到对应的纹理单元上:
```cpp
void YUVPlayer::initializeGL()
{
// 加载yuv文件
QFile file("test.yuv");
if (!file.open(QIODevice::ReadOnly))
return;
QByteArray data = file.readAll();
file.close();
m_videoWidth = 640;
m_videoHeight = 480;
// 创建纹理
glBindTexture(GL_TEXTURE_2D, m_textureY);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_videoWidth, m_videoHeight, 0, GL_RED, GL_UNSIGNED_BYTE, data.data());
glBindTexture(GL_TEXTURE_2D, m_textureU);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_videoWidth / 2, m_videoHeight / 2, 0, GL_RED, GL_UNSIGNED_BYTE, data.data() + m_videoWidth * m_videoHeight);
glBindTexture(GL_TEXTURE_2D, m_textureV);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_videoWidth / 2, m_videoHeight / 2, 0, GL_RED, GL_UNSIGNED_BYTE, data.data() + m_videoWidth * m_videoHeight * 5 / 4);
// 设置纹理过滤方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 绑定纹理单元
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textureY);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_textureU);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, m_textureV);
}
```
3. 在paintGL()函数中绘制纹理:
```cpp
void YUVPlayer::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
// 绑定纹理并绘制
glBindTexture(GL_TEXTURE_2D, m_textureY);
glActiveTexture(GL_TEXTURE0);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex3f(-1, -1, 0);
glTexCoord2i(1, 0); glVertex3f(1, -1, 0);
glTexCoord2i(1, 1); glVertex3f(1, 1, 0);
glTexCoord2i(0, 1); glVertex3f(-1, 1, 0);
glEnd();
glBindTexture(GL_TEXTURE_2D, m_textureU);
glActiveTexture(GL_TEXTURE1);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex3f(-1, -1, 0);
glTexCoord2i(1, 0); glVertex3f(1, -1, 0);
glTexCoord2i(1, 1); glVertex3f(1, 1, 0);
glTexCoord2i(0, 1); glVertex3f(-1, 1, 0);
glEnd();
glBindTexture(GL_TEXTURE_2D, m_textureV);
glActiveTexture(GL_TEXTURE2);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex3f(-1, -1, 0);
glTexCoord2i(1, 0); glVertex3f(1, -1, 0);
glTexCoord2i(1, 1); glVertex3f(1, 1, 0);
glTexCoord2i(0, 1); glVertex3f(-1, 1, 0);
glEnd();
}
```
4. 在resizeGL()函数中设置视口:
```cpp
void YUVPlayer::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
```
5. 在程序中创建YUVPlayer类的对象,并显示:
```cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
YUVPlayer player;
player.show();
return a.exec();
}
```
这样就可以使用OpenGL来播放本地yuv文件了。
阅读全文