7 Star 12 Fork 6

默认组织 / FFmpeg显示本地视频帧

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
videoopenglwidget.cpp 3.77 KB
一键复制 编辑 原始数据 按行查看 历史
#include "videoopenglwidget.h"
#include <QOpenGLShaderProgram>
#include <QDebug>
VideoOpenGLWidget::VideoOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent),
xshift(0), yshift(0), wvideo(10), hvideo(10)
{
}
void VideoOpenGLWidget::initializeGL()
{
initializeOpenGLFunctions();
// glEnable(GL_DEPTH_TEST);
// //混合
// glEnable(GL_BLEND);
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//涂黑
glClearColor(0, 0, 0, 1);
QOpenGLShaderProgram program;
// Compile vertex shader
if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vshader.vert"))
close();
// Compile fragment shader
if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fshader.frag"))
close();
// Link shader pipeline
if (!program.link())
close();
// Bind shader pipeline for use
if (!program.bind())
close();
glUseProgram(program.programId());
// video texture
float vertices[] = {
// positions // texture coords(上下颠倒)
1.0f, 1.0f, 0.0f, 1.0f, 0.0f, // top right
1.0f, -1.0f, 0.0f, 1.0f, 1.0f, // bottom right
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, // bottom left
-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, // top left
};
unsigned int indices[] = {
// note that we start from 0!
0, 1, 3, // first triangle
1, 2, 3, // second triangle
};
// video
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// 解除绑定
glBindVertexArray(0);
}
void VideoOpenGLWidget::resizeGL(int w, int h)
{
if(mImage.isNull())
{
xshift = 0;
yshift = 0;
wvideo = w;
hvideo = h;
}
else
{
int w_img = mImage.width();
int h_img = mImage.height();
qreal rw = (qreal)w/(qreal)w_img;
qreal rh = (qreal)h/(qreal)h_img;
if(rw >= rh)
{
wvideo = w_img*rh;
hvideo = h;
xshift = (w - wvideo) / 2;
yshift = 0;
}
else
{
wvideo = w;
hvideo = h_img*rw;
xshift = 0;
yshift = (h - hvideo) / 2;
}
}
}
void VideoOpenGLWidget::paintGL()
{
glViewport(xshift, yshift, wvideo, hvideo);
// video
glBindVertexArray(VAO);
glBindTexture(GL_TEXTURE_2D, textureVideo);
if (!mImage.isNull())
{
const unsigned char *data1 = mImage.constBits();
// 生成一幅纹理,实际上,每帧都生成纹理的开销很大;
// 合理的做法应该只生成一次,之后的每帧用glSubTexImage2D上传纹理数据;
// 本例子仅仅作为技术验证和参考,不做进一步的优化
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
mImage.width(), mImage.height(), 0,
GL_BGR, GL_UNSIGNED_BYTE, data1);
glGenerateMipmap(GL_TEXTURE_2D);
}
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
void VideoOpenGLWidget::slotGetOneFrame(QImage img)
{
mQueue.enqueue(img);
}
void VideoOpenGLWidget::slotUpdate()
{
if(mQueue.isEmpty()) return;
mImage = mQueue.dequeue();
update(); //调用update将执行 paintEvent函数
}
C/C++
1
https://gitee.com/pplxlee/FFmpegXianShiBenDiShiPinZheng.git
git@gitee.com:pplxlee/FFmpegXianShiBenDiShiPinZheng.git
pplxlee
FFmpegXianShiBenDiShiPinZheng
FFmpeg显示本地视频帧
master

搜索帮助