QT基于Gstreamer采集的简单示例

我们在终端敲指令可以使用gstreamer方式去采集,如下所示,按1920*1080分辨率,60帧方式采集video0的视频。

复制代码
gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw, width=1920, height=1080, framerate=60/1 ! videoconvert ! autovideosink

敲完指令后会自动弹出一个显示窗口,那么如何让gstreamer与QT结合,使得视频显示在指定的QT窗体里呢。

首先我们把gst采集部分封装一下,可传入参数视频设备,分辨率,帧率等,同时包含一个用于显示的QWidget。

下边是头文件

复制代码
class gstWidget : public QWidget
{
    Q_OBJECT

public:
    gstWidget(std::string device,int width,int height,int framerate,QWidget *parent = nullptr);
    ~gstWidget();

private:
    GstElement *pipeline;
    void startGStreamer(std::string device,int width,int height,int framerate);
};

下边是源文件

复制代码
gstWidget::gstWidget(std::string device,int width,int height,int framerate,QWidget *parent)
    : QWidget(parent)
{
    gst_init(nullptr, nullptr);
    startGStreamer(device,width,height,framerate);
}

gstWidget::~gstWidget()
{
    if (pipeline) {
        gst_element_set_state(pipeline, GST_STATE_NULL);
        gst_object_unref(pipeline);
    }
}

void gstWidget::startGStreamer(std::string device,int width,int height,int framerate)
{
     std::string pipeline_str = "v4l2src device=" + device + " ! "
     "video/x-raw,width="+std::to_string(width)+",height="+ std::to_string(height)+",framerate="+std::to_string(framerate)+"/1 ! "
     "xvimagesink name=xvimagesink ";

    pipeline = gst_parse_launch(pipeline_str.c_str(), nullptr);

    WId winId = this->winId();
    GstElement* xv_sink = gst_bin_get_by_name(GST_BIN(pipeline), "xvimagesink");
    g_object_set(xv_sink, "force-aspect-ratio", true, NULL);
    if (xv_sink) {
        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(xv_sink), (guintptr)winId);
    } else {
        qDebug() << "Failed to get xvimagesink element.";
    }

    gst_element_set_state(pipeline, GST_STATE_PLAYING);
}

后续如果要使用只需要调用gstWidget创建窗口即可,下边是一个使用示意,构造了一个带标题的cam显示窗口。

首先是头文件

复制代码
class camWidget : public QWidget
{
    Q_OBJECT

public:
    camWidget(std::string device,QString title,int width,int height,int framerate,QWidget *parent = nullptr);
    ~camWidget();

public:
    gstWidget *camDisp;

private:
    QLabel *title_label;
};

然后是源文件

复制代码
camWidget::camWidget(std::string device,QString title,int width,int height,int framerate,QWidget *parent)
    : QWidget(parent)
{
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    camDisp=new gstWidget(device,width,height,framerate,this);

    mainLayout->addWidget(camDisp);
    setLayout(mainLayout);

    title_label=new QLabel(this);

    title_label->setAlignment(Qt::AlignCenter);
    title_label->setStyleSheet("background: transparent; color: #FFFFFF");
    title_label->setText(title);
}
camWidget::~camWidget()
{
}

接下来是真正的应用,在这里创建一个video0的显示窗口,标题为"cam",按1920*1080分辨率60帧去采集,显示窗口的大小为640*480。

复制代码
camWidget cam=new camWidget("/dev/video0","cam",1920,1080,60,this);
cam->setGeometry(0,0,640,480);
相关推荐
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1234 天前
matlab画图工具
开发语言·matlab
dustcell.4 天前
haproxy七层代理
java·开发语言·前端
norlan_jame4 天前
C-PHY与D-PHY差异
c语言·开发语言
多恩Stone4 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ4022054964 天前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
遥遥江上月4 天前
Node.js + Stagehand + Python 部署
开发语言·python·node.js
m0_531237174 天前
C语言-数组练习进阶
c语言·开发语言·算法
Railshiqian4 天前
给android源码下的模拟器添加两个后排屏的修改
android·开发语言·javascript
雪人不是菜鸡4 天前
简单工厂模式
开发语言·算法·c#