xcamera_widget.h
class XCameraWidget :public QWidget
{
Q_OBJECT
public:
XCameraWidget(QWidget* p = nullptr);
//渲染视频
void Draw();//123
//清理资源,再一个窗口被覆盖后 清理之前窗口生成的资源1
~XCameraWidget();//123
private:
XDecodeTask* decode_ = nullptr;//123
XDemuxTask* demux_ = nullptr;
XVideoView* view_ = nullptr;
};
xcamera_widget.cpp
XCameraWidget::XCameraWidget(QWidget* p) :QWidget(p)
{
//接收拖拽
this->setAcceptDrops(true);
}
//拖拽松开
void XCameraWidget::dropEvent(QDropEvent* e)
{
//拿到url
qDebug() << e->source()->objectName();
auto wid = (QListWidget*)e->source();
qDebug() << wid->currentRow();
auto cam = XCameraConfig::Instance()->GetCam(wid->currentRow());
Open(cam.sub_url);
}
bool XCameraWidget::Open(const char* url)
{
if (demux_)
demux_->Stop();
if (decode_)
decode_->Stop();
//打开解封装线程
demux_ = new XDemuxTask();
if (!demux_->Open(url))
{
return false;
}
//打开视频解码器线程
decode_ = new XDecodeTask();
auto para = demux_->CopyVideoPara();
if (!decode_->Open(para->para))
{
return false;
}
//设定解码线程接收解封装数据
demux_->set_next(decode_);
//初始化渲染参数
view_ = XVideoView::Create();
view_->set_win_id((void*)winId());
view_->Init(para->para);
//启动解封装和解码线程
demux_->Start();
decode_->Start();
return true;
}
//渲染视频
void XCameraWidget::Draw()
{
if (!demux_ || !decode_ || !view_)return;
auto f = decode_->GetFrame();
if (!f)return;
view_->DrawFrame(f);
XFreeFrame(&f);
}
//清理资源
XCameraWidget::~XCameraWidget()
{
if (demux_)
{
demux_->Stop();
delete demux_;
demux_ == nullptr;
}
if (decode_)
{
decode_->Stop();
delete decode_;
decode_ == nullptr;
}
if (view_)
{
view_->Close();
delete view_;
view_ = nullptr;
}
}
xviewer.h
public:
//定时器渲染视频 回调函数
void timerEvent(QTimerEvent* ev) override;//123
xviewer.cpp
//定时器渲染视频 回调函数
void XViewer::timerEvent(QTimerEvent* ev)//123
{
//总窗口数量
int wid_size = sizeof(cam_wids) / sizeof(QWidget*);
for (int i = 0; i < wid_size; i++)
{
if (cam_wids[i])
{
//渲染多窗口视频
cam_wids[i]->Draw();
}
}
}
在xviewer的构造函数中最后一行添加 startTimer(1);即可启动计时器调用timerEvent函数来进行渲染