如何在 Qt 无框窗口中显示 GStreamer 视频?
Posted
技术标签:
【中文标题】如何在 Qt 无框窗口中显示 GStreamer 视频?【英文标题】:How to show the GStreamer video in Qt frameless window ? 【发布时间】:2015-06-11 05:38:59 【问题描述】:我正在尝试在 qt 无框窗口中显示 gstreamer 视频。 我正在为其创建代码的 gstreamer 管道是: gst-launch-1.0 -v rtspsrc location=rtsp://192.168.1.15:8554/test! rtpjitterbuffer! rtph264depay! avdec_h264 ! d3dvideosink sync=false 这是我的第一个问题,请回答我。我的代码如下 我的代码适用于 qt 窗口。它正在显示它正在接收的视频 来自 rtsp 链接,但我有两个主要问题:1.当我最小化此窗口时,它会丢失输出视频并开始显示空白屏幕。 2. 我想在无框窗口中打开这个视频,但如果我这样做了,它什么也不会显示。 我使用的是 Qt-4.8.12 和 gstreamer 1.4 版.5 适用于 Windows 7 64 位。非常感谢有关这两个问题的任何帮助。提前致谢。
#include <glib.h>
#include <gst/gst.h>
#include <gst/video/videooverlay.h>
#include <QApplication>
#include <QTimer>
#include <QWidget>
#include <stdio.h>
#include "qmainwindow.h"
static void on_pad_added (GstElement *element, GstPad *pad, gpointer data);
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data);
int main(int argc, char *argv[])
if (!g_thread_supported ())
g_thread_init (NULL);
/* Initialize GStreamer */
gst_init (&argc, &argv);
QApplication app(argc, argv);
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));
/* Creating Elements */
//GstElement *pipeLine = gst_pipeline_new ("xvoverlay");
QWidget window;
// QMainWindow window;
window.resize(1024,768);
WId xwinid=window.winId();
GMainLoop *loop;
GstElement *pipeLine, *rtspSrc, *rtpJitterBuffer, *rtpH264Depay, *avDecH264, *videoSink;
rtspSrc = gst_element_factory_make("rtspsrc", NULL);
rtpJitterBuffer = gst_element_factory_make("rtpjitterbuffer", NULL);
rtpH264Depay = gst_element_factory_make("rtph264depay", NULL);
avDecH264 = gst_element_factory_make("avdec_h264", NULL);
videoSink = gst_element_factory_make("d3dvideosink", NULL);
loop = g_main_loop_new (NULL, FALSE);
if (!rtspSrc || !rtpJitterBuffer || !rtpH264Depay || !avDecH264 || !videoSink)
g_printerr ("Not all elements could be created.\n");
return -1;
/* Set element properties */
g_object_set( rtspSrc, "location", "rtsp://192.168.1.16:8554/test" , NULL);
g_object_set( videoSink, "sync", false, NULL);
/*Initializing Pipeline*/
pipeLine = gst_pipeline_new ("TestPipeLine");
if (!pipeLine)
g_printerr ("Pipeline could not be created.");
/* we add a message handler */
GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeLine));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/*Adding Components to the pipeline */
gst_bin_add_many (GST_BIN(pipeLine),
rtspSrc,
rtpJitterBuffer,
rtpH264Depay,
avDecH264,
videoSink,
NULL);
/* if (gst_element_link (rtspSrc, rtpJitterBuffer) != TRUE)
g_printerr ("rtspSrc & rtpJitterBuffer could not be linked.\n");
gst_object_unref (pipeLine);
return -1;
*/
if (gst_element_link (rtpJitterBuffer, rtpH264Depay) != TRUE)
g_printerr ("rtpJitterBuffer and rtpH264Depay could not be linked.\n");
gst_object_unref (pipeLine);
return -1;
if (gst_element_link (rtpH264Depay, avDecH264) != TRUE)
g_printerr ("rtpH264Depay and avDecH264 could not be linked.\n");
gst_object_unref (pipeLine);
return -1;
if (gst_element_link (avDecH264, videoSink) != TRUE)
g_printerr ("avDecH264 and videoSink could not be linked.\n");
gst_object_unref (pipeLine);
return -1;
g_signal_connect (rtspSrc, "pad-added", G_CALLBACK (on_pad_added), rtpJitterBuffer);
window.setWindowFlags(Qt::FramelessWindowHint);
// else
// g_printerr("Pipeline created");zz
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY(videoSink), guintptr(xwinid));
window.show();
/* Set the pipeline to "playing" state*/
g_print ("Now playing: %s\n", argv[1]);
gst_element_set_state (pipeLine, GST_STATE_PLAYING);
app.exec();
/* Iterate */
g_print ("Running...\n");
g_main_loop_run (loop);
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeLine, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeLine));
return 0;
static void on_pad_added (GstElement *element, GstPad *pad, gpointer data)
GstPad *sinkpad;
GstElement *decoder = (GstElement *) data;
/* We can now link this pad with the vorbis-decoder sink pad */
g_print ("Dynamic pad created, linking demuxer/decoder\n");
sinkpad = gst_element_get_static_pad (decoder, "sink");
gst_pad_link (pad, sinkpad);
gst_object_unref (sinkpad);
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg))
case GST_MESSAGE_EOS:
g_print ("End of stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR:
gchar *debug;
GError *error;
gst_message_parse_error (msg, &error, &debug);
g_free (debug);
g_printerr ("Error: %s\n", error->message);
g_error_free (error);
g_main_loop_quit (loop);
break;
default:
break;
return TRUE;
【问题讨论】:
【参考方案1】:如果您切换回使用 QWindow,这将起作用:
window.setWindowFlags (Qt::FramelessWindowHint);
我不确定如何,但我认为 QWidget 可以使用类似的东西。
【讨论】:
以上是关于如何在 Qt 无框窗口中显示 GStreamer 视频?的主要内容,如果未能解决你的问题,请参考以下文章
Qt/win:无框窗口上的 showMaximized() 重叠任务栏