1

I'm using Qt and Gstreamer to create a video viewer. I'm using this simple code to show a video:

GstElement* MainWindow::addVideo(QWidget* parent, const int&  x, const int&  y, const int&  width, const int&  height) {

    GstElement* pipeline = gst_pipeline_new ("xvoverlay");
    GstElement* src = VideoView::makeElement("v4l2src", { {"device", "/dev/video0"} });
    GstElement* queue = gst_element_factory_make ("videoconvert", nullptr);
    GstElement* sink = gst_element_factory_make ("xvimagesink", nullptr);

    if (sink == nullptr)
        g_error ("Couldn't find a working video sink.");

    gst_bin_add_many (GST_BIN (pipeline), src, queue, sink, nullptr);
    gst_element_link_many (src, queue, sink, nullptr);

    QWidget* videoView = new VidView();
    videoView->setParent(parent);
    videoView->move(x, y);
    videoView->resize(width, height);
    videoView->setStyleSheet("background-color: red");
    videoView->show();

    gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), videoView->winId());
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    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()));
    }

    return pipeline;
}

It work well. But now I need to display some semi-transparent widgets above the video (for instance to have a title bar showing the name of the camera, or a popup above all the window). Here's what I get when showing a semi-transparent yellow QWidget partially overlaying the video:

enter image description here

As you can see, under the yellow widget the video view background is shown, not the video.

Here's the code used to create that second widget:

QWidget* test = new QWidget(m_mainContainer);
test->resize(100, 100);
test->move(150, 150);
test->setStyleSheet("background-color: #55ffff00;");

How can I fix this?

Note: I can't use the glimagesink, because it has performances problems when showing multiple videos (the app will be showing up to 8 4K videos).

Tim Autin
  • 6,043
  • 5
  • 46
  • 76
  • 1
    The problem is that Qt must know your background image to apply the transparency algorithms over it, as you experienced, Qt don't know it in a OpenGL widget! A simple solution is relies on OS to draw the semi transparent window for you, as i did here(Tested on Windows only, old answer!): https://stackoverflow.com/a/25468160/2014561 – Antonio Dias Oct 23 '19 at 11:40
  • Thanks for your suggestion, but that's not working for me on Ubuntu 16.04. – Tim Autin Oct 24 '19 at 09:22

0 Answers0