如何在 qwidget 中使用 GstElement 和 udpsrc 进行 gstreamer 流式传输

Posted

技术标签:

【中文标题】如何在 qwidget 中使用 GstElement 和 udpsrc 进行 gstreamer 流式传输【英文标题】:How to do gstreamer streaming using GstElement and udpsrc in qwidget 【发布时间】:2018-07-26 06:09:57 【问题描述】:

我正在尝试使用udpsrc 在 qwidget 中嵌入 IP 摄像机流。下面的管道工程:

gst-launch-1.0 udpsrc 端口=20000 ! application/x-rtp,encoding-name=JPEG,payload=26,width=640,height=460 ! rtpjpegdepay ! JPEG解析! JPEG格式!视频转换!视频缩放! ximagesink 同步=false

当试图嵌入 qwidget 时,它显示的是一个普通的窗口。我的代码如下:

#include <glib.h>
#include <gst/gst.h>
#include <gst/video/videooverlay.h>

#include <QApplication>
#include <QTimer>
#include <QWidget>

int main(int argc, char *argv[])

  if (!g_thread_supported ())
    g_thread_init (NULL);

  gst_init (&argc, &argv);
  QApplication app(argc, argv);
  app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));

  // prepare the pipeline

  GstElement *pipeline = gst_pipeline_new ("pipeline");
  GstElement *src = gst_element_factory_make ("udpsrc", NULL);
  GstCaps *caps = gst_caps_from_string ("application/x-rtp,encoding-name=JPEG,payload=26,width=640,height=460");

  g_object_set(G_OBJECT(src),
               "port", 20000,
               "caps", caps, NULL);

  GstElement *parser = gst_element_factory_make ("rtpjpegdepay", NULL);
  GstElement *mux = gst_element_factory_make ("jpegparse", NULL);
  GstElement *parse2 = gst_element_factory_make ("jpegdec", NULL);
  GstElement *dec = gst_element_factory_make ("videoconvert", NULL);
  GstElement *conv = gst_element_factory_make ("videoscale", NULL);
  GstElement *sink = gst_element_factory_make ("ximagesink", NULL);
  g_object_set(G_OBJECT(sink), "sync", FALSE, NULL);
  gst_bin_add_many (GST_BIN (pipeline), src, parser, mux, parse2, dec, conv, sink, NULL);
  gst_element_link (src, sink);
 GstState state, pending;

    //this is the call to overlay the gstreamer's output to the Qt Widgets...
    gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), xwinid);

    GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_object_unref (bus);


    GstStateChangeReturn sret = gst_element_set_state (pipeline, GST_STATE_PLAYING); //Playback can be initiated by setting the element to PLAYING state using gst_element_set_state()

    qDebug()<<"@@@@-1"<<sret;

    if (sret == GST_STATE_CHANGE_FAILURE) 
        gst_element_set_state (pipeline, GST_STATE_NULL);
        gst_object_unref (pipeline);
        // Exit application
        QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));
    

    gst_element_get_state (pipeline,
                           &state,
                           &pending,
                           10);

    qDebug()<<state<<pending;


    window->show();
    app.exec();

    g_main_loop_run (loop);
  return 0;

【问题讨论】:

【参考方案1】:

我通过使用 gst_parse_launch() 创建管道解决了这个问题

GstElement *pipeline_2= gst_parse_launch("udpsrc port=20000 ! application/x-rtp,encoding-name=JPEG,payload=26 ! rtpjpegdepay ! jpegparse ! jpegdec ! videoconvert ! videoscale ! ximagesink  name=mySink", NULL);

GstElement *sink = gst_bin_get_by_name((GstBin*)pipeline_2,"mySink");

QWidget *window = new QWidget();
window->setWindowTitle("udpsrc video stream");
window->resize(700, 700);

WId xwinid = window->winId();
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), (guintptr)xwinid);

window->show();
GstStateChangeReturn sret = gst_element_set_state (pipeline_2, GST_STATE_PLAYING);

希望这会有所帮助。

【讨论】:

以上是关于如何在 qwidget 中使用 GstElement 和 udpsrc 进行 gstreamer 流式传输的主要内容,如果未能解决你的问题,请参考以下文章

如何在 qwidget 中使用 GstElement 和 udpsrc 进行 gstreamer 流式传输

如何使用 PythonQt 在 API 中正确关闭 QWidget 窗口

如何使用 QWidget 在 QTabWidget 中包含 QList

如何在Qt中获取QWidget的QTabWidget标题文本?

如何将 QMenu 中的 QAction 转换为 QWidget?

如何从另一个 Qwidget 中删除小部件?