QT实现播放gstreamer视频
资源内容介绍
本源码为博文 《【QGroundControl二次开发】八. QT实现播放gstreamer视频 》配套源码,搭建gstreamer在Windows和linux下的环境,以及新建VS工程解码视频流请参阅之前博文。博文包含:一. QT工程配置二. 项目代码三. 测试实测可运行,运行环境为Ubuntu系统+QT+Gstreamer #include <QApplication>#include <QWidget>#include <QtConcurrent/QtConcurrent>#include <gst/gst.h>#include <gst/video/videooverlay.h>#include "ui_mainwindow.h"int main(int argc, char *argv[]) { QApplication a(argc, argv); GstElement *pipeline, *udpsrc, *capsfilter, *queue, *rtph264depay, *h264parse, *avdec_h264, *videoconvert, *vsink, *fpssink; GstCaps *caps; GstStateChangeReturn ret; QWidget *window = new QWidget(); window->resize(1920, 1080); window->show(); WId xwinid = window->winId(); // 初始化 GStreamer gst_init(NULL, NULL); // 创建元素 pipeline = gst_pipeline_new("my-pipeline"); udpsrc = gst_element_factory_make("udpsrc", "udpsrc"); capsfilter = gst_element_factory_make("capsfilter", "capsfilter"); queue = gst_element_factory_make("queue", "queue"); h264parse = gst_element_factory_make("h264parse", "h264parse"); avdec_h264 = gst_element_factory_make("avdec_h264", "avdec_h264"); rtph264depay = gst_element_factory_make("rtph264depay", "rtph264depay"); videoconvert = gst_element_factory_make("videoconvert", "videoconvert"); fpssink = gst_element_factory_make("fpsdisplaysink", "fpssink"); vsink = gst_element_factory_make("xvimagesink", "vsink");//glimagesink if (!pipeline || !udpsrc || !capsfilter || !queue || !rtph264depay || !h264parse || !avdec_h264 || !videoconvert || !fpssink || !vsink) { g_printerr("Failed to create elements. Exiting.\n0000000"); return -1; } // 设置 udpsrc 元素的参数 g_object_set(udpsrc, "port", 14556, NULL); // 创建 caps "depth", G_TYPE_STRING, "8", caps = gst_caps_new_simple("application/x-rtp", "media", G_TYPE_STRING, "video", "clock-rate", G_TYPE_INT, 90000, "encoding-name", G_TYPE_STRING, "H264", NULL); g_object_set(capsfilter, "caps", caps, NULL); gst_caps_unref(caps); // g_object_set (fpssink, "video-sink", vsink, NULL); // 将元素添加到管道中 gst_bin_add_many(GST_BIN(pipeline), udpsrc, capsfilter, queue, rtph264depay, h264parse, avdec_h264, videoconvert, vsink, NULL); // 连接元素 if (!gst_element_link_many(udpsrc, capsfilter, queue, rtph264depay, h264parse, avdec_h264, videoconvert, vsink, NULL)) { g_printerr("Failed to link elements. Exiting.\n11111111111"); gst_object_unref(pipeline); return -1; } // 连接元素// if (!gst_element_link(udpsrc, capsfilter)) {// g_printerr("Failed to link udpsrc and capsfilter. Exiting.\n");// gst_object_unref(pipeline);// return -1;// }// if (!gst_element_link(capsfilter, queue)) {// g_printerr("Failed to link capsfilter and queue. Exiting.\n");// gst_object_unref(pipeline);// return -1;// }// if (!gst_element_link(queue, rtph264depay)) {// g_printerr("Failed to link queue and rtph264depay. Exiting.\n");// gst_object_unref(pipeline);// return -1;// }// if (!gst_element_link(rtph264depay, h264parse)) {// g_printerr("Failed to link rtph264depay, h264parse. Exiting.\n");// gst_object_unref(pipeline);// return -1;// }// if (!gst_element_link(h264parse, avdec_h264)) {// g_printerr("Failed to link qh264parse, avdec_h264. Exiting.\n");// gst_object_unref(pipeline);// return -1;// }// if (!gst_element_link(avdec_h264, videoconvert)) {// g_printerr("Failed to link avdec_h264, videoconvert. Exiting.\n");// gst_object_unref(pipeline);// return -1;// }// if (!gst_element_link(videoconvert, vsink)) {// g_printerr("Failed to link avideoconvert, vsink. Exiting.\n");// gst_object_unref(pipeline);// return -1;// } // 链接QT界面 gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (vsink), xwinid); // 设置管道状态为播放 ret = gst_element_set_state(pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_printerr("Failed to set pipeline state to PLAYING. Exiting.\n"); gst_object_unref(pipeline); return -1; } auto res = a.exec(); // 释放资源 gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); return res;}//#include <gst/gst.h>//#include <gst/app/gstappsrc.h>//#include <QApplication>//#include <QWidget>//#include <QVBoxLayout>//#include <QTimer>//#include <QHostAddress>//#include <QUdpSocket>//class MainWindow : public QWidget {// Q_OBJECT//public:// MainWindow() {// QVBoxLayout *layout = new QVBoxLayout(this);// videoDisplay = new QWidget(this);// layout->addWidget(videoDisplay);// // 初始化 GStreamer// gst_init(nullptr, nullptr);// // 创建 GStreamer 管道// pipeline = gst_parse_launch("appsrc name=source is-live=True ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink",NULL);// // 配置 appsrc// appsrc = GST_ELEMENT(gst_bin_get_by_name(GST_BIN(pipeline), "source"));// g_object_set(appsrc, "format", GST_FORMAT_TIME, "stream-type", 0, nullptr);// // 启动 GStreamer 管道// gst_element_set_state(pipeline, GST_STATE_PLAYING);// // 初始化并启动 QUdpSocket 来接收数据// udpSocket = new QUdpSocket(this);// udpSocket->bind(QHostAddress::Any, 14556);// connect(udpSocket, &QUdpSocket::readyRead, this, &MainWindow::processPendingDatagrams);// }//private slots:// void processPendingDatagrams() {// while (udpSocket->hasPendingDatagrams()) {// QByteArray datagram;// datagram.resize(udpSocket->pendingDatagramSize());// QHostAddress sender;// quint16 senderPort;// udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);// // 将接收到的数据提供给 GStreamer// GstBuffer *buffer = gst_buffer_new_allocate(nullptr, datagram.size(), nullptr);// gst_buffer_fill(buffer, 0, datagram.data(), datagram.size());// gst_app_src_push_buffer(GST_APP_SRC(appsrc), buffer);// }// }//private:// GstElement *pipeline;// GstElement *appsrc;// QUdpSocket *udpSocket;// QWidget *videoDisplay;//};//#include "main.moc" // 确保包含 moc 文件//int main(int argc, char *argv[]) {// QApplication app(argc, argv);// MainWindow mainWindow;// mainWindow.show();// return app.exec();//}