当前位置:网站首页>Player practice 17 xvideowidget
Player practice 17 xvideowidget
2022-06-12 14:09:00 【Sister Suo】
int main(int argc, char *argv[])
{
testtread tt;
tt.init();
QApplication a(argc, argv);
Xplay2 w;
w.show();
w.ui.openGLWidget->Init(tt.demux.width, tt.demux.height);
tt.video = w.ui.openGLWidget;
tt.start();
return a.exec();
}
In actual combat 14 in , It is read directly yuv One fan divided into one request OpenGL Drawing :
fp = fopen(“out240x128.yuv”, “rb”);
Here we get it by decoding frame To draw
open .ui file , add to OpenGL Control :
Promote to class xvideowidget:
stay ui_Xplay2 You can see the following code in the file :
class Ui_Xplay2Class
{
public:
xvideowidget *openGLWidget;
void setupUi(QWidget *Xplay2Class)
{
if (Xplay2Class->objectName().isEmpty())
Xplay2Class->setObjectName(QString::fromUtf8("Xplay2Class"));
Xplay2Class->resize(1072, 790);
openGLWidget = new xvideowidget(Xplay2Class);
openGLWidget->setObjectName(QString::fromUtf8("openGLWidget"));
openGLWidget->setGeometry(QRect(149, 129, 800, 600));
retranslateUi(Xplay2Class);
QMetaObject::connectSlotsByName(Xplay2Class);
} // setupUi
void retranslateUi(QWidget *Xplay2Class)
{
Xplay2Class->setWindowTitle(QCoreApplication::translate("Xplay2Class", "Xplay2", nullptr));
} // retranslateUi
};
You can see xvideowidget *openGLWidget; Put a point in the big class of this interface xvideowidget The pointer to OpenGLwidget, And call with this pointer resize Other methods
Add... To the code xvideowidget.h:
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QGLShaderProgram>
#include <mutex>
struct AVFrame;
class xvideowidget : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
void Init(int width, int height);
// Whether successful or not, release frame Space
virtual void Repaint(AVFrame* frame);
xvideowidget(QWidget* parent);
~xvideowidget();
protected:
// Refresh the display
void paintGL();
// initialization gl
void initializeGL();
// Window size change
void resizeGL(int width, int height);
private:
std::mutex mux;
//shader Program
QGLShaderProgram program;
//shader in yuv Variable address
GLuint unis[3] = {
0 };
//openg Of texture Address
GLuint texs[3] = {
0 };
// Material memory space
unsigned char* datas[3] = {
0 };
int width = 0;
int height = 0;
};
xvideowidget.cpp And actual combat 14 The difference is the actual combat 14 The width and height of the lieutenant general are determined in advance , Here, the width and height are set according to the transmitted data , And provides a new interface , The purpose is to set the width and height , Allocate material memory space , Set the zoom in / out method :
void xvideowidget::Init(int width, int height)
{
mux.lock();
this->width = width;
this->height = height;
delete datas[0];
delete datas[1];
delete datas[2];
/// Allocate material memory space
datas[0] = new unsigned char[width * height]; //Y
datas[1] = new unsigned char[width * height / 4]; //U
datas[2] = new unsigned char[width * height / 4]; //V
if (texs[0])
{
glDeleteTextures(3, texs);
}
// Create materials
glGenTextures(3, texs);
//Y
glBindTexture(GL_TEXTURE_2D, texs[0]);
// Zoom in and filter , linear interpolation GL_NEAREST( Efficient , But mosaic is serious )
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Create material graphics card space
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
//U
glBindTexture(GL_TEXTURE_2D, texs[1]);
// Zoom in and filter , linear interpolation
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Create material graphics card space
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width / 2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
//V
glBindTexture(GL_TEXTURE_2D, texs[2]);
// Zoom in and filter , linear interpolation
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Create material graphics card space
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width / 2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
mux.unlock();
}
Because creating materials also uses height and width , So put it into this interface
Creating material graphics card space requires tex, Deleting will also delete tex, In order to prevent half of the application from being deleted, resulting in program downtime , Put a lock on it , Used by other functions data And tex And lock the , about repaint() This kind of frequent , Pay attention to the amount of code locked , Will affect performance , about init It doesn't matter if it only happens once
Reading and drawing will block , Therefore use QThread:
class testtread :public QThread
{
public:
void init()
{
const char* path = "E:\\ffmpeg\\test.mp4";
const char* url = "rtsp://27.22.78.122:8554/1";
cout << "demux.Open = " << demux.Open(path) << endl;
cout << "vdecode.open()" << vdecode.open(demux.CopyVPara()) << endl;
cout << "adecode.open()" << adecode.open(demux.CopyAPara()) << endl;
}
void run()
{
for (;;)
{
AVPacket* pkt = demux.readfz();
if (demux.isvideo(pkt) == true)
{
vdecode.send(pkt);
AVFrame* frame = vdecode.receive();
//cout << " Video decoding " <<frame<< endl;
video->Repaint(frame);
Sleep(40);
}
else
{
//adecode.send(pkt);
//AVFrame* frame = adecode.receive();
//cout << " Audio decoding " <<frame<< endl;
}
if (!pkt)break;
}
}
xdemux demux;
xvideowidget* video;
protected:
xdecode vdecode;
xdecode adecode;
};
Because after the main thread exits video Have been deleted , However, the thread is still , So there will be some small problems , We'll deal with it later
main function :
int main(int argc, char *argv[])
{
testtread tt;
tt.init();
QApplication a(argc, argv);
Xplay2 w;
w.show();
w.ui.openGLWidget->Init(tt.demux.width, tt.demux.height);
tt.video = w.ui.openGLWidget;
tt.start();
return a.exec();
}
1. Instantiate a thread ,
Instantiating a thread also instantiates demux,vdecode,adecode,xvideowidget*, And transmit the unpacked video information to vdecode, Audio information is transmitted to adecode
2. Open one QT The window of
3. Transmit the width and height information obtained by unpacking to ui The initialization function of the control added in the window , Give Way QT A video window with the same width and height as our media file can be displayed on the window , It just can't display the picture
tt Of demux And video,w Of ui Are all out of class accesses , So let's open these members to public
4. Let the point in the thread xvideowidget The pointer to the control we added , call start That is, the of the calling thread run, stay run Will be decoded in packet issue openg Draw and display on the control
void xvideowidget::Repaint(AVFrame* frame)
{
if (!frame)
{
qDebug() << "show failed1" ;
return;
}
mux.lock();
// Fault tolerance , Make sure the dimensions are correct
if (!datas[0] || width * height == 0 || frame->width != this->width || frame->height != this->height)
{
av_frame_free(&frame);
mux.unlock();
qDebug() << "show failed2";
return;
}
memcpy(datas[0], frame->data[0], width * height);
memcpy(datas[1], frame->data[1], width * height / 4);
memcpy(datas[2], frame->data[2], width * height / 4);
// Row alignment problem
mux.unlock();
// Refresh the display
update();
qDebug()<< "repaint" ;
}
The operation is as follows :
边栏推荐
猜你喜欢

Paw advanced user guide

Shell脚本到底是什么高大上的技术吗?

【mysql进阶】索引分类及索引优化方案(五)

阿里云开发板HaaS510连接物联网平台--HaaS征文

Redis核心配置和高级数据类型

浅谈中国程序员为什么要跳槽?
![[early knowledge of activities] list of recent activities of livevideostack](/img/d8/a367c26b51d9dbaf53bf4fe2a13917.png)
[early knowledge of activities] list of recent activities of livevideostack

For cross-border e-commerce, the bidding strategy focusing more on revenue - Google SEM

Alibaba cloud development board haas510 submission device attributes

Display logs in the database through loganalyzer
随机推荐
Leetcode 2176. Count equal and divisible pairs in an array
高考回忆录
Mémoire de l'examen d'entrée à l'université
Pay attention to click and pursue more users to enter the website. What bidding strategy can you choose?
Reverse analysis from x86 to x64tips
Display logs in the database through loganalyzer
Dismantle and modify the advertising machine - Amateur decompression
How to realize the bidding strategy that pays more attention to transformation in the company's operation Google sem
肝了一个月的原创小袁个人博客项目开源啦(博客基本功能都有,还包含后台管理)
Lua callinfo structure, stkid structure resolution
Void pointer (void*) usage
3. Process concealment under the ring ----- continuous concealment and new opening prevention
Wait function in SystemC
基于Profibus-DP协议的PLC智能从站设计
SystemC learning materials
Byte order data read / write
969. pancake sorting
Notepad common settings
What is automatic bidding? What are its advantages?
高考回憶錄