summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmytro Poplavskiy <dmytro.poplavskiy@nokia.com>2011-08-02 14:33:38 +1000
committerQt by Nokia <qt-info@nokia.com>2011-08-05 07:50:59 +0200
commite70ebfd2ed8d522478f04ab823b527b48ed24671 (patch)
treeaa52d70121ab80a07ff5036aba3be30be8aba758 /src
parent6eac3bd6488f8d8b368d97bdb8d701b804310be6 (diff)
Gstreamer media backend cleanup.
Moved controls specific bus/sync messages handling from player/camera/capture session to corresponding controls. Reviewed-by: Michael Goddard Change-Id: Ieb67976ed335b0ef1cde87dc60e8ad8da3409526 Reviewed-on: http://codereview.qt.nokia.com/2535 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp8
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinimagecapture.h6
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinservice.cpp7
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.cpp27
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.h9
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp7
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp37
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h10
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp59
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h10
-rw-r--r--src/plugins/gstreamer/qgstreamerbushelper.cpp66
-rw-r--r--src/plugins/gstreamer/qgstreamerbushelper.h18
-rw-r--r--src/plugins/gstreamer/qgstreamergltexturerenderer.cpp29
-rw-r--r--src/plugins/gstreamer/qgstreamergltexturerenderer.h13
-rw-r--r--src/plugins/gstreamer/qgstreamervideorenderer.h1
-rw-r--r--src/plugins/gstreamer/qgstreamervideorendererinterface.h5
-rw-r--r--src/plugins/gstreamer/qgstreamervideowidget.cpp32
-rw-r--r--src/plugins/gstreamer/qgstreamervideowidget.h8
-rw-r--r--src/plugins/gstreamer/qgstreamervideowindow.cpp13
-rw-r--r--src/plugins/gstreamer/qgstreamervideowindow.h9
20 files changed, 210 insertions, 164 deletions
diff --git a/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp b/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
index 910c6c2ce..f27cd7f35 100644
--- a/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
@@ -82,8 +82,8 @@ CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session)
connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateState()));
connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int)));
connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage)));
- connect(m_session, SIGNAL(busMessage(QGstreamerMessage)), SLOT(handleBusMessage(QGstreamerMessage)));
+ m_session->bus()->installMessageFilter(this);
g_signal_connect(G_OBJECT(m_session->cameraBin()), IMAGE_DONE_SIGNAL, G_CALLBACK(handleImageSaved), this);
}
@@ -281,7 +281,7 @@ gboolean CameraBinImageCapture::jpegBufferProbe(GstPad *pad, GstBuffer *buffer,
return destination & QCameraImageCapture::CaptureToFile;
}
-void CameraBinImageCapture::handleBusMessage(const QGstreamerMessage &message)
+bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
{
//Install metadata event and buffer probes
@@ -298,7 +298,7 @@ void CameraBinImageCapture::handleBusMessage(const QGstreamerMessage &message)
if (newState == GST_STATE_READY) {
GstElement *element = GST_ELEMENT(GST_MESSAGE_SRC(gm));
if (!element)
- return;
+ return false;
QString elementName = QString::fromLatin1(gst_element_get_name(element));
if (elementName.contains("jpegenc") && element != m_jpegEncoderElement) {
@@ -339,4 +339,6 @@ void CameraBinImageCapture::handleBusMessage(const QGstreamerMessage &message)
}
}
}
+
+ return false;
}
diff --git a/src/plugins/gstreamer/camerabin/camerabinimagecapture.h b/src/plugins/gstreamer/camerabin/camerabinimagecapture.h
index 6cc910dbe..ddb04e1ea 100644
--- a/src/plugins/gstreamer/camerabin/camerabinimagecapture.h
+++ b/src/plugins/gstreamer/camerabin/camerabinimagecapture.h
@@ -48,9 +48,10 @@
QT_USE_NAMESPACE
-class CameraBinImageCapture : public QCameraImageCaptureControl
+class CameraBinImageCapture : public QCameraImageCaptureControl, public QGstreamerBusMessageFilter
{
Q_OBJECT
+ Q_INTERFACES(QGstreamerBusMessageFilter)
public:
CameraBinImageCapture(CameraBinSession *session);
virtual ~CameraBinImageCapture();
@@ -62,9 +63,10 @@ public:
int capture(const QString &fileName);
void cancelCapture();
+ bool processBusMessage(const QGstreamerMessage &message);
+
private slots:
void updateState();
- void handleBusMessage(const QGstreamerMessage &message);
private:
static gboolean metadataEventProbe(GstPad *pad, GstEvent *event, CameraBinImageCapture *);
diff --git a/src/plugins/gstreamer/camerabin/camerabinservice.cpp b/src/plugins/gstreamer/camerabin/camerabinservice.cpp
index 75d820bfd..93bcc6993 100644
--- a/src/plugins/gstreamer/camerabin/camerabinservice.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinservice.cpp
@@ -160,17 +160,16 @@ QMediaControl *CameraBinService::requestControl(const char *name)
if (!m_videoOutput) {
if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
m_videoOutput = m_videoRenderer;
- m_captureSession->setViewfinder(m_videoRenderer);
} else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
m_videoOutput = m_videoWindow;
- m_captureSession->setViewfinder(m_videoWindow);
} else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
- m_captureSession->setViewfinder(m_videoWidgetControl);
m_videoOutput = m_videoWidgetControl;
}
- if (m_videoOutput)
+ if (m_videoOutput) {
+ m_captureSession->setViewfinder(m_videoOutput);
return m_videoOutput;
+ }
}
if (qstrcmp(name,QAudioEndpointSelector_iid) == 0)
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
index d1552c0af..fbcc85266 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
@@ -145,8 +145,8 @@ CameraBinSession::CameraBinSession(QObject *parent)
m_bus = gst_element_get_bus(m_pipeline);
m_busHelper = new QGstreamerBusHelper(m_bus, this);
- m_busHelper->installSyncEventFilter(this);
- connect(m_busHelper, SIGNAL(message(QGstreamerMessage)), SLOT(handleBusMessage(QGstreamerMessage)));
+ m_busHelper->installMessageFilter(this);
+
m_audioEncodeControl = new CameraBinAudioEncoder(this);
m_videoEncodeControl = new CameraBinVideoEncoder(this);
m_imageEncodeControl = new CameraBinImageEncoder(this);
@@ -534,6 +534,8 @@ void CameraBinSession::setViewfinder(QObject *viewfinder)
this, SLOT(handleViewfinderChange()));
disconnect(m_viewfinder, SIGNAL(readyChanged(bool)),
this, SIGNAL(readyChanged(bool)));
+
+ m_busHelper->removeMessageFilter(m_viewfinder);
}
m_viewfinder = viewfinder;
@@ -544,6 +546,8 @@ void CameraBinSession::setViewfinder(QObject *viewfinder)
this, SLOT(handleViewfinderChange()));
connect(m_viewfinder, SIGNAL(readyChanged(bool)),
this, SIGNAL(readyChanged(bool)));
+
+ m_busHelper->installMessageFilter(m_viewfinder);
}
emit viewfinderChanged();
@@ -795,24 +799,14 @@ bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message)
}
}
- if (gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
- if (m_viewfinderInterface)
- m_viewfinderInterface->precessNewStream();
-
- return true;
- }
-
if (gst_structure_has_name(gm->structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE))
m_cameraFocusControl->handleFocusMessage(gm);
-
- if (m_viewfinderInterface && GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_viewfinderElement))
- m_viewfinderInterface->handleSyncMessage(gm);
}
return false;
}
-void CameraBinSession::handleBusMessage(const QGstreamerMessage &message)
+bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
{
GstMessage* gm = message.rawMessage();
@@ -911,12 +905,9 @@ void CameraBinSession::handleBusMessage(const QGstreamerMessage &message)
}
//qDebug() << "New session state:" << ENUM_NAME(CameraBinSession,"State",m_state);
}
-
- if (m_viewfinderInterface && GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_viewfinderElement))
- m_viewfinderInterface->handleBusMessage(gm);
-
- emit busMessage(message);
}
+
+ return false;
}
void CameraBinSession::recordVideo()
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h
index 5504bb505..cc646cbfd 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.h
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.h
@@ -76,10 +76,13 @@ public:
virtual GstElement *buildElement() = 0;
};
-class CameraBinSession : public QObject, public QGstreamerSyncEventFilter
+class CameraBinSession : public QObject,
+ public QGstreamerBusMessageFilter,
+ public QGstreamerSyncMessageFilter
{
Q_OBJECT
Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
+ Q_INTERFACES(QGstreamerBusMessageFilter QGstreamerSyncMessageFilter)
public:
enum CameraRole {
FrontCamera, // Secondary camera
@@ -91,6 +94,7 @@ public:
GstPhotography *photography();
GstElement *cameraBin() { return m_pipeline; }
+ QGstreamerBusHelper *bus() { return m_busHelper; }
CameraRole cameraRole() const;
@@ -146,6 +150,7 @@ public:
bool isMuted() const;
bool processSyncMessage(const QGstreamerMessage &message);
+ bool processBusMessage(const QGstreamerMessage &message);
signals:
void stateChanged(QCamera::State state);
@@ -157,7 +162,6 @@ signals:
void viewfinderChanged();
void readyChanged(bool);
void busyChanged(bool);
- void busMessage(const QGstreamerMessage &message);
public slots:
void setDevice(const QString &device);
@@ -167,7 +171,6 @@ public slots:
void setMuted(bool);
private slots:
- void handleBusMessage(const QGstreamerMessage &message);
void handleViewfinderChange();
private:
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
index eb4338b3f..d063b0e13 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
@@ -160,17 +160,16 @@ QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
if (!m_videoOutput) {
if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
m_videoOutput = m_videoRenderer;
- m_captureSession->setVideoPreview(m_videoRenderer);
} else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
m_videoOutput = m_videoWindow;
- m_captureSession->setVideoPreview(m_videoWindow);
} else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
- m_captureSession->setVideoPreview(m_videoWidgetControl);
m_videoOutput = m_videoWidgetControl;
}
- if (m_videoOutput)
+ if (m_videoOutput) {
+ m_captureSession->setVideoPreview(m_videoOutput);
return m_videoOutput;
+ }
}
return 0;
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
index b092af281..b685f5466 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
@@ -96,8 +96,8 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap
m_bus = gst_element_get_bus(m_pipeline);
m_busHelper = new QGstreamerBusHelper(m_bus, this);
- m_busHelper->installSyncEventFilter(this);
- connect(m_busHelper, SIGNAL(message(QGstreamerMessage)), SLOT(busMessage(QGstreamerMessage)));
+ m_busHelper->installMessageFilter(this);
+
m_audioEncodeControl = new QGstreamerAudioEncode(this);
m_videoEncodeControl = new QGstreamerVideoEncode(this);
m_imageEncodeControl = new QGstreamerImageEncode(this);
@@ -735,6 +735,8 @@ void QGstreamerCaptureSession::setVideoPreview(QObject *viewfinder)
this, SIGNAL(viewfinderChanged()));
disconnect(m_viewfinder, SIGNAL(readyChanged(bool)),
this, SIGNAL(readyChanged(bool)));
+
+ m_busHelper->removeMessageFilter(m_viewfinder);
}
m_viewfinder = viewfinder;
@@ -745,6 +747,8 @@ void QGstreamerCaptureSession::setVideoPreview(QObject *viewfinder)
this, SIGNAL(viewfinderChanged()));
connect(m_viewfinder, SIGNAL(readyChanged(bool)),
this, SIGNAL(readyChanged(bool)));
+
+ m_busHelper->installMessageFilter(m_viewfinder);
}
emit viewfinderChanged();
@@ -917,29 +921,7 @@ void QGstreamerCaptureSession::setMetaData(const QMap<QByteArray, QVariant> &dat
}
}
-bool QGstreamerCaptureSession::processSyncMessage(const QGstreamerMessage &message)
-{
- GstMessage* gm = message.rawMessage();
-
- if (gm && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) {
- if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoPreview))
- m_viewfinderInterface->handleSyncMessage(gm);
-
- if (gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
- if (m_audioPreviewFactory)
- m_audioPreviewFactory->prepareWinId();
-
- if (m_viewfinderInterface)
- m_viewfinderInterface->precessNewStream();
-
- return true;
- }
- }
-
- return false;
-}
-
-void QGstreamerCaptureSession::busMessage(const QGstreamerMessage &message)
+bool QGstreamerCaptureSession::processBusMessage(const QGstreamerMessage &message)
{
GstMessage* gm = message.rawMessage();
@@ -1027,11 +1009,8 @@ void QGstreamerCaptureSession::busMessage(const QGstreamerMessage &message)
}
//qDebug() << "New session state:" << ENUM_NAME(QGstreamerCaptureSession,"State",m_state);
}
-
- if (m_videoPreview && m_viewfinderInterface &&
- GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoPreview))
- m_viewfinderInterface->handleBusMessage(gm);
}
+ return false;
}
void QGstreamerCaptureSession::setMuted(bool muted)
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
index 63d1b0bf6..e4c734600 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
@@ -76,12 +76,13 @@ public:
virtual QList<QSize> supportedResolutions(qreal frameRate = -1) const = 0;
};
-class QGstreamerCaptureSession : public QObject, public QGstreamerSyncEventFilter
+class QGstreamerCaptureSession : public QObject, public QGstreamerBusMessageFilter
{
Q_OBJECT
Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
Q_ENUMS(State)
Q_ENUMS(CaptureMode)
+ Q_INTERFACES(QGstreamerBusMessageFilter)
public:
enum CaptureMode { Audio = 1, Video = 2, Image=4, AudioAndVideo = Audio | Video };
enum State { StoppedState, PreviewState, PausedState, RecordingState };
@@ -89,6 +90,8 @@ public:
QGstreamerCaptureSession(CaptureMode captureMode, QObject *parent);
~QGstreamerCaptureSession();
+ QGstreamerBusHelper *bus() { return m_busHelper; }
+
CaptureMode captureMode() const { return m_captureMode; }
void setCaptureMode(CaptureMode);
@@ -122,7 +125,7 @@ public:
bool isReady() const;
- bool processSyncMessage(const QGstreamerMessage &message);
+ bool processBusMessage(const QGstreamerMessage &message);
signals:
void stateChanged(QGstreamerCaptureSession::State state);
@@ -144,9 +147,6 @@ public slots:
void setMetaData(const QMap<QByteArray, QVariant>&);
void setMuted(bool);
-private slots:
- void busMessage(const QGstreamerMessage &message);
-
private:
enum PipelineMode { EmptyPipeline, PreviewPipeline, RecordingPipeline, PreviewAndRecordingPipeline };
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
index 7cb5a661b..9e4e8bc69 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
@@ -155,8 +155,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
// Sort out messages
m_bus = gst_element_get_bus(m_playbin);
m_busHelper = new QGstreamerBusHelper(m_bus, this);
- connect(m_busHelper, SIGNAL(message(QGstreamerMessage)), SLOT(busMessage(QGstreamerMessage)));
- m_busHelper->installSyncEventFilter(this);
+ m_busHelper->installMessageFilter(this);
g_object_set(G_OBJECT(m_playbin), "video-sink", m_videoOutputBin, NULL);
@@ -188,6 +187,11 @@ QGstreamerPlayerSession::~QGstreamerPlayerSession()
}
}
+GstElement *QGstreamerPlayerSession::playbin() const
+{
+ return m_playbin;
+}
+
#if defined(HAVE_GST_APPSRC)
void QGstreamerPlayerSession::configureAppSrcElement(GObject* object, GObject *orig, GParamSpec *pspec, QGstreamerPlayerSession* self)
{
@@ -444,16 +448,20 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
this, SLOT(updateVideoRenderer()));
disconnect(m_videoOutput, SIGNAL(readyChanged(bool)),
this, SLOT(updateVideoRenderer()));
+
+ m_busHelper->removeMessageFilter(m_videoOutput);
}
- if (videoOutput) {
- connect(videoOutput, SIGNAL(sinkChanged()),
+ m_videoOutput = videoOutput;
+
+ if (m_videoOutput) {
+ connect(m_videoOutput, SIGNAL(sinkChanged()),
this, SLOT(updateVideoRenderer()));
- connect(videoOutput, SIGNAL(readyChanged(bool)),
+ connect(m_videoOutput, SIGNAL(readyChanged(bool)),
this, SLOT(updateVideoRenderer()));
- }
- m_videoOutput = videoOutput;
+ m_busHelper->installMessageFilter(m_videoOutput);
+ }
}
QGstreamerVideoRendererInterface* renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput);
@@ -877,29 +885,9 @@ void QGstreamerPlayerSession::setSeekable(bool seekable)
}
}
-bool QGstreamerPlayerSession::processSyncMessage(const QGstreamerMessage &message)
+bool QGstreamerPlayerSession::processBusMessage(const QGstreamerMessage &message)
{
GstMessage* gm = message.rawMessage();
-
- if (gm && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) {
- if (m_renderer) {
- if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink))
- m_renderer->handleSyncMessage(gm);
-
- if (gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
- m_renderer->precessNewStream();
- return true;
- }
- }
- }
-
- return false;
-}
-
-void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message)
-{
- GstMessage* gm = message.rawMessage();
-
if (gm) {
//tag message comes from elements inside playbin, not from playbin itself
if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_TAG) {
@@ -1111,19 +1099,6 @@ void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message)
default:
break;
}
- } else if (m_videoSink
- && m_renderer
- && GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink)) {
-
- m_renderer->handleBusMessage(gm);
- if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED) {
- GstState oldState;
- GstState newState;
- gst_message_parse_state_changed(gm, &oldState, &newState, 0);
-
- if (oldState == GST_STATE_READY && newState == GST_STATE_PAUSED)
- m_renderer->precessNewStream();
- }
} else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) {
GError *err;
gchar *debug;
@@ -1196,6 +1171,8 @@ void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message)
}
}
}
+
+ return false;
}
void QGstreamerPlayerSession::getStreamsInfo()
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
index be32f5f79..297754b93 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
@@ -62,14 +62,19 @@ class QGstreamerVideoRendererInterface;
QT_USE_NAMESPACE
-class QGstreamerPlayerSession : public QObject, public QGstreamerSyncEventFilter
+class QGstreamerPlayerSession : public QObject,
+ public QGstreamerBusMessageFilter
{
Q_OBJECT
+Q_INTERFACES(QGstreamerBusMessageFilter)
public:
QGstreamerPlayerSession(QObject *parent);
virtual ~QGstreamerPlayerSession();
+ GstElement *playbin() const;
+ QGstreamerBusHelper *bus() const { return m_busHelper; }
+
QNetworkRequest request() const;
QMediaPlayer::State state() const { return m_state; }
@@ -105,7 +110,7 @@ public:
int activeStream(QMediaStreamsControl::StreamType streamType) const;
void setActiveStream(QMediaStreamsControl::StreamType streamType, int streamNumber);
- bool processSyncMessage(const QGstreamerMessage &message);
+ bool processBusMessage(const QGstreamerMessage &message);
#if defined(HAVE_GST_APPSRC)
QGstAppSrc *appsrc() const { return m_appSrc; }
@@ -145,7 +150,6 @@ signals:
void playbackRateChanged(qreal);
private slots:
- void busMessage(const QGstreamerMessage &message);
void getStreamsInfo();
void setSeekable(bool);
void finishVideoOutputChange();
diff --git a/src/plugins/gstreamer/qgstreamerbushelper.cpp b/src/plugins/gstreamer/qgstreamerbushelper.cpp
index 76cc83ada..92f2ee8b7 100644
--- a/src/plugins/gstreamer/qgstreamerbushelper.cpp
+++ b/src/plugins/gstreamer/qgstreamerbushelper.cpp
@@ -39,9 +39,10 @@
**
****************************************************************************/
-#include <QMap>
-#include <QTimer>
-#include <QMutex>
+#include <QtCore/qmap.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qlist.h>
#include "qgstreamerbushelper.h"
@@ -57,7 +58,6 @@ public:
setParent(helper);
m_tag = gst_bus_add_watch_full(bus, 0, busCallback, this, NULL);
m_helper = helper;
- filter = 0;
}
void removeWatch(QGstreamerBusHelper* helper)
@@ -75,7 +75,12 @@ private:
void processMessage(GstBus* bus, GstMessage* message)
{
Q_UNUSED(bus);
- emit m_helper->message(message);
+ QGstreamerMessage msg(message);
+ foreach (QGstreamerBusMessageFilter *filter, busFilters) {
+ if (filter->processBusMessage(msg))
+ break;
+ }
+ emit m_helper->message(msg);
}
static gboolean busCallback(GstBus *bus, GstMessage *message, gpointer data)
@@ -89,8 +94,9 @@ private:
public:
GstBus* bus;
- QGstreamerSyncEventFilter *filter;
QMutex filterMutex;
+ QList<QGstreamerSyncMessageFilter*> syncFilters;
+ QList<QGstreamerBusMessageFilter*> busFilters;
};
#else
@@ -131,7 +137,13 @@ private slots:
GstMessage* message;
while ((message = gst_bus_poll(it.value(), GST_MESSAGE_ANY, 0)) != 0) {
- emit it.key()->message(message);
+ QGstreamerMessage msg(message);
+ foreach (QGstreamerBusMessageFilter *filter, busFilters) {
+ if (filter->processBusMessage(msg))
+ break;
+ }
+ emit it.key()->message(msg);
+
gst_message_unref(message);
}
@@ -153,8 +165,9 @@ private:
public:
GstBus* bus;
- QGstreamerSyncEventFilter *filter;
QMutex filterMutex;
+ QList<QGstreamerSyncMessageFilter*> syncFilters;
+ QList<QGstreamerBusMessageFilter*> busFilters;
};
#endif
@@ -164,12 +177,12 @@ static GstBusSyncReply syncGstBusFilter(GstBus* bus, GstMessage* message, QGstre
Q_UNUSED(bus);
QMutexLocker lock(&d->filterMutex);
- bool res = false;
-
- if (d->filter)
- res = d->filter->processSyncMessage(QGstreamerMessage(message));
+ foreach (QGstreamerSyncMessageFilter *filter, d->syncFilters) {
+ if (filter->processSyncMessage(QGstreamerMessage(message)))
+ return GST_BUS_DROP;
+ }
- return res ? GST_BUS_DROP : GST_BUS_PASS;
+ return GST_BUS_PASS;
}
@@ -194,10 +207,31 @@ QGstreamerBusHelper::~QGstreamerBusHelper()
gst_bus_set_sync_handler(d->bus,0,0);
}
-void QGstreamerBusHelper::installSyncEventFilter(QGstreamerSyncEventFilter *filter)
+void QGstreamerBusHelper::installMessageFilter(QObject *filter)
{
- QMutexLocker lock(&d->filterMutex);
- d->filter = filter;
+ QGstreamerSyncMessageFilter *syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
+ if (syncFilter) {
+ QMutexLocker lock(&d->filterMutex);
+ if (!d->syncFilters.contains(syncFilter))
+ d->syncFilters.append(syncFilter);
+ }
+
+ QGstreamerBusMessageFilter *busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
+ if (busFilter && !d->busFilters.contains(busFilter))
+ d->busFilters.append(busFilter);
+}
+
+void QGstreamerBusHelper::removeMessageFilter(QObject *filter)
+{
+ QGstreamerSyncMessageFilter *syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
+ if (syncFilter) {
+ QMutexLocker lock(&d->filterMutex);
+ d->syncFilters.removeAll(syncFilter);
+ }
+
+ QGstreamerBusMessageFilter *busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
+ if (busFilter)
+ d->busFilters.removeAll(busFilter);
}
#include "qgstreamerbushelper.moc"
diff --git a/src/plugins/gstreamer/qgstreamerbushelper.h b/src/plugins/gstreamer/qgstreamerbushelper.h
index cfe6a6b1c..d09192a42 100644
--- a/src/plugins/gstreamer/qgstreamerbushelper.h
+++ b/src/plugins/gstreamer/qgstreamerbushelper.h
@@ -47,11 +47,23 @@
#include <qgstreamermessage.h>
#include <gst/gst.h>
-class QGstreamerSyncEventFilter {
+class QGstreamerSyncMessageFilter {
public:
//returns true if message was processed and should be dropped, false otherwise
virtual bool processSyncMessage(const QGstreamerMessage &message) = 0;
};
+#define QGstreamerSyncMessageFilter_iid "com.nokia.Qt.QGstreamerSyncMessageFilter/1.0"
+Q_DECLARE_INTERFACE(QGstreamerSyncMessageFilter, QGstreamerSyncMessageFilter_iid)
+
+
+class QGstreamerBusMessageFilter {
+public:
+ //returns true if message was processed and should be dropped, false otherwise
+ virtual bool processBusMessage(const QGstreamerMessage &message) = 0;
+};
+#define QGstreamerBusMessageFilter_iid "com.nokia.Qt.QGstreamerBusMessageFilter/1.0"
+Q_DECLARE_INTERFACE(QGstreamerBusMessageFilter, QGstreamerBusMessageFilter_iid)
+
class QGstreamerBusHelperPrivate;
@@ -64,12 +76,12 @@ public:
QGstreamerBusHelper(GstBus* bus, QObject* parent = 0);
~QGstreamerBusHelper();
- void installSyncEventFilter(QGstreamerSyncEventFilter *filter);
+ void installMessageFilter(QObject *filter);
+ void removeMessageFilter(QObject *filter);
signals:
void message(QGstreamerMessage const& message);
-
private:
QGstreamerBusHelperPrivate* d;
};
diff --git a/src/plugins/gstreamer/qgstreamergltexturerenderer.cpp b/src/plugins/gstreamer/qgstreamergltexturerenderer.cpp
index 2f5919f83..af68096bd 100644
--- a/src/plugins/gstreamer/qgstreamergltexturerenderer.cpp
+++ b/src/plugins/gstreamer/qgstreamergltexturerenderer.cpp
@@ -364,13 +364,16 @@ bool QGstreamerGLTextureRenderer::isReady() const
return m_surface->supportedPixelFormats(EGLImageTextureHandle).isEmpty();
}
-void QGstreamerGLTextureRenderer::handleBusMessage(GstMessage* gm)
+bool QGstreamerGLTextureRenderer::processBusMessage(const QGstreamerMessage &message)
{
+ GstMessage* gm = message.rawMessage();
+
#ifdef GL_TEXTURE_SINK_DEBUG
qDebug() << Q_FUNC_INFO << GST_MESSAGE_TYPE_NAME(gm);
#endif
- if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED) {
+ if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED &&
+ GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink)) {
GstState oldState;
GstState newState;
gst_message_parse_state_changed(gm, &oldState, &newState, 0);
@@ -387,22 +390,20 @@ void QGstreamerGLTextureRenderer::handleBusMessage(GstMessage* gm)
updateNativeVideoSize();
}
}
+
+ return false;
}
-void QGstreamerGLTextureRenderer::handleSyncMessage(GstMessage* gm)
+bool QGstreamerGLTextureRenderer::processSyncMessage(const QGstreamerMessage &message)
{
+ GstMessage* gm = message.rawMessage();
+
+ if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
+ gst_structure_has_name(gm->structure, "prepare-xwindow-id") &&
+ m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
#ifdef GL_TEXTURE_SINK_DEBUG
qDebug() << Q_FUNC_INFO;
#endif
-
- if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT &&
- gst_structure_has_name(gm->structure, "prepare-xwindow-id"))
- precessNewStream();
-}
-
-void QGstreamerGLTextureRenderer::precessNewStream()
-{
- if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
GstXOverlay *overlay = GST_X_OVERLAY(m_videoSink);
gst_x_overlay_set_xwindow_id(overlay, m_winId);
@@ -417,7 +418,11 @@ void QGstreamerGLTextureRenderer::precessNewStream()
GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this);
+
+ return true;
}
+
+ return false;
}
void QGstreamerGLTextureRenderer::stopRenderer()
diff --git a/src/plugins/gstreamer/qgstreamergltexturerenderer.h b/src/plugins/gstreamer/qgstreamergltexturerenderer.h
index 330fb4630..7a1bc65df 100644
--- a/src/plugins/gstreamer/qgstreamergltexturerenderer.h
+++ b/src/plugins/gstreamer/qgstreamergltexturerenderer.h
@@ -44,6 +44,7 @@
#include <qvideorenderercontrol.h>
#include "qvideosurfacegstsink.h"
+#include "qgstreamerbushelper.h"
#include "qgstreamervideorendererinterface.h"
#include <QtGui/qcolor.h>
@@ -54,10 +55,13 @@ QT_USE_NAMESPACE
class QGLContext;
-class QGstreamerGLTextureRenderer : public QVideoRendererControl, public QGstreamerVideoRendererInterface
+class QGstreamerGLTextureRenderer : public QVideoRendererControl,
+ public QGstreamerVideoRendererInterface,
+ public QGstreamerSyncMessageFilter,
+ public QGstreamerBusMessageFilter
{
Q_OBJECT
- Q_INTERFACES(QGstreamerVideoRendererInterface)
+ Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter QGstreamerBusMessageFilter)
Q_PROPERTY(bool overlayEnabled READ overlayEnabled WRITE setOverlayEnabled)
Q_PROPERTY(qulonglong winId READ winId WRITE setWinId)
@@ -75,9 +79,8 @@ public:
GstElement *videoSink();
bool isReady() const;
- void handleBusMessage(GstMessage* gm);
- void handleSyncMessage(GstMessage* gm);
- void precessNewStream();
+ bool processBusMessage(const QGstreamerMessage &message);
+ bool processSyncMessage(const QGstreamerMessage &message);
void stopRenderer();
int framebufferNumber() const;
diff --git a/src/plugins/gstreamer/qgstreamervideorenderer.h b/src/plugins/gstreamer/qgstreamervideorenderer.h
index 298ad9448..4fb8dda35 100644
--- a/src/plugins/gstreamer/qgstreamervideorenderer.h
+++ b/src/plugins/gstreamer/qgstreamervideorenderer.h
@@ -61,7 +61,6 @@ public:
void setSurface(QAbstractVideoSurface *surface);
GstElement *videoSink();
- void precessNewStream() {}
bool isReady() const { return m_surface != 0; }
diff --git a/src/plugins/gstreamer/qgstreamervideorendererinterface.h b/src/plugins/gstreamer/qgstreamervideorendererinterface.h
index 600f0dfe5..da5107e07 100644
--- a/src/plugins/gstreamer/qgstreamervideorendererinterface.h
+++ b/src/plugins/gstreamer/qgstreamervideorendererinterface.h
@@ -51,7 +51,6 @@ class QGstreamerVideoRendererInterface
public:
virtual ~QGstreamerVideoRendererInterface();
virtual GstElement *videoSink() = 0;
- virtual void precessNewStream() {}
//stopRenderer() is called when the renderer element is stopped.
//it can be reimplemented when video renderer can't detect
@@ -62,10 +61,6 @@ public:
//(winId is known,
virtual bool isReady() const { return true; }
- //video renderer may handle video sink specific gstreamer messages.
- virtual void handleBusMessage(GstMessage*) {};
- virtual void handleSyncMessage(GstMessage*) {};
-
//signals:
//void sinkChanged();
//void readyChanged(bool);
diff --git a/src/plugins/gstreamer/qgstreamervideowidget.cpp b/src/plugins/gstreamer/qgstreamervideowidget.cpp
index 2f92e990a..e1bf0037d 100644
--- a/src/plugins/gstreamer/qgstreamervideowidget.cpp
+++ b/src/plugins/gstreamer/qgstreamervideowidget.cpp
@@ -179,10 +179,36 @@ bool QGstreamerVideoWidgetControl::eventFilter(QObject *object, QEvent *e)
return false;
}
-void QGstreamerVideoWidgetControl::precessNewStream()
+bool QGstreamerVideoWidgetControl::processSyncMessage(const QGstreamerMessage &message)
{
- setOverlay();
- QMetaObject::invokeMethod(this, "updateNativeVideoSize", Qt::QueuedConnection);
+ GstMessage* gm = message.rawMessage();
+
+ if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
+ gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
+
+ setOverlay();
+ QMetaObject::invokeMethod(this, "updateNativeVideoSize", Qt::QueuedConnection);
+ return true;
+ }
+
+ return false;
+}
+
+bool QGstreamerVideoWidgetControl::processBusMessage(const QGstreamerMessage &message)
+{
+ GstMessage* gm = message.rawMessage();
+
+ if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED &&
+ GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink)) {
+ GstState oldState;
+ GstState newState;
+ gst_message_parse_state_changed(gm, &oldState, &newState, 0);
+
+ if (oldState == GST_STATE_READY && newState == GST_STATE_PAUSED)
+ updateNativeVideoSize();
+ }
+
+ return false;
}
void QGstreamerVideoWidgetControl::setOverlay()
diff --git a/src/plugins/gstreamer/qgstreamervideowidget.h b/src/plugins/gstreamer/qgstreamervideowidget.h
index 0f0adea0d..8f3d62316 100644
--- a/src/plugins/gstreamer/qgstreamervideowidget.h
+++ b/src/plugins/gstreamer/qgstreamervideowidget.h
@@ -45,6 +45,7 @@
#include <qvideowidgetcontrol.h>
#include "qgstreamervideorendererinterface.h"
+#include "qgstreamerbushelper.h"
QT_USE_NAMESPACE
@@ -53,15 +54,16 @@ class QGstreamerVideoWidget;
class QGstreamerVideoWidgetControl
: public QVideoWidgetControl
, public QGstreamerVideoRendererInterface
+ , public QGstreamerSyncMessageFilter
+ , public QGstreamerBusMessageFilter
{
Q_OBJECT
- Q_INTERFACES(QGstreamerVideoRendererInterface)
+ Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter QGstreamerBusMessageFilter)
public:
QGstreamerVideoWidgetControl(QObject *parent = 0);
virtual ~QGstreamerVideoWidgetControl();
GstElement *videoSink();
- void precessNewStream();
QWidget *videoWidget();
@@ -86,6 +88,8 @@ public:
void setOverlay();
bool eventFilter(QObject *object, QEvent *event);
+ bool processSyncMessage(const QGstreamerMessage &message);
+ bool processBusMessage(const QGstreamerMessage &message);
public slots:
void updateNativeVideoSize();
diff --git a/src/plugins/gstreamer/qgstreamervideowindow.cpp b/src/plugins/gstreamer/qgstreamervideowindow.cpp
index 0f92d76a9..d8d822269 100644
--- a/src/plugins/gstreamer/qgstreamervideowindow.cpp
+++ b/src/plugins/gstreamer/qgstreamervideowindow.cpp
@@ -115,14 +115,23 @@ void QGstreamerVideoWindow::setWinId(WId id)
emit readyChanged(false);
}
-void QGstreamerVideoWindow::precessNewStream()
+bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message)
{
- if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+ GstMessage* gm = message.rawMessage();
+
+ if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
+ gst_structure_has_name(gm->structure, "prepare-xwindow-id") &&
+ m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId);
GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this);
+
+ return true;
}
+
+ return false;
}
QRect QGstreamerVideoWindow::displayRect() const
diff --git a/src/plugins/gstreamer/qgstreamervideowindow.h b/src/plugins/gstreamer/qgstreamervideowindow.h
index acc22cdca..3a483e2c1 100644
--- a/src/plugins/gstreamer/qgstreamervideowindow.h
+++ b/src/plugins/gstreamer/qgstreamervideowindow.h
@@ -45,6 +45,7 @@
#include <qvideowindowcontrol.h>
#include "qgstreamervideorendererinterface.h"
+#include "qgstreamerbushelper.h"
QT_BEGIN_NAMESPACE
class QAbstractVideoSurface;
@@ -55,10 +56,12 @@ class QX11VideoSurface;
QT_USE_NAMESPACE
-class QGstreamerVideoWindow : public QVideoWindowControl, public QGstreamerVideoRendererInterface
+class QGstreamerVideoWindow : public QVideoWindowControl,
+ public QGstreamerVideoRendererInterface,
+ public QGstreamerSyncMessageFilter
{
Q_OBJECT
- Q_INTERFACES(QGstreamerVideoRendererInterface)
+ Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter)
Q_PROPERTY(QColor colorKey READ colorKey WRITE setColorKey)
Q_PROPERTY(bool autopaintColorKey READ autopaintColorKey WRITE setAutopaintColorKey)
public:
@@ -103,7 +106,7 @@ public:
GstElement *videoSink();
- void precessNewStream();
+ bool processSyncMessage(const QGstreamerMessage &message);
bool isReady() const { return m_windowId != 0; }
signals: