要打开xvideothread(初始化播放控件需要将其抽象类传进来),xaudiothread,xedmux,
将testtread类封装到解封装线程中
1.xdemuxthread.h
#pragma once
#include<qthread.h>
#include<mutex>
#include"ivideocall.h"
#include"xdemux.h"
#include"xaudiothread.h"
#include"xvideothread.h"
class xdemuxthread:public QThread
{
public:
virtual bool open(const char* url,ivideocall *call);
//启动所有线程,创建对象并打开
virtual void start();
xdemuxthread();
virtual ~xdemuxthread();
void run();
protected:
xdemux *demux=0;
xvideothread *vt=0;
xaudiothread *at=0;
std::mutex mux;
bool isexit = false;
};
#include "xdemuxthread.h"
#include<iostream>
using namespace std;
void xdemuxthread::run()
{
while (!isexit)
{
mux.lock();
if (!demux)
{
mux.unlock();//若demux未打开则解锁让其他线程进来,等待5秒盼望demux能打开,然后再进行下次判断,判断demux是否打开
msleep(5);
continue;
}
AVPacket* pkt = demux->readfz();
if (!pkt)
{
//读到结尾了
mux.unlock();
msleep(5);
continue;
}
if (demux->isvideo(pkt))
{
if (vt)vt->push(pkt);
}
else
{
if (at)at->push(pkt);
}
mux.unlock();
}
}
xdemuxthread::xdemuxthread()
{
}
xdemuxthread::~xdemuxthread()
{
isexit = false;//调用析构后才停止当前线程
wait();
cout << "解封装线程退出" << endl;
}
bool xdemuxthread::open(const char* url, ivideocall* call)
{
mux.lock();
if (!demux)demux = new xdemux();
if (!vt)vt = new xvideothread();
if (!at)at = new xaudiothread();
bool re=demux->Open(url);
if (!re)
{
cout << "demux->open(url) failed!";
return false;
}
re = vt->open(demux->CopyVPara(),call,demux->width,demux->height);
if (!re)
{
cout << "vt->open(url) failed!";
re = false;
}
re = at->open(demux->CopyAPara(), demux->sampletrate, demux->channels);
if (!re)
{
cout << "at->open(url) failed!";
re = false;
}
mux.unlock();
cout << "xdemuxopen open:(1成功0失败)" << re << endl;
return true;
}
void xdemuxthread::start()
{
mux.lock();
QThread::start();//启动当前线程,调用当前类的run()
if (at)at->start();
if (vt)vt->start();
mux.unlock();
}
1.在open中打开音频线程与视频线程
2.当主函数调用解码线程的run时会调用xdemuxthread::start(),在该函数中调用音频线程的run与视频线程的run
3.在run中通过读封装获得packet,判断其类型,若是视频则push给视频线程的队列,若是音频则push给音频线程的队列
此时的main()函数得到了大大的简化:
using namespace std;
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Xplay2 w;
w.show();
xdemuxthread dt;
dt.open("E:\\ffmpeg\\test222.mp4",w.ui.openGLWidget);
dt.start();
return a.exec();
}