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);
相关推荐
侃侃_天下3 天前
最终的信号类
开发语言·c++·算法
echoarts3 天前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix3 天前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
每天回答3个问题3 天前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
伍哥的传说3 天前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔3 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
我是菜鸟0713号3 天前
Qt 中 OPC UA 通讯实战
开发语言·qt
JCBP_3 天前
QT(4)
开发语言·汇编·c++·qt·算法
Brookty3 天前
【JavaEE】线程安全-内存可见性、指令全排序
java·开发语言·后端·java-ee·线程安全·内存可见性·指令重排序
百锦再3 天前
[特殊字符] Python在CentOS系统执行深度指南
开发语言·python·plotly·django·centos·virtualenv·pygame