@ystreet00, hoping I can get some input from you since it seems you are the original author.
First, the warning I am encountering:
qtsink gstqml6glsink.cc:367:gst_qml6_gl_sink_change_state:<sink> error: Could not initialize window system
I am trying to utilize GstGLQt6VideoItem
inside of a mixed QML/Qt Widgets application.
I can create a minimal reproducible example if that is requested.
My application begins by creating a QApplication
and setting the Qt Quick graphics API to OpenGL (i.e. QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL)
)
I then instantiate a widget which contains a QQuickWidget
. Here is the rough logic for the GStreamer + QQuickWidget integration:
VideoWidget::VideoWidget(QWidget* parent)
: QWidget(parent), _impl(std::make_unique<impl>(this))
{
setLayout(new QVBoxLayout(this));
// Construct quick widget
auto qw = new QQuickWidget(this);
_impl->_quick_widget = qw;
qw->setResizeMode(QQuickWidget::SizeRootObjectToView);
connect(qw, &QQuickWidget::statusChanged, this, &VideoWidget::quickWidgetStatusChanged);
connect(qw, &QQuickWidget::sceneGraphError, this, &VideoWidget::sceneGraphError);
qw->resize(300, 300);
qw->setResizeMode(QQuickWidget::SizeRootObjectToView);
// Build the GStreamer pipeline
std::stringstream ss;
// clang-format off
auto desktopDir = std::filesystem::path(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).toStdString());
auto filesrcPath = desktopDir / "test.mp4";
ss << fmt::format("filesrc location={} ! qtdemux", filesrcPath.string());
ss << " ! " << "queue";
ss << " ! " << "decodebin";
ss << " ! " << "queue";
ss << " ! " << "videoconvert";
ss << " ! " << "queue";
ss << " ! " << "glupload";
ss << " ! " << "qml6glsink name=sink";
LOG_INFO("Pipeline: {}", ss.str());
// clang-format on
_impl->_pipeline = gst_parse_launch(ss.str().c_str(), NULL);
if(!_impl->_pipeline) {
LOG_ERROR("VideoWidget: failed to parse Gstreamer Pipeline");
return;
}
auto sink = gst_bin_get_by_name(GST_BIN(_impl->_pipeline), "sink");
qw->setSource(QUrl("qrc:qml/Video.qml"));
// Find and set the videoItem on the sink
auto rootObject = qw->rootObject();
if(rootObject) {
QQuickItem* videoItem = rootObject->findChild<QQuickItem*>("videoItem");
g_assert(videoItem);
g_object_set(sink, "widget", videoItem, NULL);
}
QTimer::singleShot(1000, this, [this]() {
LOG_INFO("VideoWidget: set playing");
gst_element_set_state(_impl->_pipeline, GST_STATE_PLAYING);
});
// Add quick widget to this widgets layout
layout()->addWidget(qw);
}
When the oneshot timer attempts to set the pipeline state to playing, I receive the warning above and the video fails to play.