weirdgyn
weirdgyn

Reputation: 926

GStreamer qmlglsink vs gst_parse_launch()

I'm new to Qt and GStreamer, but I need to create a simple player for a QuickTime/H.264 video file into a Qt 5.15.2 application (running on Linux Ubuntu 20.04 (Focal Fossa)).

I managed to play a standard videotestsrc (bouncing ball pattern) inside my application, and this is the code (main.cpp):

#include "mainwindow.h"

#include <QApplication>

#include <QQuickView>
#include <QWidget>
#include <QQuickItem>

#include <gst/gst.h>

int main(int argc, char *argv[])
{
    GstElement* mPipeline = nullptr;
    GstElement* mSource = nullptr;
    GstElement* mGLUpload = nullptr;
    GstElement* mSink = nullptr;
    QQuickView* mView = nullptr;
    QWidget* mWidget = nullptr;
    QQuickItem* mItem = nullptr;

    gst_init(argc, argv);

    QApplication app(argc, argv);

    MainWindow* window = new MainWindow;

    mPipeline = gst_pipeline_new(NULL);
    mSource = gst_element_factory_make("videotestsrc", NULL);
    mGLUpload = gst_element_factory_make("glupload", NULL);
    mSink = gst_element_factory_make("qmlglsink", NULL);

    gst_bin_add_many(GST_BIN (mPipeline), mSource, mGLUpload, mSink, NULL);
    gst_element_link_many(mSource, mGLUpload, mSink, NULL);

    g_object_set(mSource, "pattern", 18, NULL);

    mView = new QQuickView;

    mView->scheduleRenderJob(new SetPlaying (mPipeline),
                            QQuickView::BeforeSynchronizingStage);

    mView->setSource(QUrl(QStringLiteral("qrc:/video.qml")));

    mWidget = QWidget::createWindowContainer(mView, parent);

    mItem = mView->findChild<QQuickItem*>("videoItem");

    window->setCentralWidget(mWidget);

    window->show();

    ret = app.exec();

    g_object_set(mSink, "widget", mItem, NULL);

    gst_deinit();
}

SetPlaying class...

#include <QRunnable>

#include <gst/gst.h>

class SetPlaying : public QRunnable
{
public:
  SetPlaying(GstElement *pipeline) {
    this->pipeline_ = pipeline ? static_cast<GstElement *> (gst_object_ref (pipeline)) : NULL;
  }

  ~SetPlaying() {
    if (this->pipeline_)
        gst_object_unref (this->pipeline_);
  }

  void run () {
    if (this->pipeline_)
        gst_element_set_state (this->pipeline_, GST_STATE_PLAYING);
  }

private:
  GstElement * pipeline_;
};

The MainWindow code should not be relevant for the issue management (it's a standard empty window).

This is the source code of the only .qml item that's needed to provide an acceptable widget surface to qmlglsink:

import QtQuick 2.15
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

Item {
    anchors.fill: parent

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

Now since the actual pipeline to plays the file is quite long and complex to manage the @ code I opted to use a gst_parse_launch() approach.

To proceed step by step, I tried to use such a method to create a videotestsrc pipeline, i.e.:

mPipeline = gst_parse_launch( "videotestsrc ! glupload ! qmlglsink", NULL);

mSink = gst_bin_get_by_name(GST_BIN(mPipeline), "sink");
mSource = gst_bin_get_by_name(GST_BIN(mPipeline), "source");

If I run the code this is the result:

(videotest:14930): GLib-GObject-CRITICAL **: 16:33:08.868: g_object_set: assertion 'G_IS_OBJECT (object)' failed

(videotest:14930): GLib-GObject-CRITICAL **: 16:33:09.342: g_object_set: assertion 'G_IS_OBJECT (object)' failed

Of course, the application window displays nothing.

Upvotes: 0

Views: 851

Answers (1)

Florian Zwoch
Florian Zwoch

Reputation: 7373

You should give the elements a name property. They will default to ones, but they include a numerical value and are incremented whenever you rebuild the pipeline. So it is better to not rely on those.

To make your existing code work, try this:

mPipeline = gst_parse_launch( "videotestsrc name=source ! glupload ! qmlglsink name=sink", NULL);

Upvotes: 2

Related Questions