How to use qmlglsink and GstGLVideoItem

Glenn Coombs glenn.coombs at gmail.com
Mon Jul 24 07:19:13 UTC 2017


I'm trying to use the qmlglsink together with the GstGLVideoItem to display
video from an IP camera.  My target is an imx6q system using EGLFS and I've
based my code on the example from here:


https://github.com/GStreamer/gst-plugins-bad/tree/master/tests/examples/qt/qmlsink

I am creating a gstreamer pipeline like so:

VideoPlayerImpl::VideoPlayerImpl(const QString& uri)
{
    GError* error = nullptr;
    m_pipeline = gst_element_factory_make("playbin", "playbin");
    if (error || !m_pipeline)
    {
        CleanUp();
        throw std::runtime_error(error->message);
    }

    m_bus = gst_element_get_bus(m_pipeline);
    gst_bus_add_signal_watch(m_bus);
    g_signal_connect(m_bus,      "message",
G_CALLBACK(VideoPlayerImpl::OnBusMessage),         this);
    g_signal_connect(m_pipeline, "source-setup",
G_CALLBACK(VideoPlayerImpl::OnSourceSetupWrapper), this);

    m_sink = gst_element_factory_make("qmlglsink", "qmlglsink");
    if (m_sink)
    {
        g_object_set(m_sink, "sync", false, nullptr);
    }
    else
    {
        qDebug() << "Failed to create video sink";
    }

    g_object_set(m_pipeline,
                 "flags",               GST_PLAY_FLAG_VIDEO,      // play
only the video (no audio or subtitles)
                 "force-aspect-ratio",  false,
                 "uri",                 uri.toStdString().c_str(),
                 "video-sink",          m_sink,
                 nullptr);
}

void VideoPlayer::SetVideoItem(QQuickItem* videoItem) {
g_object_set(m_impl->m_sink, "widget", videoItem, nullptr); }

and then in my main program I create the QML side of things and attempt to
set the pipeline playing.  The problem is that the pipeline never starts
playing.  A call to gst_element_get_state shows that the state is
GST_STATE_CHANGE_ASYNC with the pending state GST_STATE_PLAYING but it
seems to be stuck in the pending state.  The main code is as follows:

int main(int argc, char* argv[])
{
    gst_init(&argc, &argv);
    // the plugin must be loaded before loading the qml file to register
the GstGLVideoItem qml item
    GstElement* sink = gst_element_factory_make ("qmlglsink", nullptr);

    MyApp app(argc, argv);
    int ret = app.exec();
    return 0;
}

//--------------------------------------------------------------------------------------------------

class MyApp : public QGuiApplication
{
public:
    MyApp(int argc, char* argv[]);
public slots:
    void OnTimer();
private:
    void CreatePlayer(const char* url);

    QQmlApplicationEngine m_engine;
    QQuickWindow*   m_rootObject;
    QQuickItem*     m_videoItem;
    VideoPlayer*    m_player;
};

//--------------------------------------------------------------------------------------------------

MyApp::MyApp(int argc, char* argv[]) : QGuiApplication(argc, argv)
{
    m_engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    // find and set the videoItem on the sink
    m_rootObject = static_cast<QQuickWindow *>
(m_engine.rootObjects().first());
    m_videoItem = m_rootObject->findChild<QQuickItem *>("videoItem");
    g_assert(m_videoItem);

    CreatePlayer("rtsp://username:password@172.16.17.11/ch1/main");

//    m_rootObject->scheduleRenderJob (new SetPlaying (pipeline),
QQuickWindow::BeforeSynchronizingStage);
}

//--------------------------------------------------------------------------------------------------

void MyApp::CreatePlayer(const char* url)
{
    m_player = new VideoPlayer (url);
    m_player->SetVideoItem(m_videoItem);
    m_player->Play();
    int maxLoops = 3;
    while (maxLoops != 0 && !m_player->IsPlaying())
    {
        qDebug() << "   not playing yet, sleeping 3 seconds";
        sleep(3);
        maxLoops--;
    }
    qDebug() << (m_player->IsPlaying() ? "Stream is now playing" : "Failed
to set stream state to playing");
}

//--------------------------------------------------------------------------------------------------
// main.qml
import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.3
import QtQuick.Dialogs 1.2
import QtQuick.Window 2.1

import org.freedesktop.gstreamer.GLVideoItem 1.0

ApplicationWindow
{
    id: window
    visible: true
    width: 640
    height: 480
    x: 30
    y: 30
    color: "blue"

    Item
    {
        anchors.fill: parent
        opacity: 0.5

        GstGLVideoItem
        {
            id: video
            objectName: "videoItem"
            anchors.centerIn: parent
            width: parent.width
            height: parent.height
        }
    }
}

I've tried using a different sink without the QML side of things and that
displays okay so the problem seems to be related to the
qmlglsink/GstGLVideoItem side of things.  Any ideas on why the pipeline
never transitions to the playing state ?

--
Glenn
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20170724/6b7c3ad0/attachment.html>


More information about the gstreamer-devel mailing list