Unsolved Qt5Gstreamer and QML
-
Hi everyone,
I'm currently trying to get a custom Gstreamer pipeline with its video output dislayed on a QML UI. My problem is that, no matter the pipeline I try, the element VideoSurface and its linked VideoItem remains black on the UI (audio is ok but no video).
The environment that I'm currently using is :
- QT5Gstreamer
- Last Version of QT (5.5.9)
- All QT5 packages downloaded and installed from Ubuntu repositories ( x64 Version).
In order to locate the problem more easily, I tried simple projects like the qmlplayer2 exemple provided here (and modified to work on last version of QT).
I also tried a simple pipeline using a similar way to implement(videotestsrc + QGst::Quick::VideoSurface)
In both situation, the VideoItem remains black (no video stream), but the audio stream works (and there is apparently no execution error).Also, the debug Log of of Gstreamer does not seems to raise any problem ( elements linking successful, pads founds, pipeline set on Playing, ...)
Any Idea of the part I could miss ?
Here is the only part I modified from the example qmlplayer2 (in order to make it work with the last QT version) :
-
Hi and welcome to devnet,
Do you get any message if you run the pipeline directly in the terminal ?
-
Hi,
Thanks for your reply.
If I try the pipeline in command line, it seems to work well also. I don't get any rendering, but I suppose it is normal as the qtquick2videosink (used in the VideoSurface class) is supposed to be interfaced with QML at some point :
The player2 project, modified to reflect the pipeline in command line above :
#include "player.h" #include <QUrl> #include <QDebug> #include <QtGui/QGuiApplication> #include <QtQuick/QQuickView> #include <QtQml/QQmlContext> #include <QtQml/QQmlEngine> #include <Qt5GStreamer/QGst/Init> #include <Qt5GStreamer/QGst/Quick/VideoSurface> #include <Qt5GStreamer/QGlib/Connect> #include <Qt5GStreamer/QGlib/Error> #include <Qt5GStreamer/QGst/ElementFactory> #include <Qt5GStreamer/QGst/Bus> #include <Qt5GStreamer/QGst/Pipeline> int main(int argc, char **argv) { #if defined(QTVIDEOSINK_PATH) //this allows the example to run from the QtGStreamer build tree without installing QtGStreamer qputenv("GST_PLUGIN_PATH", QTVIDEOSINK_PATH); #endif QGuiApplication app(argc, argv); QGst::init(&argc, &argv); QQuickView view; QGst::Quick::VideoSurface *surface = new QGst::Quick::VideoSurface; QGst::ElementPtr m_videoSink; QGst::PipelinePtr m_pipeline; m_videoSink = surface->videoSink(); m_pipeline = QGst::Pipeline::create(); QGst::ElementPtr videoSourceElement = QGst::ElementFactory::make("videotestsrc"); m_pipeline->add(videoSourceElement); m_pipeline->add(m_videoSink); // Add video sink (QML) if(videoSourceElement->link(m_videoSink) == false) { qDebug("videoScaleElement -> videoSink Link failed"); } else { QGst::BusPtr bus = m_pipeline->bus(); bus->addSignalWatch(); // QGlib::connect(bus, "message", this, &Player::onBusMessage); qDebug("Calling start..."); m_pipeline->setState(QGst::StatePlaying); } view.rootContext()->setContextProperty(QLatin1String("videoSurface1"), surface); #if defined(UNINSTALLED_IMPORTS_DIR) //this allows the example to run from the QtGStreamer build tree without installing QtGStreamer view.engine()->addImportPath(QLatin1String(UNINSTALLED_IMPORTS_DIR)); #endif view.setSource(QUrl(QLatin1String("qrc:///qmlplayer2.qml"))); view.show(); return app.exec(); }
And the Gstreamer log :
The QML Side remains unchanged and the .pro file is like the screen on my previous post:
VideoItem { id: video width: window.width height: 260 surface: videoSurface1 //bound on the context from main() }
A blind guess could be because I use a virtual machine for development and the rendering needs a graphic card... (OpenGL windows for "autovideosink" element works properly).
-
Did you try to run this example ?
-
Hi,
I have faced with the same problem.
To workaround this problem, I did the following steps:
- Built qt-gstreamer with the next options inside /BUILD_PATH/build folder: cmake .. -DCMAKE_BUILD_TYPE=Release -DQT_VERSION=5 -DQTGSTREAMER_STATIC=OFF -DCMAKE_INSTALL_PREFIX=/INSTALLATION_PATH/QtGstreamer
- Installed it without sudo
- Updated pro file:
# This is a qmake project file, provided as an example on how to use qmake with QtGStreamer. TEMPLATE = app TARGET = qmlplayer2 # produce nice compilation output #CONFIG += silent # Tell qmake to use pkg-config to find QtGStreamer. #CONFIG += link_pkgconfig # Now tell qmake to link to QtGStreamer and also use its include path and Cflags. #PKGCONFIG += Qt5GStreamerQuick-1.0 INCLUDEPATH += /INSTALLATION_PATH/QtGstreamer/include/Qt5GStreamer LIBS += -L/INSTALLATION_PATH/QtGstreamer/lib -lQt5GLib-2.0 -lQt5GStreamer-1.0 -lQt5GStreamerQuick-1.0 -lQt5GStreamerUi-1.0 -lQt5GStreamerUtils-1.0 QML_IMPORT_PATH = /BUILD_PATH/build/src/qml/quick2 QML2_IMPORT_PATH = /BUILD_PATH/build/src/qml/quick2 # Recommended if you are using g++ 4.5 or later. Must be removed for other compilers. #QMAKE_CXXFLAGS += -std=c++0x # Recommended, to avoid possible issues with the "emit" keyword # You can otherwise also define QT_NO_EMIT, but notice that this is not a documented Qt macro. DEFINES += QT_NO_KEYWORDS # link against QtDeclarative and QtOpenGL QT += qml quick core widgets # Input HEADERS += player.h SOURCES += main.cpp player.cpp RESOURCES += qmlplayer2.qrc
- Updated main.cpp file:
#include "player.h" #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QtGui/QGuiApplication> #include <QtQuick/QQuickView> #include <QtQml/QQmlContext> #include <QtQml/QQmlEngine> #include <QGst/Init> #include <QGst/Quick/VideoSurface> int main(int argc, char **argv) { //this allows the example to run from the QtGStreamer build tree without installing QtGStreamer qputenv("GST_PLUGIN_PATH", "/BUILD_PATH/build/elements/gstqtvideosink"); QGuiApplication app(argc, argv); QGst::init(&argc, &argv); QQmlApplicationEngine engine; QGst::Quick::VideoSurface *surface = new QGst::Quick::VideoSurface; engine.rootContext()->setContextProperty(QLatin1String("videoSurface"), surface); Player *player = new Player(&engine); player->setVideoSink(surface->videoSink()); if (argc > 1) player->setUri(QString::fromLocal8Bit(argv[1])); else player->setUri(QLatin1Literal("file:///some media file.mp4")); engine.rootContext()->setContextProperty(QLatin1String("player"), player); //this allows the example to run from the QtGStreamer build tree without installing QtGStreamer engine.addImportPath("/BUILD_PATH/build/src/qml/quick2"); engine.load(QUrl(QLatin1String("qrc:/qmlplayer2.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); }
- Done
If I build static libraries, it does not work - I did not try to find solution of this issue.
It started to work after using only built headers and libs.Probably there will be problem with output HUE, if so, please check these links: http://gstreamer-devel.966125.n4.nabble.com/qtgstreamer-plugins-QMLPlayer-video-has-red-hue-td4670397.html and https://bugzilla.gnome.org/show_bug.cgi?id=740614
-
Perhaps a bit silly question, but... why use qt-gstreamer at all? The video playing is fully integrated into upstream Qt's multimedia module. So as long as you have gstreamer-1.0 and newest Qt installed (that's 5.9.3, by the way. There is no Qt version 5.5.9), it should work - no need to link anything special to your project.
-
The pipeline used by Qt is pretty generic and more toward reading multimedia files so depending on what you need you need a finer level of control.
For example, for one of my talk, I needed to get images from a camera on screen while streaming it through the network. So basically one input, two outputs (on screen and network)
Pretty easily done with GStreamer but not that much with QtMultimedia so QtGstreamer is pretty handy in that respect.
-
OK, thanks for info :-)