How to use qmlglsink and GstGLVideoItem

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to use qmlglsink and GstGLVideoItem

glenn.coombs
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


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Loading...