Added sample player for project

master
Mehran Dehghanian 3 years ago
parent eef6bfaf9e
commit 702e0498ae

@ -0,0 +1,2 @@
# qt-gstreamer
Video rendering using gstreamer over Qt5 surface (QML) using qtquick2videosink

@ -0,0 +1,28 @@
#ifndef VIDEOITEM_H
#define VIDEOITEM_H
#include <gst/gst.h>
#include <QSet>
#include <QtCore/QObject>
#include <QtQuick/QQuickItem>
#include <QtCore/QPointer>
#include <QtQuick/QSGNode>
#include <QtQuick/QSGFlatColorMaterial>
#include "VideoItem.h"
#include "videosurface.h"
class VideoSurface;
class VideoItem: public QQuickItem{
Q_OBJECT
Q_PROPERTY(VideoSurface* surface READ surface WRITE setSurface)
public:
explicit VideoItem(QQuickItem *parent = 0);
virtual ~VideoItem();
VideoSurface *surface();
void setSurface(VideoSurface *surface);
virtual QSGNode* updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *UpdatePaintNodeData);
struct Private;
Private* const d;
};
#endif // VIDEOITEM_H

@ -0,0 +1,58 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml/QQmlContext>
#include <QtQml/QQmlEngine>
#include <QApplication>
#include <QSet>
#include <gst/gst.h>
#include <QtCore/QObject>
#include <QtQuick/QQuickItem>
#include <QtCore/QPointer>
#include <QtQuick/QSGNode>
#include <QtQuick/QSGFlatColorMaterial>
#include <VideoItem.h>
#include <videosurface.h>
int main(int argc, char *argv[])
{
gst_init(NULL, NULL);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<VideoItem>("VideoItem", 1, 0,"VideoItem");
GstElement *pipeline = gst_pipeline_new(NULL);
GstElement *testsrc = gst_element_factory_make("videotestsrc", NULL);
GstElement *videoconvert = gst_element_factory_make("videoconvert", NULL);
GstElement *videosink = gst_element_factory_make("qt5videosink", NULL);
GstElement *testsrc1 = gst_element_factory_make("videotestsrc", NULL);
GstElement *videoconvert1 = gst_element_factory_make("videoconvert", NULL);
GstElement *videosink1 = gst_element_factory_make("qt5videosink", NULL);
QQmlApplicationEngine engine;
// QGLContext *gl;
// QGLContext::create(gl);
// gl->currentContext();
//engine.rootContext()->setContextProperty((QString)QGLContext::currentContext(),NULL);
// g_object_set(G_OBJECT(videosink),"glcontext",(GValue *)QGLContext::currentContext(), NULL);
// gl->doneCurrent();
VideoSurface *surface = new VideoSurface;
videosink = surface->videoSink();
engine.rootContext()->setContextProperty(QLatin1String("videoSurface1"), surface);
VideoSurface *surface1 = new VideoSurface;
videosink1 = surface1->videoSink();
engine.rootContext()->setContextProperty(QLatin1String("videoSurface2"), surface1);
gst_bin_add_many(GST_BIN(pipeline), testsrc, videoconvert, videosink, testsrc1, videoconvert1, videosink1, NULL);
gst_element_link_many(testsrc, videoconvert, videosink, NULL);
gst_element_link_many(testsrc1, videoconvert1, videosink1, NULL);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
gst_element_set_state(pipeline, GST_STATE_PLAYING);
return app.exec();
}

@ -0,0 +1,47 @@
import QtQuick 2.9
import QtQuick.Controls 2.12
import QtQuick.Window 2.2
import VideoItem 1.0
import QtMultimedia 5.12
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
VideoItem{
id: video
width: 300
height: 300
surface: videoSurface1
z: 3
}
VideoItem{
id: video1
x: 300
y: 300
width: 300
height: 300
surface: videoSurface2
z: 3
}
// MediaPlayer{
// id: mediaplayer
// source: "gst-pipeline: videotestsrc ! xvimagesink name=\"qtvideosink\""
// autoPlay: true
// }
// VideoOutput{
// source: mediaplayer
// width: 800
// height: 800
// Label{
// text: "2323232"
// }
// }
}

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>

@ -0,0 +1,42 @@
QT += quick
CONFIG += c++11
QT += opengl
QT += core
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp \
videoitem.cpp \
videosurface.cpp \
videosurfaceprivate.cpp
RESOURCES += qml.qrc
CONFIG += link_pkgconfig
PKGCONFIG += gstreamer-1.0
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
videosurface.h \
videosurfaceprivate.h \
VideoItem.h

@ -0,0 +1,78 @@
#include "VideoItem.h"
struct VideoItem::Private{
QPointer<VideoSurface> surface;
bool surfaceDirty;
QRectF targetArea;
};
VideoItem::VideoItem(QQuickItem *parent): QQuickItem(parent), d(new Private){
d->surfaceDirty = true;
setFlag(QQuickItem::ItemHasContents, true);
}
VideoItem::~VideoItem(){
setSurface(0);
delete d;
}
VideoSurface *VideoItem::surface(){
return d->surface.data();
}
void VideoItem::setSurface(VideoSurface *surface)
{
if(d->surface){
d->surface.data()->d->items.remove(this);
}
d->surface = surface;
d->surfaceDirty = true;
if(d->surface){
d->surface.data()->d->items.insert(this);
}
}
QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *UpdatePaintNodeData){
Q_UNUSED(UpdatePaintNodeData);
QRectF r = boundingRect();
QSGNode* newNode = 0;
if(d->surfaceDirty){
delete oldNode;
oldNode = 0;
d->surfaceDirty = false;
}
if(!d->surface || d->surface.data()->d->videosink == NULL ){
if(!oldNode){
QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
material->setColor(Qt::black);
QSGGeometryNode *node = new QSGGeometryNode;
node->setMaterial(material);
node->setFlag(QSGNode::OwnsMaterial);
node->setFlag(QSGNode::OwnsGeometry);
newNode = node;
d->targetArea = QRectF();
}else{
newNode = oldNode;
}
if( r != d->targetArea ){
QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
geometry->vertexDataAsPoint2D()[0].set(r.x(),r.y());
geometry->vertexDataAsPoint2D()[1].set(r.x(), r.height());
geometry->vertexDataAsPoint2D()[2].set(r.width(), r.y());
geometry->vertexDataAsPoint2D()[3].set(r.width(), r.height());
QSGGeometryNode *node = static_cast<QSGGeometryNode*>(newNode);
node->setGeometry(geometry);
d->targetArea = r;
}
} else {
g_signal_emit_by_name(d->surface.data()->d->videosink,"update-node", (void *)oldNode, r.x(), r.y(), r.width(), r.height(), (void**)&newNode);
}
return newNode;
}

@ -0,0 +1,26 @@
#include "videosurface.h"
VideoSurface::VideoSurface(QObject *parent): QObject(parent), d(new VideoSurfacePrivate){
}
VideoSurface:: ~VideoSurface(){
delete d;
}
void VideoSurface::onUpdate(){
Q_FOREACH(QQuickItem *item, d->items){
item->update();
}
}
void VideoSurface::onUpdateThunk(GstElement *sink, gpointer data){
Q_UNUSED(sink);
VideoSurface *pThis = (VideoSurface *)data;
pThis->onUpdate();
}
GstElement *VideoSurface::videoSink(){
d->videosink = gst_element_factory_make("qtquick2videosink", NULL);
g_signal_connect(d->videosink,"update",G_CALLBACK(onUpdateThunk),(void *)this);
return d->videosink;
}

@ -0,0 +1,25 @@
#ifndef VIDEOSURFACE_H
#define VIDEOSURFACE_H
#include <QSet>
#include <gst/gst.h>
#include <QtCore/QObject>
#include <QtQuick/QQuickItem>
#include <QtCore/QPointer>
#include <QtQuick/QSGNode>
#include <QtQuick/QSGFlatColorMaterial>
#include "videosurfaceprivate.h"
class VideoSurface: public QObject{
Q_OBJECT
Q_DISABLE_COPY(VideoSurface)
public:
explicit VideoSurface(QObject *parent = 0);
virtual ~VideoSurface();
GstElement *videoSink();
void onUpdate();
static void onUpdateThunk(GstElement* sink, gpointer data);
VideoSurfacePrivate *const d;
};
#endif // VIDEOSURFACE_H

@ -0,0 +1,17 @@
#ifndef VIDEOSURFACEPRIVATE_H
#define VIDEOSURFACEPRIVATE_H
#include <QSet>
#include <gst/gst.h>
#include "videosurface.h"
#include "VideoItem.h"
class VideoItem;
class VideoSurfacePrivate {
public:
VideoSurfacePrivate(): videosink(NULL){}
QSet<VideoItem *> items;
GstElement* videosink;
};
#endif // VIDEOSURFACEPRIVATE_H
Loading…
Cancel
Save