Commit caaa8542 authored by Val Doroshchuk's avatar Val Doroshchuk

mediaobject 2 mediaplayer

parent f0b82df4
TARGET = QtGstreamerExtras TARGET = QtGstreamerExtras
QT = multimediagsttools-private QT = multimediagsttools_private
PUBLIC_HEADERS += \ PUBLIC_HEADERS += \
qgstreamerpipeline.h \ qgstreamerpipeline.h \
qgstreamerplaybin.h qgstreamerplaybin.h
PRIVATE_HEADERS += \ PRIVATE_HEADERS += \
qgstreamerpipeline_p.h qgstreamerpipeline_p.h
SOURCES += \ SOURCES += \
qgstreamerplaybin.cpp \ qgstreamerplaybin.cpp \
......
...@@ -49,15 +49,26 @@ void QGstreamerPipelinePrivate::updateMediaObject() ...@@ -49,15 +49,26 @@ void QGstreamerPipelinePrivate::updateMediaObject()
{ {
Q_Q(QGstreamerPipeline); Q_Q(QGstreamerPipeline);
QMediaObject *obj = qobject_cast<QMediaObject*>(source->property("mediaObject").value<QObject*>()); QMediaPlayer *obj = qobject_cast<QMediaPlayer*>(source->property("mediaObject").value<QObject*>());
q->setMediaObject(obj);
q->setMediaPlayer(obj);
}
QGstreamerPipeline::QGstreamerPipeline(QObject *parent)
: QGstreamerPipeline(new QGstreamerPipelinePrivate(this), nullptr, parent)
{
}
QGstreamerPipeline::QGstreamerPipeline(QMediaPlayer *player, QObject *parent)
: QGstreamerPipeline(new QGstreamerPipelinePrivate(this), player, parent)
{
} }
QGstreamerPipeline::QGstreamerPipeline(QGstreamerPipelinePrivate *d, QMediaObject *media, QObject *parent) QGstreamerPipeline::QGstreamerPipeline(QGstreamerPipelinePrivate *d, QMediaPlayer *player, QObject *parent)
: QObject(parent) : QObject(parent)
, d_ptr(d) , d_ptr(d)
{ {
setMediaObject(media); setMediaPlayer(player);
} }
QGstreamerPipeline::~QGstreamerPipeline() QGstreamerPipeline::~QGstreamerPipeline()
...@@ -82,14 +93,12 @@ void QGstreamerPipeline::setSource(QObject *src) ...@@ -82,14 +93,12 @@ void QGstreamerPipeline::setSource(QObject *src)
d->source = src; d->source = src;
if (d->source) { if (d->source) {
const QMetaObject *metaObject = d->source->metaObject(); const auto *metaObject = d->source->metaObject();
int propId = metaObject->indexOfProperty("mediaObject");
int mediaObjectPropertyIndex = metaObject->indexOfProperty("mediaObject"); if (propId != -1) {
if (mediaObjectPropertyIndex != -1) { const auto prop = metaObject->property(propId);
const QMetaProperty mediaObjectProperty = metaObject->property(mediaObjectPropertyIndex); if (prop.hasNotifySignal()) {
QMetaMethod method = prop.notifySignal();
if (mediaObjectProperty.hasNotifySignal()) {
QMetaMethod method = mediaObjectProperty.notifySignal();
QMetaObject::connect(d->source.data(), method.methodIndex(), QMetaObject::connect(d->source.data(), method.methodIndex(),
d, d->metaObject()->indexOfSlot("updateMediaObject()"), d, d->metaObject()->indexOfSlot("updateMediaObject()"),
Qt::DirectConnection, 0); Qt::DirectConnection, 0);
...@@ -101,12 +110,12 @@ void QGstreamerPipeline::setSource(QObject *src) ...@@ -101,12 +110,12 @@ void QGstreamerPipeline::setSource(QObject *src)
emit sourceChanged(); emit sourceChanged();
} }
QMediaObject *QGstreamerPipeline::mediaObject() const QMediaPlayer *QGstreamerPipeline::mediaPlayer() const
{ {
return d_func()->mediaObject.data(); return d_func()->mediaPlayer.data();
} }
void QGstreamerPipeline::setMediaObject(QMediaObject *src) void QGstreamerPipeline::setMediaPlayer(QMediaPlayer *src)
{ {
Q_D(QGstreamerPipeline); Q_D(QGstreamerPipeline);
...@@ -116,9 +125,29 @@ void QGstreamerPipeline::setMediaObject(QMediaObject *src) ...@@ -116,9 +125,29 @@ void QGstreamerPipeline::setMediaObject(QMediaObject *src)
auto control = qobject_cast<QGstreamerPlayerControl *>(service->requestControl(QMediaPlayerControl_iid)); auto control = qobject_cast<QGstreamerPlayerControl *>(service->requestControl(QMediaPlayerControl_iid));
d->session = control ? control->session() : nullptr; d->session = control ? control->session() : nullptr;
d->mediaObject = src; if (!d->session)
return;
emit mediaObjectChanged(); connect(d->session, &QGstreamerPlayerSession::pipelineChanged, this, &QGstreamerPipeline::pipelineChanged);
d->mediaPlayer = src;
emit mediaPlayerChanged();
}
QString QGstreamerPipeline::pipeline() const
{
return d_func()->pipeline;
}
void QGstreamerPipeline::setPipeline(const QString &desc)
{
Q_D(QGstreamerPipeline);
d->pipeline = desc;
if (d->mediaPlayer) {
QString pl = QLatin1String("gst-pipeline:") + desc;
d->mediaPlayer->setMedia(QMediaContent(pl));
}
} }
template <class T> template <class T>
......
...@@ -46,32 +46,39 @@ ...@@ -46,32 +46,39 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QMediaObject; class QMediaPlayer;
class QGstreamerPipelinePrivate; class QGstreamerPipelinePrivate;
class Q_MULTIMEDIA_EXPORT QGstreamerPipeline : public QObject class Q_MULTIMEDIA_EXPORT QGstreamerPipeline : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QObject* source READ source WRITE setSource NOTIFY sourceChanged) Q_PROPERTY(QObject* source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(QMediaObject* mediaObject READ mediaObject NOTIFY mediaObjectChanged SCRIPTABLE false DESIGNABLE false) Q_PROPERTY(QMediaPlayer* mediaPlayer READ mediaPlayer NOTIFY mediaPlayerChanged SCRIPTABLE false DESIGNABLE false)
Q_PROPERTY(QString pipeline READ pipeline WRITE setPipeline NOTIFY pipelineChanged)
public: public:
QGstreamerPipeline(QObject *parent = nullptr);
QGstreamerPipeline(QMediaPlayer *player, QObject *parent = nullptr);
~QGstreamerPipeline(); ~QGstreamerPipeline();
QObject *source() const; QObject *source() const;
void setSource(QObject *source); void setSource(QObject *source);
QMediaObject *mediaObject() const; QMediaPlayer *mediaPlayer() const;
void setMediaObject(QMediaObject *source); void setMediaPlayer(QMediaPlayer *source);
QString pipeline() const;
void setPipeline(const QString &desc);
Q_INVOKABLE bool set(const QString &elementName, const QVariantMap& map); Q_INVOKABLE bool set(const QString &elementName, const QVariantMap& map);
Q_SIGNALS: Q_SIGNALS:
void sourceChanged(); void sourceChanged();
void mediaObjectChanged(); void mediaPlayerChanged();
void pipelineChanged();
protected: protected:
QGstreamerPipeline(QGstreamerPipelinePrivate *d, QGstreamerPipeline(QGstreamerPipelinePrivate *d,
QMediaObject *player = nullptr, QObject *parent = nullptr); QMediaPlayer *player = nullptr, QObject *parent = nullptr);
QGstreamerPipelinePrivate *d_ptr = nullptr; QGstreamerPipelinePrivate *d_ptr = nullptr;
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QMediaObject; class QMediaPlayer;
class QGstreamerPlayerSession; class QGstreamerPlayerSession;
class QGstreamerPipeline; class QGstreamerPipeline;
class QGstreamerPipelinePrivate : public QObject class QGstreamerPipelinePrivate : public QObject
...@@ -72,8 +72,9 @@ public Q_SLOTS: ...@@ -72,8 +72,9 @@ public Q_SLOTS:
protected: protected:
QPointer<QObject> source; QPointer<QObject> source;
QPointer<QMediaObject> mediaObject; QPointer<QMediaPlayer> mediaPlayer;
QGstreamerPlayerSession *session = nullptr; QGstreamerPlayerSession *session = nullptr;
QString pipeline;
QGstreamerPipeline *q_ptr = nullptr; QGstreamerPipeline *q_ptr = nullptr;
}; };
......
...@@ -70,7 +70,7 @@ public: ...@@ -70,7 +70,7 @@ public:
public Q_SLOTS: public Q_SLOTS:
void streamsChanged(); void streamsChanged();
void updatePipeline(); void updatePipeline();
void mediaObjectChanged(); void mediaPlayerChanged();
protected: protected:
QString videoSinkDesc; QString videoSinkDesc;
...@@ -96,7 +96,7 @@ protected: ...@@ -96,7 +96,7 @@ protected:
QList<QVariantMap> textStreamProperties; QList<QVariantMap> textStreamProperties;
}; };
void QGstreamerPlaybinPrivate::mediaObjectChanged() void QGstreamerPlaybinPrivate::mediaPlayerChanged()
{ {
Q_Q(QGstreamerPlaybin); Q_Q(QGstreamerPlaybin);
...@@ -239,15 +239,15 @@ void QGstreamerPlaybinPrivate::streamsChanged() ...@@ -239,15 +239,15 @@ void QGstreamerPlaybinPrivate::streamsChanged()
emit q->textStreamPropertiesChanged(); emit q->textStreamPropertiesChanged();
} }
QGstreamerPlaybin::QGstreamerPlaybin(QMediaObject *media, QObject *parent) QGstreamerPlaybin::QGstreamerPlaybin(QMediaPlayer *media, QObject *parent)
: QGstreamerPipeline(new QGstreamerPlaybinPrivate(this), media, parent) : QGstreamerPipeline(new QGstreamerPlaybinPrivate(this), media, parent)
{ {
Q_D(QGstreamerPlaybin); Q_D(QGstreamerPlaybin);
connect(this, &QGstreamerPipeline::mediaObjectChanged, connect(this, &QGstreamerPipeline::mediaPlayerChanged,
d, &QGstreamerPlaybinPrivate::mediaObjectChanged); d, &QGstreamerPlaybinPrivate::mediaPlayerChanged);
d->mediaObjectChanged(); d->mediaPlayerChanged();
} }
QGstreamerPlaybin::QGstreamerPlaybin(QObject *parent) QGstreamerPlaybin::QGstreamerPlaybin(QObject *parent)
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QMediaObject; class QMediaPlayer;
class QGstreamerPlaybinPrivate; class QGstreamerPlaybinPrivate;
class Q_MULTIMEDIA_EXPORT QGstreamerPlaybin : public QGstreamerPipeline class Q_MULTIMEDIA_EXPORT QGstreamerPlaybin : public QGstreamerPipeline
{ {
...@@ -63,7 +63,7 @@ class Q_MULTIMEDIA_EXPORT QGstreamerPlaybin : public QGstreamerPipeline ...@@ -63,7 +63,7 @@ class Q_MULTIMEDIA_EXPORT QGstreamerPlaybin : public QGstreamerPipeline
Q_PROPERTY(int textStream READ textStream WRITE setTextStream NOTIFY textStreamChanged) Q_PROPERTY(int textStream READ textStream WRITE setTextStream NOTIFY textStreamChanged)
public: public:
QGstreamerPlaybin(QMediaObject *player, QObject *parent = nullptr); QGstreamerPlaybin(QMediaPlayer *player, QObject *parent = nullptr);
QGstreamerPlaybin(QObject *parent = nullptr); QGstreamerPlaybin(QObject *parent = nullptr);
~QGstreamerPlaybin(); ~QGstreamerPlaybin();
......
...@@ -58,6 +58,7 @@ public: ...@@ -58,6 +58,7 @@ public:
{ {
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtGstreamerExtras")); Q_ASSERT(QLatin1String(uri) == QLatin1String("QtGstreamerExtras"));
qmlRegisterType<QGstreamerPipeline>(uri, 5, 12, "Pipeline");
qmlRegisterType<QGstreamerPlaybin>(uri, 5, 12, "Playbin"); qmlRegisterType<QGstreamerPlaybin>(uri, 5, 12, "Playbin");
qmlRegisterType<QTransparentRectangle>(uri, 5, 12, "TransparentRectangle"); qmlRegisterType<QTransparentRectangle>(uri, 5, 12, "TransparentRectangle");
} }
......
TEMPLATE = subdirs TEMPLATE = subdirs
SUBDIRS += \ SUBDIRS += \
qml \ qml \
qgstreamerpipeline \
qgstreamerplaybin qgstreamerplaybin
CONFIG += testcase
TARGET = tst_qgstreamerpipeline
QT += network gstreamerextras-private multimedia-private testlib
SOURCES += tst_qgstreamerpipeline.cpp
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QMediaPlayer>
#include <QGstreamerPipeline>
#include <QAbstractVideoSurface>
QT_USE_NAMESPACE
class tst_QGstreamerPipeline: public QObject
{
Q_OBJECT
private slots:
void testMediaPlayer();
void testPipeline();
void testSetProperty();
private:
QMediaPlayer *mediaPlayer = nullptr;
QGstreamerPipeline *control = nullptr;
};
void tst_QGstreamerPipeline::testMediaPlayer()
{
QMediaPlayer mediaPlayer;
QGstreamerPipeline p(&mediaPlayer);
QVERIFY(!p.source());
QCOMPARE(p.mediaPlayer(), &mediaPlayer);
}
void tst_QGstreamerPipeline::testPipeline()
{
QMediaPlayer mediaPlayer;
QGstreamerPipeline p(&mediaPlayer);
QSignalSpy spy(&p, &QGstreamerPipeline::pipelineChanged);
QString pl = "videotestsrc ! autovideosink";
p.setPipeline(pl);
QTRY_COMPARE(spy.count(), 1);
QCOMPARE(mediaPlayer.error(), QMediaPlayer::NoError);
QCOMPARE(p.pipeline(), pl);
}
void tst_QGstreamerPipeline::testSetProperty()
{
QMediaPlayer mediaPlayer;
QGstreamerPipeline p(&mediaPlayer);
p.setPipeline(QLatin1String("videotestsrc name=src ! autovideosink"));
QVariantMap m;
m["name"] = "new_name";
QVERIFY(p.set("src", m));
QCOMPARE(mediaPlayer.error(), QMediaPlayer::NoError);
}
QTEST_GUILESS_MAIN(tst_QGstreamerPipeline)
#include "tst_qgstreamerpipeline.moc"
...@@ -53,7 +53,6 @@ private slots: ...@@ -53,7 +53,6 @@ private slots:
void testSetTextStream(); void testSetTextStream();
void testTextStreamProperties(); void testTextStreamProperties();
void testTextUriStreamProperties(); void testTextUriStreamProperties();
void testSetProperty();
private: private:
QMediaPlayer *mediaPlayer = nullptr; QMediaPlayer *mediaPlayer = nullptr;
...@@ -212,12 +211,5 @@ void tst_QGstreamerPlaybin::testTextUriStreamProperties() ...@@ -212,12 +211,5 @@ void tst_QGstreamerPlaybin::testTextUriStreamProperties()
QCOMPARE(control->textStreamProperties(2)["Language"], QVariant("no")); QCOMPARE(control->textStreamProperties(2)["Language"], QVariant("no"));
} }
void tst_QGstreamerPlaybin::testSetProperty()
{
QVariantMap m;
m["name"] = "new_name";
QVERIFY(control->set("source", m));
}
QTEST_GUILESS_MAIN(tst_QGstreamerPlaybin) QTEST_GUILESS_MAIN(tst_QGstreamerPlaybin)
#include "tst_qgstreamerplaybin.moc" #include "tst_qgstreamerplaybin.moc"
TEMPLATE = app
TARGET = tst_pipeline
CONFIG += qmltestcase
SOURCES += tst_qml.cpp
importFiles.files = pipeline
importFiles.path = .
DEPLOYMENT += importFiles
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
import QtMultimedia 5.0
import QtGstreamerExtras 5.12
import QtTest 1.0
Item {
id: top
VideoOutput {
id: video
source: player
}
MediaPlayer {
id: player
autoPlay: false
loops: Audio.Infinite
}
Pipeline {
id: control
source: player
}
SignalSpy {
id: spySource
target: control
signalName: "sourceChanged"
}
SignalSpy {
id: spyMediaPlayer
target: control
signalName: "mediaPlayerChanged"
}
SignalSpy {
id: spyPipeline
target: control
signalName: "pipelineChanged"
}
TestCase {
name: "GstreamerPipelineControl"
function initTestCase() {
compare(control.source, player);
compare(spySource.count, 1);
compare(spyMediaPlayer.count, 1);
}
function test_pipeline() {
var pp = "videotestsrc ! autovideosink";
control.pipeline = pp;
compare(spyPipeline.count, 1);
compare(control.pipeline, pp);
}
function test_setProp() {
control.pipeline = "videotestsrc name=src ! autovideosink";
compare(spyPipeline.count, 2);
control.set("src", {"num-buffers": 1});
compare(player.error, MediaPlayer.NoError);
}
}
}
TEMPLATE = app
TARGET = tst_playbin
CONFIG += qmltestcase
SOURCES += tst_qml.cpp
importFiles.files = playbin
importFiles.path = .
DEPLOYMENT += importFiles
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtQuickTest/quicktest.h>
QUICK_TEST_MAIN(qml)
TEMPLATE=app TEMPLATE = subdirs
TARGET=tst_qml SUBDIRS += \
CONFIG += qmltestcase pipeline \
SOURCES += tst_qml.cpp playbin
importFiles.files = player
importFiles.path = .
DEPLOYMENT += importFiles
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment