I running AGL on RSPi4, master branch.
Gstreamer version 1.16.2 and QT version 5.14.2.
Im writing QT application that uses Gstremer and qmlglsink to display webrtc video stream.
So I have problem when I want to stop pipeline with qmlglsink in it. Basically when I stop it in blocks all QT background tasks (timers, callbacks...).
I try same thing(same program) on:
Ubuntu 20.4 (on PC), with same version of Gstreamer and QT. this problem is no present.
Ubuntu 20.4 (on RSPi4), with same version of Gstreamer and QT. this problem is no present.
In attachment is cpp file and qml file that Im using.
any assistance would be very much appreciated.
_._,_._,_
Links:
You receive all messages sent to this group.
View/Reply Online (#8725) | Reply To Group | Reply To Sender | Mute This Topic | New Topic
Mute #help
Your Subscription | Contact Group Owner | Unsubscribe [list-automotive-discussions82@xxxxxxxxxxx]
_._,_._,_
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickWindow> #include <QQuickItem> #include <QRunnable> #include <QTimer> #include <QThread> #include <QCommandLineParser> #include <QtQuickControls2/QQuickStyle> #include <gst/gst.h> GstElement *pipeline; QQuickItem *videoItem; GstElement *sink; QQuickWindow *rootObject; QQmlApplicationEngine * engine; class SetPlaying : public QRunnable { public: SetPlaying(GstElement *); ~SetPlaying(); void run (); private: GstElement * pipeline_; }; SetPlaying::SetPlaying (GstElement * pipeline) { this->pipeline_ = pipeline ? static_cast<GstElement *> (gst_object_ref (pipeline)) : NULL; } SetPlaying::~SetPlaying () { if (this->pipeline_) gst_object_unref (this->pipeline_); } void SetPlaying::run () { qDebug() << ">>BeforeSynchronizingStage<<" << endl; static int i=0; if (this->pipeline_) { if (i==0) gst_element_set_state (this->pipeline_, GST_STATE_PLAYING); else { qDebug() << ">>BeforeSynchronizingStage<<" << endl; //GstPad *srcpad, *sinkpad; //sinkpad = gst_element_get_static_pad (sink, "sink"); //gst_pad_send_event (sinkpad, gst_event_new_eos ()); //gst_object_unref (sinkpad); //gst_element_set_state (sink, GST_STATE_NULL); //g_object_set(sink, "widget", NULL, NULL); //gst_bin_remove (GST_BIN (pipeline), sink); //gst_bin_add (GST_BIN (pipeline), sink); //videoItem->setFlag (QQuickItem::ItemHasContents, false); //gst_element_link (sink, NULL); //gst_element_sync_state_with_parent (sink); //rootObject->close(); //videoItem->deleteLater(); //videoItem->blockSignals(true); gst_element_set_state (this->pipeline_, GST_STATE_PAUSED); gst_element_set_state (this->pipeline_, GST_STATE_NULL); } i++; } } void startP () { gst_element_set_state (pipeline, GST_STATE_PLAYING); //gst_element_set_state (pipeline, GST_STATE_PAUSED); //gst_element_set_state (pipeline, GST_STATE_NULL); //engine->clearComponentCache(); //gst_element_set_state (pipeline, GST_STATE_PAUSED); //gst_element_set_state (pipeline, GST_STATE_NULL); //engine->load(QUrl(QStringLiteral("qrc:/qml/sample_app.qml"))); //rootObject = static_cast<QQuickWindow *> (engine->rootObjects().first()); // videoItem = rootObject->findChild<QQuickItem *> ("videoItem"); //QQmlEngine::setObjectOwnership(videoItem, QQmlEngine::CppOwnership); //g_assert (videoItem); //g_object_set(sink, "widget", videoItem, NULL); /*rootObject->scheduleRenderJob (new SetPlaying (pipeline), QQuickWindow::BeforeSynchronizingStage);*/ } int main(int argc, char *argv[]) { int ret; { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QString myname = QString("sample_app"); QGuiApplication app(argc, argv); app.setDesktopFileName(myname); qputenv("GST_DEBUG", "4"); //qputenv("GST_DEBUG", "qt*:7"); gst_init (&argc, &argv); QMetaObject::Connection con; QQuickStyle::setStyle("AGL"); QCommandLineParser parser; parser.addPositionalArgument("port", app.translate("main", "port for binding")); parser.addPositionalArgument("secret", app.translate("main", "secret for binding")); parser.process(app); QStringList positionalArguments = parser.positionalArguments(); pipeline = gst_pipeline_new (NULL); GstElement *src = gst_element_factory_make ("videotestsrc", NULL); GstElement *glupload = gst_element_factory_make ("glupload", NULL); /* the plugin must be loaded before loading the qml file to register the * GstGLVideoItem qml item */ sink = gst_element_factory_make ("qmlglsink", NULL); g_assert (src && glupload && sink); gst_bin_add_many (GST_BIN (pipeline), src, glupload, sink, NULL); gst_element_link_many (src, glupload, sink, NULL); engine = new QQmlApplicationEngine(); engine->load(QUrl(QStringLiteral("qrc:/qml/sample_app.qml"))); /* find and set the videoItem on the sink */ rootObject = static_cast<QQuickWindow *> (engine->rootObjects().first()); videoItem = rootObject->findChild<QQuickItem *> ("videoItem"); QQmlEngine::setObjectOwnership(videoItem, QQmlEngine::CppOwnership); g_assert (videoItem); g_object_set(sink, "widget", videoItem, NULL); rootObject->scheduleRenderJob (new SetPlaying (pipeline), QQuickWindow::BeforeSynchronizingStage); QTimer * timer = new QTimer(); timer->setSingleShot(true); QObject::connect(timer, &QTimer::timeout, [] () { qDebug() << ">>Stop pipeline<<" << endl; rootObject->scheduleRenderJob (new SetPlaying (pipeline), QQuickWindow::BeforeSynchronizingStage); }); timer->start(10000); //in ms*/ QTimer * timer1 = new QTimer(); QObject::connect(timer1, &QTimer::timeout, [] () { qDebug() << ">>Alive!!!<<" << endl; }); timer1->start(1000); //in ms QTimer * timer2 = new QTimer(); QObject::connect(timer2, &QTimer::timeout, [] () { qDebug() << ">>startP();!!!<<" << endl; startP(); }); timer2->start(20000); //in ms qDebug() << "Start QT event loop" << endl; ret = app.exec(); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); } gst_deinit (); return ret; }
import QtQuick 2.5 import QtQuick.Window 2.0 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.1 import QtMultimedia 5.1 import org.freedesktop.gstreamer.GLVideoItem 1.0 ApplicationWindow { id: window objectName: "window" visible: true // width: Screen.desktopAvailableWidth // height: Screen.desktopAvailableHeight width: 1080 height: 1920 flags: Qt.FramelessWindowHint color: "transparent" Item { id: root Rectangle { id: videoPlayerRect width: 1080 height: 1487 color: "transparent" border.width: 0 visible: true /*MediaPlayer { id: mediaPlayer source: "http://media.developer.dolby.com/Atmos/MP4/Universe_Fury.mp4" autoPlay: false autoLoad: false onError: { console.log("DISPLAY_SCREEN.qml: ERROR " + errorString) console.debug(error, errorString) } onPlaying: { console.log("DISPLAY_SCREEN.qml: onPlaying(" + playbackState + ")") } onStopped: { console.log("DISPLAY_SCREEN.qml: onStopped(" + playbackState + ")") } onAutoPlayChanged: { console.log("DISPLAY_SCREEN.qml: onAutoPlayChanged(" + autoPlay + ")") } onPlaybackStateChanged: { console.log("DISPLAY_SCREEN.qml: onPlaybackStateChanged(" + playbackState + ")") } onSourceChanged: { console.log("DISPLAY_SCREEN.qml: onSourceChanged(" + source + ")") } }*/ /*VideoOutput { id: videoOutput visible: true objectName: "videoItem" anchors.fill: parent source: mediaPlayer fillMode: VideoOutput.Stretch orientation: 0 }*/ GstGLVideoItem { id: video objectName: "videoItem" anchors.centerIn: parent width: parent.width height: parent.height } Column { Label { text: "Hello World!" font.pixelSize: 28 font.bold: true anchors.horizontalCenter: parent.horizontalCenter } Button { text: "Quit" onClicked: { Qt.quit() } anchors.horizontalCenter: parent.horizontalCenter } anchors.centerIn: parent spacing: 20 } } } }