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);
相关推荐
nice_lcj5202 小时前
Java Lambda 表达式入门:怎么写、怎么用、常用方法有哪些
java·开发语言·后端·面试
码农小河662 小时前
基于SSM+JSP+MySQL的在线医疗服务系统的设计与实现
java·开发语言·mysql
nice_lcj5206 小时前
ThreadLocal 入门:它是怎么隔离数据的、为什么会导致内存泄漏
java·开发语言·后端·面试·并发编程·内存泄漏·threadlocal
紧跟先前的步伐7 小时前
Go AI Agent 实战 28|Agent 的预算、超时与停止条件
开发语言·人工智能·后端·ai·golang
bksczm8 小时前
InnoDB 行格式详解:DYNAMIC / COMPACT / COMPRESSED / REDUNDANT
java·开发语言·数据库
春涧草茶8 小时前
慢就是快16-1协程
开发语言·前端·python
Dovis(誓平步青云)9 小时前
启元 T1 Pro 人机相声搭档:语音-触摸双通道的启元机器人节奏引擎设计
开发语言·前端·javascript·microsoft·交互
做科研的周师兄9 小时前
【R语言实战】MixSIAR 氢氧同位素水源解析全流程:从混合空间校验到贝叶斯 MCMC 收敛诊断(后附完整代码)
java·大数据·开发语言
.痞老板.10 小时前
java ee--计算机是如何工作的
java·开发语言·java-ee
奇树谦10 小时前
Qt Quick 图片加载与 GPU 纹理机制详解:QImage、QQuickTextureFactory、QSGTexture 与异步加载
开发语言·qt·系统架构