PDA

View Full Version : What is the correct way to link Qt5 videoplayers to gstreamer sinks?



mapcol
20th July 2016, 14:43
See my question here:

http://stackoverflow.com/questions/38465223/what-is-the-correct-way-to-link-qt5-videoplayers-to-gstreamer-sinks

have linked a simple videotestsrc to an autovideosink, but when I try to play with

gst_element_set_state(data->pipeline_1, GST_STATE_PLAYING);

my application opens a "GStreamer Direct3D sink default window" and outputs the video there.

Before running the video I try to connect the sink to the QVideoWidget by doing:

video_widget_1->setAttribute(Qt::WA_NativeWindow, true); // this is a QVideoWidget
WId win_1_id = video_widget_1->winId();
QApplication::sync();
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(data->el_autovideo_snk_1), win_1_id);

By the way I saw that QApplication::syncX() is deprecated in Qt5, and noone gave an answer on what to use instead, so I'm guessing sync() is a suitable alternative. Still, even by commenting sync() line as well as setAttribute(Qt::WA_NativeWindow), it opens the sink default window and plays the video there.

I don't plan to use QtGstreamer since I found it very difficult to install; it was giving always errors.

My gstreamer pipeline contains only a videotest src and the autovideosink. The elements are correctly created with:

gst_bin_add_many(GST_BIN(data->pipeline_1), data->el_videotest_src, data->el_autovideo_snk_1, NULL);
if (!gst_element_link(data->el_videotest_src, data->el_autovideo_snk_1))
console_out_err("STREAMING", "Failed to link test elements");
else
console_out_good("STREAMING", "Test elements linked correctly");

Am I missing anything?

wysota
25th July 2016, 15:03
I don't really understand how you are trying to link the Gst pipeline with a QVideoWidget. If you create an autovideosink, it will create a suitable window for you and you won't need QVideoWidget. If you want to render the video on QVideoWidget then you don't need an autovideosink. Instead you can use an appsink, read frames from the sink and render them on a bare QWidget by reimplementing its paintEvent. Just make sure the sink receives frames that are already decoded into a format you can render on a widget (some kind of RGB). You can probably also use glimagesink and pass it a window id of a QOpenGLWindow or QOpenGLWidget.

mapcol
2nd August 2016, 12:13
Very interesting.
I believed autovideosink was the endpoint of a pipeline and you could link it to a surface or widget (like qvideowidget) so that it would render the media there.

Now, as suggested, I created an appsink and I linked it to the qvideowidget with


video_widget->setAttribute(Qt::WA_NativeWindow, true);
WId win_id = video_widget->winId();
QApplication::sync();
gst_x_overlay_set_window_handle(GST_X_OVERLAY(data->appsink), win_id);


but it still outputs the video on a new window.
Can you explain better how to render the video from an appsink to a qvideowidget?
Especially the part of the paintEvent.

Before the app sink, the pipeline contains: videoscale and ffmpegcolorspace

Thank you for your answer though.
Marko