To connect Gstreamer with Qt in order to play a gstreamer video in the Qt Widget

*爱你&永不变心* 提交于 2019-12-04 11:15:15
Tim

http://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/tests/examples/overlay

has a minimal Qt example.

In your code, you should probably set the window ID before you do the state change to ready (I'm not 100% sure this is the problem though).

For playback, you should idally use the playbin2 element, something like this (completely untested):

GstElement *playbin, *videosink;
gchar *uri;

 playbin = gst_element_factory_make ("playbin2", "myplaybin");
 videosink = gst_element_factory_make ("xvimagesink", NULL);

 g_object_set (playbin, "video-sink", videosink, NULL);

 uri = g_filename_to_uri ("/path/to/file", NULL, NULL);
 g_object_set (playbin, "uri", uri, NULL);
 g_free (uri);

 /* NOTE: at this point your main window needs to be realized,
  * ie visible on the screen, and you might need to make sure
  * that your widget w indeed has a 'native window' (just some
  * things to check for if it doesn't work; there should be Qt
  * API for this kind of thing if needed) */
 QApplication::syncX();
 gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(videosink), w.winId());

 gst_element_set_state (playbin, GST_STATE_PLAYING);

.. check for messages like error/statechanges/tags/eos on pipeline/playbin bus

I just did this same thing using python. What I had to do was connect to 'sync-message::element' on the bus and listen for a message called 'prepare-xwindow-id' (disregard the name as it works on all platforms, not just X11) sent after the video sink is setup. It sends you the sink inside that message, and that is where you pass it the window id.

Midhat

The sample code given above will link GStreamer video window to QtWidget provided the elements are linked correctly.

  • filesrc should be linked to the demuxer
  • decoder should be linked to the filesink
  • Finally, the demuxer should be linked to the decoder at runtime
// link filesrc to demuxer
gst_element_link(filesrc,demux)

// link vdecoder to filesink
gst_element_link_many(vdecoder,filesink,NULL)

/*
  The demuxer will be linked to the decoder dynamically.
  The source pad(s) will be created at run time,
  by the demuxer when it detects the amount and nature of streams.
  Connect a callback function which will be executed
  when the "pad-added" is emitted.
*/

g_signal_connect(demux,"pad-added",G_CALLBACK(on_pad_added),vdecoder);

// callback definition
static void on_pad_added(GstElement* element,GstPad* pad,gpointer* data)
{
  GstPad* sinkpad;
  GstElement * decoder = (GstElement*)data;
  GstCaps* caps;
  GstStructure* str;
  gchar* tex;

  caps = gst_pad_get_caps(pad);
  str = gst_caps_get_structure(caps,0);
  tex = (gchar*)gst_structure_get_name(str);

  if(g_strrstr(tex,"video"))
  {
    sinkpad = gst_element_get_static_pad(decoder,"sink");
    gst_pad_link(pad,sinkpad);
    gst_object_unref(sinkpad);
  }
}

A project wrapping gstreamer into usable C++/Qt classes including example code: http://code.google.com/p/qbtgstreamer/

I don't know about a direct approach, as I am not familiar with gstreamer itself.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!