To connect Gstreamer with Qt to play gstreamer videos in Qt Widget

I tried to use phonon to play the video, but could not. Off-late, it became known on the Qt forums that even the latest version of Qt does not support phonons. This is when I started using Gstreamer. Any suggestions on how to link a Gstreamer window to a Qt widget? My goal is to play the video using Gstreamer in a Qt widget. So how do I link the Gstreamer window and the Qt widget?

I successfully got the widget Id through winid() . Next, with the help of Gregory Pakosh, I added the following 2 lines of code to my application -

 QApplication::syncX(); gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), widget->winId()); 

However, I cannot associate the Qt widget with the gstreamer video window.

Here is what my sample code will look like:

 int main(int argc, char *argv[]) { printf("winid=%d\n", w.winId()); gst_init (NULL,NULL); /* create a new bin to hold the elements */ bin = gst_pipeline_new ("pipeline"); /* create a disk reader */ filesrc = gst_element_factory_make ("filesrc", "disk_source"); g_assert (filesrc); g_object_set (G_OBJECT (filesrc), "location", "PATH_TO_THE_EXECUTABLE", NULL); demux = gst_element_factory_make ("mpegtsdemux", "demuxer"); if (!demux) { g_print ("could not find plugin \"mpegtsmux\""); return -1; } vdecoder = gst_element_factory_make ("mpeg2dec", "decode"); if (!vdecoder) { g_print ("could not find plugin \"mpeg2dec\""); return -1; } videosink = gst_element_factory_make ("xvimagesink", "play_video"); g_assert (videosink); /* add objects to the main pipeline */ gst_bin_add_many (GST_BIN (bin), filesrc, demux, vdecoder, videosink, NULL); /* link the elements */ gst_element_link_many (filesrc, demux, vdecoder, videosink, NULL); gst_element_set_state(videosink, GST_STATE_READY); QApplication::syncX(); gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(videosink), w.winId()); /* start playing */ gst_element_set_state (bin, GST_STATE_PLAYING); } 

Could you tell us more about using gst_x_overlay_set_xwindow_id () in my context?

Can I get any advice on how I can integrate gstreamer into Qt? Please help me solve this problem.

+4
source share
4 answers

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 identifier before making a change to the ready state (although I'm not 100% sure that this is a problem).

For playback, you should use the playbin2 element, something like this (not fully verified):

 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 messages like error / statechanges / tags / eos on the pipeline / playbin bus

+2
source

I just did the same using python. I needed to connect to the "sync-message :: element" on the bus and listen to the message called "prepare-xwindow-id" (ignore the name, since it works on all platforms, not just X11), sent after the video receiver is configured . It sends you a shell inside this message, and that is where you pass it the window id.

+1
source

The above code example will link the GStreamer video to QtWidget if the elements are connected correctly.

  • filesrc should be associated with demuxer
  • the decoder must be associated with the file.
  • Finally, demuxer must be connected 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); } } 
+1
source

A project that translates gstreamer into C ++ / Qt classes used, including a sample code: http://code.google.com/p/qbtgstreamer/

I do not know about the direct approach, since I am not familiar with gstreamer itself.

0
source

Source: https://habr.com/ru/post/1301083/


All Articles