Search code examples
qtqt5video-streaminggstreamer-1.0

How properly use Gstreamer in QtWidget?


I want to play a local file inside the QVideowidget by using the gstreamer. I tested gstreamer in the terminal without any problem with: gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink,and it showed this

enter image description here

But when I came to Qt,

#include <QApplication>
#include <QMediaPlayer>
#include <QWidget>
#include <QVideoWidget>
#include <gst/gst.h>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QVideoWidget *videoWidget = new QVideoWidget;
QMediaPlayer *player  = new QMediaPlayer;
videoWidget->show();

player->setVideoOutput(videoWidget);
player->setMedia(QUrl("gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink"));
//    player->setMedia(QUrl("gst-launch-1.0 videotestsrc ! xvimagesink name=\"qtvideosink\""));
//    player->setMedia(QUrl("gst-pipeline udpsrc port=5801 ! application/x-rtp,payload=   (int)96,encoding-name=(string)H264,clock-rate=(int)90000 ! rtpjitterbuffer latency=50 ! rtph264depay ! h264parse ! omxh264dec ! videoconvert ! ximagesink"));
player->play();

return a.exec();
}

and in my .pro file I put these:

CONFIG += link_pkgconfig
PKGCONFIG += gstreamer-1.0
PKGCONFIG += gstreamer-video-1.0

I faced the following error:

DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x80040216 (IDispatch error #22)

the output is:

enter image description here

I searched a lot, but I couldn't solve the issue. Could anyone please help me?


Solution

  • I could play a video test inside the Qwidget with the below method. Be aware that picking a compatible sink is essential. for more information about sink (and other elements), use gst-inspect-1.0 | findstr sink in the terminal.

    #include <gst/gst.h>;
    #include <gst/video/videooverlay.h>;
    #include <QApplication>;
    #include <QTimer>;
    #include <QWidget>;
    
    
    int main(int argc, char *argv[])
    {
      QApplication app(argc, argv);
      app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));
    
      if (!g_thread_supported ())
      g_thread_init (NULL);
      gst_init (&argc, &argv);
    
      // prepare the pipeline
      GstElement *pipeline = gst_pipeline_new ("xvoverlay");
      GstElement *src  = gst_element_factory_make ("videotestsrc", NULL);
      GstElement *sink = gst_element_factory_make ("glimagesink", NULL);
      gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
      gst_element_link (src, sink);
      // getting more information
      gst_debug_set_active(true);
      gst_debug_set_default_threshold(GST_LEVEL_WARNING);
    
      QWidget window;
      window.resize(320, 240);
      window.show();
      WId xwinid = window.winId();
      gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), xwinid);
    
      // run the pipeline
    
      GstStateChangeReturn sret = gst_element_set_state (pipeline,
      GST_STATE_PLAYING);
      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()));
      }
    
      int ret = app.exec();
      window.hide();
      gst_element_set_state (pipeline, GST_STATE_NULL);
      gst_object_unref (pipeline);
    
      return ret;
    }
    

    the output inside widget:

    enter image description here