Commit 24638fbb authored by Val Doroshchuk's avatar Val Doroshchuk

Reverted to GstreamerMediaPlayer

parent 4d56161c
......@@ -2,18 +2,9 @@ TARGET = QtGstreamerExtras
QT += multimediagsttools-private
CONFIG += simd optimize_full
PUBLIC_HEADERS += \
qgstreamerpipeline.h \
qgstreamerplaybin.h
include(playback/playback.pri)
PRIVATE_HEADERS += \
qgstreamerpipeline_p.h
SOURCES += \
qgstreamerpipeline.cpp \
qgstreamerplaybin.cpp
CONFIG += simd optimize_full
HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
......
INCLUDEPATH += playback
PUBLIC_HEADERS += \
playback/qgstreamermediaplayer.h
SOURCES += \
playback/qgstreamermediaplayer.cpp
......@@ -37,8 +37,8 @@
**
****************************************************************************/
#include "qgstreamerplaybin.h"
#include "qgstreamerpipeline_p.h"
#include "qgstreamermediaplayer.h"
#include <private/qgstreamervideorenderer_p.h>
#include <private/qgstreamerplayercontrol_p.h>
#include <private/qgstreamerplayersession_p.h>
#include <private/qgstvideorenderersink_p.h>
......@@ -60,23 +60,36 @@ typedef enum {
GST_PLAY_FLAG_BUFFERING = 0x000000100
} GstPlayFlags;
class QGstreamerPlaybinPrivate : public QGstreamerPipelinePrivate
class QGstreamerMediaPlayerPrivate : public QObject
{
Q_DECLARE_PUBLIC(QGstreamerPlaybin)
public Q_SLOTS:
Q_DECLARE_PUBLIC(QGstreamerMediaPlayer)
QGstreamerPlaybinPrivate(QGstreamerPipeline *parent)
: QGstreamerPipelinePrivate(parent)
public:
QGstreamerMediaPlayerPrivate(QGstreamerMediaPlayer *q, QObject *parent)
: QObject(parent)
, q_ptr(q)
{
}
void mediaObjectChanged();
void streamsChanged();
void updatePipeline();
public Q_SLOTS:
void updateMediaObject();
void streamsChanged();
protected:
QPointer<QObject> source;
QPointer<QMediaObject> mediaObject;
QGstreamerVideoRenderer *renderer = nullptr;
QGstreamerPlayerSession *session = nullptr;
GstElement *playbin = nullptr;
QString pipelineDesc;
QString pendingPipelineDesc;
//GstElement *pipeline = nullptr;
QString videoSinkDesc;
QString pendingVideoSinkDesc;
bool showText = false;
bool pendingShowText = showText;
QUrl textUri;
......@@ -95,51 +108,16 @@ protected:
int pendingTextStream = -1;
int textStream = -1;
QList<QVariantMap> textStreamProperties;
QGstreamerMediaPlayer *q_ptr = nullptr;
};
void QGstreamerPlaybinPrivate::mediaObjectChanged()
void QGstreamerMediaPlayerPrivate::updateMediaObject()
{
Q_Q(QGstreamerPlaybin);
auto service = q->mediaObject() ? q->mediaObject()->service() : nullptr;
if (!service)
return;
auto control = qobject_cast<QGstreamerPlayerControl *>(service->requestControl(QMediaPlayerControl_iid));
session = control ? control->session() : nullptr;
if (!session)
return;
playbin = session->playbin();
Q_Q(QGstreamerMediaPlayer);
connect(session, &QGstreamerPlayerSession::streamsChanged,
this, &QGstreamerPlaybinPrivate::streamsChanged);
connect(session, &QGstreamerPlayerSession::rendererChanged,
[this](QGstreamerVideoRendererInterface *r) {
renderer = static_cast<QGstreamerVideoRenderer *>(r);
updatePipeline();
});
connect(q, &QGstreamerPipeline::pipelineChanged,
[this]() {
if (!pipeline || !session)
return;
gst_object_ref(GST_OBJECT(pipeline));
session->setPipeline(pipeline);
playbin = nullptr;
});
// In case if these values've been applied
// before mediaObject is available.
q->setShowText(pendingShowText);
q->setTextUri(pendingTextUri);
q->setTextFont(pendingTextFont);
q->setAudioStream(pendingAudioStream);
q->setVideoStream(pendingVideoStream);
q->setTextStream(pendingTextStream);
QMediaObject *obj = qobject_cast<QMediaObject*>(source->property("mediaObject").value<QObject*>());
q->setMediaObject(obj);
}
static QVariantMap getStreamProperties(GstElement *pipeline, const char *name, int i)
......@@ -164,9 +142,9 @@ static QVariantMap getStreamProperties(GstElement *pipeline, const char *name, i
return streamProperties;
}
void QGstreamerPlaybinPrivate::streamsChanged()
void QGstreamerMediaPlayerPrivate::streamsChanged()
{
Q_Q(QGstreamerPlaybin);
Q_Q(QGstreamerMediaPlayer);
if (!playbin)
return;
......@@ -226,29 +204,171 @@ void QGstreamerPlaybinPrivate::streamsChanged()
emit q->textStreamPropertiesChanged();
}
QGstreamerPlaybin::QGstreamerPlaybin(QMediaObject *media, QObject *parent)
: QGstreamerPlaybin(parent)
static GstElement *parseDesc(const QString &name)
{
GError *error = NULL;
GstElement *element = gst_parse_launch(name.toLatin1().constData(), &error);
if (error) {
g_printerr("ERROR: %s: %s\n", name.toLatin1().constData(), GST_STR_NULL(error->message));
g_clear_error(&error);
}
return element;
}
void QGstreamerMediaPlayerPrivate::updatePipeline()
{
Q_Q(QGstreamerMediaPlayer);
if (!renderer || !renderer->isReady())
return;
if (!pendingPipelineDesc.isEmpty()) {
QGstVideoRendererSink::setSurface(renderer->surface());
GstElement *pipeline = parseDesc(pendingPipelineDesc);
if (pipeline) {
pipelineDesc = pendingPipelineDesc;
pendingPipelineDesc.clear();
session->setPipeline(pipeline);
emit q->pipelineChanged();
}
}
}
QGstreamerMediaPlayer::QGstreamerMediaPlayer(QMediaObject *media, QObject *parent)
: QGstreamerMediaPlayer(parent)
{
setMediaObject(media);
}
QGstreamerPlaybin::QGstreamerPlaybin(QObject *parent)
: QGstreamerPipeline(new QGstreamerPlaybinPrivate(this), parent)
QGstreamerMediaPlayer::QGstreamerMediaPlayer(QObject *parent)
: QObject(parent)
, d_ptr(new QGstreamerMediaPlayerPrivate(this, parent))
{
}
QObject *QGstreamerMediaPlayer::source() const
{
return d_func()->source.data();
}
void QGstreamerMediaPlayer::setSource(QObject *src)
{
Q_D(QGstreamerMediaPlayer);
if (d->source == src)
return;
if (d->source)
disconnect(d->source.data(), 0, d, SLOT(updateMediaObject()));
d->source = src;
if (d->source) {
const QMetaObject *metaObject = d->source->metaObject();
int mediaObjectPropertyIndex = metaObject->indexOfProperty("mediaObject");
if (mediaObjectPropertyIndex != -1) {
const QMetaProperty mediaObjectProperty = metaObject->property(mediaObjectPropertyIndex);
if (mediaObjectProperty.hasNotifySignal()) {
QMetaMethod method = mediaObjectProperty.notifySignal();
QMetaObject::connect(d->source.data(), method.methodIndex(),
d, d->metaObject()->indexOfSlot("updateMediaObject()"),
Qt::DirectConnection, 0);
}
}
}
d->updateMediaObject();
emit sourceChanged();
}
QMediaObject *QGstreamerMediaPlayer::mediaObject() const
{
Q_D(QGstreamerPlaybin);
return d_func()->mediaObject.data();
}
void QGstreamerMediaPlayer::setMediaObject(QMediaObject *src)
{
Q_D(QGstreamerMediaPlayer);
auto service = src ? src->service() : nullptr;
if (!service)
return;
auto control = qobject_cast<QGstreamerPlayerControl *>(service->requestControl(QMediaPlayerControl_iid));
d->session = control ? control->session() : nullptr;
if (!d->session)
return;
connect(this, &QGstreamerPipeline::mediaObjectChanged,
d, &QGstreamerPlaybinPrivate::mediaObjectChanged);
d->playbin = d->session->playbin();
connect(d->session, &QGstreamerPlayerSession::streamsChanged,
d, &QGstreamerMediaPlayerPrivate::streamsChanged);
connect(d->session, &QGstreamerPlayerSession::rendererChanged,
[d](QGstreamerVideoRendererInterface *r) {
d->renderer = static_cast<QGstreamerVideoRenderer *>(r);
d->updatePipeline();
});
// In case if these values've been applied
// before mediaObject is available.
setVideoSink(d->pendingVideoSinkDesc);
setShowText(d->pendingShowText);
setTextUri(d->pendingTextUri);
setTextFont(d->pendingTextFont);
setAudioStream(d->pendingAudioStream);
setVideoStream(d->pendingVideoStream);
setTextStream(d->pendingTextStream);
}
bool QGstreamerPlaybin::showText() const
QString QGstreamerMediaPlayer::pipeline() const
{
return d_func()->pipelineDesc;
}
void QGstreamerMediaPlayer::setPipeline(const QString &desc)
{
Q_D(QGstreamerMediaPlayer);
d->pendingPipelineDesc = desc;
if (d->pipelineDesc == desc)
return;
d->updatePipeline();
}
QString QGstreamerMediaPlayer::videoSink() const
{
return d_func()->videoSinkDesc;
}
void QGstreamerMediaPlayer::setVideoSink(const QString &desc)
{
Q_D(QGstreamerMediaPlayer);
d->pendingVideoSinkDesc = desc;
if (!d->playbin || d->videoSinkDesc == desc)
return;
GstElement *videoSink = parseDesc(desc);
if (videoSink) {
d->videoSinkDesc = desc;
d->session->setVideoSink(videoSink);
emit videoSinkChanged();
}
}
bool QGstreamerMediaPlayer::showText() const
{
return d_func()->showText;
}
void QGstreamerPlaybin::setShowText(bool show)
void QGstreamerMediaPlayer::setShowText(bool show)
{
Q_D(QGstreamerPlaybin);
Q_D(QGstreamerMediaPlayer);
d->pendingShowText = show;
if (!d->playbin || d->showText == show)
......@@ -267,14 +387,14 @@ void QGstreamerPlaybin::setShowText(bool show)
emit showTextChanged();
}
QUrl QGstreamerPlaybin::textUri() const
QUrl QGstreamerMediaPlayer::textUri() const
{
return d_func()->textUri;
}
void QGstreamerPlaybin::setTextUri(const QUrl &uri)
void QGstreamerMediaPlayer::setTextUri(const QUrl &uri)
{
Q_D(QGstreamerPlaybin);
Q_D(QGstreamerMediaPlayer);
d->pendingTextUri = uri;
if (!d->playbin || d->textUri == uri)
......@@ -287,14 +407,14 @@ void QGstreamerPlaybin::setTextUri(const QUrl &uri)
emit textUriChanged();
}
QString QGstreamerPlaybin::textFont() const
QString QGstreamerMediaPlayer::textFont() const
{
return d_func()->textFont;
}
void QGstreamerPlaybin::setTextFont(const QString &str)
void QGstreamerMediaPlayer::setTextFont(const QString &str)
{
Q_D(QGstreamerPlaybin);
Q_D(QGstreamerMediaPlayer);
d->pendingTextFont = str;
if (!d->playbin || d->textFont == str)
......@@ -305,19 +425,19 @@ void QGstreamerPlaybin::setTextFont(const QString &str)
emit textFontChanged();
}
int QGstreamerPlaybin::audioStreamsCount() const
int QGstreamerMediaPlayer::audioStreamsCount() const
{
return d_func()->audioStreamsCount;
}
int QGstreamerPlaybin::audioStream() const
int QGstreamerMediaPlayer::audioStream() const
{
return d_func()->audioStream;
}
void QGstreamerPlaybin::setAudioStream(int i)
void QGstreamerMediaPlayer::setAudioStream(int i)
{
Q_D(QGstreamerPlaybin);
Q_D(QGstreamerMediaPlayer);
d->pendingAudioStream = i;
if (!d->playbin || d->audioStream == i)
......@@ -328,24 +448,24 @@ void QGstreamerPlaybin::setAudioStream(int i)
emit audioStreamChanged();
}
QVariantMap QGstreamerPlaybin::audioStreamProperties(int i)
QVariantMap QGstreamerMediaPlayer::audioStreamProperties(int i)
{
return d_func()->audioStreamProperties[i];
}
int QGstreamerPlaybin::videoStreamsCount() const
int QGstreamerMediaPlayer::videoStreamsCount() const
{
return d_func()->videoStreamsCount;
}
int QGstreamerPlaybin::videoStream() const
int QGstreamerMediaPlayer::videoStream() const
{
return d_func()->videoStream;
}
void QGstreamerPlaybin::setVideoStream(int i)
void QGstreamerMediaPlayer::setVideoStream(int i)
{
Q_D(QGstreamerPlaybin);
Q_D(QGstreamerMediaPlayer);
d->pendingVideoStream = i;
if (!d->playbin || d->videoStream == i)
......@@ -356,24 +476,24 @@ void QGstreamerPlaybin::setVideoStream(int i)
emit videoStreamChanged();
}
QVariantMap QGstreamerPlaybin::videoStreamProperties(int i)
QVariantMap QGstreamerMediaPlayer::videoStreamProperties(int i)
{
return d_func()->videoStreamProperties[i];
}
int QGstreamerPlaybin::textStreamsCount() const
int QGstreamerMediaPlayer::textStreamsCount() const
{
return d_func()->textStreamsCount;
}
int QGstreamerPlaybin::textStream() const
int QGstreamerMediaPlayer::textStream() const
{
return d_func()->textStream;
}
void QGstreamerPlaybin::setTextStream(int i)
void QGstreamerMediaPlayer::setTextStream(int i)
{
Q_D(QGstreamerPlaybin);
Q_D(QGstreamerMediaPlayer);
d->pendingTextStream = i;
if (!d->playbin || d->textStream == i)
......@@ -384,11 +504,68 @@ void QGstreamerPlaybin::setTextStream(int i)
emit textStreamChanged();
}
QVariantMap QGstreamerPlaybin::textStreamProperties(int i)
QVariantMap QGstreamerMediaPlayer::textStreamProperties(int i)
{
return d_func()->textStreamProperties[i];
}
#include "moc_qgstreamerplaybin.cpp"
template <class T>
static void setGstProperty(GstElement *element, const QString &name, T v)
{
g_object_set(G_OBJECT(element), name.toLatin1().constData(), v, NULL);
}
void QGstreamerMediaPlayer::set(const QString &elementName, const QVariantMap& map)
{
Q_D(QGstreamerMediaPlayer);
GstElement *element = nullptr;
if (elementName == QLatin1String("videoSink"))
element = d->session ? d->session->videoSink() : nullptr;
else if (d->playbin)
element = gst_bin_get_by_name(GST_BIN(d->playbin), elementName.toLatin1().constData());
if (!element) {
qWarning() << "Could not find element by name:" << elementName;
if (d->playbin) {
qWarning() << "Available elements:";
qDebug() << " " << "videoSink";
GstIterator *children = gst_bin_iterate_recurse(GST_BIN(d->playbin));
gst_iterator_foreach(children, [](const GValue *item, gpointer) {
GstElement *element = GST_ELEMENT(g_value_get_object(item));
qDebug() << " " << GST_ELEMENT_NAME(element);
}, nullptr);
gst_iterator_free(children);
} else {
qWarning() << "No pipeline available";
}
return;
}
for (auto it = map.begin(); it != map.end(); ++it) {
QString name = it.key();
QVariant value = it.value();
switch (value.type()) {
case QMetaType::Int:
setGstProperty(element, name, value.toInt());
break;
case QMetaType::Bool:
setGstProperty(element, name, value.toBool());
break;
case QMetaType::Double:
setGstProperty(element, name, value.toDouble());
break;
case QMetaType::QString:
setGstProperty(element, name, value.toString().toUtf8().constData());
break;
default:
break;
}
}
}
#include "moc_qgstreamermediaplayer.cpp"
QT_END_NAMESPACE
......@@ -37,18 +37,25 @@
**
****************************************************************************/
#ifndef QGSTREAMERPLAYBIN_H
#define QGSTREAMERPLAYBIN_H
#ifndef QGSTREAMERMEDIAPLAYER_H
#define QGSTREAMERMEDIAPLAYER_H
#include "qgstreamerpipeline.h"
#include <QObject>
#include <QVariantMap>
#include <QtMultimedia/qtmultimediaglobal.h>
#include <QUrl>
QT_BEGIN_NAMESPACE
class QGstreamerPlaybinPrivate;
class Q_MULTIMEDIA_EXPORT QGstreamerPlaybin : public QGstreamerPipeline
class QMediaObject;
class QGstreamerMediaPlayerPrivate;
class Q_MULTIMEDIA_EXPORT QGstreamerMediaPlayer : public QObject
{
Q_OBJECT
Q_PROPERTY(QObject* source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(QMediaObject* mediaObject READ mediaObject NOTIFY mediaObjectChanged SCRIPTABLE false DESIGNABLE false)
Q_PROPERTY(QString pipeline READ pipeline WRITE setPipeline NOTIFY pipelineChanged)
Q_PROPERTY(QString videoSink READ videoSink WRITE setVideoSink NOTIFY videoSinkChanged)
Q_PROPERTY(bool showText READ showText WRITE setShowText NOTIFY showTextChanged)
Q_PROPERTY(QUrl textUri READ textUri WRITE setTextUri NOTIFY textUriChanged)
Q_PROPERTY(QString textFont READ textFont WRITE setTextFont NOTIFY textFontChanged)
......@@ -60,8 +67,20 @@ class Q_MULTIMEDIA_EXPORT QGstreamerPlaybin : public QGstreamerPipeline
Q_PROPERTY(int textStream READ textStream WRITE setTextStream NOTIFY textStreamChanged)
public:
QGstreamerPlaybin(QMediaObject *player, QObject *parent = nullptr);
QGstreamerPlaybin(QObject *parent = nullptr);
QGstreamerMediaPlayer(QMediaObject *player, QObject *parent = nullptr);
QGstreamerMediaPlayer(QObject *parent = nullptr);
QObject *source() const;
void setSource(QObject *source);
QMediaObject *mediaObject() const;
void setMediaObject(QMediaObject *source);
QString pipeline() const;
void setPipeline(const QString &name);
QString videoSink() const;
void setVideoSink(const QString &name);
bool showText() const;
void setShowText(bool show);
......@@ -87,7 +106,13 @@ public:
void setTextStream(int i);
Q_INVOKABLE QVariantMap textStreamProperties(int i);
Q_INVOKABLE void set(const QString &elementName, const QVariantMap& map);
Q_SIGNALS:
void sourceChanged();
void mediaObjectChanged();
void pipelineChanged();
void videoSinkChanged();
void showTextChanged();
void textUriChanged();
void textFontChanged();
......@@ -105,10 +130,12 @@ Q_SIGNALS:
void textStreamPropertiesChanged();
private:
Q_DISABLE_COPY(QGstreamerPlaybin)
Q_DECLARE_PRIVATE(QGstreamerPlaybin)
Q_DISABLE_COPY(QGstreamerMediaPlayer)
Q_DECLARE_PRIVATE(QGstreamerMediaPlayer)
QGstreamerMediaPlayerPrivate *d_ptr = nullptr;
};
QT_END_NAMESPACE