基于Qt、FFMpeg的音视频播放器设计三(Qt界面设计及OpenGL绘制视频)

2023-05-16

本部分总结了一下界面绘制和OpenGL绘制视频,由于使用的是Qt的openGL,功能上没有那么复杂,实现起来也比较简单,毕竟人家已经给封好的,完整的代码中使用OpenGL绘制视频,对数据的顶点shader、片元shader着色,对yuv材质的绑定,分配材质内存空间、创建材质显卡空间、纹理以及显卡绘制每帧视频时如何对齐等等一些内容,这部分内容是OpenGL中的,较为复杂,待继续学习后有一定收获再来总结,现在我们继续看这里。

一、基于QT的播放器界面绘制

在做opengl绘制视频前,我们先需要设计一个界面,打开vs2013中该项目中的ui,进入Qt设计界面,设置好界面的属性后,在我们绘制视频时,可以选择3D引擎UX,或者OpenGL,但在这里我们用Qt自带的OpenGL。选择Qt的控件Open GL Widget,在界面中绘制一片区域,设置大小以及属性,之后加入两个按钮控件为打开文件和播放视频,加入相对应的图标,如何加入,网上有很多方法,这里就不啰嗦了,主要得知道这里两个按钮的变量名为openButton和playButton,后面需要用到的。

二、通过QT显示转码后的RGB数据

现在我们需要将FFMpeg解码后的视频播放出来,如何播放?在上面中我们创建了窗口openGLWidget,这里我们重载这个类(是对象openGLWidget的类QOpenGLWidget,重载的是这个类),然后使用我们自己的方法来控制这个窗口。这里我将QOpenGLWidget类提升为VideoWidget类。

然后我们在VS2013中用类向导创建该类进行实现(要继承自QOpenGLWidget)。首先在VideoWidget.h中申明定时器和窗口的重新绘制的函数。

#pragma once
#include <QtWidgets/qwidget.h>
#include <QOpenGLWidget>

class VideoWidget:public QOpenGLWidget
{
public:
	VideoWidget(QWidget *parent = NULL);

	void paintEvent(QPaintEvent *event);//窗口的重新绘制
	void timerEvent(QTimerEvent *event);//定时器
	virtual ~VideoWidget();
};

对于paintEvent的定义,我们知道绘制时需要FFMpeg解码出来的视频帧,而对于解封装、解码我们都在XFFMpeg类中完成,这里我们需要使用它。而在VideoWidget的构造函数里需要打开视频,同时设置定制器来显示播放,目前这是测试阶段,我们就先考虑单线程,播放时有些卡顿,当然后面我们会使用多线程解决这一问题,现在我们看下paintEvent的定义。

void VideoWidget::paintEvent(QPaintEvent *e)
{//绘制
	static QImage *image = NULL;

	if (image == NULL)
	{
		uchar *buf = new uchar[width()*height() * 4];//存放解码后的视频空间
		image = new QImage(buf, width(), height(), QImage::Format_ARGB32);
	}

	AVPacket pkt = XFFmpeg::Get()->Read();//读取视频帧
	if (pkt.stream_index != XFFmpeg::Get()->videoStream)
	{//不为视频帧,释放pkt的空间
		av_packet_unref(&pkt);
		return;
	}
	if (pkt.size == 0) return;

	AVFrame *yuv = XFFmpeg::Get()->Decode(&pkt);//解码读取到的视频帧
	av_packet_unref(&pkt);//解码成后也需要释放空间
	if (yuv == NULL) return;

	//将解码后的视频帧转化为RGB
	XFFmpeg::Get()->ToRGB(yuv, (char *)image->bits(),width(),height());


	QPainter painter;//hua
	painter.begin(this);
	painter.drawImage(QPoint(0, 0), *image);//绘制FFMpeg解码后的视频
	painter.end();//


}

XFFMpeg的读取、解码、转换为RGB在之前我们也都说明过。这里要说下的可能就是

if (image == NULL)
           {
              uchar *buf = new uchar[width()*height() * 4];//存放解码后的视频空间
              image = new QImage(buf, width(), height(), QImage::Format_ARGB32);
           }

这里的buf用来后面对于解码后的视频帧绘制时用到的,开辟的空间后*4是RGB有三个色彩同时这里还有一个通道数,共占用了四个字节,后面的image 的格式 QImage::Format_ARGB32也选择了32位的设置,都对应了在XFFMPeg中解码以及转化RGB格式时所设置的一些参数。

后面就是它的构造函数以及定时器函数,里面也都比较简单。

VideoWidget::VideoWidget(QWidget *parent) :QOpenGLWidget(parent)
{
	XFFmpeg::Get()->Open("1080.mp4");//打开视频
	startTimer(10);//设置定时器
}
void VideoWidget::timerEvent(QTimerEvent *event)
{
	this->update();//定时器更新
}

对于这部分内容大概就这么多,绘制基本如此,下一篇中我们进行视频播放进度控制,处理之前的卡顿现象。

下一篇链接:https://blog.csdn.net/hfuu1504011020/article/details/82705890

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于Qt、FFMpeg的音视频播放器设计三(Qt界面设计及OpenGL绘制视频) 的相关文章

  • SpringBoot集成Ehcache缓存

    SpringBoot集成Ehcache缓存 Ehcache有两种缓存方式 xff0c 分别是堆内存 磁盘 xff08 非堆内存 xff09 一 堆内存缓存 也就是MemoryStore xff0c 速度最快 xff0c 不适合存放大量数据
  • Spring的切面编程(AOP)概念与使用AOP实现日志记录

    Spring的切面编程 xff08 AOP xff09 概念与使用 一 面向切面编程 定义 面向切面编程 xff08 AOP xff09 是通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术 作用 xff1a 利用AOP对业务
  • 关于intrins.h头文件的介绍

    在单片机中应用最多的当然就是移位函数 xff0c 利用移位函数可以更简便的实现流水灯等效果 移位函数 移位函数名 左移 span class token function crol span span class token punctua
  • 大批量数据分批批量插入或更新(Mybatis+MySQL)

    大批量数据分批批量插入或更新 在MySQL数据库的前提下 xff0c 插入或更新大批量数据 首先批量插入需要考虑到以下几个因素 xff1a 数据库一次可以承受多大或者多少条数据的插入批量插入是否会占用Mysql资源太久 xff0c 影响系统
  • VSCode配置C++开发环境

    更新细节 2020 7 3 更新细节及排版 2022 6 9 昨天从下午一直研究到晚上十一点 xff0c 查阅了很多博客资料 xff0c 还是没配置好VSCode的C 43 43 开发环境 xff0c 今天早上又弄了一下 xff0c 现在O
  • stm32模拟输出PPM信号

    PPM信号周期为20ms xff0c 分成10分代表10个通道信号 xff0c 也就是2ms代表一个信号 0 5ms代表一个通道信号的开始 xff0c 所以0 5ms 2ms为通道范围控制 LED p1 39 A 39 8 IO口初始化 x
  • 使用JSON.parse,解决ie6-7上JSON未定义问题

    使用JSON parse时出现JSON未定义问题 xff0c JSON不是标准的javascript类型 xff0c 一些高级的浏览器支持 xff0c 但一些老一点的浏览器不支持JSON 如ie6 7 若需要 ie6 7 支持JSON只需要
  • C语言中的大小端转换与高低位颠倒

    在说大小端高低位之前 xff0c 肯定要说明数据在计算机内是如何存储的 在计算机中 xff0c 我们将数据分割成了一个一个的字节 xff08 byte xff09 xff0c 而每个字节又有8位 xff08 bit xff09 一个字节 x
  • C语言库函数中的Strcat函数

    一 Strcat函数的参数 Strcat函数所引用的头文件是 lt string h gt char strcat char strDestination const char strSource 参数说明 xff1a strDestina
  • SLAM中的marginalization 和 Schur complement

    在视觉SLAM的很多论文中 xff0c 会大量或者偶尔出现marginalization这个词 翻译为边缘化 xff0c 有的论文是特地要用它 xff0c 比如sliding window slam 2 okvis 3 dso 4 而有的论
  • 数据结构之单链表循环

    单链表循环代码如下 xff1a include lt stdio h gt include lt stdlib h gt typedef struct node int data struct node next sqlist sqlist
  • 数据结构之双链表循环

    定义是 xff1a 每个数据结点都有两个指针 xff0c 分别指向直接后继和直接前驱 因此双向链表中单任意一个结点开始 xff0c 都可以很方便的访问它的前驱结点和后继结点 循环链表指 xff1a 最后一个结点next指向头结点 xff0c
  • linux学习之进程

    进程概念 xff1a 活跃度程序 xff0c 占用系统资源 xff0c 在内存中执行产生一个进程 孤儿进程 xff1a 父进程先于子进程结束 xff0c 则子进程称为孤儿进程 xff0c 并且这个子进程被init进程回收 include l
  • 使用libcurl实现http通信——post上传数据并获取response

    接口释义 使用libcurl实现http通信 get获取response 代码实现 size t span class token function responseStr span span class token punctuation
  • C语言学习之sprintf

    sprintf函数介绍 xff1a 该函数原型为 xff1a int sprintf char str const char format 该函数的功能为 xff1a 本该输出到显示上的数据 xff0c 改为输出到str所指导内存空间中 x
  • linux学习之存储器

    存储器的种类 xff1a 分为易失性存储器和非易失性存储器 易失性存储器 掉电数据会丢失 读写速度快 xff1a RAM random access memory 随机存储内存 又分为DRAM xff08 动态随机存储内存 xff09 和S
  • HTTP请求报文(请求行、请求头、请求体)

    HTTP协议 1 简介 HTTP协议 xff08 Hyper Text Transfer Protocol xff0c 超文本传输协议 xff09 是用于从万维网 xff08 WWW World Wide Web xff09 服务器传输超文
  • UART详解

    UART 通用异步收发传输器 xff08 Universal Asynchronous Receiver Transmitter xff0c 通常称作UART 是一种异步全双工串行通信协议 xff0c 它将要传输的资料在串行通信与并行通信之
  • 基于STM32的NB-IoT模块驱动

    一 概述 目前这个NB IoT在国内还是比较火的 xff0c 最近刚好使用了一款NB IoT模块 将驱动程序贡献给大家 希望能对用到的朋友有点帮助 二 NB IoT模块介绍 本次采用的是有人物联网公司的WHNB75模块 xff08 支持电信
  • 将十六进制转换为对应的字符串,将字符串转换为对应的十六进制字符串,

    功能 xff1a 将输入的字符串转成对应的HEX 16进制格式 作者 xff1a 贺远 日期 xff1a 2019 05 15 参数 xff1a hexdata 要转换的HEX数字 n 字符串长度 xff0c buff 输出缓存区 返回值

随机推荐